views:

1189

answers:

3

If I use the maven-dependency-plugin plugin, than I can't use a version range. Also it seems the version of a there defined artifact doesn't get updated though a newer version is in the remote repository.

Why is that so?

Uses the maven-dependency-plugin some other mechanism than the rest of maven to resolve dependencies? And if that is the case, why?

Here a example:

I have created a project org.example:org.example.simple.project1:jar and put it in the repository using the versions 1.0.0-SNAPSHOT, 1.0.0, 1.0.1 and 1.1.0-SNAPSHOT

I have now configured the dependency plugin in the following way:

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-dependency-plugin</artifactId>
 <executions>
  <execution>
   <id>unpack-stuff<id>
   <phase>initialize</phase>
   <goals>
    <goal>unpack</goal>
   </goals>
   <configuration>
    <artifactItems>
     <artifactItem>
      <groupId>org.example</groupId>
      <artifactId>org.example.simple.project1.</artifactId>
      <version>[1.0,1.1)</version>
      <type>jar</type>
      <overWrite>true</overWrite>
      <outputDirectory>target/stuff</outputDirectory>
      <includes>**/*.*</includes>
     </artifactItem>
    </artifactItems>
   </configuration>
  </execution>
 </executions>
</plugin>

If the dependency resolution would be the same as in the other dependencies, the version shoud resolve (at least in my opinion) to 1.0.1.

Instead I get the following exception:

[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] version was null for org.example:org.example.simple.project1.
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NullPointerException: version was null for org.example:org.example.simple.project1.
at org.apache.maven.artifact.DefaultArtifact.getBaseVersion(DefaultArtifact.java:362)
at org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout.pathOf(DefaultRepositoryLayout.java:47)
at org.apache.maven.artifact.repository.DefaultArtifactRepository.pathOf(DefaultArtifactRepository.java:110)
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:125)
at org.apache.maven.artifact.resolver.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:74)
at org.apache.maven.plugin.dependency.fromConfiguration.AbstractFromConfigurationMojo.getArtifact(AbstractFromConfigurationMojo.java:242)
at org.apache.maven.plugin.dependency.fromConfiguration.AbstractFromConfigurationMojo.getProcessedArtifactItems(AbstractFromConfigurationMojo.java:143)
at org.apache.maven.plugin.dependency.fromConfiguration.UnpackMojo.getProcessedArtifactItems(UnpackMojo.java:138)
at org.apache.maven.plugin.dependency.fromConfiguration.UnpackMojo.execute(UnpackMojo.java:88)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:453)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:559)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:500)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:479)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:331)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:292)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:301)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4 seconds
[INFO] Finished at: Mon Aug 03 17:21:41 CEST 2009
[INFO] Final Memory: 13M/133M
[INFO] ------------------------------------------------------------------------

WTF?!

+2  A: 

The dependency plugin uses the same resolution mechanism as everything else. It may be that your repositories are not updating the metadata because the is set to never or weekly or something. You can force Maven to refresh all the remote repository metadata by running with a -U.

The dependency plugin also doesn't overwrite downloaded dependencies by default if they already exist in the target. You can do a clean or configure the goal to force overwrites. There are three parameters you can set to true: overWriteIfNewer, overWriteReleases, and overWriteSnapshots. See the documentation for more details.

Edit: based on your updated question, the problem is that you are using a dependency range. Ranges are fine as long as there is something to resolve the version (for example you have the version defined in the parent project or in your dependencies section). If you change the range to an exact version, or use one of the LATEST or RELEASE keywords, Maven will be able to resolve the version number (though be aware that those keywords carry their own risks.

I'd recommend defining a dependencyManagement section in your parent with the versions you use, then your projects can inherit those versions. I answered another question about this recently, I'll post a link if I find it

Rich Seller
I have updated my question with an example. The project in question is always called with -U as a parameter. As in the given example the configuration has set *<overWrite>true</overWrite>* (Maybe I need to add the other overwrite* options as well.
Mauli
Here's a way you can define your dependencies in a parent project: http://stackoverflow.com/questions/921599/maven-dependency-best-practices/1207350#1207350
Rich Seller
it is a problem with the dependency ranges indeed.
Mauli
see my answer above. The answer is actually I never implemented ranges for this goal.
Brian Fox
A: 

The problem with dependency ranges is that you did not specify one of the versions you used. If you specified the range as [1.0.0,1.1.0-SNAPSHOT) then it may do as you expect. You can't assume 1.0 and 1.1 will resolve to 1.0.* and 1.1.* which is what you seem to imply.

thar
+1  A: 

Ok here's the real answer (I wrote the dependency plugin):

The unpack and copy goals have to replicate some of the core resolution code. Unfortunately that resolution code was not really in a useable form api-wise. Because of this, those goals do not handle version ranges, and also don't resolve artifacts directly from the reactor (I frankly just never implemented them because it broke too many of the existing use cases, yeah core the resolution code was that bad)

A much better approach is to use the xxx-dependencies forms of these goals. These goals ask Maven to do the resolution before they are invoked and so it's 100% compatible. You can use the filters like the groupId and artifactId filter to effectively get the list of artifacts you want and the end result will be the same.

The copy and unpack are definately more flexible and were intended for a much simpler use case I had at the time. Knowing what I know now, I probably would have implemented it more like the xxx-dependencies forms to start with.

All that said, in Maven 3, the resolution code is finally completely decoupled...the dependency plugin driving most of the use cases needed for this. I'll be starting to work on a new version of the plugin to fully leverage this soon...and while it will require maven 3, it will finally work 100% with all the goals.

Brian Fox
Hah! I knew it! This explains it quite clearly. I will have a look at maven 3, but I'm not very hopeful, since my builds don't work with any maven version other than 2.0.10 (so much to compatibility promises).
Mauli