簡體   English   中英

如何在運行時從jar從工作目錄加載.class?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM