2009-11-10 6 views
15

Mam plik JAR zawierający aplikację, a także pliki konfiguracyjne dla tej aplikacji. Aplikacja ładuje pliki konfiguracyjne ze ścieżki klas (przy użyciu ClassLoader.getResource()) i ma całkowicie zadowalające zależności za pomocą plików konfiguracyjnych zapakowanych do pliku JAR.Czy mogę użyć ścieżki classpath do przesłonięcia pliku w uruchomionym słoiku?

Czasami chcę, aby aplikacja była uruchamiana z nieco inną konfiguracją (konkretnie chcę zastąpić adres URL JDBC, aby wskazać inną bazę danych), więc utworzę nowy plik konfiguracyjny, zapisuję go we właściwej strukturze katalogów (co oznacza, że ​​w katalogu /config z wejściem ścieżce klasy), i chcę zrobić coś takiego:

java -cp new-config:. -jar application.jar 

Ale nie mogę uzyskać classpath mieć wpis new-config ścieżce przed zawartości słoika aplikacji. Czy trudno jest zakodować, że zawartość JAR jest zawsze pierwszą rzeczą w ścieżce klas?

+0

Czy próbowali uruchomieniem config poza de słoika, w jego własnym pliku jar w ścieżce względem application.jar (../conf/config.jar)? Jeśli to zrobisz, myślę, że możesz ustawić ścieżkę klas wskazując na ten jar konfiguracji w manifeście aplikacji i możesz ustawić nową konfigurację zmieniającą plik config.jar. Chciałbym mieć więcej czasu, aby zrobić demo, aby potwierdzić moją odpowiedź, ale nie mogę ... więc napisałem to jako komentarz – JuanZe

+0

Masz na myśli, zamiast w środku JAR? – Guss

+0

tak, zamiast wewnątrz tego samego słoika co aplikacja, umieszczenie config wewnątrz drugiego słoika ... – JuanZe

Odpowiedz

20

Dlaczego nie wystarczy powołać się na aplikację bez określania -jar i zamiast nazwać główną klasę aplikacji jawnie? Umożliwi to umieszczenie pliku new-config i pliku application.jar na ścieżce klas w wymaganej kolejności:

np. (Zakładając, że „nowy-config” to katalog zawierający plik właściwości przesłoniętych)

java -cp new-config:application.jar Application.Main.Class 

wierzę nazwa głównej klasy można znaleźć w pliku MANIFEST.MF wewnątrz słoika ....

+2

Głównym problemem jest to, że w rzeczywistości nie używam argumentu -cp, ale określam ścieżkę klasy w pliku manifestu, ponieważ aplikacja wymaga wielu innych zewnętrznych JAR-ów - wyodrębnia wszystko, co może być podatne na błędy. Ale założę się, że mogę napisać skrypt, który wyodrębnia ścieżkę klasy z pliku manifestu i automatycznie tworzy odpowiednią linię poleceń, więc jest to prawdopodobnie odpowiedź, której użyję. – Guss

1

Może być niemożliwe przy użyciu tylko CLASSPATH. Istnieją sposoby, aby uzyskać wywołanie ClassLoader.getResource() użyć statycznej ścieżki, aby znaleźć zasób. Jeśli to robi, omija CLASSPATH.

3

Archiwum JAR określone w opcji -jar zastępuje wszystkie pozostałe wartości.

Powinieneś ogólnie zrobić to z zewnętrznym plikiem konfiguracyjnym lub zbudować własne rozwiązanie withod ClassLoader.getResource().

Używamy rozwiązań niestandardowych, aby rozwiązać ten problem - możemy załadować właściwości wewnętrznych tak:

final Properties p = new Properties(); 
p.load(DefaultConfiguration.class.getResourceAsStream("config.properties")); 

Następnie załadowania pliku zewnętrznego w taki sam sposób i nadpisać wartości wewnętrznych z tymi zewnętrznymi.

Dla informacji, w jaki sposób działa klasa ładowanie patrz:

http://java.sun.com/javase/6/docs/technotes/tools/findingclasses.html

+0

To jest rzeczywiście problem. Rozumiem, że nie da się tego obejść, z wyjątkiem uruchamiania aplikacji w inny sposób - jak sugeruje alasdairg, lub pisania niestandardowego kodu ładowania. Dzięki. – Guss

13

w przypadku korzystania z opcji -jar, aby uruchomić aplikację:

... plik JAR jest źródłem wszystkich klas użytkowników oraz inne ustawienia klasa użytkownik ścieżki są ignorowane.

zgodnie z opisem here. Obejściem byłoby określenie ścieżki klas w manifeście pliku jar, aby uwzględnić dodatkową ścieżkę (opisaną jako here).

Jednakże, biorąc pod uwagę, że mówisz tylko o zmianie konfiguracji, możesz wybrać inne podejście, które nie jest zależne od ścieżki klas. Na przykład zwykle konfiguruję aplikacje za pomocą Spring, używając plików właściwości, aby określić lokalizację baz danych, itp. Moja konfiguracja Spring jest spójna w środowiskach testowych, kontroli jakości i środowiskach aktywnych, ale podczas uruchamiania aplikacji przekazuję inny plik właściwości jako argument wiersza poleceń .

Wiosna Konfiguracja Snippet

<bean id="MyDataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource"> 
    <property name="url" value="jdbc:microsoft:sqlserver://${dbServer}:${dbPort};DatabaseName=${dbName}"/> 
    <property name="username" value="${dbUserName}"/> 
    <property name="password" value="${dbPassword}"/> 
    <property name="suppressClose" value="false"/> 
</bean> 

właściwości Plik Fragment

dbServer=MyServer 
dbPort=1433 
dbName=MyDb 
dbUserName=Me 
dbPassword=foobar 
+0

Przekazywanie pliku konfiguracyjnego jako opcjonalnego parametru jest dobrym pomysłem, ale moja aplikacja obecnie akceptuje całkiem sporo parametrów, a dodanie kolejnego może być problematyczne dla użytkowników. Dzięki za odpowiedź. – Guss

+0

Jak uruchomić aplikację? Wydawało mi się, że parametry przekazane zostaną ukryte dla użytkownika przez uruchomienie aplikacji za pośrednictwem skryptu WebStart, .bat lub .sh, itp. – Adamski

+0

Nie - użytkownicy uruchamiają aplikację sami z poziomu wiersza poleceń, przekazując wymagane parametry - daty , pliki do przetworzenia itp. – Guss

Powiązane problemy