jeudi 3 août 2017

Read a properties file in a test that is located in JVM lib directory

The objective is to read a parameter called 'environment' from a properties file when executing a test. The test is executed by Maven, but the application which has the test is run in a WebSphere server.

Cause of problem

The problem is that in WebSphere I have a directory where there are a lot of jars, and WebSphere loads all of them by a ClassLoader so that all applications running in the server share the same jars. In that directory I have a properties file (let's call environment.properties) and a static method that gives me the value of the environment as a String, which is called in the next way:

String environment = EnvironmentVariables.getEnvironment();

The implementation of that method is something like this:

Properties properties = new Properties();

InputStream inputStream = EnvironmentVariables.class.getClassLoader().getResourceAsStream("environment.properties");
if (inputStream == null) {
  inputStream = new FileInputStream("c:\\environment.properties");
}
properties.load(inputStream);
inputStream.close();

return properties.getProperty("entorno");

As you can see, this will work only when the same classloader loads the properties file and the class EnvironmentVariables (or when the properties file is located in c:\environment.properties). But when running the tests, the classloader of maven will load the EnvironmentVariables class, and the classloader of JVM will load the properties file, am I right?

So I have placed the properties file in the JVM directory:

/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/jre/lib/environment.properties

and tried to get the value of the environment in the next test:

@Test
public void readEnvironment() throws IOException {
    final Properties properties = new Properties();
    final InputStream inputStream = String.class.getClassLoader().getResourceAsStream("environment.properties");
    properties.load(inputStream);
    inputStream.close();

    final String environment = properties.getProperty("environment");
    Assert.assertEquals("LOCAL", environment);
}

But it gives me a java.lang.NullPointerException running mvn clean test:

Running ReadEnvironmentTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.056 sec <<< FAILURE!
readEnvironment(ReadEnvironmentTest)  Time elapsed: 0.008 sec  <<< ERROR!
java.lang.NullPointerException

at ReadEnvironmentTest.readEnvironment(ReadEnvironmentTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)``

Line 23 (where the error occurs) is the next line:

final InputStream inputStream = String.class.getClassLoader().getResourceAsStream("environment.properties");

I have tried to use the static method mentioned above, but as expected, it return null.

As last mention, I am developing in a Mac, but the test is supposed to be run in a CentOS.

So, to sum up, I am not able to read a properties file in a test, which running the application in a server is supposed to be in a directory.

I will be glad to provide more information, and any help would be appreciated.

Aucun commentaire:

Enregistrer un commentaire