[英]How to load a class which implements a interface from a jar file at runtime?
[英]How to load .class from working directory at runtime from jar?
嘗試為我的應用程序實現一個插件系統,其代碼擴展了我的Plugin類以定義自定義功能。
此代碼可以從jar中加載與應用程序.jar相同的目錄中的類,可以正常工作:
if(pluginName.endsWith(".jar"))
{
JarFile jarFile = new JarFile(pluginName);
Enumeration jarComponents = jarFile.entries();
while (jarComponents.hasMoreElements())
{
JarEntry entry = (JarEntry) jarComponents.nextElement();
if(entry.getName().endsWith(".class"))
{
className = entry.getName();
}
}
File file = new File(System.getProperty("user.dir")+"/"+pluginName);
URLClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});
Class newClass = Class.forName(className.replace(".class", ""), true, loader);
newPlugin = (Plugin) newClass.newInstance();
}
導致正確的響應:
benpalmer$ java -jar assignment.jar test_subproject.jar
- INFO: Add new plugin: source.com
問題是我還想向用戶提供選項來指定.class文件,因為實際上是出於插件系統目的打包到.jar中的所有文件。
else if(pluginName.endsWith(".class"))
{
File file = new File(System.getProperty("user.dir")+"/"+pluginName);
URLClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});
Class newClass = Class.forName(className.replace(".class", ""), true, loader);
newPlugin = (Plugin) newClass.newInstance();
}
... exception handling
結果如下:
benpalmer$ java -jar assignment.jar TestPlugin.class
SEVERE: Error: Plugin class not found. Class name:
java.lang.ClassNotFoundException:
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at newsfeed.model.Plugin.loadClassFromJarFile(Plugin.java:144)
at newsfeed.controller.NFWindowController.initPlugins(NFWindowController.java:81)
at newsfeed.controller.NewsFeed$1.run(NewsFeed.java:20)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
我已經嘗試了上面的代碼以及路徑名/其他選項的許多變體,但是每次都得到ClassNotFoundException。 最初在加載罐子時遇到了麻煩,但是使用了完全限定的路徑進行了修復,現在我無法加載類。
有任何想法嗎? :)
這是URLClassLoader的一項功能,它可用於類目錄(您可以將.jar
視為打包目錄)。
您使用的構造函數具有以下javadoc
使用默認的委托父類ClassLoader為指定的URL構造一個新的URLClassLoader。 在首次在父類加載器中搜索后,將按照為類和資源指定的順序搜索URL。 假定任何以“ /”結尾的URL均指向目錄。 否則,假定該URL指向將要根據需要下載並打開的JAR文件。
如果您絕對想為每個單獨的類創建類加載器,則應考慮將SecureClassLoader
子類化,並使用defineClass
方法手動定義新類。
Java類加載器的基礎知識應該對您有所幫助。
再次看到我的問題,意識到我忘了發布找到的解決方案。 我希望這對以后的人有所幫助,因為這是我針對自己的情況找到的唯一可行的例子-大學分配問題。 我簡直不敢這么簡單:
byte[] classData = Files.readAllBytes(Paths.get(fileName));
Class<?> cls = defineClass(null, classData, 0, classData.length);
return (PluginClassName)cls.newInstance();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.