为什么当其他班级间接加载课程时,我为什么要获得classNotFoundException?

发布于 2025-01-26 11:02:48 字数 6013 浏览 2 评论 0原文

我可以使用此类加载程序单独加载正确的类,尽管当我从其他类中间接加载classNotFoundException。为什么会发生这种情况?

stacktrace

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

class Loader在SpringBoot Loader pockain中启动了durlclassloader。我正在尝试使用它来加载我的应用Bootstrap类。另一个问题是为什么classNotFoundException在 无法加载Referenecd类,就好像它没有由启动durlclassloader启动

durlclassloader加载:

@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);
    }

}

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?

stacktrace

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);
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文