Load Properties File in Jar

Load properties file in JAR?

The problem is that you are using getSystemResourceAsStream. Use simply getResourceAsStream. System resources load from the system classloader, which is almost certainly not the class loader that your jar is loaded into when run as a webapp.

It works in Eclipse because when launching an application, the system classloader is configured with your jar as part of its classpath. (E.g. java -jar my.jar will load my.jar in the system class loader.) This is not the case with web applications - application servers use complex class loading to isolate webapplications from each other and from the internals of the application server. For example, see the tomcat classloader how-to, and the diagram of the classloader hierarchy used.

EDIT: Normally, you would call getClass().getResourceAsStream() to retrieve a resource in the classpath, but as you are fetching the resource in a static initializer, you will need to explicitly name a class that is in the classloader you want to load from. The simplest approach is to use the class containing the static initializer,
e.g.

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

How to read properties file inside jar?

To obtain the stream you don't need FileInputStream at all. You can get the properties' file stream like this

InputStream is = VerifyFolderStructure.class.getResourceAsStream("/com/abc/properties/config.properties");

How to reload a properties file on a jar

For your first question: you should not do it. A common way woul be to use a builtin configuration in you executable jar with the option of passing a config file as argument. Storing changes of the configuration back into the jar is not a great idea because it means modifing the running binary.

Second question: a usual way to implement such a functionality would be to add a change listener to your config file. This can be done using the java.nio.file package:
https://docs.oracle.com/javase/tutorial/essential/io/notification.html

Read specific property from a property file in a jar

Try something like (untested):

private static int getProductBuildNumber(Path artefactFilePath) throws IOException{
try(FileSystem zipFileSystem = FileSystems.newFileSystem(artefactFilePath, null)){
Path versionPropertiesPath = zipFileSystem.getPath("/version.properties");
Properties versionProperties = new Properties();
try (InputStream is = Files.newInputStream(versionPropertiesPath)){
versionProperties.load(is);
}
return Integer.parseInt(versionProperties.getProperty("product.build.number"));
}
}

Read properties file outside JAR file

So, you want to treat your .properties file on the same folder as the main/runnable jar as a file rather than as a resource of the main/runnable jar. In that case, my own solution is as follows:

First thing first: your program file architecture shall be like this (assuming your main program is main.jar and its main properties file is main.properties):

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

With this architecture, you can modify any property in the main.properties file using any text editor before or while your main.jar is running (depending on the current state of the program) since it is just a text-based file. For example, your main.properties file may contain:

app.version=1.0.0.0
app.name=Hello

So, when you run your main program from its root/base folder, normally you will run it like this:

java -jar ./main.jar

or, straight away:

java -jar main.jar

In your main.jar, you need to create a few utility methods for every property found in your main.properties file; let say the app.version property will have getAppVersion() method as follows:

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

In any part of the main program that needs the app.version value, we call its method as follows:

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

Read properties file from jar

So I found the solution.

I use this method to get the file's InputStream what is in your application's jar:

public InputStream getLanguageStream(String languageName) {
languageName = languageName.replace(".properties", "");
return MainClass.class.getResourceAsStream("/me/s3ns3iw00/resources/languages/" + languageName + ".properties");
}

Now you can load it to Properties:

properties.load(new InputStreamReader(getLanguageStream("ENG"), Charset.forName("UTF-8")));

And an extra:

I use this method to get files' name in jar path:

public List<String> getFileNamesInJarPath(String jarPath) {
List<String> fileNames = new ArrayList<>();
CodeSource src = MainClass.class.getProtectionDomain().getCodeSource();
try {
if (src != null) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream(jar.openStream());
while (true) {
ZipEntry e = zip.getNextEntry();
if (e == null)
break;
String name = e.getName();
if (name.startsWith(jarPath)) {
String substringedName = name.substring(name.lastIndexOf("/") + 1);
if (!substringedName.equalsIgnoreCase("")) {
fileNames.add(substringedName);
}
}
}
} else {
/* Fail... */
}
} catch (IOException e) {
e.printStackTrace();
}
return fileNames;
}

You get a list of jarPath's directory content what is in your applications's jar.

Java properties file in .jar folder

To copy a file (config.properties) into target directory (dist/), you can modify your build.xml:

<target name="-post-compile">
<copy todir="${dist.dir}">
<fileset dir="" includes="config.properties"/>
</copy>
</target>

To package properties file in jar itself, you can just put the properties file into the same directory as your source files. In this case, you can use Class.getResouce() to read it at runtime, but one has to re-package jar to modify it. Source directories are listed under "Source package folders" in project -> properties -> sources.



Related Topics



Leave a reply



Submit