J'ai un fichier JAR où tout mon code est archivé pour l'exécution. Je dois accéder à un fichier de propriétés qui doit être modifié/modifié avant chaque exécution. Je souhaite conserver le fichier de propriétés dans le même répertoire que le fichier JAR. Est-il possible de demander à Java de récupérer le fichier de propriétés dans ce répertoire?
Remarque: je ne souhaite pas conserver le fichier de propriétés dans le répertoire de base ni transmettre le chemin du fichier de propriétés dans l'argument de ligne de commande.
Par conséquent, vous souhaitez traiter votre fichier .properties
dans le même dossier que le fichier jar principal/exécutable en tant que fichier plutôt qu'en tant que ressource du fichier jar principal/exécutable. Dans ce cas, ma propre solution est la suivante:
La première chose à faire: l’architecture de votre programme doit être la suivante (en supposant que votre programme principal est main.jar et que son fichier de propriétés principal est main.properties):
./ - the root of your program
|__ main.jar
|__ main.properties
Avec cette architecture, vous pouvez modifier n’importe quelle propriété du fichier main.properties en utilisant n’importe quel éditeur de texte avant ou pendant l’exécution de votre fichier main.jar (selon l’état actuel du programme), car il s’agit d’un fichier texte. Par exemple, votre fichier main.properties peut contenir:
app.version=1.0.0.0
app.name=Hello
Ainsi, lorsque vous exécutez votre programme principal à partir de son dossier racine/base, vous l’exécuterez normalement comme suit:
Java -jar ./main.jar
ou tout de suite:
Java -jar main.jar
Dans votre fichier main.jar, vous devez créer quelques méthodes utilitaires pour chaque propriété trouvée dans votre fichier main.properties. supposons que la propriété app.version
aura la méthode getAppVersion()
comme suit:
/**
* Gets the app.version property value from
* the ./main.properties file of the base folder
*
* @return app.version string
* @throws IOException
*/
import Java.util.Properties;
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;
}
Dans toute partie du programme principal nécessitant la valeur app.version
, nous appelons sa méthode comme suit:
String version = null;
try{
version = getAppVersion();
}
catch (IOException ioe){
ioe.printStackTrace();
}
Je l'ai fait par un autre moyen.
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();
}
Il y a toujours un problème pour accéder aux fichiers de votre répertoire à partir d'un fichier jar. Fournir le classpath dans un fichier jar est très limité. Au lieu de cela, essayez d’utiliser un fichier bat ou un fichier sh pour démarrer votre programme. De cette façon, vous pouvez spécifier votre chemin de classe quand bon vous semble, en référençant n'importe quel dossier du système.
Vérifiez également ma réponse à cette question:
Création du fichier .exe pour un projet Java contenant sqlite
J'ai un cas similaire: vouloir que mon fichier *.jar
puisse accéder à un fichier situé dans un répertoire à côté dudit fichier *.jar
. Reportez-vous à CETTE RÉPONSE aussi.
Ma structure de fichier est:
./ - the root of your program
|__ *.jar
|__ dir-next-to-jar/some.txt
Je suis en mesure de charger un fichier (par exemple, some.txt
) dans un flux InputStream dans le fichier *.jar
avec les éléments suivants:
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());
}
Ensuite, faites ce que vous voulez avec la variable stream
J'ai un exemple de faire les deux par classpath ou de config externe avec 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
Cela fonctionne pour moi. Chargez votre fichier de propriétés à partir de current directory
Properties properties = new Properties();
properties.load(new FileReader(new File(".").getCanonicalPath() + File.separator + "Java.properties"));
properties.forEach((k, v) -> {
System.out.println(k + " : " + v);
});
Assurez-vous que Java.properties
est au current directory
. Vous pouvez simplement écrire un petit script de démarrage qui bascule dans le bon répertoire auparavant, comme
#! /bin/bash
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $scriptdir
Java -jar MyExecutable.jar
cd -
Dans votre projet, placez simplement le fichier Java.properties
à la racine de votre projet, afin que ce code fonctionne également à partir de votre IDE.