我有一个带有一些模块的maven mantained项目。 一个模块包含一个XML文件和一个解析类。
第二个模块取决于第一个模块。 有一个类在第一个模块中调用解析类,但maven似乎无法在第二个模块中测试该类。 Maven测试报告:
java.lang.NullPointerException
at java.util.Properties.loadFromXML(Properties.java:851)
at foo.firstModule.Parser.<init>(Parser.java:92)
at foo.secondModule.Program.<init>(Program.java:84)
在“Parser.java”(在第一个模块中)中,它使用Properties和InputStream来读取/解析XML文件:
InputStream xmlStream = getClass().getResourceAsStream("Data.xml");
Properties properties = new Properties();
properties.loadFromXML(xmlStream);
“data.xml”位于第一个模块的resources / foo / firstModule目录中,它在第一个模块中测试OK。
在测试第二个模块时,maven似乎无法在第一个模块中正确加载Data.xml。
我认为我可以使用 maven-dependency-plugin:unpack 来解决问题。在第二个模块的POM文件中,我添加了以下片段:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>data-copying</id>
<phase>test-compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>foo</groupId>
<artifactId>firstModule</artifactId>
<type>jar</type>
<includes>foo/firstModule/Data.xml</includes>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
在这个POM文件中,我尝试解压缩第一个模块,并将Data.xml复制到classes / foo / firstModule /目录,然后运行测试。
实际上,它被复制到正确的目录,我可以在“target / classes / foo / firstModule”目录中找到“Data.xml”文件。但是maven测试仍然抱怨它无法读取文件(Properties.loadFromXML()抛出NPE)。
我不知道如何解决这个问题。 我尝试了其他输出目录,例如$ {project.build.directory} / resources和$ {project.build.directory} / test-classes,但都是徒劳的......
现在有什么建议吗?谢谢你提前。
环境:Maven 2.2.1,eclipse,m2eclipse
----更新----
对不起,我忘了提到,第2个模块中的程序扩展第1个模块中的Parser, 在Parser的构造函数中,属性被加载和解析。 事实上,Program是另一个具有更多功能的Parser ......
我认为可能是因为程序扩展Parser ,导致问题(可能是类加载器问题)。
如果我断开“继承”,在程序中初始化(新)解析器,它就可以了,测试通过! 但是我无法改变继承关系......它的设计......
现在有什么解决方案吗?
----用完整代码更新----
这是第一个模块中的Parser:
package foo.firstModule;
import java.io.IOException;
import java.io.InputStream;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;
public class Parser
{
private Properties properties;
public Parser()
{
InputStream xmlStream = getClass().getResourceAsStream("Data.xml");
properties = new Properties();
try
{
properties.loadFromXML(xmlStream);
}
catch (InvalidPropertiesFormatException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public Properties getProperties()
{
return properties;
}
}
这是Parser的测试用例,已通过。
package foo.firstModule;
import junit.framework.TestCase;
public class ParserTest extends TestCase
{
public void testParser()
{
Parser p = new Parser();
assertEquals(64 , p.getProperties().size());
}
}
这是第二个模块中的ParserExtend,它在第一个模块中扩展了Parser:
package foo.secondModule;
import java.util.Properties;
import foo.firstModule.Parser;
public class ParserExtend extends Parser
{
private Properties properties;
public ParserExtend()
{
this.properties = getProperties();
}
public int getSize()
{
return properties.size();
}
}
这是ParserExtend的测试用例:
package foo.secondModule;
import junit.framework.TestCase;
public class ParserExtendTest extends TestCase
{
public void testParserExtend()
{
ParserExtend pe = new ParserExtend();
assertEquals(64 , pe.getSize());
}
}
上述测试用例失败,因为 Properties.loadFromXML (Properties.java:851)抛出NPE
但是,如果我不扩展Parser,只需更新Parser:
package foo.secondModule;
import java.util.Properties;
import foo.firstModule.Parser;
public class ParserInit
{
private Properties properties;
public ParserInit()
{
Parser p = new Parser();
this.properties = p.getProperties();
}
public int getSize()
{
return properties.size();
}
}
这是测试用例:
package foo.secondModule;
import junit.framework.TestCase;
public class ParserInitTest extends TestCase
{
public void testParserInit()
{
ParserInit pi = new ParserInit();
assertEquals(64 , pi.getSize());
}
}
测试用例通过了!
这是我的整个测试场景。 有谁能找到如何通过ParserExtend的测试用例? 谢谢你提前。
答案 0 :(得分:0)
在测试第二个模块时,maven似乎无法在第一个模块中正确加载Data.xml。
我创建了完全相同的结构,但无法重现您的问题。第二个模块中的Program
类使用第一个模块中的Parser
类,该类从XML文件加载属性而没有任何问题。在Eclipse和命令行下测试。
我认为我可以使用
maven-dependency-plugin:unpack
来解决问题。
使用dependency:unpack
绝对不是解决方案,如果第一个JAR包含foo/firstModule/Data.xml
,则使用其他模块中的Parser
类应该可以正常工作。其他地方一定有问题。如果你可以上传一个代表性的测试项目,那么请这样做,我会看看ti。如果没有允许重现的项目,我担心你得到的最好答案是“调试你的代码”:)
答案 1 :(得分:0)
我同意,这听起来像是类加载器问题。
如果您一直打算在/foo/firstModule/Data.xml位置使用Data.xml,请尝试foo.firstModule.Parser
:
InputStream xmlStream = getClass().getResourceAsStream("/foo/firstModule/Data.xml");
或者,如果你明确地希望找到“本地”Data.xml的行为应该在其他地方重用firstModule(例如secondModule或thirdModule有自己的Data.xml),试试这个:
InputStream xmlStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Data.xml");