开发者

How To: Dynamically-defined properties in Java

开发者 https://www.devze.com 2023-01-04 23:07 出处:网络
How can I define some properties dynamically in Java. For now, I\'m using a prope开发者_如何学编程rties file, but I need to change these properties before installation, so these properties should be s

How can I define some properties dynamically in Java. For now, I'm using a prope开发者_如何学编程rties file, but I need to change these properties before installation, so these properties should be set in a file outside the jar (or install) file.

These properties define my IBatis connection.


Keep going with the .properties and load the file as a resource.

If it is in the classpath it would be found.

What I use, because it is much easier to me is a resource bundle instead.

edit

If the file is in your classpath you can loaded it either as a resource with: Some.class.loadResource(...) or what I do is use a ResourceBundle which does basically the same.

For instance if I have:

import java.util.ResourceBundle;

public class ResourceBundleTest {
    public static void main( String [] args ) {
        ResourceBundle bundle = ResourceBundle.getBundle("connection");
        for( String key: bundle.keySet() ){
            System.out.printf("bundle[%s]=%s%n",key, bundle.getString(key));
        }
    }
}

I can load that file if is in the class path. The property is outside, in "some/nested/dir"

$ls -l some/nested/dir/
total 8
-rw-r--r--  1 oscarreyes  staff  35 Jun 25 12:06 connection.properties
$cat some/nested/dir/connection.properties 
name=Oscar
lastName=Reyes
age=0x1F

If I run it without adding that directory to my classpath it wont work:

$java ResourceBundleTest 
Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name connection, locale es_ES
    at java.ut...ceBundle.java:1427)
    at java.ut...urceBundle.java:1250)
    at java.ut...ceBundle.java:705)
    at Resourc...st.java:6)

But if I add the directory to my classpath, then the file will be found easily.

$java -cp some/nested/dir/:.  ResourceBundleTest 
bundle[lastName]=Reyes
bundle[age]=0x1F
bundle[name]=Oscar
$

In a similar fashion, you can have a .jar file, and put your .properties file wherever you want, you just have to include it in your classpath.

The equivalent using properties would be:

import java.util.Properties;

public class LoadProperties {
    public static void main( String [] args ) throws java.io.IOException {
        Properties properties = new Properties();
        properties.load( LoadProperties.class.getResourceAsStream("connection.properties"));
        properties.list( System.out );
    }
}

But for some reason I prefer the resource bundle.


Just put the file in one of the paths covered by the runtime classpath, or to add the file's path to the (default) runtime classpath. This way the Java code can continue accessing it as classpath resource.

When you execute JAR files using java -jar command or by doubleclicking the file, the -cp or -classpath arguments and even the %CLASSPATH% environment variable will be ignored. You can define the JAR file's default classpath as Class-Path entry in META-INF/MANIFEST.MF file.

E.g.

Class-Path: .

The dot . means that the path where the JAR file is currently sitting is included in the runtime classpath. So if you put the properties file in the same folder as the JAR file, it'll work.

You can also specify an absolute disk file system path:

Class-Path: /var/foo

This way the folder /var/foo is taken in the runtime classpath. So if you put the properties file in that folder, it'll work.


A properties file is fine, you just have to include it in the classpath and it can live outside the jar.

If you want to get fancier, you have the Preferences API, but while that will keep things more to the standard of your operating system, it can make deployment complicated as you will have different locations for your configuration depending on your platform, and will require a platform dependent install.


Yes, Using a properties file is common practice. In addition the general practice is to have separate properties file for each environment and the build process will pick the right one depending on the target. All you need to do is keep the file in classpath and use classloader to find it.

0

精彩评论

暂无评论...
验证码 换一张
取 消