java - getResourceAsStream 在一种情况下返回 null,但在另一种情况下不返回 null,具有相同的类路径

标签 java eclipse maven junit contextclassloader

我有同一应用程序的两个衍生版本,例如版本 (A) 和 (B)。它们各自包含项目: (1) test-data-war,具有 target/test-classes/log4j.properties,以及 (2) test-kernel,具有 target/test-classes/log4j.properties target/test-classes/test.properties

当我在 (1) 中运行特定的 jUnit 测试时,它会调用 (2) 中的一个方法,该方法调用 Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName); 在 (A) 中,resourceName 为“log4j.properties”,结果不为 null,且带有 a (1) 中的路径,但将 resourceName 作为“test.properties”时,它为 null。在 (B) 中,当 resourceName 为“log4j.properties”时,它不为 null,而对于 (1) 中的路径,当 resourceName 为“test.properties”时,它不为 null (2) 中的路径为 null。

为什么(A)中的Thread.currentThread().getContextClassLoader().getResourceAsStream("test.properties");为null?起初,我认为类路径可能不同,但 (1) 和 (2) 的类路径是相同的。

编辑: (1) 的 .classpath 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/classes"    path="src/main/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
     <classpathentry kind="src" output="target/test-classes"  path="src/test/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
     </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes> 
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
        <attributes>
             <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="con" pat h="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
            <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
        </attributes>
    </classpathentry>
    <classpathentry kind="output" path="target/classes"/>
</classpath>

这是 (2) 的 .classpath 文件的样子:

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" output="target/classes" path="src/main/java">
        <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
    </classpathentry>
     <classpathentry kind="src" output="target/test-classes" path="src/test/java">
         <attributes>
            <attribute name="optional" value="true"/>
            <attribute name="maven.pomderived" value="true"/>
          </attributes>
    </classpathentry>
    <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
         </attributes> 
    </classpathentry>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
        <attributes>
            <attribute name="maven.pomderived" value="true"/>
        </attributes>
     </classpathentry>
     <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
        <attributes>
           <attribute name="maven.pomderived" value="true"/>
            <attribute name="org.eclipse.jst.component.nondependency" value=""/>
        </attributes> 
    </classpathentry>
    <classpathentry kind="output" path="target/classes"/>
</classpath>

最佳答案

模块 test-kernel 中测试类路径中的资源对于模块 test-data-war 不可见。当您将模块作为依赖项添加到另一个模块时,模块仅导出 src/main/resources 下的资源。

令人困惑的是 Eclipse 和 Maven 在这里不一致。在 Eclipse 中,模块的整个类路径是可见的(也是测试资源)。但是当你在 Maven 中运行相同的测试时,测试资源会突然消失。这是因为 Eclipse 没有“测试类路径”的概念。

如果 mvn dependency:tree 显示出差异,那么您需要检查模块的文件 pom.xml

关于java - getResourceAsStream 在一种情况下返回 null,但在另一种情况下不返回 null,具有相同的类路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29285165/

相关文章:

android - 如何使用 Espresso 在 Android 上进行测试?

java - Eclipse WTP、maven 和 m2eclipse - 不复制提供的 jar

android - Eclipse (Kepler) 使用 JUnit3 运行器而不是 Junit4 运行器运行每个新的 JUnit 测试

JavaFX 多任务

java - Window Builder 忘记了哪些文件可以编辑

eclipse - 绝对路径到相对路径(Eclipse、JSP)

android - 创建 gradle 依赖项 - 删除对其自身依赖项的访问

java - Spring 启动。 Bean 依赖于服务

java - 使用 LWJGL 渲染 2D 图 block 的最快方法?

java - 用 Java 从文本文件中读取行并分割内容