目标是阅读一个名为“环境”的参数。执行测试时从属性文件中。测试由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
)中的资源。
我很乐意提供更多信息,我们将不胜感激。
答案 0 :(得分:0)
您的代码存在两个问题:
AFAICT,您的environment.properties
文件直接位于您的jre/lib/ext
。唉,Java extension mechanism只通过扩展类公开jre/lib/ext
(或java.ext.dirs
系统属性中列出的任何其他目录)中的JAR 的内容加载器。
扩展类加载器是加载String
的系统类加载器的子;因此,您通过String.class.getClassLoader()
获取的系统类加载器将看不到您的environment.properties
(即使捆绑在JAR中)。请尝试使用应用程序类加载器:ReadEnvironmentTest.class.getClassLoader()
;它将委托给它的父,扩展类加载器。