2010-06-10 22 views
8

我有一個多模塊maven項目。內堅持模塊我有很多的引用DTD的XML文件中的數據文件:多模塊Java/Maven項目中用於DBUnit的XML DTD的路徑?

<?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文件本身的同一目錄中查找DTD(例如myproject/persist/target/test-data)。

查看DBUnit源代碼,它有這樣的說法:「相對DOCTYPE uri從當前工作dicrectory解析」。

解決這個問題的好方法是什麼?

回答

8

好吧,我想我想出了這一個。謝天謝地,開源。

FlatXmlDataSetBuilder上有一個將流傳送給DTD的方法。這真是瘋了,這是一個公共方法IMO,但是再一次,它的瘋狂之處在於DBUnit不會像dtd文件的XML那樣查看相同的目錄。所以在這裏,它是:

String dtdResourceName = "classpath:test-data/myapp-data.dtd";  
Resource res = applicationContext.getResource(dtdResourceName); 
builder.setMetaDataSetFromDtd(res.getInputStream()); 

現在我離開DOCTYPE聲明與DTD在同一目錄中的XML,並使用這個技巧來愚弄DBUnit的去做正確的事情。

+0

你使用的是什麼版本?我在這裏找不到這個代碼:http://dbunit.sourceforge.net/xref/org/dbunit/dataset/xml/FlatXmlDataSetBuilder.html – 2010-06-13 09:49:17

+0

它在你提供的鏈接中...檢查第195行 - 很難找到其實。 http://dbunit.sourceforge.net/xref/org/dbunit/dataset/xml/FlatXmlDataSetBuilder.html#195 – HDave 2010-06-13 21:40:55

3

始終使用正確的變量來訪問特殊目錄,因爲多模塊構建有不同的工作目錄比本地編譯:

所以

  • ,而不是mydir使用${project.basedir}/mydir
  • ,而不是target/mydir使用${project.build.directory}/mydir
  • 而不是target/classes/mydir使用${project.build.outputDirectory}/mydir

這些變量總是評估爲當前項目,無論它從哪裏調用。下面是一個Overview of POM variables(沒有完成,但最重要的東西是在那裏)

另外,如果你想要做一些交互式查詢式的調試,help:evaluate mojo就派上用場了:

就叫

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},而不是父項目dir。

+1

我不認爲問題是與Maven,它與DBUnit。它在DTD的錯誤位置查找。是否有另一種更好的方式來指定在XML文件內?有沒有我缺少的DBUnit設置? – HDave 2010-06-11 18:35:13

+0

使用新方法解決了運行時問題 - 但現在Eclipse正在抱怨它無法找到用於驗證的DTD。我想要我的蛋糕,也吃它! – HDave 2010-06-13 00:26:44

+0

「目標」目錄僅在maven構建之後才存在。如果我運行mvn clean,它不在那裏,然後Eclipse迴歸抱怨!我已經檢查了源代碼到DBUnit,他們真的走出去了,沒有找到dtd .... – HDave 2010-07-09 02:12:53

0

打開XML文件時,請嘗試使用「File」而不是「FileInputStream」。

例如:

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

這種方式,DTD相對路徑應與XML文件的目錄中啓動。

如果您使用

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

路徑應是相對於當前的工作目錄。

1

你可以發佈DTD到Web服務器,然後把它的HTTP URL到DOCTYPE,如:

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

它涉及到一些醜陋的重複,但你可以在DTD的內容粘貼到XML有問題的文件,然後用它們作爲internal DTDs