2

プログラムの外側から「コマンド」を追加するシステムを追加したかったのです。

基本的に、さまざまな数の「拡張子」を持つことができる私のjar(実行可能ファイル)と同じディレクトリにあるフォルダー

各「拡張」は、識別などのために定義されたメソッドを持つ特定の抽象クラスを拡張する .class ファイルになります。

.classただし、これらのファイルをメイン パッケージの外から制御することさえ可能かどうかはわかりません。

これは可能ですか?もしそうなら、どのように?そうでない場合、私が試すことができる代替手段はありますか?

ありがとう!

4

4 に答える 4

3

私があなたを理解する限り。プラグイン システムを構築したい。その場合は、Java サービス プロバイダーのアプローチを検討する必要があります。

このアプローチでは、メイン パッケージでサービス プロバイダー インターフェイス (SPI) を定義し、Java META-INF/services の場所を使用して実装を検索します。この場合、jar ファイルをクラスパスに配置するだけで拡張機能を追加できます。

Java 1.6 以降では、java.util.ServiceLoader を使用できます。

または、Apache Discovery http://commons.apache.org/proper/commons-discovery/apidocs/org/apache/commons/discovery/tools/Service.htmlをご覧ください。

インスタンス化するサービスにコンストラクター引数を渡すことができるため、java.util.SerivceLoader よりも強力です。

考えられるプラグイン ローダーの実装は次のようになります。

public interface ServiceInterface {

}

public class PluginHost {   

    public ServiceLoader<ServiceInterface> loadPlugins() {
        File[] pluginLibraries = getPluginLibraries();
        URL[] pluginLibUrls = new URL[pluginLibraries.length];

        for (int i = 0; i < pluginLibUrls.length; i++) {
            try {
                pluginLibUrls[i] = pluginLibraries[i].toURI().toURL();
            } catch (MalformedURLException e) {
                throw new IllegalStateException("Unable to load plugin: "
                        + pluginLibraries[i], e);
            }
        }

        URLClassLoader pluginsClassLoader = new URLClassLoader(pluginLibUrls,
                ServiceInterface.class.getClassLoader());

        ServiceLoader<ServiceInterface> serviceLoader = ServiceLoader.load(
                ServiceInterface.class, pluginsClassLoader);

        return serviceLoader;
    }

    private File[] getPluginLibraries() {
        // please implement
    }
}
于 2013-07-05T09:18:48.920 に答える
1

それが可能だ。

Jar は単に圧縮されたクラス ファイルです。

クラスファイルがクラスパスにある限り、問題ありません。


jar ファイルを解凍し (.jar から .zip に名前を変更して解凍)、Java パッケージのディレクトリ構造を確認します。

于 2013-07-05T09:17:18.730 に答える
0

実行時にクラスをロードして Class オブジェクトを作成することもできます:

これを参照してくださいClass#forName(String, boolean, ClassLoader) API

例については、このチュートリアルを参照してください。

于 2013-07-05T09:17:42.323 に答える