2010-10-20 3 views
42

Sto riscontrando problemi con l'esecuzione di più classi diverse da un file JAR. So che posso impostare una delle classi all'interno JAR per classe principale che verranno eseguiti dopo il comando java -jar myjar.jar, ma quello che voglio è qualcosa di simile:Più classi eseguibili all'interno di JAR, come eseguirle?

java -jar myjar.jar MyClass 

E 'possibile fare questo in quel modo, o fare Devo creare più JAR (ognuno per una classe eseguibile), o è meglio creare una classe "manager" che eseguirà le mie altre classi passando a loro gli argomenti della riga di comando?
Cercavo documentazione o riferimento, ma non sono riuscito a trovarne.

risposta

52

Il formato file Jar eseguibile consente solo di specificare una classe principale. Al fine di poter essere in grado di eseguire applicazioni diverse, è necessario creare un "manager" come lei suggerisce, o di utilizzare il percorso di classe, invece:

java -cp myjar.jar MyClass 

Tuttavia, questo approccio ignorerà il classpath voi configurato nel file manifest di Jar.

+0

Ignorig classpath all'interno di manifest era una delle mie preoccupazioni. Ma ho provato questa soluzione, e sembra funzionare (ma non so perché davvero, perché ho impostato classpath all'interno di manifest) – wlk

+2

È perché questa forma di avvio non si preoccupa di leggere il manifest. Solo la forma -jar legge manifest. –

8

si dovrà utilizzare:

java -cp myjar.jar MyClass 

e

java -cp myjar.jar OtherMainClass 
4

lo si fa in questo modo:

java -cp myjar.jar MyClass 

cioè mettere il JAR nel classpath, allora ogni classe con un metodo principale può essere eseguito specificando il suo nome completo. L'opzione -jar esiste solo come collegamento per utilizzare le informazioni nel manifest di JAR (che può anche includere altri JAR nel classpath e specificare la classe principale).

0

I file jar possono contenere solo un attributo Main-Class nel manifest, il che significa che java -jar myjar.jar può avviare solo una classe.

È possibile avviare altre classi eseguibili con

java -cp myjar.jar OtherClass 

ma che non supporta gli utenti facendo doppio clic sul file jar.

A seconda dell'abilità dei vostri utenti, forse la riga di comando è OK per loro. In caso contrario, è possibile creare uno script per ogni classe eseguibile o uno script che accetta argomenti per scegliere la classe giusta.

1

Come la risposta corretta è stata fornita c'è una soluzione che è possibile utilizzare per costruire un barattolo per ogni classe principale con manifesti diversi. Ciò ti consentirebbe di creare file jar eseguibili, facendo doppio clic su ciascun programma separato.

Ci sono diversi modi per ottenere questo risultato, ma le basi sono di mettere una singola classe simile alla seguente che richiama il metodo principale inteso che passa gli argomenti.

package com.acme.myapp; 

public final class Stub1 { 
    public static void main(String[] args) { 
     App1.main(args); 
    } 
} 

Per quanto riguarda il confezionamento di questo, un modo usando maven sarebbe con il maven-assembly-plugin: jar-with-dependencies mojo.Il vantaggio qui è che il mojo costruirà un jar per il metodo main target che è autonomo e non ha bisogno di avere altri assembly sul classpath. Lo fa copiando il contenuto di ciascun barattolo di dipendenza nel barattolo risultante.

2

Non sarebbe meglio servire con l'uso di una classe principale "Launcher", la cui funzione è solo quella di inviare le chiamate alle classi effettive del controller e utilizzare un file di collegamento come wrapper finale, invece di giocherellare con il - opzione cp del wm?

In Windows, è sorprendentemente facile farlo.

La "classe principale" non ha bisogno di essere qualcosa di molto più complesso, qualcosa di simile a

/** 
* Sample launcher 
*/ 
public class Launcher { 
    /** 
    * @param args 
    */ 
    public static void main(String[] args) throws Exception { 
     if (args != null && args.length > 0) { 
      String option= args[0]; 
      String[] args2=new String[0];    

      if(args.length>1){ 
       args2= new String[args.length-1]; 
       System.arraycopy(args, 1, args2, 0, args2.length); 
      } 

      if(option.equals("a"));     
       new ClassA().exec(args2); 
      else if(option.equals("b"));     
       new ClassB().exec(args2); 


     } 
    } 
} 

Sul lato finestre delle cose, è abbastanza qualcosa come la creazione di un collegamento di questo tipo

javaw.exe -jar "jarfile" "a" 

È molto utile per posizionare il link nella cartella "sendTo" ... un jar, nascosto, chiamato da molti link che attivano uno dei suoi aspetti rende più semplice la distribuzione degli aggiornamenti della logica jar.

I file effettivi selezionati vengono passati come un elenco di stringhe dopo i parametri nella definizione del collegamento.

In questo modo, non dovresti preoccuparti di tutti i problemi del classpath.