【问题标题】:Dynamic loading java classes in terminal在终端中动态加载java类
【发布时间】:2014-11-16 06:20:28
【问题描述】:

该应用程序是模块化插件架构。也就是说,在完成工作的同时动态加载类。为此,自定义类加载器扩展了 ClassLoader。

问题的本质是在Eclipse应用程序运行,而在终端(ubuntu)使用以下代码行(其中目录“m /”表示模块的位置* .class):

java -jar ModularApp.jar m/

我收到以下消息:

10:07:24,085 DEBUG main CModuleLoader:findClass:39 - 系统类加载器的运行。 线程“主”java.lang.reflect.InvocationTargetException 中的异常 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58) 引起:java.lang.NoClassDefFoundError: ru/intetech/module/CModule 在 java.lang.ClassLoader.defineClass1(Native Method) 在 java.lang.ClassLoader.defineClass(ClassLoader.java:800) 在 java.lang.ClassLoader.defineClass(ClassLoader.java:643) 在 ru.intetech.moduleloader.CModuleLoader.findClass(CModuleLoader.java:35) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:425) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:358) 在 ru.intetech.modularApp.Main.main(Main.java:42) ... 5 更多原因: java.lang.ClassNotFoundException:ru.intetech.module.CModule 在 java.lang.ClassLoader.findClass(ClassLoader.java:531) 在 ru.intetech.moduleloader.CModuleLoader.findClass(CModuleLoader.java:40) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:425) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 12 更多

这是一段sn-p的代码,用户类加载器(扩展ClassLoader),这里有错误:

protected Class<?> findClass(String className) throws ClassNotFoundException
{
    try
    {
        byte b[]=getClassAsBytes(m_pathToBin+className+".class");
        return (defineClass(className, b, 0, b.length));
    }
    catch(FileNotFoundException ex)
    {
        m_log.debug("Run of the System Classloader.");
        return (super.findClass(className));
    }
    catch(IOException ex)
    {
        m_log.debug("Run of the Bootstrap.");
        return (super.findClass(className));
    }
}

可能是什么问题?

附:在本文的基础上实现的Loader: http://sysmagazine.com/posts/104229/

【问题讨论】:

    标签: java eclipse terminal classloader


    【解决方案1】:

    看:堆栈跟踪显示消息“Run of the System Classloader”,证明执行了第一个catch。这是由 FileNotFoundException 引起的,这显然发生在 getClassAsBytes 方法中:这是您必须调查的内容:找出您正在尝试读取的文件(放置显示 absolute 路径的跟踪),以及为什么那个文件不存在。

    (最终,catch 块尝试通过系统类加载器加载所需的类,系统类加载器无法访问该类,因此它抛出 ClassNotFoundException)。

    【讨论】:

    • 我按照你的建议做了。
    • 添加了行日志记录。 //... m_log.debug("#Path: "+m_pathToBin+className+".class"); byte b[]=getClassAsBytes(m_pathToBin+className+".class"); //... 现在我收到消息: 15:55:39,634 DEBUG main Main:main: 36 - 加载文件:CModulePrinter2.class 15:55:39,637 DEBUG main CModuleLoader:findClass:34 - #Path: m/CModulePrinter2.class 15:55:39,637 DEBUG main CModuleLoader:findClass:34 - #Path: m/ru.intetech .module.CModule.class 15:55:39,638 DEBUG main CModuleLoader:findClass:40 - 系统类加载器的运行。 CModulePrinter 导入试图加载 ClassLoader 的类 CModule。
    • 阅读此日志,我可以看到您忘记了完整路径中的 包部分:您的 .class 文件肯定在 m/ru/intetech/module/CModulePrinter2.class
    • 我放了这个类,没有任何变化。你可能想到了:m/ru/intetech/module/CModule.class
    • 这很简单:记录getClassAsBytes 方法尝试读取文件的绝对路径,并检查该路径是否对应于您预期的.class 文件。这一切的根本原因是 FileNotFoundException。
    猜你喜欢
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2012-10-10
    • 1970-01-01
    • 2011-07-31
    • 1970-01-01
    相关资源
    最近更新 更多