J'ai un fichier JAR avec 4 classes, chacune ayant la méthode Main. Je veux être en mesure de gérer chacun d'entre eux selon les besoins. J'essaye de l'exécuter en ligne de commande sous Linux.
E.g. The name of my JAR is MyJar.jar
Il a une structure de répertoire pour les classes principales comme suit:
com/mycomp/myproj/dir1/MainClass1.class
com/mycomp/myproj/dir2/MainClass2.class
com/mycomp/myproj/dir3/MainClass3.class
com/mycomp/myproj/dir4/MainClass4.class
Je sais que je peux spécifier une classe comme principale dans mon fichier Manifest. Mais y a-t-il un moyen par lequel je peux spécifier un argument sur la ligne de commande pour exécuter la classe que je souhaite exécuter?
J'ai essayé ceci:
jar cfe MyJar.jar com.mycomp.myproj.dir2.MainClass2 com/mycomp/myproj/dir2/MainClass2.class /home/myhome/datasource.properties /home/myhome/input.txt
Et j'ai eu cette erreur:
com/mycomp/myproj/dir2/MainClass2.class : no such file or directory
(Dans la commande ci-dessus, '/home/myhome/datasource.properties' et '/home/myhome/input.txt' sont les arguments de la ligne de commande).
Vous pouvez créer votre pot sans classe principale dans son fichier manifeste. Ensuite :
Java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt
Vous pouvez exécuter la classe n'importe laquelle qui a une méthode public final static main
à partir d'un fichier JAR, même si le fichier jar a un Main-Class
défini.
Exécuter la classe principale:
Java -jar MyJar.jar // will execute the Main-Class
Exécutez une autre classe avec une méthode public static void main
:
Java -cp MyJar.jar com.mycomp.myproj.AnotherClassWithMainMethod
Remarque: le premier utilise -jar
, le second utilise -cp
.
En plus d'appeler Java -jar myjar.jar com.mycompany.Myclass
, vous pouvez également transformer la classe principale de votre classe Manifest en classe Dispatcher.
Exemple:
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);
}
}
Tout d'abord, jar
crée un fichier jar et ne l'exécute pas. Essayez Java -jar
à la place.
Deuxièmement, pourquoi passez-vous la classe deux fois, en tant que FQCN (com.mycomp.myproj.dir2.MainClass2
) et en tant que fichier (com/mycomp/myproj/dir2/MainClass2.class
)?
Modifier:
Il semble que Java -jar
nécessite la spécification d'une classe principale. Vous pouvez essayer Java -cp your.jar com.mycomp.myproj.dir2.MainClass2 ...
à la place. -cp
définit le fichier jar sur le chemin de classe et permet à Java de rechercher la classe principale à cet endroit.
Une autre option similaire que Nick a brièvement évoquée dans les commentaires consiste à créer plusieurs bocaux. Je ne l'ai pas essayé, mais je pense qu'ils pourraient être complètement vides, à l'exception du fichier manifeste, qui devrait spécifier la classe principale à charger ainsi que l'inclusion du fichier MyJar.jar dans le chemin d'accès aux classes.
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
etc. Ensuite, lancez-le avec Java -jar MyJar2.jar