Maven include file contents from one module in another
I have a maven application that looks like this
application_name/
module1
src/main/resources
file_snippet.xml
module2
src/main/resources
file_snippet.xml
module3
src/main/resources
file.xml
file.xml should be like this
&l开发者_Python百科t;workflow>
<action>
<%= module1/src/main/resources/file_snippet.xml %>
</action>
<action>
<%= module2/src/main/resources/file_snippet.xml %>
</action>
</workflow>
I want to include the contents of file_snippet.xml from module2 and module2 into file.xml of module3 before the build. Is that possible in maven? Is there some sort of templating language or plugin I can use?
This is not easy, there are two parts you need to implement.
- get the snippets from the other module
- assemble the xml file using the include
for 1. you can use the dependency:unpack mojo:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/snippets</outputDirectory>
<includes>snippets/*.xml</includes>
<artifactItems>
<artifactItem>
<groupId>your.app</groupId>
<artifactId>module1</artifactId>
<version>${project.version}</version>
<type>jar</type>
</artifactItem>
<artifactItem>
<groupId>your.app</groupId>
<artifactId>module2</artifactId>
<version>${project.version}</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now you have copied all snippets from module1.jar/snippets and module2.jar/snippets to target/snippets (this was the easier part).
For 2. you need to pick a template engine and create a main class to assemble your template with it, probably using the exec:java mojo something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.yourcompany.YourTemplateParser</mainClass>
<arguments>
<argument>path/to/your/template</argument>
<argument>path/to/the/snippets/folder</argument>
<argument>target/path</argument>
</arguments>
</configuration>
</plugin>
(Personally, I tend to use GMaven instead of exec:java, as you can write inline groovy scripts without creating custom java classes)
I would like to know about some template engine for maven too, but maybe you don't need maven at first for that.
There is a way to include another xml file in a xml file : http://bobcat.webappcabaret.net/javachina/faq/xml_01.htm#dtd_Q408
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xmlfrag SYSTEM "xmlfrag.txt" >
<!ELEMENT root (tag1, tag2) >
<!ELEMENT tag1 (childtag) >
<!ELEMENT tag2 (childtag) >
<!ELEMENT childtag (#PCDATA) >
<!ATTLIST childtag att NMTOKEN #REQUIRED >
]>
<root>
&xmlfrag;
</root>
xmlfrag.txt(well formed xml fragment without xml decl)
<tag1>
<childtag att="child1">text1</childtag>
</tag1>
<tag2>
<childtag att="child2">text2</childtag>
</tag2>
else, for merging xml resources between dependencies/modules in maven, you can use maven-shade-plugin (with the resource transformer).
In your case :
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.XmlAppendingTransformer">
<resource>file.xml</resource>
<!-- Add this to enable loading of DTDs
<ignoreDtd>false</ignoreDtd>
-->
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
to merge module1/src/main/resources/file.xml and module2/src/main/resources/file.xml (depending on dependencies) in module3/src/main/resources/file.xml.
Quite an old post - but solution may still be useful in other contexts.
You can use maven-velocity-plugin in module3/pom.xml.
This will trigger velocity template expansion in the generate-sources phase.
<build>
<plugins>
<plugin>
<groupId>com.github.vdubus</groupId>
<artifactId>velocity-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<id>Generate source velocity</id>
<phase>generate-sources</phase>
<goals>
<goal>velocity</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
<removeExtension>.vm</removeExtension>
<templateFiles>
<directory>${project.basedir}/..</directory>
<includes>
<include>**/*.vm</include>
</includes>
</templateFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
module3/src/main/resources/file.xml.vm :
<workflow>
<action>
#include("module1/src/main/resources/file_snippet.xml")
</action>
<action>
#include("module2/src/main/resources/file_snippet.xml")
</action>
</workflow>
Note that velocity requires that all files must be under the same TEMPLATE_ROOT directory.
If included files must transitively include other files, this can be achieved by using "#parse", and processing all files with velocity ( eg rename them to FILE.xml.vm )
References
- https://velocity.apache.org/engine/1.7/user-guide.html#include
- https://github.com/vdubus/velocity-maven-plugin
- solution for same problem for avro schema aggregation : https://github.com/vgheo/kafka-avro-schema-aggregation/tree/master/example-avro-agg-build
精彩评论