私のアプリケーション用のプラグインシステムを実装しようとしています。そのコードは、カスタム機能を定義するためにPluginクラスを拡張しています。実行時に.classをjarから作業ディレクトリにロードするには?
アプリケーションの.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
問題は、プラグインシステムの目的のために.jarに実際にすべてがパックされているので、代わりに.classファイルを指定するオプションをユーザに提供することです。以下になり
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が毎回取得しました。もともとはJARファイルの読み込みに問題がありましたが、完全修飾パスを使用して固定されていたので、クラスを読み込めません。
アイデア? :)
あなたは本当に使うべき[ServiceLoader](https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html)このため。 – VGR