2010-06-05 60 views
0

我有一个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”(在第一模块中),它使用性能及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:解压来解决它。在第二个模块的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中复制到类/富/ firstModule /目录,然后运行试验。

事实上,它被复制到正确的目录,我可以在“target/classes/foo/firstModule”目录中找到“Data.xml”文件。但maven测试仍然抱怨它无法读取文件(Properties.loadFromXML()抛出NPE)。

我不知道如何解决这个问题。 我试过其他输出目录,比如$ {project.build.directory}/resources和$ {project.build.directory}/test-classes,但都是徒劳的...

现在有什么建议?先谢谢了。

环境:Maven的2.2.1,日食,m2eclipse的

---- ----更新

对不起,我忘了提,即第2个模块中的程序,延伸的解析器在第一个模块中, 和解析器的构造函数中,属性被加载和解析。 事实上,程序与其它性能分析器另一个......

我想这可能是因为计划扩展分析器,造成问题的原因(也许类加载器的问题)。

如果我断开“继承”,初始化(新)程序中的解析器,它会好的,测试通过! 但我不能改变继承关系......它的设计......

现在的任何解决方案?

----全代码更新----

这是解析器第一模块:

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

这是解析器的测试案例,通过。

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在secondModule,延伸分析器在firstModule:

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

上面的测试案例失败,因为属性。 loadFromXML(Properties.java:851)throws NPE

但是,如果我不延长分析器,只是新的解析器:

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

看来在测试第二个模块时,maven无法正确加载第一个模块中的Data.xml。

我创建了完全相同的结构,我无法重现您的问题。我的Program类在第二个模块中使用了第一个模块的Parser类,它从XML文件加载属性而没有有任何问题。在Eclipse和命令行下进行测试。

我想我可以通过使用maven-dependency-plugin:unpack来解决这个问题。

使用dependency:unpack绝对不是一个解决方案,如果第一个JAR包含foo/firstModule/Data.xml,使用Parser类从另一个模块应该只是工作。别的地方一定有什么问题。如果你可以上传一个有代表性的测试项目,那么请这样做,我会看看ti。没有一个允许重现的项目,恐怕你得到的最佳答案是“调试你的代码”:)

+0

嗨, 请尽量让计划扩展解析器和解析器的构造函数,来完成分析工作,并重新运行测试。 ..(这是我的架构工作原理...) 如果它适用于您,我必须更深入地检查我的代码... – smallufo 2010-06-05 23:32:34

+0

@smallufo:请更新您的问题以显示您的代码,以便我可以重现。 – 2010-06-05 23:46:27

+0

谢谢,我在问题的尾部添加了更多评论。 – smallufo 2010-06-05 23:50:19

0

我同意,这听起来像是类加载器的问题。

如果你总是打算在/foo/firstModule/Data.xml位置开始data.xml中,让这个尝试在foo.firstModule.Parser

InputStream xmlStream = getClass().getResourceAsStream("/foo/firstModule/Data.xml");

或者,如果你想明确的行为寻找一个“本地”Data.xml应该首先在其他地方重用(例如,secondModule或thirdModule都有自己data.xml中),试试这个:

InputStream xmlStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Data.xml");

+0

嗨,感谢您的答复。 如果我改为Thread.currentThread()。getContextClassLoader()。getResourceAsStream(“Data.xml”); ParserTest也会失败。 – smallufo 2010-06-07 09:05:39