web-dev-qa-db-ja.com

マニフェストファイルのメインクラスではないJarからクラスを実行する方法

4つのクラスを持つJARがあり、それぞれにMainメソッドがあります。私は必要に応じてそれらのそれぞれを実行できるようにしたいです。 Linuxボックスのコマンドラインから実行しようとしています。

E.g. The name of my JAR is MyJar.jar

次のように、メインクラスのディレクトリ構造があります。

com/mycomp/myproj/dir1/MainClass1.class
com/mycomp/myproj/dir2/MainClass2.class
com/mycomp/myproj/dir3/MainClass3.class
com/mycomp/myproj/dir4/MainClass4.class

マニフェストファイルでメインとして1つのクラスを指定できることを知っています。しかし、実行したいクラスを実行するためにコマンドラインで引数を指定する方法はありますか?

私はこれを試しました:

jar cfe MyJar.jar com.mycomp.myproj.dir2.MainClass2 com/mycomp/myproj/dir2/MainClass2.class /home/myhome/datasource.properties /home/myhome/input.txt

そして、私はこのエラーを受け取りました:

com/mycomp/myproj/dir2/MainClass2.class : no such file or directory

(上記のコマンドでは、「/ home/myhome/datasource.properties」および「/home/myhome/input.txt」がコマンドライン引数です)。

133
Bhushan

マニフェストファイルでMain-Classなしでjarを作成できます。それから:

Java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt
168
lxu4net

JARファイルからpublic final static mainメソッドを持つクラスanyを実行できますjarファイルにMain-Classが定義されている場合でもです。

メインクラスの実行:

Java -jar MyJar.jar  // will execute the Main-Class

public static void mainメソッドを使用して別のクラスを実行します。

Java -cp MyJar.jar com.mycomp.myproj.AnotherClassWithMainMethod

注:最初は-jarを使用し、2番目は-cpを使用します。

110
fadedbee

Java -jar myjar.jar com.mycompany.Myclassの呼び出しとは別に、マニフェストのメインクラスをDispatcherクラスにすることもできます。

例:

public class Dispatcher{

    private static final Map<String, Class<?>> ENTRY_POINTS =
        new HashMap<String, Class<?>>();
    static{
        ENTRY_POINTS.put("foo", Foo.class);
        ENTRY_POINTS.put("bar", Bar.class);
        ENTRY_POINTS.put("baz", Baz.class);
    }

    public static void main(final String[] args) throws Exception{

        if(args.length < 1){
            // throw exception, not enough args
        }
        final Class<?> entryPoint = ENTRY_POINTS.get(args[0]);
        if(entryPoint==null){
            // throw exception, entry point doesn't exist
        }
        final String[] argsCopy =
            args.length > 1
                ? Arrays.copyOfRange(args, 1, args.length)
                : new String[0];
        entryPoint.getMethod("main", String[].class).invoke(null,
            (Object) argsCopy);

    }
}
13

最初にjarはjarを作成し、実行しません。代わりにJava -jarを試してください。

次に、なぜFQCN(com.mycomp.myproj.dir2.MainClass2)とファイル(com/mycomp/myproj/dir2/MainClass2.class)としてクラスを2回渡すのですか?

編集:

Java -jarではメインクラスを指定する必要があるようです。代わりにJava -cp your.jar com.mycomp.myproj.dir2.MainClass2 ...を試すことができます。 -cpはjarをクラスパスに設定し、Javaがそこでメインクラスを検索できるようにします。

2
Thomas

ニックがコメントで簡単に示唆した別の同様のオプションは、複数のラッパーjarを作成することです。試したことはありませんが、ロードするメインクラスとクラスパスへのMyJar.jarのインクルードを指定するマニフェストファイル以外は、完全に空である可能性があると思います。

MyJar 1。jar\META-INF\MANIFEST.MF

Manifest-Version: 1.0
Main-Class: com.mycomp.myproj.dir1.MainClass1
Class-Path: MyJar.jar

MyJar 2。jar\META-INF\MANIFEST.MF

Manifest-Version: 1.0
Main-Class: com.mycomp.myproj.dir2.MainClass2
Class-Path: MyJar.jar

など。その後、Java -jar MyJar2.jarで実行します。

1
JSub