2011-03-29 15 views
80

Tengo un JAR con 4 clases, cada una tiene el método principal. Quiero poder ejecutar cada uno de ellos según la necesidad. Estoy tratando de ejecutarlo desde la línea de comandos en el cuadro de Linux.Cómo ejecutar una clase desde Jar que no es la clase principal en su archivo de manifiesto

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

Tiene estructura de directorios para las clases principales de la siguiente manera:

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

Sé que puedo especificar una clase como principal en mi archivo de manifiesto. ¿Pero hay alguna manera por la cual puedo especificar algún argumento en la línea de comando para ejecutar cualquier clase que desee ejecutar?

yo probamos este:

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

Y me dio este mensaje:

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

(En el comando anterior, '/home/myhome/datasource.properties' y '/ home/micarpetapersonal /input.txt 'son los argumentos de línea de comando).

+0

¿Simplemente empaquételas en diferentes jarras, usando otro jar para guardar las dependencias? – Nick

+6

¿Por qué no tener una sola clase principal que llama al método específico (de los 4) en función de los argumentos de línea de comando? –

Respuesta

111

Puede crear su jar sin Main-Class en su archivo Manifest. Entonces:

java -cp MyJar.jar com.mycomp.myproj.dir2.MainClass2 /home/myhome/datasource.properties /home/myhome/input.txt 
+2

De acuerdo con el documento esto no funcionará: "Para que esta opción funcione, el manifiesto del archivo JAR debe contener una línea del formulario Clase principal: nombre de clase." – Thomas

+0

"Error al cargar el atributo de manifiesto de clase principal de MyJar.jar " – Bhushan

+2

Thomas tiene razón. necesita reemplazar "-jar" con "-cp". Ver mi código actualizado – lxu4net

2

En primer lugar, jar crea un jar y no lo ejecuta. Pruebe java -jar en su lugar.

En segundo lugar, ¿por qué pasa la clase dos veces, como FQCN (com.mycomp.myproj.dir2.MainClass2) y como archivo (com/mycomp/myproj/dir2/MainClass2.class)?

Editar:

Parece como si java -jar requiere una clase principal que se determine. Puede intentar java -cp your.jar com.mycomp.myproj.dir2.MainClass2 ... en su lugar. -cp establece el jar en el classpath y permite a java buscar allí la clase principal.

+0

Hice lo mencionado aquí: http://download.oracle.com/javase/tutorial/deployment/jar/appman.html – Bhushan

+0

De esa página: "Se puede utilizar al crear o actualizar un archivo jar". - Entonces esto se usa para establecer el atributo de clase principal, no para ejecutar el jar. – Thomas

8

Aparte de llamar java -jar myjar.jar com.mycompany.Myclass, también puede hacer que la clase principal en su manifiesto de una clase Dispatcher.

Ejemplo:

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

    } 
} 
0

Otra opción similar que creo que Nick brevemente aludido en los comentarios es la creación de varios frascos de envoltura. No lo he probado, pero creo que podrían estar completamente vacíos, aparte del archivo de manifiesto, que debería especificar la clase principal a cargar, así como la inclusión de MyJar.jar en la ruta de clase.

MYJAR .jar \ META-INF \ MANIFEST.MF

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

MYJAR .jar \ META-INF \ MANIFEST.MF

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

etc. A continuación, sólo lo hace funcionar con java -jar MyJar2.jar

67

Puede ejecutar cualquier clase que tiene un método public final static main de un archivo JAR, incluso si el archivo tiene un tarro de Main-Class definido.

Ejecutar principal Clase:

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

Ejecutar otra clase con un método public static void main:

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

Nota: el primero utiliza -jar, el segundo utiliza -cp.

+4

Y si quiere también todos los archivos jar en el directorio actual en classpath (por ejemplo, ejecutando Main class desde el directorio lib) puede usar 'java -cp" ./* "com.mycomp.myproj.AnotherClassWithMainMethod' Tenga en cuenta las comillas dobles alrededor' ./* 'evitar que las máquinas Unix lo expandan. También tenga en cuenta que '" ./*. Jar "' no funcionará. –

1

Agregue el complemento siguiente en su archivo pom.xml y especifique la clase principal con el nombre totalmente calificado en el 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> 
Cuestiones relacionadas