Carica la risorsa da qualsiasi posizione nel classpath

Ho una semplice applicazione java che carica un file di proprietà dal pacchetto corrente.

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

Funziona bene quando il file di proprietà che voglio è nel pacchetto corrente. Tuttavia, voglio impacchettare questa applicazione come JAR e definire e sovrascrivere un nuovo file delle proprietà in cui lo utilizzo. C’è un modo per caricare la prima risorsa denominata “props.properties” che si trova sul classpath?

Voglio che sia facile sovrascrivere il file delle proprietà tramite la riga di comando:

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

Non voglio dover decomprimere il JAR e modificare il file delle proprietà per cambiare qualcosa. Mi sento come se mi mancasse qualcosa di ovvio …

Se tutto il resto fallisce potresti usare due diversi nomi di file, ad esempio props-default.properties in myJar.jar e props.properties per sovrascrivere la riga di comando. Nel codice, si proverebbe a caricare prima il file props.properties e il fallback su props-default.properties se non è stato trovato.

Class.getResourceAsStream() per Class.getResourceAsStream() documenta la logica di ricerca:

Se il nome inizia con un '/' ( '\u002f' ), il nome assoluto della risorsa è la parte del nome che segue il ‘/’.

Altrimenti, il nome assoluto ha la seguente forma:
modified_package_name/name

Dove il modified_package_name è il nome del pacchetto di questo object con “/” sostituito da '.' ( '\u002e' ).

In altre parole, il nome della risorsa passato al metodo dovrebbe apparire come /com/package/p2/props.properties se props.properties è memorizzato nel pacchetto com.package.p2 invece delle attuali.

Sono sicuro che sia troppo tardi per la risposta, ma potrebbe essere interessante per i googler questi piccoli aiutanti di snippet di codice per caricare un file di proprietà da qualsiasi punto del 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 } } } 

Non sono sicuro, ma forse: ClassLoader.getResourceAsStream()

MODIFICARE:

Non penso che questo sia significativamente diverso da this.getClass().getResourceAsStream() dalla domanda, poiché come accennato devi ancora ottenere il ClassLoader che vuoi utilizzare per caricare la risorsa.

Dato che nel tuo esempio fornisci la risorsa nel percorso -classpath , dovrebbe essere disponibile dallo stesso programma di caricamento class della tua class “main” (nella SUN JVM, che è sun.misc.Launcher$AppClassLoader , non è sicuro se questo può / fa variare per altre implementazioni JVM).