Ler o arquivo de propriedades fora do arquivo JAR

Eu tenho um arquivo JAR onde todo o meu código é arquivado para execução. Eu tenho que acessar um arquivo de propriedades que precisa ser alterado / editado antes de cada execução. Eu quero manter o arquivo de propriedades no mesmo diretório onde o arquivo JAR é. Existe alguma maneira de dizer ao Java para pegar o arquivo de propriedades desse diretório?

Nota: Eu não quero manter o arquivo de propriedades no diretório home ou passar o caminho do arquivo de propriedades no argumento da linha de comandos.

   

Portanto, você deseja tratar seu arquivo .properties na mesma pasta que o jarra principal / runnable como um arquivo, e não como um recurso do jar principal / runnable. Nesse caso, minha própria solução é a seguinte:

Primeira coisa: sua arquitetura de arquivo de programa deve ser assim (supondo que seu programa principal seja main.jar e seu principal arquivo de propriedades seja main.properties):

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

Com essa arquitetura, você pode modificar qualquer propriedade no arquivo main.properties usando qualquer editor de texto antes ou enquanto seu main.jar estiver em execução (dependendo do estado atual do programa), pois é apenas um arquivo baseado em texto. Por exemplo, seu arquivo main.properties pode conter:

 app.version=1.0.0.0 app.name=Hello 

Então, quando você executa seu programa principal a partir de sua pasta raiz / base, normalmente você o executa assim:

 java -jar ./main.jar 

ou, imediatamente:

 java -jar main.jar 

No seu main.jar, você precisa criar alguns methods de utilitário para cada propriedade localizada em seu arquivo main.properties; digamos que a propriedade app.version tenha o método getAppVersion() seguinte maneira:

 /** * 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; } 

Em qualquer parte do programa principal que precisa do valor app.version , chamamos seu método da seguinte forma:

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

Eu fiz de outra maneira.

 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. Obtenha o caminho do arquivo Jar.
  2. Obter pasta pai desse arquivo.
  3. Use esse caminho no InputStreamPath com o nome do arquivo de propriedades.

Há sempre um problema ao acessar arquivos no diretório de arquivos a partir de um arquivo jar. Fornecer o classpath em um arquivo jar é muito limitado. Em vez disso tente usar um arquivo bat ou sh para iniciar seu programa. Dessa forma, você pode especificar o seu caminho de class da maneira que desejar, fazendo referência a qualquer pasta em qualquer lugar do sistema.

Além disso, verifique minha resposta nesta pergunta:

fazendo o arquivo .exe para o projeto java contendo sqlite

Eu tenho um caso similar: querer que meu arquivo *.jar acesse um arquivo em um diretório próximo ao dito arquivo *.jar . Consulte também esta resposta .

Minha estrutura de arquivos é:

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

Eu sou capaz de carregar um arquivo (digamos, some.txt ) para um InputStream dentro do arquivo *.jar com o seguinte:

 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()); } 

Então faça o que quiser com o stream

Eu tenho um exemplo de fazer tanto por classpath ou de configuração externa com 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