2010-07-20 17 views
24

Mam prostą aplikację java, która ładuje plik właściwości z bieżącego pakietu.Załaduj zasób z dowolnego miejsca w ścieżce klasy

this.getClass().getResourceAsStream("props.properties"); 

Działa to dobrze, gdy żądany plik właściwości jest w bieżącym pakiecie. Jednak chcę spakować tę aplikację jako plik JAR i zdefiniować i zastąpić nowym plikiem właściwości, w którym go używam. Czy istnieje sposób na załadowanie pierwszego zasobu o nazwie "props.properties", który znajduje się w ścieżce klas?

I ma to być tak proste, aby zastąpić plik właściwości poprzez linię poleceń:

java.exe -classpath props.properties;myJar.jar com.test.MyApp 

nie chcę mieć do rozpakowania JAR i zmodyfikować właściwości pliku, aby coś zmienić. Czuję się jakbym brakuje czegoś oczywiste ...

Odpowiedz

4

Jeśli wszystko inne zawiedzie, można użyć dwóch różnych nazw plików, na przykład props-default.properties wewnątrz myJar.jar i props.properties, aby zastąpić w wierszu polecenia. W twoim kodzie, najpierw próbujesz załadować plik props.properties i zastąpić go props-default.properties, jeśli nie został znaleziony.

0

Nie jestem pewien, ale może: ClassLoader.getResourceAsStream()

EDIT:

Nie sądzę, jest to znacznie różni się this.getClass () .getResourceAsStream() z pytania, ponieważ, jak wspomniano, nadal musisz uzyskać ClassLoader, którego chcesz użyć do załadowania zasobu.

Ponieważ podajesz zasób w -classpath w twoim przykładzie, powinien on być dostępny z tego samego programu ładującego klasy co twoja "główna" klasa (w JVM SUN, to jest sun.misc.Launcher $ AppClassLoader, nie wiem czy to może/nie jest różne dla innych implementacji JVM).

+0

Dźwięki o prawych: Chcesz poprosić ClassLoader, że jest "szefem" tego, który załadował twoją klasę, aby mógł mieć dostęp do większej liczby pakietów. Inną możliwością jest wypróbowanie 'ClassLoader.getSystemClassLoader()' - jak sama nazwa wskazuje, jest "szefem" pozostałych. –

+0

nie ma statycznej metody 'getResourceAsStream()' w klasie 'ClassLoader'. –

+0

i systemowy program ładujący prawdopodobnie załaduje zasoby spoza ścieżki klasy aplikacji, np. Przeglądając katalogi bootstrap w ścieżce instalacji JRE –

26

javadoc for Class.getResourceAsStream() dokumentuje logiki odnośników:

Jeżeli nazwa rozpoczyna się '/' ('\u002f'), a następnie absolutny nazwa surowca jest część nazwy po „/”.

W przeciwnym razie, to bezwzględna nazwa ma następującą postać:
modified_package_name/name

Jeżeli modified_package_name nazwę pakietu tego obiektu z „/” zastąpiono '.' ('\u002e').

Więc innymi słowy, nazwa zasobu przekazywane do metody powinien wyglądać /com/package/p2/props.properties jeśli props.properties jest przechowywany w opakowaniu com.package.p2 zamiast bieżącego klasa jest.

13

Jestem pewien, że jest za późno na odpowiedź, ale może to być interesujące dla googlersów ten mały fragment kodu, który pomoże załadować plik właściwości z dowolnego miejsca w ścieżce Classpath.

ClassLoader cl = ClassLoader.getSystemClassLoader(); 
    if (cl != null) { 
     URL url = cl.getResource(CONF_PROPERTIES); 
     if (url == null) { 
      url = cl.getResource("/" + CONF_PROPERTIES); 
     } 
     if (url != null) { 
      try { 
       InputStream in = url.openStream(); 
       props = new Properties(); 
       props.load(in); 
      } catch (IOException e) { 
       // Log the exception 
      } finally { 
       // close opened resources 
      } 

     } 
    } 
+2

Czy istnieje szczególny powód, dla którego nie używasz getResourceAsStream? –

+0

Używam tego rodzaju inicjalizacji, ponieważ rozwijam aplikację EE. Podczas programowania Moja aplikacja wie o tym, że plik rzuca Eclipse Classpath. Ale podczas tworzenia EAR, aplikacja wie o tym pliku, który rzuca konfigurację ClassPath na serwer WebSphere. Doceniam kolejne eleganckie rozwiązanie. –

+0

Rozumiem. Nie spodziewałbym się, że to wyrzuci różne wyjątki (lub przynajmniej spodziewaliby się, że obaj mają wspólnego rodzica, jak IOException). Interesujące podejście. –

Powiązane problemy