ClassNotFoundException: how to find dependency conflict in Java

江枫思渺然 提交于 2019-12-06 08:46:14

I was finally able to solve the dependency conflict by doing the following.

To find the jar file which is used by application I used the below simple code:

public void listJarFilesAndClassVersions() {    
    Class classToCheck = javax.servlet.ServletRequestWrapper.class;
    URL location = classToCheck.getResource('/'
        + classToCheck.getName().replace('.', '/') + ".class");

    System.out.println(location.toString());

    for(Package p : Package.getPackages()) {
        if (p.getName().startsWith("javax.servlet")) {
            System.out.println("Class: " + p.getName()
                + ", version: " + p.getSpecificationVersion());
        }
    }
}

The class javax.servlet.ServletRequestWrapper was chosen because it does exist in the old Servlet 2.5.

The execution of the above script gives me the following:

jar:file:/C:/Users/[username]/.m2/repository/org/apache/tomcat/servlet-api/6.0.29/servlet-api-6.0.29.jar!/javax/servlet/ServletRequestWrapper.class
Class: javax.servlet.jsp, version: 2.1
Class: javax.servlet, version: 2.5
Class: javax.servlet.http, version: null

So, first, it confirms that the Servlet of version 2.5 is used, and second, the "bad" jar is located in the maven repository under the tomcat directory.

After a short reasearch I was finally able to find the root cause of that: when deploying and running the maven application I need to specify the concrete version of tomcat, otherwise maven uses the libraries from tomcat of version 6. So the fix for me was to change

mvn -Dmaven.tomcat.port=8080 tomcat:run-war

to

mvn -Dmaven.tomcat.port=8080 tomcat7:run-war

Now if I execute the above script it gives the following result:

jar:file:/C:/Users/[username]/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/7.0.47/tomcat-embed-core-7.0.47.jar!/javax/servlet/ServletRequestWrapper.class
Class: javax.servlet.jsp, version: 2.2
Class: javax.servlet, version: 7.0
Class: javax.servlet.http, version: 7.0
Class: javax.servlet.annotation, version: 7.0
Class: javax.servlet.descriptor, version: 7.0

Hope it helps others who is running into the same issue.

There're two ways in which I usually find a conflict.

  1. If you are using Eclipse, open the pom.xml in IDE, and switch to "Dependency Hierarchy" tab. In the left panel is the dependency tree, and in the right panel are the dependencies actually getting used. Right after each dependency it's its scope (eg. compile / test / runtime / omitted for conflict)

  1. In terminal run the command. mvn dependency:tree It will print out the dependency like in Eclipse.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!