我在这个组织中有一些课程
--> : 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可以动态处理它,还是还有其他我不能约会的东西?
谢谢你的时间!
答案 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。