mvn dependency:copy-dependencies removes the versions - maven-2

I'm using "mvn dependency:copy-dependencies" to get all sources of the dependencies my project uses.
I use it from command line, so it looks like this:
mvn dependency:copy-dependencies -Dclassifier=sources -DincludeScope=compile
It works fine except of a small problem: For some reason the version is removed by this plugin. So instead of commons-logging-1.1.1-sources.jar, I'm getting commons-logging-sources.jar
The documentation says that "stripVersion" argument should effect this behavior, but the default value is false. Moreover, I tried to set it explicitly and it didn't help.
I'm using apache-maven-2.2.1 with jdk1.6.0_21
Thanks,
Tarlog.

That's very strange, you can see in the source (Mojo, Parent Mojo, DependencyUtil) that stripVersion does what it says it does.
Several possibilities:
a) Are you using the current version of the dependencies plugin?
Either configure your pom
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
</plugin>
</plugins>
</build>
or use the fully qualified goal name:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:copy-dependencies
b) stripVersion is the parameter name in XML configuration. The command line version is
-Dmdep.stripVersion=false
Try using that.

I found the root cause of a problem. Somewhere in the parent of parent of parent of ... my pom, stripVersion was set to true.
I didn't know about it and anyway thought that setting the system property must override the xml. I even tried to put this property in my pom and it still didn't help. Somehow, the parent pom stayed the dominant one, so I thought that the property doesn't work.
When I ran with -X param I saw it no changing despite my configuration, so I started digging in the parent poms unless I found the problem.
Thanks to everyone!

Related

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1,Cannot access javax.annotation.concurrent.NotThreadSafe

