How to configure a Maven plugin with classpath resource? - maven

Today I configure the Maven war plugin like this :
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${basedir}/../common/WEB-INF/web.xml</webXml>
</configuration>
This allows me to share that web.xml between several projects.
The problem with this approach is that my Maven project is not self contained. It depends on a relative path on the file system.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
And of course, make that file available on the classpath of the plugin.
Thanks

First step is to create a dedicated Maven module with packaging type jar containing the web.xml. Let's call it com.mycompany:common.
Is it somehow possible to do something like this ? :
<webXml>classpath:com/mycompany/common/web.xml</webXml>
Have you tried i.e. you know for sure that it doesn't work? If it did I suppose you'd have to use a leading '/' (/com/...).
And of course, make that file available on the classpath of the
plugin.
That'd be easy then...just add a dependency to com.mycompany:common to make it available in the classpath. Of course it'd have to be available in your Maven repository.
If classpath: doesn't work, I'm really not sure anymore myself, you could use the maven-dependency-plugin to unpack web.xml from the JAR in order to make it available to the maven-war-plugin.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-web-xml</id>
<phase>..any phase before packaging..</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mycompany</groupId>
<artifactId>common</artifactId>
<version>1.0</version>
<outputDirectory>...dir you'll use for the war plugin later...</outputDirectory>
<includes>/com/mycompany/common/web.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Related

Change default pom.xml and project layout of Maven

I am just starting using maven and I use Apache Maven Shade Plugin a lot. Is it possible to add these code
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- put your configurations here -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
to default pom.xml. Yes, it can change setting.xml to make this plugin work with all project. But if I have some specific project which will not need this plugin, do I have to rewrite setting.xml again?
Another problem is that is it possible to change project layout of Maven. I use git a lot. Can I add sample .gitignore every time when I run mvn archetype:generate.
For you first issue, I think you can benefit from the parent POM:
http://books.sonatype.com/mvnex-book/reference/multimodule-sect-simple-parent.html
It's a defined POM file in which you put whatever you want. You publish it as a "pom" in your Maven repository and then, you can inherit from it in other projects. It is very convenient to lock dependency verions as well.
Your second issue seems more related to the archetype you are using than maven itself. You will probably have to create your own with a default .gitignore in it.

Unpack an EAR file using maven

I have an EAR file from some build. I want to extract the contents of this EAR file into another folder. I am confused how to do this. I have looked and tried
http://maven.apache.org/plugins/maven-ear-plugin/
and
http://maven.apache.org/plugins/maven-dependency-plugin/usage.html
but either maven is unable to find the file or it has dependency issues.
Since I am new to maven I don not understand how to set these plugins up.
I got the following error on using the below plugin.
Failure to find ECM:ECM:ear:1.0 in http://repo.maven.apache.org/maven2 was cached in the local repository
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
You can do it using dependency:unpack-dependencies. I just modify my answer because according to your comments, your ear is generated by some other build. If you do not have an Enterprise repository that you can deploy your ear artifact, you have to use "system" scope, but please note that it is usually discouraged.
Add below dependency to your pom.xml
<dependency>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
<scope>system</scope>
<systemPath>/path/to/your/abc.ear</systemPath>
</dependency>
Add the below plugin to your postBuild module pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>ECM</includeArtifactIds>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Have you looked at this example of Maven EAR plugin for Unpacking a module yet?
The Maven Dependency Plugin and its unpack goal can do this.
Sample configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>myear</groupId>
<artifactId>myear</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This takes the 'myear.ear' artifact and extracts it to the 'target/earoutput' directory. This also works with JARs, WARs and any other zip-like file. The phase this executes under is 'package' - this may be too late if you need to use these resources in other parts of the build. Change the phase to something earlier such as 'generate-resources' if needed.
You mentioned that you already tried using the dependency plugin. Is the EAR file from another Maven project, and has it been installed in the local Maven repository? If it still doesn't work post the plugin configuration you tried to use.
(edit: update information on dependencies and local repository)
For this to work, your EAR file needs to be put into your local Maven repository (this is just a directory on your disk). But if other people need to build your project as well, you have a few options:
import the EAR into your local repository, and also deploy to a remote repository so everyone can get it (recommended, but requires you to set up a corporate Maven repository)
give the EAR to everyone and have them put it into their local repository using a couple of Maven commands (might be OK for a few developers, less overhead than setting up a whole repository server)
check the dependent EAR into source control under your project and unpack it (not the recommended way of doing things) in a goal in your project
Importing into your local repository is easy. It's very similar to these instructions.
Use the following command:
mvn install:install-file -Dfile=<path-to-EAR-file-on-local-filesystem> -DgroupId=myear
-DartifactId=myear -Dversion=1.0 -Dpackaging=ear
(modify path, groupId, artifactId and version as needed)
Group ID and artifact ID are there simply to uniquely identify artifacts.
Once you install this in the local repository, the dependency plugin should work and find the artifact.

XML maven artifact not on classpath

