亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 從目錄中加載 jar 文件

Java 從目錄中加載 jar 文件

胡子哥哥 2022-09-14 17:59:05
我目前正在開發一個開源項目,人們可以添加自己的.jar來擴展所包含的功能。但是,我一直堅持如何在jar中加載類。我有一個抽象類,它有一個抽象方法和一些getter,它提供了一些對象來處理應用程序。該插件需要子類我的插件類。jar應該添加到/plugins中,因此我希望在應用程序啟動時加載/plugins文件夾中的所有*.jar文件。onEnable()BasePlugin我現在遇到的問題是,在我發現的所有方法中,我需要在jar文件中聲明類的類路徑,我不知道。我也不知道 jar 文件的名稱。因此,我需要掃描 /plugins 文件夾中的任何 *.jar 文件,并在實現和調用該方法的 jar 中加載相應的類。BasePluginonEnable()
查看完整描述

4 回答

?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

基本思想也是...

  1. 讀取特定目錄中的所有文件

  2. 將每個結果的引用轉換為FileURL

  3. 使用與結果一起設定種子的 ,加載每個結果URLClassLoaderURL

  4. 用于查找具有特定名稱的所有匹配資源URLClassLoader#findResources

  5. 迭代匹配的資源并加載每個資源,這至少應該給出“入口點”類名

  6. 裝入由“入口點”屬性指定的類

例如。。。

public List<PluginClass> loadPlugins() throws MalformedURLException, IOException, ClassNotFoundException {

    File plugins[] = new File("./Plugins").listFiles(new FileFilter() {

        @Override

        public boolean accept(File file) {

            return file.getName().endsWith(".jar");

        }

    });

    List<URL> plugInURLs = new ArrayList<>(plugins.length);

    for (File plugin : plugins) {

        plugInURLs.add(plugin.toURI().toURL());

    }

    URLClassLoader loader = new URLClassLoader(plugInURLs.toArray(new URL[0]));

    Enumeration<URL> resources = loader.findResources("/META-INFO/Plugin.properties");

    List<PluginClass> classes = new ArrayList<>(plugInURLs.size());

    while (resources.hasMoreElements()) {

        URL resource = resources.nextElement();

        Properties properties = new Properties();

        try (InputStream is = resource.openStream()) {

            properties.load(is);

            String className = properties.getProperty("enrty-point");

            PluginClass pluginClass = loader.loadClass(className);

            classes.add(pluginClass);

        }

    }

    return classes

}

nb:我沒有運行這個,但這是“基本”


查看完整回答
反對 回復 2022-09-14
?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

SpigotMC也使用JAR文件作為插件,jar內部是一個文件,用于存儲有關插件的額外信息,包括類路徑。您不需要使用 YAML 文件,而是可以使用 JSON 甚至純文本文件之類的文件。plugin.yaml

YAML 文件位于 jar 中,可以使用此處介紹的一些方法來訪問該文件。然后,您可以獲取類路徑屬性,然后使用此處介紹的方法加載 jar??梢源鎯τ嘘P插件的額外信息,例如名稱,版本和依賴項。


查看完整回答
反對 回復 2022-09-14
?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

Java已經有一個這樣的類:服務加載器。


服務加載器類是隨 Java 6 引入的,但“SPI jar”概念實際上與 Java 1.3 一樣古老。這個想法是每個jar都包含一個簡短的文本文件,該文件描述了其特定服務提供者接口的實現。


例如,如果一個.jar文件包含兩個名為 FooPlugin 和 BarPlugin 的 BasePlugin 子類,則該.jar文件還將包含以下條目:


META-INF/services/com.example.BasePlugin

該 jar 條目將是一個文本文件,包含以下行:


com.myplugins.FooPlugin

com.myplugins.BarPlugin

您的項目將通過創建一個從目錄中讀取的類加載器來掃描插件:plugins


Collection<URL> urlList = new ArrayList<>();


Path pluginsDir = Paths.get(

    System.getProperty("user.home"), "plugins");


try (DirectoryStream<Path> jars =

    Files.newDirectoryStream(pluginsDir, "*.jar")) {


    for (Path jar : jars) {

        urlList.add(jar.toUri().toURL());

    }

}


URL[] urls = urlList.toArray(new URL[0]);

ClassLoader pluginClassLoader = new URLClassLoader(urls,

    BasePlugin.class.getClassLoader());


ServiceLoader<BasePlugin> plugins =

    ServiceLoader.load(BasePlugin.class, pluginClassLoader);


for (BasePlugin plugin : plugins) {

    plugin.onEnable();

    // etc.

}

使用 ServiceLoader 的另一個優點是,您的代碼將能夠與模塊一起使用,這是 Java 9 引入的更完整的代碼封裝形式,可提供更高的安全性。


查看完整回答
反對 回復 2022-09-14
?
哆啦的時光機

TA貢獻1779條經驗 獲得超6個贊

這里有一個例子,它可能會有所幫助。另外,你應該看看OSGi。


查看完整回答
反對 回復 2022-09-14
  • 4 回答
  • 0 關注
  • 239 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號