4

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?

Andy Guibert
  • 41,446
  • 8
  • 38
  • 61
Bruno
  • 43
  • 5
  • Fix the third party lib to use `getResourceAsStream()` method like this: `InputStream is = this.getClass().getClassLoader().getResourceAsStream("myproperty.properties");` – Gas Jul 09 '18 at 14:50
  • Unfortunately we dont have access to the third party source code – Bruno Jul 27 '18 at 11:10

2 Answers2

3

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

Andy McCright
  • 1,273
  • 6
  • 8
  • This solved my problem. The property file is read now. Thank you so much – Bruno Jul 10 '18 at 13:17
  • You're welcome - glad to hear that it works for you. I upvoted @Andy Guibert's answer because it is probably the better long term solution, but this answer works for cases where you don't control the library that loads the resource/class/etc. – Andy McCright Jul 10 '18 at 14:06
  • Hi Andy, Just wanted to check if this would work on Linux too ? – Bruno Jul 27 '18 at 11:07
  • @Bruno yes. it should work on all platforms, but I have only tested it on Mac with the Oracle Java 8 JDK. – Andy McCright Jul 28 '18 at 00:04
  • Will this be a good approach to load lot of properties in JVM directly? Will this not make JVM heavy and impact on performance of whole application? Any different opinion? – Joy Dec 22 '21 at 12:31
2

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

Andy Guibert
  • 41,446
  • 8
  • 38
  • 61
  • 1
    Hi @Andy Guibert, Thank you for the response. We are not able to implement the above approach because the code snippet `InputStream is = ClassLoader.getSystemResource("myproperty.properties")` is inside a third party jar. So, is there a way to override the classpath, without the changing the reading logic. – Bruno Jul 09 '18 at 07:04