2015-04-23 15 views
5

Ho un file app.properties nel mio progetto Maven nella cartella resources come mostrato qui (semplificato):.properties carico da IDE e anche al di fuori dei JAR

 
myApp 
    |----src 
    |  | 
    |  |--main 
    |   |--java 
    |   | |--ApplicationInitializer.java 
    |   | 
    |   |--resources 
    |    |--app.properties 
    | 
    |---target 
     |--myApp.jar 
     |--app.properties  

In ApplicationInitializer classe voglio caricare oggetti di il file con i seguenti app.properties pezzo di codice:

Properties props = new Properties(); 

String path = "/app.properties"; 

try { 
    props.load(ApplicationInitializer.class.getResourceAsStream(path)); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

System.out.println(props.getProperty("property")); 

Questo pezzo di codice carica proprietà in modo corretto quando l'eseguo da dentro la mia IDE, ma non riesce ad eccezione

Exception in thread "main" java.lang.NullPointerException 
    at java.util.Properties$LineReader.readLine(Properties.java:434) 
    at java.util.Properties.load0(Properties.java:353) 
    at java.util.Properties.load(Properties.java:341) 
    at cz.muni.fi.fits.ApplicationInitializer.main(ApplicationInitializer.java:18) 

quando si cerca di eseguire come file JAR.

Per la creazione di un file jar Sto usando combinazione di maven-shade-plugin, maven-jar-plugin (per l'esclusione file di proprietà al di fuori della JAR) e maven-resources-plugin (per la copia di file di proprietà di cartella specifica) in pom.xml file come mostrato qui :

<plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-shade-plugin</artifactId> 
     <version>2.3</version> 
     <executions> 
      <execution> 
       <phase>package</phase> 
       <goals> 
        <goal>shade</goal> 
       </goals> 
       <configuration> 
        <transformers> 
         <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
          <mainClass>cz.muni.fi.fits.ApplicationInitializer</mainClass> 
         </transformer> 
        </transformers> 
       </configuration> 
      </execution> 
     </executions> 
    </plugin> 

    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-jar-plugin</artifactId> 
     <version>2.5</version> 
     <configuration> 
      <excludes> 
       <exclude>**/*.properties</exclude> 
      </excludes> 
     </configuration> 
    </plugin> 

    <plugin> 
     <artifactId>maven-resources-plugin</artifactId> 
     <version>2.7</version> 
     <executions> 
      <execution> 
       <id>copy-resource</id> 
       <phase>package</phase> 
       <goals> 
        <goal>copy-resources</goal> 
       </goals> 
       <configuration> 
        <outputDirectory>${basedir}/target</outputDirectory> 
        <resources> 
         <resource> 
          <directory>src/main/resources</directory> 
         </resource> 
        </resources> 
       </configuration> 
      </execution> 
     </executions> 
    </plugin> 

ho poi acceso il codice nel metodo principale per questo:

Properties props = new Properties(); 

String path = "./app.properties"; 

try (FileInputStream file = new FileInputStream(path)) { 
    props.load(file); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

System.out.println(props.getProperty("property")); 

ed è riuscito a caricare le proprietà dal file durante l'esecuzione di JAR ma questa volta non ero in grado di caricarle durante l'esecuzione in IDE, si è conclusa con la stessa eccezione di cui sopra.

Quindi la mia domanda è: Come impostare il filepath (o il file pom.xml?) Che sarò in grado di caricare le proprietà in esecuzione sia dal file IDE che da quello JAR?

Grazie in anticipo :)

+0

vedo nel 'target' hai' myApp.jar' e 'app.properties'. Puoi controllare se 'app.properties' si trova nel file' .jar'? – Kuba

+0

No, non è così, è per questo che sto usando 'maven-jar-plugin' per escluderlo dal jar –

+0

Perché stai cercando di mettere il file delle proprietà al di fuori del file jar? Se lo fai, non puoi usare 'getResourcesAsStream()'. – khmarbaise

risposta

0

Il modo in cui si sta lavorando in questo momento si dipende la directory di lavoro del vostro processo di Java. In genere questa è la tua linea di comando (nota anche come shell), quando si avvia l'applicazione.

Sulla maggior parte degli IDE è possibile configurare questa directory nelle impostazioni del programma di avvio. (Per eclipse è nella seconda scheda 'Argomenti') Quindi sarà necessario nella directory di destinazione (per eclissi c'è un pulsante 'Area di lavoro ...')

In particolare in intelliJ è possibile trovare questa impostazione in Esegui/Modifica configurazioni ... Si aprirà una finestra come questa: enter image description here Qui puoi modificare la directory di lavoro. Devi semplicemente aggiungere un obiettivo alla fine.

Modifica: In realtà hai aggiunto src/main/risorse alla fine.

+0

Allora qual'è il tuo suggerimento? Mi dispiace ma non capisco la tua risposta. –

+0

Il mio suggerimento è di configurare l'IDE per avviare il processo java con la directory di lavoro corretta. Che IDE stai usando? –

+0

Sto usando IntelliJ IDEA 14 –

0

Nel codice Java leggere il file app.properties in questo modo:

final String ROOT_PATH = "custom.path"; // Or whatever you most like 
final String PROPERTIES_FILE = "app.properties"; 

// start :: try-catch here to manage I/O resources 
File directory = new File(System.getProperty(ROOT_PATH), "conf"); 
File file = new File(directory, PROPERTIES_FILE); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); 
// ... 
// end :: try-catch here to manage I/O resources 

Poi bisogna modi per l'impostazione/dichiarando custom.path:

  • Dichiarare come una variabile d'ambiente
  • Impostando a tempo di esecuzione (proprietà dell'ambiente) con -Dcustom.path=/somewhere/in/your/filesystem (preferisco questo, a meno che il percorso sia corretto e/o condiviso OSS diverse applicazioni)

Poi, alla fine è necessario copiare/inserire il file app.properties all'interno /somewhere/in/your/filesystem/conf. E perché all'interno di /conf? Perché lo usi quando dichiari il campo directory. Se non lo desideri, non impostarlo e elimina la parte , "conf".

Inoltre, per la sua esecuzione "a livello locale" (nel vostro IDE) utilizzare il VM opzioni impostazione (IntelliJ IDEA):

enter image description here

+0

Grazie, sembra promettente, ma è un po 'eccessivo per me definire il percorso come variabile di ambiente e inoltre non posso usare l'argomento di runtime perché farebbe male ai miei argomenti correnti. –

+0

@Supermartzin Riesco a capire la parte "variabile d'ambiente", ma gli argomenti di runtime (proprietà di ambiente) si possono avere quanti ne vuoi e non interferiranno tra loro –

+0

Certo, hai ragione, ma indebolirebbe un lucidità del mio programma e voglio farlo. Grazie comunque per il consiglio. –