Carica il file delle proprietà in JAR?

Ho problemi quando uno dei vasi da cui dipende la mia app Web tenta di caricare un file di proprietà all’interno del jar. Ecco il codice nel barattolo.

static { Properties props = new Properties(); try { props.load(ClassLoader.getSystemResourceAsStream("someProps.properties")); } catch (IOException e) { e.printStackTrace(); } someProperty = props.getProperty("someKey"); } 

Il file delle proprietà si trova nella mia directory “src / main / resources” del progetto Maven. Quando eseguo questo codice dal test di junit in Eclipse, viene eseguito correttamente. Quando il progetto viene creato con Maven in un jar e incluso come dipendenza nella mia app Web, non riesce a individuare il file delle proprietà. So che il file delle proprietà si trova nella directory di base del deploy su jar, non so come risolvere questo problema.

Il problema è che stai usando getSystemResourceAsStream . Usa semplicemente getResourceAsStream . Le risorse di sistema vengono caricate dal classloader del sistema, che non è quasi certamente il caricatore di classi in cui viene caricato il tuo jar quando viene eseguito come webapp.

Funziona in Eclipse perché all’avvio di un’applicazione, il classloader del sistema viene configurato con il tuo jar come parte del suo classpath. Ad esempio, java -jar my.jar caricherà my.jar nel caricatore di classi di sistema. Questo non è il caso delle applicazioni Web: i server delle applicazioni utilizzano il caricamento di classi complesse per isolare le applicazioni Web l’una dall’altra e dai componenti interni del server delle applicazioni. Ad esempio, consultare il how-to del classloader tomcat e il diagramma della gerarchia del classloader utilizzato.

MODIFICA: Normalmente, chiamerai getClass().getResourceAsStream() per recuperare una risorsa nel classpath, ma mentre stai recuperando la risorsa in un inizializzatore statico, dovrai nominare esplicitamente una class che si trova nel classloader che vuoi caricare da. L’approccio più semplice consiste nell’utilizzare la class contenente l’inizializzatore statico, ad es

 [public] class MyClass { static { ... props.load(MyClass.class.getResourceAsStream("/someProps.properties")); } } 

Per la cronaca, questo è documentato in Come faccio ad aggiungere risorse al mio JAR? (illustrato per i test unitari ma lo stesso vale per una risorsa “regolare”):

Per aggiungere risorse al classpath per i test delle unità, si segue lo stesso schema utilizzato per aggiungere risorse al JAR, tranne per il fatto che la directory in cui si posizionano le risorse è ${basedir}/src/test/resources . A questo punto avresti una struttura di directory del progetto che sarebbe simile alla seguente:

 my-app |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mycompany | | `-- app | | `-- App.java | `-- resources | `-- META-INF | |-- application.properties `-- test |-- java | `-- com | `-- mycompany | `-- app | `-- AppTest.java `-- resources `-- test.properties 

In un test unitario è ansible utilizzare un semplice snippet di codice come il seguente per accedere alla risorsa richiesta per il test:

 ... // Retrieve resource InputStream is = getClass().getResourceAsStream("/test.properties" ); // Do something with the resource ...