简体   繁体   中英

URLClassLoader throws ClassNotFoundException for some entries

I'm writing a piece of code which loads java classes from JAR file using URLClassLoader on Java version v8 u112

I'm using excerpt below:

// Create URlClassLoader
Path jarFilePath = Paths.get(...);
URLClassLoader loader = URLClassLoader.newInstance(new URL[] { jarFilePath .toUri().toURL() }, ClassLoader.getSystemClassLoader());

// Filter only .class entries from JAR file since JAR contains *.xml, *.txt etc.
JarFile jarFile = new JarFile(path.toAbsolutePath().toFile()));
List<String> javaClasses = filterJavaClasses(jarFile); // filters only entries with .class extension.

// Attempt class loading. I used the help of BCEL since it converts class to JavaClass which is easier to work with. 
javaClasses.map(clazz -> Repository.lookupClass(loader.loadClass(clazz)))...

Note, the same issue happens even if I don't use BCEL...

While loading JAR file, most of the classes are loaded without problems, but I run into an issue while loading some specific classes, ie com/sun/javadoc/Doclet, com/sun/tools/javadoc/Messager, org/apache/sshd/server/SshServer etc.

has anyone met such an issue while working with URLClassLoader?

Exception example below

java.lang.NoClassDefFoundError: com/sun/javadoc/Doclet
    at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_112]
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_112]
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_112]
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[?:1.8.0_112]
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[?:1.8.0_112]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[?:1.8.0_112]
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[?:1.8.0_112]
    at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_112]
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[?:1.8.0_112]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_112]
    at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814) ~[?:1.8.0_112]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_112]

You not only need to put your jars in the url list but also the jars that these jars depends on and their dependencies...

for example com/sun/javadoc/Doclet is part of JAVA_HOME/lib/tools.jar which is not loaded by systemclassloader by default, unless you specifically add tools.jar to the classpath.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM