How to get Maven dependencies printed to a file in a readable format? - maven

I am working on a big projects with many pom.xml files and I need to specify all the libraries that I use. This means that I need to read pom.xml files recursively and get groupId, artifactId, scope and version. I checked out mvn dependency:tree but I can't find a way to print it to a file in a readable format. I saw appendOutput but I saw no example on how to use it in cmd. I saw some solutions done in Linux but I only have access to Windows XP.

This can (at least now) be done with command line options to the dependency:tree plugin.
Try:
mvn dependency:tree -Doutput=/path/to/file
Reference: Maven Dependency Plugin Page
You only asked about "readable" format, but you can also pass the -DoutputType parameter with various options. Also note that the version I have installed, I get the following warning:
[WARNING] The parameter output is deprecated. Use outputFile instead.
So, consider trying it with -DoutputFile=/path/to/file
Also, I was unable to get the -DoutputType paramater to give me anything other than the default text, but didn't have a chance to play around with it. YMMV.

If you have multiple modules under the same repo/project and want the dependencies of all the modules in one file, so as to be able to diff b/w one build and another to see if something changed somewhere, you can do
$project_dir> mvn dependency:tree -DoutputFile=<absolute_path_to_file> -DappendOutput=true
e.g.
$project_dir> mvn dependency:tree -DoutputFile=`pwd`/mvn_dependency_tree.txt -DappendOutput=true
See other options available at https://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html

Adding the
<plugin>
<groupId>org.apache.servicemix.tooling</groupId>
<artifactId>depends-maven-plugin</artifactId>
</plugin>
plugin produces a classes/META-INF/maven/dependencies.properties file with the project dependencies easily parseable.
Example of the output produced:
# Project dependencies generated by the Apache ServiceMix Maven Plugin
# Generated at: Mon Oct 10 17:43:00 CEST 2011
groupId = my.group.name
artifactId = my.artifact.name
version = 0.0.1-SNAPSHOT
my.group.name/my.artifact.name/version = 0.0.1-SNAPSHOT
# dependencies
junit/junit/version = 4.8
junit/junit/type = jar
junit/junit/scope = test
org.easymock/easymock/version = 2.4
org.easymock/easymock/type = jar
org.easymock/easymock/scope = test

On GNU/Linux I would just do mvn dependency:tree > myFile. However, if you're restricted to Windows only, than I would look for Windows' syntax for streaming the output of a command.
According to this site (just a top-results from Google) it seems that Windows' console also use > sign to direct the output stream to i.e. a file.
So would you mind trying this?

I have run the below command and got the file having all the maven dependency.
mvn dependency:tree -DoutputFile=temp/mvn_dependency_tree.txt
This command will create a folder named "temp" and inside this folder a file name mvn_dependency_tree.txt will be created with all the dependencies.

You can always install MinGW and MSYS and then use the Linux examples using dependency:tree in Windows

Perhaps effective-pom (in conjunction with some linux commands for saving the file) can be sufficient for your needs.

Related

How to list only direct dependencies in mvn dependency tree command?

mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:tree -DoutputFile=/tmp/dependencies.txt -DoutputType=dot -DappendOutput=true
I'm using the above command to get a list of dependencies i.e the direct and transitive dependencies. I want an alteration in the above command which would give me a list of only the direct dependencies and ignore all the transitive dependencies. I don't want to use any other command nor do i want to change the output file format. Our parsers are dependent on the output file format. Does anyone have any solution for this?
I think the excludeTransitive property is what you want.
Oh, sorry, strike that, that property is only for dependency:list, not dependency:tree.
If you were willing to live with a format change, you'd want...
mvn org.apache.maven.plugins:maven-dependency-plugin:3.0.2:list -DoutputFile=/tmp/dependencies.txt -DexcludeTransitive=true

Gradle equivalent of maven-versions-plugin

This is my build.gradle:
group 'whatever'
version '1.0.0-SNAPSHOT'
...
dependencies {
compile 'whatever:2.2.1-SNAPSHOT'
}
I want to automate releasing process, which includes the need to set both versions to particular values, e.g. 1.1.0 or 2.2.0 using command line only. Any kind of autoincrement is not an option.
With Maven, I'd do this using maven-versions-plugin:
mvn versions:set -DnewVersion=${WHATEVER_NEW_VERSION}
How can I do the same with Gradle? I only found this unanswered question. There must be some simple way to do that?
I ended up extracting version numbers to gradle.properties and updating them as part of the automated build script using sed:
sed -i -e \"/someVersionNumber=/ s/=.*/=${SOME_NEW_VERSION_NUMBER}/\" gradle.properties
It's what I want. Although for me, coming from the Maven background, this doesn't seem natural. I may research another alternative later.
Though not related to publishing, one way to pass command-line properties is as follows:
gradle -PWHATEVER_NEW_VERSION=2.0.0
Consider the following build.gradle snippet:
def newVersion = project."WHATEVER_NEW_VERSION"
println newVersion
See ~/utils/gradle/version.gradle in this project for another approach. It uses separate environment variables for major, minor, and incremental versions and then builds the string automatically. Because it resides in the gradle directory, it can simply be imported into build.gradle, which hides some boilerplate.
I successfully used Axion Release Plugin a couple of times and was very satisfied. Functionality-wise it comes the closest to what Maven's

Is there a way to set the Maven version number dynamically?

I would like to use Maven to produce an artifact in zip format. To give you some background; my project includes an APS package (Application Packaging Standard, used to provision cloud applications on the Parallels platform). This package is a zip file that contains a combination of XML as well as PHP files. It is generated by an APS plugin from within Eclipse and its name always includes the version and release number of its contents.
What I am trying to do is generate a zip file with Maven that would be kind of a release candidate that will be eventually sent to customers and would include not only the actual APS package but also other files such as README, User Guide.pdf, etc;. I would like the name of this zip file to contain the version number of the version number of the APS package. Currently I can generate this manually by using something like "mvn -Dversion=1.2.3-4 package" but I would like to automate the process and ideally run this from Jenkins.
Basically, my strategy is to run a script that would extract the version number from the initial APS package, once that is done, my script can invoke Maven and can pass this parameter to it so it can generate the final zip with the proper version number. This is fine but again, I need to run this script manually and I am looking for an automated process.
My question is; is it possible to invoke this script from within Maven and use its return as a parameter to set the version name (or the name of the file that will be generated) at run time? As I mentioned, I would like eventually Jenkins to handle this. It can pick up the pom file but I am not sure how it could kind of "auto configure" itself to have the proper version number.
Thanks is advance.
From jenkins build you can use profile with ${BUILD_NUMBER}:
<profile>
<id>jenkins</id>
<build>
<finalName>${artifactId}-${version}-${BUILD_NUMBER}</finalName>
</build>
</profile>
Then run in jenkins:
clean install -Pjenkins
I use the SVN (or any source versioning system) version to identify the software builds.
By simply executing this
REVISION=`svn info | grep '^Revision:' | sed -e 's/^Revision: //'`
on the sourcers folder you get the right value in $REVISION, then you can use it for your maven build
mvn -Dversion=1.2.3-$REVISION package
easy and clean

Activate a profile based on environment

Here's my scenario:
Maven 2.0.9 is our build system
We install code to multiple environments
All of our environment-specific properties are contained in property files, one for each environment
We currently read these properties into maven using the properties-maven-plugin; this sub-bullet is not a requirement, just our current solution
Goal:
Perform certain parts of the build (ie. plugin executions) only for certain environments
Control which parts are run by setting values in the environment-specific property files
What I've tried so far:
Maven allows plugins executions to be put inside pom profiles, which can be activated by properties; unfortunately these must be system properties - ie. from settings.xml or the command-line, not from properties loaded by the properties-maven-plugin
If possible, we'd like to keep everything encapsulated within the build workspace, which looks something like this:
project
pom.xml
src
...
conf
dev.properties
test.properties
prod.properties
build-scripts
build.groovy <-- the script that wraps maven to do the build
install.groovy <-- ... wraps maven to do the install
Running a build looks like:
cd build-scripts
./build.groovy
./install.groovy -e prod
Is there any possible way to accomplish these goals with the version of maven we are using? If not, is it possible with a newer version of maven?
This isn't possible using just Maven. (See also How to activate profile by means of maven property?) The reason is that profiles are the first thing evaluated before anything else to determine the effective POM.
My suggestion is to write some preprocessor that parses your environment specific property files and converts them to the required system properties before launching Maven. This script can be included in your ~/.mavenrc so that it runs automatically before Maven is launched. Here is an example script that that assumes the properties file is in a fixed location:
properties=`cat /etc/build-env.properties`
while read line; do
MAVEN_OPTS="$MAVEN_OPTS -D$line"
done <<< "$properties"
If the properties file is not fixed, you'll just need to add something to the script to discover the location (assuming it is discoverable).

sbt 0.11: Using a corporate maven repository

How can a corporate Maven repository be used (to the exclusion of other repositories) with sbt 0.11.x, as described in how do I get sbt to use a local maven proxy repository (Nexus)? ? There is no mention of ivyRepositories in the new sbt wiki at github, so I'm assuming the accepted solution there is out of date.
Step 1: Follow the instructions at Detailed Topics: Proxy Repositories, which I have summarised and added to below:
(If you are using Artifactory, you can skip this step.) Create an entirely separate Maven proxy repository (or group) on your corporate Maven repository, to proxy ivy-style repositories such as these two important ones:
http://repo.typesafe.com/typesafe/ivy-releases/
http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/
This is needed because some repository managers cannot handle Ivy-style and Maven-style repositories being mixed together.
Create a file repositories, listing both your main corporate repository and any extra one that you created in step 1, in the format shown below:
[repositories]
my-maven-proxy-releases: http://repo.example.com/maven-releases/
my-ivy-proxy-releases: http://repo.example.com/ivy-releases/, [organization]/[module]/(scala_[scalaVersion]/)(sbt_[sbtVersion]/)[revision]/[type]s/[artifact](-[classifier]).[ext]
Either save that file in the .sbt directory inside your home directory, or specify it on the sbt command line (you will need to specify if you have disabled sharing):
sbt -Dsbt.repository.config=<path-to-your-repo-file>
Good news for those using older versions of sbt: Even though, in the sbt 0.12.0 launcher jar at least, the boot properties files for older sbt versions don't contain the required line (the one that mentions repository.config), it will still work for those versions of sbt if you edit those files to add the required line, and repackage them into the sbt 0.12.0 launcher jar! This is because the feature is implemented in the launcher, not in sbt itself. And the sbt 0.12.0 launcher is claimed to be able to launch all versions of sbt, right back to 0.7!
Step 2: To make sure external repositories are not being used, remove the default repositories from your resolvers. This can be done in one of three ways:
Add the command line option -Dsbt.override.build.repos=true mentioned on the Detailed Topics page above. This will cause the repositories you specified in the file to override any repositories specified in any of your sbt files. This might only work in sbt 0.12 and above, though - I haven't tried it yet.
Having the same effect as 1, you can use overrideBuildResolvers := true, with the advantage that you can control the projects where it is applicable, depending on which scope (a project / ThisBuild / Global) you define it in. This works in sbt 0.13.
Use fullResolvers := Seq( resolver(s) for your corporate maven repositories ) in your build files, instead of resolvers ++= or resolvers := or whatever you used to use.
Finally, note that the sbt launcher script has a bug in reading the sbtopts file, so if you decide to put your common sbt command-line options in there, make sure the last line of the file ends in a newline (Emacs in particular can fail to ensure this, unless configured to do so).
An alternative for Step 2 of the accepted answer (am using sbt 0.13.1):
Add file .sbtopts to the project root directory with contents:
-Dsbt.override.build.repos=true
Another alternative is to add this line in $SBT_HOME/conf/.sbtopts, but this would force the setting for all projects.
Unpack the sbt-launcher.jar and copy the sbt.boot.properties file to a location of your choice. Change the launch script to use this file. In the file, change the repositories section to only contain your local repo and the corporate one. The distinction between Maven and Ivy comes from the given pattern (no pattern means Maven pattern by default).
Here is an example:
[repositories]
local
corporate: http://inhouse.acme.com/releases/

Resources