Frage

Ich habe ein Multi-Modul-Maven-Projekt. Innerhalb des Persist -Moduls habe ich eine Reihe von XML -Dateiendatendateien, die auf eine DTD verweisen:

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

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

Der DTD wird im selben Verzeichnis mit den XML -Dateien gespeichert und sogar über Eclipse berichtet diese XML -Dateien als gültig.

Wenn ich jedoch die Anwendung ausführe, legt der DBunit flatXmldataset eine Filenotfound -Ausnahme aus, da er die DTD nicht lokalisiert hat. Es ist anscheinend nach der DTD im Stammprojektverzeichnis (z. B. MyProject/). Ich hätte erwartet, dass es im selben Verzeichnis wie die XML-Datei selbst nach dem DTD gesucht hätte (z. B. MyProject/Persist/Target/Test-Data).

Wenn man sich den Dbunit -Quellcode ansieht, muss dies darüber sagen: "Relative DocType URI werden vom aktuellen arbeitenden Dictectory gelöst."

Was ist eine gute Möglichkeit, dies zu beheben?

War es hilfreich?

Lösung

Ok, ich glaube, ich habe das herausgefunden. Gott sei Dank für Open Source.

Es gibt eine Methode auf FlatXMldatasetBuilder, die einen Stream zum DTD bringt. Es ist verrückt, dass dies eine öffentliche Methode ist, aber es ist verrückt, dass Dbunit nicht im selben Verzeichnis wie das XML für die DTD -Datei aussieht. Hier ist es also:

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

Jetzt lasse ich die DocType -Erklärung mit der DTD im selben Verzeichnis wie das XML und benutze diesen Hack, um Dbunit zu täuschen, um das Richtige zu tun.

Andere Tipps

Verwenden Sie immer die richtigen Variablen, um auf spezielle Verzeichnisse zuzugreifen, da Multi-Modul-Builds ein anderes Arbeitsverzeichnis haben als lokale Builds:

So

  • Anstatt von mydir verwenden ${project.basedir}/mydir
  • Anstatt von target/mydir verwenden ${project.build.directory}/mydir
  • Anstatt von target/classes/mydir verwenden ${project.build.outputDirectory}/mydir

Diese Variablen bewerten immer das aktuelle Projekt, egal woher es aufgerufen wird. Hier ist ein Überblick über POM -Variablen (Nicht vollständig, aber das wichtigste Zeug ist da drin)

Auch wenn Sie jemals ein interaktives Debuggen im Abfragen im Stil haben möchten, die Hilfe: Bewerten Sie Mojo kommt nützlich:

Ruf einfach an

mvn help:evaluate

Und Sie werden für einen Ausdruck aufgefordert. Wenn Sie einen Ausdruck eingeben, z. ${project.build.plugins[0]} Das fusionierte DOM für das angegebene Element wird aufgeführt


BEARBEITEN:

Ok, jetzt denke ich, ich sehe das Problem. Verweisen Sie dann nicht einfach auf das Verzeichnis im XML:

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

Ich weiß, dass es nicht hübsch ist, aber es sollte funktionieren, Multi-Modul oder nicht. Das aktuelle Verzeichnis für Unit -Tests ist immer das aktuelle $ {project.basedir}, nicht das übergeordnete Projekt Dir.

Sie können die DTD an einem Webserver veröffentlichen und dann seine HTTP -URL in den docType, z. B.:

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

Versuchen Sie, "Datei" anstelle von "fileInputStream" beim Öffnen einer XML -Datei zu verwenden.

Zum Beispiel:

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

Auf diese Weise sollte der relative Pfad zu DTD mit dem Verzeichnis der XML -Datei beginnen.

Und wenn Sie verwenden

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

Der Pfad sollte relativ zum aktuellen Arbeitsverzeichnis sein.

Es handelt Interne DTDs.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top