I have some external configuration (XML files) that are installed in Maven. I need to have them on my test classpath but they aren't appearing.
They must stay as XML, I cannot package them inside a Jar - but I am willing to try anything else for this, custom plugin etc.
(Please don't inform me that Maven is only for Jars - that's simply not true (and if you provide a reference refuting that I can assure you it's out-of-date/misinformation).
The dependencies are specified thus:
<dependency>
<groupId>some.group</groupId>
<artifactId>some.artifact</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<type>xml</type>
<classifier>some.classifier</classifier>
</dependency>
These XML artifacts have been created by the build-helper plugin (so there's no 1-2-1 with their project's POM).
My only current hacky solution is to, check for the M2_HOME property and load the files from there (as they're defined as dependencies Maven does pull them down) - but I'm not happy with this.
EDIT: The next best hack is probably to use the maven-dependency-plugin to copy these to the output directory (target/classes). If my config is fine for Jars then this smells like a Maven bug.
EDIT 2: #khmarbaise asked for the build-helper-plugin config:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>target/classes/ddl-seed.xml</file>
<type>xml</type>
<classifier>ddl-seed</classifier>
</artifact>
<!-- ... more definitions -->
This generates the correct maven-metadata-local.xml data for all the XML artifacts.
Unfortunately I can find no way of forcing maven to add the test dependency specified to the test classpath, other than this stinky hack of copying it to a directory on the test classpath.
This seems the quickest way (it's for a test dependency), avoiding any JAR creation.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.acme.gid</groupId>
<artifactId>com.acme.aid</artifactId>
<version>${project.version}</version>
<classifier>ddl</classifier>
<type>xml</type>
<outputDirectory>${project.build.directory}/test-classes</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Maven assembly: copy from specific sub-folder of dependency

I'm using Maven assembly plugin to build a WAR of our product (previously done by Ant). As there're many leftovers of Apache Ant, there's one specific requirement that would make build process easier: copy specific sub-folder of dependency (e.g., jar or war resource) to a specific target sub-folder.
So far I learned that Assembly descriptors allow to specify <outputDirectory>, but is there's any chance to specify a <sourceDirectory>? E.g., I want to apply this rule for one single WAR or JAR type dependency.
Consider this example of assembly descriptor fragment (not 100% accurate):
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>my-specific-dependency:war</include>
</includes>
<outputDirectory>WEB-INF/myresources</outputDirectory>
</dependencySet>
I want to say that I want to copy some folder from my-specific-dependency:war to WEB-INF/myresources.
EDIT NB: I'm aware that this is not a very correct requirement as we shouldn't know what's inside an artifact, the correct way would be declaring to extract the whole artifact to the target directory (neat declarative approach).
You should be able to use the Maven Dependency plugin to do this, with the unpack goal:
http://maven.apache.org/plugins/maven-dependency-plugin/unpack-mojo.html
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-database-scripts</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>myGroup</groupId>
<artifactId>myArtifact</artifactId>
<version>1.0</version>
<type>war</type>
<overWrite>true</overWrite>
<includes>...</includes>
<outputDirectory>…</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
First i recomment that you check the maven-war-plugin to do that job instead with maven-assembly-plugin. Furthermore check the documentation about the dependencySet which contains such options for unpacking etc. Change your packaging of the module to war and make it fit to the maven conventions and don't use Maven as ant...which currently looks like it.
It turned out that assembly descriptor (since ver. 2.2-beta-1) provides unpackOptions instructions, including <dependencySet>. Exactly what I needed.

maven-install-plugin: Can i define a custom packaging type but get the artifact installed as jar in the repo?

I am trying to come out with a plugin to detect and process Java EE application clients.
I created a new packaging type called 'car' through META-INF/plexus/components.xml (http://maven-car-plugin.googlecode.com/svn/trunk/maven-car-plugin/src/main/resources/META-INF/plexus/components.xml) and a corresponding mojo for Java EE app clients. I have pretty much followed the same steps as the maven-ejb-plugin.
The behaviour i want is the same as the maven-ejb-plugin: Defines an ejb packaging type but the artifact gets installed in the repo as a .jar and gets bundled in the ear as .jar too.
I believe must be configurable some how because ejb packaging type gets installed as .jar but war packaging type produces a .war.
The problem in my case is that a .car file gets installed in the repo and a .car file gets bundled in the ear.
Does anyone know how to make sure it gets installed in the repo as a .jar file?
I ran into the same issue you have, except, I'm building a .war file and wanted a .jar file installed into my local repo. What I did was use the maven-jar-plugin to create a jar file in addition to a war file, it's generated in my /target directory. I also used the maven-install-plugin to install the outputted jar to my local repo.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>make-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-jar</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<packaging>jar</packaging>
<artifactId>${project.artifactId}</artifactId>
<groupId>${project.groupId}</groupId>
<version>${project.version}</version>
<file>${project.build.directory}/${project.artifactId}.jar</file>
</configuration>
</execution>
</executions>
</plugin>
Perhaps you could try using the packaging parameter in maven install plugin to see if that helps in your case?
I would assume you would have to specify
<packaging>jar</packaging>
as well in the component descriptor. Otherwise it looks correct to me..

Resources