多模块Java/Maven项目中DBUnit的XML DTD路径?

多模块Java/Maven项目中DBUnit的XML DTD路径?,xml,maven-2,dtd,dbunit,Xml,Maven 2,Dtd,Dbunit,我有一个多模块maven项目。在persist模块中,我有许多引用DTD的XML文件和数据文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE myapp-data SYSTEM "myapp-data.dtd" > <dataset> .....omitted for brevity.... </dataset> …为简洁起见省略了。。。。 DTD与XML文件存储在同一个目录

我有一个多模块maven项目。在persist模块中,我有许多引用DTD的XML文件和数据文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "myapp-data.dtd" >

<dataset>
      .....omitted for brevity....
</dataset>

…为简洁起见省略了。。。。
DTD与XML文件存储在同一个目录中,甚至Eclipse也报告这些XML文件是有效的

但是,当我运行应用程序时,DBUnit FlatXMLDataSet抛出一个FileNotFound异常,因为它找不到DTD。它显然是在根项目目录(例如myproject/)中查找DTD。我希望它在与XML文件本身相同的目录(例如myproject/persist/target/testdata)中查找DTD

查看DBUnit源代码,可以这样说:“相对DOCTYPE uri是从当前工作目录解析的。”


解决此问题的好方法是什么?

始终使用正确的变量访问特殊目录,因为多模块生成与本地生成具有不同的工作目录:

所以

  • 使用
    ${project.basedir}/mydir
  • 使用
    ${project.build.directory}/mydir
  • 使用
    ${project.build.outputDirectory}/mydir
无论从何处调用,这些变量始终计算为当前项目。这是一个(不完整,但最重要的东西在里面)

此外,如果您想要执行一些交互式查询样式的调试,则以下命令也会派上用场:

就打电话

mvn help:evaluate
系统将提示您输入表达式。如果输入表达式,例如
${project.build.plugins[0]}
,将列出指定元素的合并dom


编辑:

好的,现在我想我明白问题了。那么为什么不直接引用xml中的目录呢

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE myapp-data SYSTEM "target/test-classes/myapp-data.dtd" >


我知道它不漂亮,但它应该工作,多模块或不。单元测试的当前目录始终是当前的${project.basedir},而不是父项目目录。

好的,我想我已经解决了这个问题。谢天谢地,开源

FlatXmlDataSetBuilder上有一个方法,它将流传送到DTD。在IMO中,这是一个公共方法,这很疯狂,但是,对于dtd文件,DBUnit与XML不在同一个目录中,这也很疯狂。这就是:

String dtdResourceName = "classpath:test-data/myapp-data.dtd";      
Resource res = applicationContext.getResource(dtdResourceName);
builder.setMetaDataSetFromDtd(res.getInputStream());
现在,我将DOCTYPE声明和dtd放在与XML相同的目录中,并使用此技巧欺骗DBUnit做正确的事情。

打开XML文件时,尝试使用“File”而不是“FileInputStream”

例如:

ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(new File(fileName)));
这样,DTD的相对路径应该以XML文件的目录开始

如果你使用

ReplacementDataSet dataSet = new ReplacementDataSet(new FlatXmlDataSet(new FileInputStream(fileName)));

路径应相对于当前工作目录。

您可以将DTD发布到web服务器,然后将其HTTP URL放入DOCTYPE,例如:

<!DOCTYPE myapp-data SYSTEM "-//The Owner//The Description//EN" "http://host/path/to/myapp-data.dtd">


这涉及到一些难看的复制,但是您可以将DTD的内容粘贴到相关的XML文件中,然后将其用作。

我认为问题不在于Maven,而在于DBUnit。它在错误的地方寻找DTD。有没有其他更好的方法在XML文件中指定它?有没有我缺少的DBUnit设置?使用新方法可以很好地解决运行时问题——但现在Eclipse抱怨它无法找到DTD进行验证。我想要我的蛋糕,也要吃!!“目标”目录仅在maven构建之后存在。如果我运行mvn clean,它就不存在了,然后Eclipse又开始抱怨了!我已经检查了DBUnit的源代码,他们真的千方百计找不到dtd……您使用的是什么版本?我在这里找不到这个代码:它在你提供的链接中……检查第195行——实际上很难找到。