【问题标题】:Load a class from a jar从 jar 加载一个类
【发布时间】:2013-12-31 05:06:29
【问题描述】:

我正在尝试从 jar 中加载一个类,我正在使用一个类加载器。

我有这部分代码用于准备类加载器:

private void loadClass(){

    try{
        JarFile jarFile = new JarFile( Path);
        Enumeration e = jarFile.entries();

        URL[] urls = { new URL("jar:file:" + Path +"!/") };
        classLoader = URLClassLoader.newInstance(urls);


    } catch (MalformedURLException ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

现在我加载一个类,并尝试获取一个新实例

....           
           loadClass();

           Class device = classLoader.loadClass( "org.myPackage.MyClass");

           MyMotherClass Device = ( MyMotherClass) device.newInstance();
...

MyClass 扩展了 MyMotherClass,当我执行 classLoader.loadClass("org.myPackage.MyClass") 时,MyMotherClass 它在 classLoader 中。 此刻,还好。

现在,在 device.newInstance() 中,我得到了一个异常。问题是 MyClass 使用的其他类不在类路径中。

我能做什么?

我有另一个方法可以在 classLoader 中加载所有需要的类,但是当我获得新实例时它不起作用。 我不能改变 MyClass 和其他人

【问题讨论】:

  • 你不能在启动 JVM 之前更改你的类路径设置吗?
  • 这对您有帮助吗? stackoverflow.com/questions/402330/…
  • @Bathsheba 不,我不知道必须加载 jar。它在运行时创建的名称
  • 您能否更具体地了解“MyClass 使用的其他类”?另外,您正在加载MyClass 的类加载器与系统类加载器不同吗?
  • 这是有道理的,但没有回答我的任何一个问题,这很难提供帮助。在黑暗中拍摄,听起来您正在使用不委托回系统类加载器的类加载器加载 MyClass。如果不是这种情况,则缺少的类没有被正确加载。

标签: java classloader


【解决方案1】:

这是我用来在运行时动态加载 jar 的一些代码。我利用反射来规避您真的不应该这样做的事实(即,在 JVM 启动后修改类路径)。只需将my.proprietary.exception 更改为合理的即可。

    /*
     * Adds the supplied library to java.class.path.
     * This is benign if the library is already loaded.
     */
    public static synchronized void loadLibrary(java.io.File jar) throws my.proprietary.exception
    {
        try {
            /*We are using reflection here to circumvent encapsulation; addURL is not public*/
            java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
            java.net.URL url = jar.toURI().toURL();
            /*Disallow if already loaded*/
            for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
                if (it.equals(url)){
                    return;
                }
            }
            java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
            method.setAccessible(true); /*promote the method to public access*/
            method.invoke(loader, new Object[]{url});
        } catch (final NoSuchMethodException | 
            java.lang.IllegalAccessException | 
            java.net.MalformedURLException | 
            java.lang.reflect.InvocationTargetException e){
            throw new my.proprietary.exception(e.getMessage());
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2015-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多