从具有动态类加载JAR的超类转换而来

时间:2012-01-08 18:05:13

标签: java class inheritance casting jar

我在这个组织中有一些课程

--> : Inherit 

TwittEntititesNetwork --> TwitterGephiStreamer

TwittGrapher          --> TwitterGephiStreamer

TwitterGephiStreamer is Abstract 
TwitterGephiStreamer have a method : myMethod()

Directory
    ./myApp.jar
    ./NetworkLogicDirectory/TwittGrapher.jar
    ./NetworkLogicDirectory/TwittEntititesNetwork.jar

我使用此代码动态加载女儿类(在另一个.jar文件中)

public static TwitterGephiStreamer LoadNetworkLogicJar() throws Exception
    {
        File dir = new File(NetworkLogicDirectory);
        URL[] urls = new URL[dir.listFiles().length];
        for(int i = 0;i < dir.listFiles().length;i++)
        {
            File s = dir.listFiles()[i];
            String url  = "file:///"+s.getAbsolutePath();
            urls[i] = new URL(url);

        }
        ClassLoader = new URLClassLoader(urls);

        if(defaultProps.containsKey("NetworkLogic") &&  !defaultProps.getProperty("NetworkLogic").isEmpty())
        {
            Class<?> networkLogicClassLoader = ClassLoader.loadClass("org.naoyun.gephistream.networklogic."+defaultProps.getProperty("NetworkLogic"));
            Object object = networkLogicClassLoader.newInstance();



            return (TwitterGephiStreamer) object;
        }
        else
        {
            throw new Exception("blabalbalbal ");
        }
    }

所以必须返回一个TwitterGephiStreamer,它可以作为普通类使用,我可以正常使用myMethod()。

当我在eclispe上运行时,它运行良好我没有任何错误。

当我将我的应用程序导出为runnable .jar(myApp.jar)时,它会抛出这个错误:

java.lang.ClassCastException: org.naoyun.gephistream.networklogic.TwittEntitiesNetwork cannot be cast to org.naoyun.gephistream.TwitterGephiStreamer
        at org.naoyun.utils.ConfigurationTools.LoadNetworkLogicJar(ConfigurationTools.java:62)
        at org.naoyun.TwitterStreamer.<init>(TwitterStreamer.java:34)
        at org.naoyun.TwitterStreamer.main(TwitterStreamer.java:26)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)

所以,我不知道如何解决这个问题。我的代码是否令人毛骨悚然,但Eclispe可以动态处理它,还是还有其他我不能约会的东西?

谢谢你的时间!

2 个答案:

答案 0 :(得分:0)

您可能在动态类路径中不止包含org.naoyun.gephistream.TwitterGephiStreamer。加载子类时,它会加载一个与之前加载的副本冲突的TwitterGephiStreamer副本。

因为,TwittGrapher.jar和TwittEntititesNetwork.jar依赖于相同的核心类/接口(即TwitterGephiStreamer),我建议将这些类型放在一个单独的实用程序jar中。这应该有助于消除类路径上的任何重复类型,并提供一个干净的jar依赖树:

           myApp
          /     \
TwittGrapher  TwittEntitiesNetwork
        \         /
         TwittUtil

答案 1 :(得分:0)

您不应该使用Eclipse来构建可执行jar,而是手动创建一个,例如:使用Ant构建脚本。

当Eclipse构建一个可执行jar时,它将所有内容打包在一个整洁的包中,通过自己的类加载器加载相关的jar,可以在堆栈跟踪中引用的“jarinjarloader”包中找到。当这个类加载器不是Eclipse构建的“omni-jar”的一部分时,它找不到你的外部jar。

我过去曾使用URLClassLoader来成功完成你想要做的事情:在运行时加载外部jar。这是一个关于SO的问题,解释了如何使用它: Is it possible to “add” to classpath dynamically in java?

本教程应该有助于使用Ant构建可执行jar: Build an executable jar file by referencing your dependencies

这个Ant tutorial是类似的,并展示了如何使用Eclipse,尽管它没有在清单中设置依赖项。您需要为核心应用程序类执行此操作,而不是在运行时加载任何外部jar。