I am upgrading the swagger and related versions to swagger2.
While doing maven clean install getting the below error.
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project : Compilation failure[ERROR] cannot access javax.annotation.concurrent.NotThreadSafe.
plugin from POM.xml which is throwing exception:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
I could see javax.annotation-api 1.3.1 maven dependency in my pom.xml. Still class file for javax.annotation.concurrent.NotThreadSafe not found
Please don't suggest the solutions given in https://stackoverflow.com/questions/42525139/maven-build-compilation-error-failed-to-execute-goal-org-apache-maven-plugins/49299241 or any other stack overflow links. Since I have tried all but no progress.
Ok so after spending a full day to sort this out, I have found the systematic approach to it. Here it goes:
1. As we all know, class file not found error is when compiler is not able to find the class itself. So when you add some dependency, cross check in your repository jar, if class is present there or not(you will find on google that many dependencies claimed for the class, though it wasn't there in any)
2. To confirm if the class is present,
a. Go to the repository directory of the jar file.
b. And run command : jar tf {jar_file_name}.jar
c. It will list out the classes present in the jar file.
3. In this way you can add the exact desired dependency required.
Note: this solution is generic for all the class not found error.

Arquillian Shrinkwrap provide custom settings.xml file

I have set up a arquillian project and it all works fine locally but when running the maven build on our continuous integration box it fails. I managed to get to the bottom of the problem and it is because the maven user settings.xml file on the CI box actually has some server definitions (for another project) whereas locally to my machine it is the default file (with no servers defined). The tests throw a RuntimeException because the MavenResolver goes looking for settings-security.xml file which doesn't exist on the CI box.
I would prefer not to go adding the settings-security.xml and instead would like to provide the resolver with a 'empty' settings.xml file, or even better, tell it not to use one. Is this possible?
I tried the answer from this thread https://developer.jboss.org/thread/174873 which pretty much says to add the following option to the failsafe plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version><!-- or upper -->
<configuration>
<systemPropertyVariables>
<org.apache.maven.user-settings>nonExistentSetting.xml</org.apache.maven.user-settings>
</systemPropertyVariables>
</configuration>
</plugin>
If i do this and provide an xml file that doesnt exist all work fine from the command line running 'mvn clean install' but when i debug within my IDE it still fails.
Is there a way i can either:
Tell the maven resolver not to use a settings.xml / use a 'default' file
Create an empty settings.xml in my project and tell the maven resolver to use that
I did try the following line in my code to build my archive but it didnt seem to have an effect:
.addAsLibraries(Maven.configureResolver().fromFile("test-settings.xml").loadPomFromFile("pom.xml").importRuntimeDependencies().resolve().withTransitivity().asFile())
Thanks for any help,
Craig
ShrinkWrap resolver by default loads settings-security.xml from
DEFAULT_SETTINGS_SECURITY_PATH = userHome == null ? ".settings-security.xml" : userHome.concat("/.m2/settings-security.xml").replace('/', File.separatorChar);
but you can override this location by setting
System.setProperty(MavenSettingsBuilder.ALT_SECURITY_SETTINGS_XML_LOCATION,
"someDir/empty-settings-security.xml");
When alternative location (non-empty string) is provided theoretically it should skip the default location. However I am not 100% sure this method will work.

Unable to download the artifact maven-compiler-plugin from repository

I've created a maven project and wanted to change the java compiler version to 1.6 so I added the ff:
<build>
<plugins>
<plugin>
<artifactId>org.apache.maven.plugins</artifactId>
<groupId>maven-compiler-plugin</groupId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
When I run any maven goal in eclipse, it works. But when I run in terminal I got the ff errors:
Project ID: maven-compiler-plugin:org.apache.maven.plugins
Reason: POM 'maven-compiler-plugin:org.apache.maven.plugins' not found in repository: Unable to download the artifact from any repository
maven-compiler-plugin:org.apache.maven.plugins:pom:2.3.2
from the specified remote repositories:
central (http://repo1.maven.org/maven2),
apache.repo (https://repository.apache.org/content/repositories/releases),
jboss.repo.deprecated (https://repository.jboss.org/nexus/content/repositories/deprecated),
Any idea what's causing this issue?
I was able to solved this issue by updating to maven3. But my problem right now is although I specified maven-compiler-plugin version to be 2.4, I'm still seeing 2.3.2 in the log.
Your groupId and artifactId are reversed.
If Eclipse and the command line create different results, then they use different local Maven repositories. The default is in $HOME/.m2/repository/. So the first step is to find out which one (command line or Eclipse) uses a different local cache and why.
The next question is why the download failed. The usual reason is that Maven tried the download and got an error. Maven will remember the error and not try again. To force it to try again, you have to delete the folder $M2_REPO/repository/org/apache/maven/plugins/maven-compiler-plugin/2.3.2/.
Lastly, when you configure 2.4 but see 2.3.2 in the log, then you're either building the wrong project of one of the POMs of your build overwrites the version for the compiler plugin.
To avoid issues like this, use a parent POM where you keep all the versions in dependencyManagement (for dependencies) and pluginManagement (for plugins) elements. That way, you will never have to define a version in a module POM or in other projects which inherit from this one.
After installing maven 3 from a repository and added maven3 home in /etc/environment what I forgot to do is to reboot my machine, after that it worked.
My /etc/environment now looks like:
M3_HOME="/home/edward/java/apache/maven-3.0.4"
MAVEN_HOME="/home/edward/java/apache/maven-3.0.4"
M3="home/edward/java/apache/maven-3.0.4"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/edward/java/apache/maven-3.0.4"
Here's how I uninstalled and install maven 3:
http://czetsuya-tech.blogspot.com/2012/05/how-to-install-maven-3-in-ubuntu-1110.html

Maven variable for reactor root

In a multi-module maven project, is there a variable that points to the root project folder?
${project.basedir} points to the current project's directory,
${project.parent.basedir} points to the parent project's directory,
but is there a variable that always points to the root directory (the one from which the maven command was executed), no matter from which project inside the reactor?
I realized that the problem I wanted to solve is pretty much unsolvable. I wanted a variable that pointed to either project.basedir, project.parent.basedir, project.parent.parent.basedir etc, whichever is higher. But since a project's parent pom need not be it's parent in the file system, my whole approach won't help. So I am accepting Pascal's answer because it answers my question (even if my question does not solve my problem).
is there a variable that always points to the root directory (the one from which the maven command was executed)
user.dir (the working directory) should be that directory.
In the latest maven, you can use ${maven.multiModuleProjectDirectory}.
In Maven 3, ${session.executionRootDirectory} is "a variable that always points to the ... directory ... from which the maven command was executed."
Note that this is distinct from a property that gives the top-level root directory of a multi-module project, regardless of where in the directory structure mvn is executed from. Such a property does not exist to my knowledge, but you can use the ${basedir}/.. hack to achieve it. See this thread on maven-users for more details.
See also: Finding the root directory of a multi module maven reactor project
Use directory-maven-plugin with directory-of goal.
Unlike other suggestions:
This solution works for multi-module projects.
It works whether you build the whole project or a sub-module
It works whether you run maven from the root folder or a sub-module (unlike ${session.executionRootDirectory}
There's no need to set a relative path property in each and every sub-module!
The plugin lets you set a property of your choice to the absolute-path of any of the project's modules. In my case I set it to the root module...
In my project root pom:
<plugin>
<groupId>org.commonjava.maven.plugins</groupId>
<artifactId>directory-maven-plugin</artifactId>
<version>0.1</version>
<executions>
<execution>
<id>directories</id>
<goals>
<goal>directory-of</goal>
</goals>
<phase>initialize</phase>
<configuration>
<property>myproject.basedir</property>
<project>
<groupId>com.my.domain</groupId>
<artifactId>my-root-artifact</artifactId>
</project>
</configuration>
</execution>
</executions>
</plugin>
From then on, ${myproject.basedir} in any sub-module pom always has the path of the project root module. And of course, you can set the property to any module, not just the root...
Such property can be created using: directory-maven-plugin.
Using the plugin's highest-basedir goal you can assign the root path to any property you specify.
For me, there was a need for root directory during variable interpolation, not for plugins section - for local directory relative to root with hand-crafted jars. I know this is a bad practice to have local directory with jars, but this was a requirement of project.
Why I was unable to use different solutions:
${session.executionRootDirectory} and ${user.dir} are tied with directory from which maven command was executed. I want to refer to the same directory independently of directory, from which maven was launched.
${project.basedir} ,as mentioned above, points to current project directory, so child modules will search for jars in wrong location.
I had about 100 projects, so defining relative paths or usage of accepted answer for this question is quite complex in my case.
Directory plugin can be used only for plugin configurations, not for variable interpolation
So, in my case with bad requirements I have used environment variable which refers project root and used it in pom.xml. Use it as last resort, when other solutions do not work. Here is example, how I use environment variable in my case:
<repositories>
<repository>
<id>local-maven-repo</id>
<!--NOTE: export PROJECT_ROOT=<location>-->
<url>file:///${env.PROJECT_ROOT}/local-repo</url>
</repository>
</repositories>
As far I think, there is no such variable. There are only workaround like in accepted answer of Maven2 property that indicates the parent directory .

using maven to manage java dependencies in a jruby rails app

I'm trying to write a pom.xml that will allow me to run a command locally and fetch all dependencies that my jruby Rails app has. I'm seeing two different configs though and I'm not totally sure which to use (as I'm not a java person whatsoever)
First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)
Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib
So I don't fully understand what the purpose of the first option's dependency list is for. All I want is mvn to copy my jars locally (and then eventually when my CI server does a deploy). Can someone point me in the right direction?
First Option
<project>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
</project>
Second Option
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<artifactItems>
<artifactItem>
<groupId>[ groupId ]</groupId>
<artifactId>[ artifactId ]</artifactId>
<version>[ version ]</version>
<type>[ packaging ]</type>
<classifier> [classifier - optional] </classifier>
<overWrite>[ true or false ]</overWrite>
<outputDirectory>[ output directory ]</outputDirectory>
<destFileName>[ filename ]</destFileName>
</artifactItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</plugin>
</plugins>
</build>
</project>
First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)
This is the traditional way to declare and use dependencies on a Java project. Dependencies declared under the <dependencies> element are downloaded from a "remote repository" and installed to your "local repository" (in ~/.m2/repository by default) and artifacts are then handled from there. Maven projects (at least the Java ones) don't use a local lib/ folder for their dependencies.
Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib
The maven dependency plugin allows to interact with artifacts and to copy/unpack them from the local or remote repositories to a specified location. So it can be used to get some dependencies and copy them in lets say a lib/ directory indeed. Actually, it has several goals allowing to do this:
dependency:copy takes a list of artifacts defined in the plugin
configuration section and copies them
to a specified location, renaming them
or stripping the version if desired.
This goal can resolve the artifacts
from remote repositories if they don't
exist in local.
dependency:copy-dependencies takes the list of project direct
dependencies and optionally transitive
dependencies and copies them to a
specified location, stripping the
version if desired. This goal can also
be run from the command line.
The first goal would use the setup you described in your second option. The second goal would use the standard project dependencies that you described in your first option. Both approaches would work.
The problem here is that I don't know exactly what a JRuby Rails app is, what the development workflow is, how to build such an app, etc so I don't know exactly what you need to do and, consequently, what would be the best way to implement that with Maven.
So I googled a bit and found this post that shows another approach based on OS commands (using the maven exec plugin) and has a complete pom.xml doing some other things. Maybe you should look at it and use it as a starting point instead of reinventing everything. This is my suggestion actually.