'Why am I getting a ClassNotFoundException when class is indirectly loaded by other class?
I am able to use this class loader to load the right class separately, though I get a ClassNotFoundException when it is indirectly loaded by other class. Why does this happen?
D:\programming\github\scm\scm.web\jar\tt\repack>java -Dspring.profiles.active=dev -XX:-OmitStackTraceInFastThrow -jar scm.web.jar
LaunchedURLClassLoader loadClass org.apache.catalina.LifecycleException
LaunchedURLClassLoader load org.apache.catalina.LifecycleException by parent sun.misc.Launcher$AppClassLoader@7852e922
LaunchedURLClassLoader load by self org.apache.catalina.LifecycleException
LaunchedURLClassLoader try find class org.apache.catalina.LifecycleException
LaunchedURLClassLoader loadClass java.lang.Exception
LaunchedURLClassLoader load java.lang.Exception by parent sun.misc.Launcher$AppClassLoader@7852e922
LaunchedURLClassLoader loadClass pers.zcc.scm.web.launch.AppBootstrap
LaunchedURLClassLoader load pers.zcc.scm.web.launch.AppBootstrap by parent sun.misc.Launcher$AppClassLoader@7852e922
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/catalina/LifecycleException
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at pers.zcc.scm.web.launch.MainMethodRunner.run(MainMethodRunner.java:32)
at pers.zcc.scm.web.launch.Launcher.launch(Launcher.java:70)
at pers.zcc.scm.web.launch.Launcher.launch(Launcher.java:34)
at pers.zcc.scm.web.launch.JarLauncher.main(JarLauncher.java:55)
Caused by: java.lang.ClassNotFoundException: org.apache.catalina.LifecycleException
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 6 more
the class loader is LaunchedURLClassLoader in springboot loader package. i am trying to use it to load my app bootstrap class. another question is why the ClassNotFoundException wasn't caught when failed to load the referenecd class, as if it was't loaded by the LaunchedURLClassLoader
LaunchedURLClassLoader:
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
System.out.println("LaunchedURLClassLoader loadClass " + name);
Handler.setUseFastConnectionExceptions(true);
try {
try {
definePackageIfNecessary(name);
} catch (IllegalArgumentException ex) {
// Tolerate race condition due to being parallel capable
if (getPackage(name) == null) {
// This should never happen as the IllegalArgumentException indicates
// that the package has already been defined and, therefore,
// getPackage(name) should not return null.
throw new AssertionError(
"Package " + name + " has already been " + "defined but it could not be found");
}
}
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
ClassLoader parent = this.getParent();
if (parent != null) {
System.out.println("LaunchedURLClassLoader load " + name + " by parent " + parent);
c = parent.loadClass(name);
} else {
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
System.out.println("LaunchedURLClassLoader load by self " + name);
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
} finally {
Handler.setUseFastConnectionExceptions(false);
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("LaunchedURLClassLoader try find class " + name);
return super.findClass(name);
}
runner class:
public class MainMethodRunner {
private final String mainClassName;
private final String[] args;
/**
* Create a new {@link MainMethodRunner} instance.
* @param mainClass the main class
* @param args incoming arguments
*/
public MainMethodRunner(String mainClass, String[] args) {
this.mainClassName = mainClass;
this.args = (args != null) ? args.clone() : null;
}
public void run() throws Exception {
// Class<?> mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName);
// Method mainMethod = mainClass.getDeclaredMethod("main", String[].class);
// mainMethod.invoke(null, new Object[] { this.args });
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class.forName("org.apache.catalina.LifecycleException", true, cl);
Class.forName(mainClassName, true, cl);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
