I've been using Maven for quite a number of years now and have, in the
last year or so, started creating a number of plugins to support the
needs of our local development organizations. However, I'm having some
trouble with dependency resolution when artifacts that are generated by
my custom plugins are included in another project's dependency list.
Maven version information...
mvn -version
Apache Maven 2.2.1 (r801777; 2009-08-06 15:16:01-0400)
Java version: 1.6.0_14
Java home: C:\jdk1.6.0_14\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"
Here's some background on the plugins I created...
The first plugin I created is a "TPAR" plugin. This plugin creates
artifacts that are physically structured as JAR files. I'm using the
MavenArchiver/JarArchiver classes to create these JAR files. However,
in order to keep these artifacts separate from other 'real' jar files
(the ones with java class files in them), I am using an artifact type of
"tpar" for these artifacts. This first plugin works perfectly and is
generating artifacts in exactly the format that I describe. For
reference purposes, here is the full contents of this plugin's
META-INF/plexus/components.xml file:
<component-set>
<components>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>tpar</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMappi
ng</implementation>
<configuration>
<lifecycles>
<lifecycle>
<id>default</id>
<phases>
<process-resources>org.apache.maven.plugins:maven-tpar-plugin:tpar-resou
rces</process-resources>
<package>org.apache.maven.plugins:maven-tpar-plugin:tpar</package>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</lifecycle>
</lifecycles>
</configuration>
</component>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>tpar</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler
</implementation>
<configuration>
<type>tpar</type>
<includesDependencies>true</includesDependencies>
<language>java</language>
<addedToClasspath>true</addedToClasspath>
<extension>jar</extension>
<packaging>jar</packaging>
</configuration>
</component>
</components>
</component-set>
The second plugin that I created is a "KIT" plugin. This plugin creates
a tar.gz file that contains everything required for the application to
be deployed and launched. This plugin is very similar to the assembly
plugin, but different enough that I could not use the assembly plugin to
generate exactly what I needed. For this plugin, I am using Archiver
instaances that are created by the ArchiverManager class to generate the
tar.gz file. Like the first plugin, this plugin works perfectly and
generates exactly what I want. The key behavior I am looking for from
this project is its ability to include every directly or indirectly
referenced JAR file in the tar.gz file that it generates.
Now, some background on the projects that use these plugins...
You only need two projects to create this situation. The first project
uses the TPAR plugin to generate a "TPAR" artifact. The dependency list
for this project contains a single jar file entry. For illustration
purposes, I'll use version 2.3 of the commons-lang component. The
second project uses the KIT plugin to generate a "KIT" artifact. The
dependency list for this second project contains a single entry that
references the TPAR artifact that's generated by the first project. A
very simplified view of the dependency graph would look something like
this:
KIT Project "A" ---> TPAR Project "B" ---> commons-lang.jar
Finally, here's the problem that I'm having...
Running I run a build of just the TPAR project will generate a properly
structured TPAR artifact which can be installed in my local repository.
Running a build of just the KIT project will generate a properly
structure KIT artifact which can also be installed in my local
repository. This kit contains both the TPAR artifact and the jar file
that it references (i.e. commons-lang-2.3.jar)
Running each of these builds in isolation works perfectly. However,
things don't work so well when I run them within a multi-module project.
When I do that, Maven accurately resolves the inter-project references
and builds the TPAR project before the KIT project. The KIT that is
generated contains the TPAR artifact that was generated by project "A".
However, that KIT DOES NOT contain the commons-lang-2.3.jar file that is
referenced by the TPAR project. The KIT file only contains the TPAR
artifact.
In other words...
* If I build the KIT project by itself, the generated KIT contains all
dependencies in the full dependency graph. In this scenario, Maven's
dependency resolution mechanisms work perfectly.
* If I build the KIT project as a part of a multi-module project that
contains the referenced TPAR project, the generated KIT does not contain
any dependencies that are referenced by artifacts that are generated by
my custom plugin. In this situation, it appears that Maven's dependency
resolution mechanisms can't see beyond the artifacts that are generated
by my custom plugin.
Here is the code from the KIT plugin that defines the parameter that
receives the maven project and the code that I use to pull in the full
dependency graph.
/**
* Stage all resource files that are to be included in an installation
kit.
*
* @goal kit-resources
* @requiresProject
* @requiresDependencyResolution runtime
*/
public class TkitResourcesMojo extends AbstractTkitMojo {
/**
* The maven project.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private org.apache.maven.project.MavenProject project;
public void execute() throws MojoExecutionException,
MojoFailureException {
List deps = getProject().getDependencies();
}
}
When the KIT plugin is used to build just the KIT project, the call to
getDependencies() returns a list with 2 entries in it. Those two
entries correspond to the TPAR that's directly referenced and the
transitively referenced commons-lang component.
When the KIT plugin is used in a multi-module build, that same call to
getDependencies() returns a list with just 1 entry in it. That entry
corresponds to the TPAR that's directly referenced.
I guess my question is this...
What do I need to do with my custom plugin which will enable Maven to
resolve the full dependency graph when these plugins, and artifacts
generated by them, are used/referenced in a multi-module build?
Ron Gallagher
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]