读取位于JVM lib目录中的测试中的属性文件

时间:2017-08-03 07:18:00

标签: java maven testing jvm

目标是阅读一个名为“环境”的参数。执行测试时从属性文件中。测试由Maven执行,但是具有测试的应用程序在WebSphere服务器中运行。

问题原因

问题是在WebSphere中我有一个存在大量jar的目录,而WebSphere通过ClassLoader加载所有这些jar,以便在服务器中运行的所有应用程序共享相同的jar。在该目录中,我有一个属性文件(让我们调用environment.properties)和一个静态方法,它将环境的值作为String给出,并以下一种方式调用:

String environment = EnvironmentVariables.getEnvironment();

该方法的实现是这样的:

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");

正如您所看到的,只有当同一个类加载器加载属性文件和类EnvironmentVariables时(或者当属性文件位于c:\ environment.properties中时),这才会起作用。但是在运行测试时,maven的类加载器将加载EnvironmentVariables类,JVM的类加载器将加载属性文件,对不对?

所以我将属性文件放在JVM目录中:

  

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

并试图在下一次测试中获得环境的价值:

@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);
}

但是它给了我一个运行mvn clean test的java.lang.NullPointerException:

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)``

第23行(发生错误的地方)是下一行:

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

我尝试使用上面提到的静态方法,但正如预期的那样,它会返回null

如上所述,我在Mac上开发,但测试应该在CentOS中运行。

摘要

我无法在测试中读取属性文件,在服务器中运行应用程序应该在目录中。我的意思是,我无法读取位于JRE路径(jre/lib/ext)中的资源。

我很乐意提供更多信息,我们将不胜感激。

1 个答案:

答案 0 :(得分:0)

您的代码存在两个问题:

  1. AFAICT,您的environment.properties 文件直接位于您的jre/lib/ext。唉,Java extension mechanism只通过扩展类公开jre/lib/ext(或java.ext.dirs系统属性中列出的任何其他目录)中的JAR 内容加载器。

  2. 扩展类加载器是加载String系统类加载器的;因此,您通过String.class.getClassLoader()获取的系统类加载器将看不到您的environment.properties(即使捆绑在JAR中)。请尝试使用应用程序类加载器:ReadEnvironmentTest.class.getClassLoader();它将委托给它的父,扩展类加载器。