Leggi il file delle proprietà al di fuori del file JAR

Ho un file JAR in cui tutto il mio codice è archiviato per essere eseguito. Devo accedere a un file delle proprietà che deve essere modificato / modificato prima di ogni corsa. Voglio mantenere il file delle proprietà nella stessa directory in cui si trova il file JAR. C’è comunque da dire a Java di prendere il file delle proprietà da quella directory?

Nota: non voglio mantenere il file delle proprietà nella directory home o passare il percorso del file delle proprietà nell’argomento della riga di comando.

Pertanto, si desidera trattare il file .properties nella stessa cartella del jar principale / eseguibile come un file anziché come una risorsa del jar principale / eseguibile. In tal caso, la mia soluzione è la seguente:

Per prima cosa: l’architettura del tuo file di programma sarà così (supponendo che il tuo programma principale sia main.jar e il suo file di proprietà principale sia main.properties):

 ./ - the root of your program |__ main.jar |__ main.properties 

Con questa architettura, è ansible modificare qualsiasi proprietà nel file main.properties utilizzando qualsiasi editor di testo prima o durante l’esecuzione di main.jar (a seconda dello stato corrente del programma) poiché si tratta solo di un file di testo. Ad esempio, il tuo file main.properties può contenere:

 app.version=1.0.0.0 app.name=Hello 

Quindi, quando esegui il tuo programma principale dalla sua cartella root / base, normalmente lo eseguirai in questo modo:

 java -jar ./main.jar 

o, subito:

 java -jar main.jar 

Nel tuo main.jar, devi creare alcuni metodi di utilità per ogni proprietà trovata nel tuo file main.properties; diciamo che la proprietà app.version avrà il metodo getAppVersion() come segue:

 /** * Gets the app.version property value from * the ./main.properties file of the base folder * * @return app.version string * @throws IOException */ public static String getAppVersion() throws IOException{ String versionString = null; //to load application's properties, we use this class Properties mainProperties = new Properties(); FileInputStream file; //the base folder is ./, the root of the main.properties file String path = "./main.properties"; //load the file handle for main.properties file = new FileInputStream(path); //load all the properties from this file mainProperties.load(file); //we have loaded the properties, so close the file handle file.close(); //retrieve the property we are intrested, the app.version versionString = mainProperties.getProperty("app.version"); return versionString; } 

In qualsiasi parte del programma principale che ha bisogno del valore di app.version , chiamiamo il suo metodo come segue:

 String version = null; try{ version = getAppVersion(); } catch (IOException ioe){ ioe.printStackTrace(); } 

L’ho fatto in altro modo.

 Properties prop = new Properties(); try { File jarPath=new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()); String propertiesPath=jarPath.getParentFile().getAbsolutePath(); System.out.println(" propertiesPath-"+propertiesPath); prop.load(new FileInputStream(propertiesPath+"/importer.properties")); } catch (IOException e1) { e1.printStackTrace(); } 
  1. Ottieni il percorso del file Jar.
  2. Ottieni la cartella principale di quel file.
  3. Utilizzare quel percorso in InputStreamPath con il nome del file delle proprietà.

C’è sempre un problema nell’accedere ai file nella tua directory di file da un file jar. Fornire il classpath in un file jar è molto limitato. Prova invece a utilizzare un file bat o un file sh per avviare il programma. In questo modo è ansible specificare il classpath in ogni caso, facendo riferimento a qualsiasi cartella in qualsiasi punto del sistema.

Controlla anche la mia risposta su questa domanda:

creare file .exe per il progetto java contenente sqlite

Ho un caso simile: volendo il mio file *.jar per accedere a un file in una directory accanto a detto file *.jar . Fare riferimento anche a QUESTA RISPOSTA .

La mia struttura di file è:

 ./ - the root of your program |__ *.jar |__ dir-next-to-jar/some.txt 

Sono in grado di caricare un file (ad esempio, some.txt ) in un InputStream all’interno del file *.jar con il seguente:

 InputStream stream = null; try{ stream = ThisClassName.class.getClass().getResourceAsStream("/dir-next-to-jar/some.txt"); } catch(Exception e) { System.out.print("error file to stream: "); System.out.println(e.getMessage()); } 

Quindi fai tutto ciò che vuoi con il stream

Ho un esempio di fare entrambi per classpath o da una configurazione esterna con log4j2.properties

 package org.mmartin.app1; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.LogManager; public class App1 { private static Logger logger=null; private static final String LOG_PROPERTIES_FILE = "config/log4j2.properties"; private static final String CONFIG_PROPERTIES_FILE = "config/config.properties"; private Properties properties= new Properties(); public App1() { System.out.println("--Logger intialized with classpath properties file--"); intializeLogger1(); testLogging(); System.out.println("--Logger intialized with external file--"); intializeLogger2(); testLogging(); } public void readProperties() { InputStream input = null; try { input = new FileInputStream(CONFIG_PROPERTIES_FILE); this.properties.load(input); } catch (IOException e) { logger.error("Unable to read the config.properties file.",e); System.exit(1); } } public void printProperties() { this.properties.list(System.out); } public void testLogging() { logger.debug("This is a debug message"); logger.info("This is an info message"); logger.warn("This is a warn message"); logger.error("This is an error message"); logger.fatal("This is a fatal message"); logger.info("Logger's name: "+logger.getName()); } private void intializeLogger1() { logger = LogManager.getLogger(App1.class); } private void intializeLogger2() { LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false); File file = new File(LOG_PROPERTIES_FILE); // this will force a reconfiguration context.setConfigLocation(file.toURI()); logger = context.getLogger(App1.class.getName()); } public static void main(String[] args) { App1 app1 = new App1(); app1.readProperties(); app1.printProperties(); } } --Logger intialized with classpath properties file-- [DEBUG] 2018-08-27 10:35:14.510 [main] App1 - This is a debug message [INFO ] 2018-08-27 10:35:14.513 [main] App1 - This is an info message [WARN ] 2018-08-27 10:35:14.513 [main] App1 - This is a warn message [ERROR] 2018-08-27 10:35:14.513 [main] App1 - This is an error message [FATAL] 2018-08-27 10:35:14.513 [main] App1 - This is a fatal message [INFO ] 2018-08-27 10:35:14.514 [main] App1 - Logger's name: org.mmartin.app1.App1 --Logger intialized with external file-- [DEBUG] 2018-08-27 10:35:14.524 [main] App1 - This is a debug message [INFO ] 2018-08-27 10:35:14.525 [main] App1 - This is an info message [WARN ] 2018-08-27 10:35:14.525 [main] App1 - This is a warn message [ERROR] 2018-08-27 10:35:14.525 [main] App1 - This is an error message [FATAL] 2018-08-27 10:35:14.525 [main] App1 - This is a fatal message [INFO ] 2018-08-27 10:35:14.525 [main] App1 - Logger's name: org.mmartin.app1.App1 -- listing properties -- dbpassword=password database=localhost dbuser=user