使用动态类加载JAR从超类转换java
我在这个组织有一些课程
--> : 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可以在运行中处理它,还是有其他我没有更新的东西
谢谢你的时间
# 1 楼答案
您不应该使用Eclipse来构建可执行jar,而应该手动创建一个,例如使用Ant构建脚本
当Eclipse构建一个可执行jar时,它将所有内容打包在一个整洁的包中,通过自己的类加载器加载依赖jar,该类加载器位于堆栈跟踪中引用的“jarinjarloader”包中。当外部jar不是Eclipse构建的“omni jar”的一部分时,这个类加载器无法找到您的外部jar
我在过去使用过
URLClassLoader
来成功地完成您试图做的事情:在运行时加载外部jar。下面是一个关于的问题,解释了如何使用它: 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
# 2 楼答案
你可能有组织。娜云。gephistream。TwitterGephiStreamer在动态类路径中包含多次。加载子类时,它会加载TwitterGephiStreamer的一个副本,该副本与以前加载的副本冲突
从那时起,twitgrapher。jar和Twittentites网络。jar依赖于相同的核心类/接口(即TwitterGephiStreamer),我建议将这些类型放在一个单独的实用程序jar中。这将有助于消除类路径上的任何重复类型,并提供一个干净的jar依赖关系树: