2012-06-22 15 views
21

Ho creato un jar eseguibile e utilizzando commons-cli per dare all'utente la possibilità di specificare i parametri della riga di comando all'avvio del client. Tutto funziona bene Tuttavia, quando stampo l'istruzione di utilizzo per il vaso, vorrei mostrare il seguente:Ottieni il nome del jar eseguibile dal metodo main()

usage: java -jar myprog.jar <options> <file> 
--help Display the help message 
--debug Enable debugging 
.... 

stampa di tutte le opzioni è fatto facilmente con commons-CLI. Tuttavia, la linea di "utilizzo" è la graffatrice. Non riesco a capire un modo per ottenere il nome "myprog.jar" dagli arg [] che vengono passati all'applicazione.

C'è un modo semplice per farlo? Potrei usare un metodo piuttosto complesso per risalire alla traccia del classloader della mia classe e capire se è contenuto in un jar, ma sembra una risposta abbastanza brutta a quella che dovrebbe essere una domanda piuttosto semplice.

private String getPath(Class cls) { 
    String cn = cls.getName(); 
    String rn = cn.replace('.', '/') + ".class"; 
    String path = 
      getClass().getClassLoader().getResource(rn).getPath(); 
    int ix = path.indexOf("!"); 
    if(ix >= 0) { 
     return path.substring(0, ix); 
    } else { 
     return path; 
    } 
} 
+0

provato http://stackoverflow.com/questions/320542/how-to-get-the-path-of-a-running-jar-file?lq=1? – Charles

+0

Ho già visto quel link, ma sembrava che fosse quasi un "hack". Non posso credere che non esista una soluzione più diretta. Inoltre, l'API afferma che "getCodeSource()" può restituire null, ma non elaborare in quali condizioni, quindi mi chiedevo naturalmente se questo fosse un metodo "fail-safe" da usare. –

risposta

33

Qui si va:

new java.io.File(SomeClassInYourJar.class.getProtectionDomain() 
    .getCodeSource() 
    .getLocation() 
    .getPath()) 
.getName() 

Edit: Ho visto i suoi commenti su getSourceCode API. Bene, questo è probabilmente il meglio che puoi fare in Java. Informazioni su getCodeSource() restituendo null, penso che accada principalmente sulle classi in java.lang.* e altre classi speciali per le quali la posizione di origine è "nascosta". Dovrebbe funzionare per le tue classi però.

+0

Grazie - è la stessa cosa che @Charles ha indicato nel link SO. La mia più grande preoccupazione, come ho detto sopra, è che l'api per 'getCodeSource()' indica che può essere nullo, ma non elaborare in quali condizioni. –

+0

L'altro problema con questo è che non tiene conto del fatto che il file di classe può essere annidato all'interno degli archivi. Quindi avrei ancora bisogno di cercare una sottostringa '!'. Come ho detto, sembra un po 'goffo e sono abbastanza sorpreso che Java non abbia una soluzione migliore. –

+0

Principalmente perché raramente c'è un motivo per conoscere il nome del file jar da cui stai eseguendo. La funzionalità dovrebbe (idealmente) essere indipendente dal nome. – Charles