Come eseguire una classe da Jar che non è la classe principale nel suo file Manifest


Ho un JAR con 4 classi, ognuna ha il metodo principale. Voglio essere in grado di eseguire ognuno di quelli secondo la necessità. Sto cercando di eseguirlo da riga di comando su Linux box.

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

Ha una struttura di directory per le classi principali come segue:

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

So che posso specificare una classe come principale nel mio file Manifest. Ma c'è un modo in cui posso specificare qualche argomento sulla riga di comando per eseguire qualsiasi classe che desidero eseguire?

Ho provato questo:

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

E Ho ottenuto questo errore:

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

(Nel comando precedente, '/home/myhome/datasource.proprietà ' e ' /home/myhome / ingresso.txt ' sono gli argomenti della riga di comando).

Author: Bhushan, 2011-03-29

6 answers

Puoi creare il tuo jar senza Main-Class nel suo file Manifest. Quindi:

java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt
 130
Author: lxu4net, 2011-03-29 15:21:58

È possibile eseguire qualsiasi classe che ha un metodo public final static mainda un file JAR, anche se il file jar ha un Main-Class definito.

Esegui classe principale:

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

Eseguire un'altra classe con un metodo public static void main:

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

Nota: il primo utilizza -jar, il secondo utilizza -cp.

 83
Author: fadedbee, 2016-02-10 16:54:53

Oltre a chiamare java -jar myjar.jar com.mycompany.Myclass, puoi anche rendere la classe principale nel Manifest una classe Dispatcher.

Esempio:

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);

    }
}
 9
Author: Sean Patrick Floyd, 2011-03-29 15:33:53

Prima di tutto jar crea un jar e non lo esegue. Prova invece java -jar.

In secondo luogo, perché passi la classe due volte, come FQCN (com.mycomp.myproj.dir2.MainClass2) e come file (com/mycomp/myproj/dir2/MainClass2.class)?

Modifica:

Sembra che java -jar richieda una classe principale da specificare. Potresti invece provare java -cp your.jar com.mycomp.myproj.dir2.MainClass2 .... -cp imposta il jar sul classpath e consente a java di cercare la classe principale lì.

 2
Author: Thomas, 2011-03-29 15:14:38

Un'altra opzione simile a cui penso che Nick abbia brevemente accennato nei commenti è quella di creare più jar wrapper. Non l'ho provato, ma penso che potrebbero essere completamente vuoti oltre al file manifest, che dovrebbe specificare la classe principale da caricare e l'inclusione di MyJar.jar al classpath.

MyJar1.jar \ META-INF \ MANIFEST.MF

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

MyJar2.jar \ META-INF \ MANIFEST.MF

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

Ecc. Quindi eseguilo con java -jar MyJar2.jar

 0
Author: JSub, 2015-05-07 14:35:34

Aggiungi sotto il plugin nel tuo pom.file xml e specificare la classe principale con nome completo nell'elemento.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.2.5.RELEASE</version>
    <configuration>
        <mainClass>**main Class name with full qualified name**</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>
 0
Author: Ajay, 2017-09-21 09:06:47