3
votes

We are migrating our application from WAS 6.1 to Liberty. Our application uses third party jars that read property files byInputStream is = ClassLoader.getSystemResource("myproperty.properties"). In WAS 6.1, we set server classpath to the location of myproperty.properties. We tried the below approaches to set classpath in Liberty, but nothing works

Approach 1: Set the below in jvm.options (D:\ConfigFiles\DEV\ - path containing myproperty.properties)

-Djava.class.path=D:\\ConfigFiles\\DEV\\

Approach 2: Setting the classloader in server.xml,

<library id="config">
 <folder dir="${server.config.dir}/config/" includes="*.properties" scanInterval="5s"/>
</library>

<enterpriseApplication id="applicationEAR" location="application.ear" name="application">
 <classloader privateLibraryRef="config"/>
</enterpriseApplication>

Please let us know if there is any other ways to override/set classpath in Liberty profile?

2
Fix the third party lib to use getResourceAsStream() method like this: InputStream is = this.getClass().getClassLoader().getResourceAsStream("myproperty.properties"); - Gas
Unfortunately we dont have access to the third party source code - Bruno

2 Answers

3
votes

Try setting this property in jvm.options (instead of -Djava.class.path=path/to/propertyDir):

-Xbootclasspath/a:path/to/propertyDir

This will append the path of the property directory (containing your resource file) to the JVM's bootstrap classpath. Because this is an append, it should also work in Java 9+ (some related options have been removed in Java 9).

I suspect that the reason -Djava.class.path=... doesn't work is that the JVM gets the classpath from the WLP server script - so the system property is essentially applied too late in the startup of the server JVM.

You might also be able to put the properties file(s) in your JVM's lib/ext directory, but I haven't tested that. The -Xbootclasspath/a:path approach works for me on Mac - I assume it will also work on Windows.

HTH, Andy

2
votes

If your end goal is to load a properties file, a more straightforward way to do this would be using a bootstrap/env/system property or <jndiEntry> in server.xml to store the location of the properties file, and then load it. For example, using an environment variable:

(in server.xml file)

<server>
  <featureManager>
    <feature>jndi-1.0</feature>
    ...
  </featureManager>

  <jndiEntry jndiName="configDir" value="D:\\ConfigFiles\\Dev"/>    
</server>

Then, you can load the resource in your application like this:

@Resource(lookup = "configDir")
String configDir;

InputStream is = new FileInputStream(configDir + "/myproperty.properties");

Or, if you will always put your config property files somewhere under ${server.config.dir}, then you can utilize the built-in SERVER_CONFIG_DIR environment variable in Liberty:

String configDir = System.getenv("SERVER_CONFIG_DIR"); // equivalent to ${server.config.dir} in server.xml
InputStream is = new FileInputStream(configDir + "/myproperty.properties");

On the topic of managing configuration, check out MicroProfile Config (e.g. <feature>microProfile-1.2</feature>) which you may find useful:
Configuring microservices with Liberty