2012-06-22 21 views
21

Utworzono plik wykonywalny i za pomocą komendy commons-cli nadano użytkownikowi możliwość określenia parametrów wiersza polecenia podczas uruchamiania klienta. Wszystko dziala. Jednak podczas drukowania instrukcji użytkowania do słoika, chciałbym pokazać, co następuje:Pobierz nazwę pliku wykonywalnego słoika z metody main().

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

Drukowanie wszystkich opcji jest łatwo zrobić z Commons CLI. Jednak linia "użytkowania" to drapak głowy. Nie mogę wymyślić sposób, aby uzyskać nazwę "myprog.jar" z args [], które są przekazywane do aplikacji.

Czy jest jakiś łatwy sposób na zrobienie tego? Mógłbym użyć dość zawiłej metody, aby cofnąć ślad od klasy classloader klasy i dowiedzieć się, czy jest ona zawarta w słoiku, ale wydaje się to dość brzydką odpowiedzią na pytanie, które powinno być dość proste.

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

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

+0

Widziałem już ten link, ale wyglądało na to, że był to prawie "hack". Nie mogę uwierzyć, że nie ma bardziej bezpośredniego rozwiązania. Dodatkowo API stwierdza, że ​​"getCodeSource()" może zwracać wartość null, ale nie wyjaśnia, w jakich warunkach, więc naturalnie zastanawiałem się, czy jest to metoda "bezpieczna". –

Odpowiedz

33

Proszę bardzo:

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

Edit: Widziałem komentarz o getSourceCode API. Cóż, jest to prawdopodobnie najlepsze, co możesz zrobić w Javie. O getCodeSource() powracając null, myślę, że dzieje się to głównie na zajęciach w java.lang.* i innych specjalnych klasach, dla których lokalizacja źródła jest "ukryta". Powinien jednak pracować dla własnych klas.

+0

Dzięki - to jest to samo, co @Charles wskazał w linku SO. Moją największą obawą, o której wspomniałem powyżej, jest to, że api dla 'getCodeSource()' wskazuje, że może on mieć wartość zerową, ale nie wyjaśnia, w jakich warunkach. –

+0

Innym problemem jest to, że nie bierze pod uwagę faktu, że plik klasy może być zagnieżdżony w archiwach. Musiałbym więc sprawdzić podciąg '' '. Tak jak powiedziałem, wydaje się to trochę niezgrabne i jestem całkiem zaskoczony, że Java nie ma lepszego rozwiązania. –

+0

Dzieje się tak głównie dlatego, że rzadko kiedy jest znana nazwa pliku jar, z którego korzystasz. Funkcjonalność powinna (najlepiej) być niezależna od nazwy. – Charles

Powiązane problemy