Maven - how to verify that dependencies compiled with specific Java level (1.7 for example)? - maven

For example, Java Maven project have ben compiled with maven-compiler-plugin with target level 1.7 have number of dependencies.
How to verify that those dependencies compiled with some specific Java target level as well (1.7 for example)?

As suggested in the comments, i have used Extra Enforcer Rules as additional dependency to Maven enforcer plugin that provides extra rules, as a solution.
The usage of this functionality described here, and specifically in my code it looks like that:
<properties>
<extra-enforcer-rules>1.0-beta-4</extra-enforcer-rules>
</properties>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>enforce-bytecode-version</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<enforceBytecodeVersion>
<maxJdkVersion>1.7</maxJdkVersion>
</enforceBytecodeVersion>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>extra-enforcer-rules</artifactId>
<version>${extra-enforcer-rules}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>

Related

Maven enforce no duplicate dependencies even of same version

We can use the maven-enforcer-plugin to prevent duplicate dependencies with difference versions.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>no-duplicate-dependencies</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<banDuplicatePomDependencyVersions/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
What about for duplicate dependency declarations of the same version?
Consider that we are building a multi-module project.
Say we start with project Foo.
Foo pom.xml
<dependencies>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
Later, we introduce the module Bar, which also depends on the same version someArtifact.
Bar pom.xml:
<dependencies>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
And Foo depends on Bar, so we update the POM.
Foo pom.xml
<dependencies>
<dependency>
<groupId>myGroup</groupId>
<artifactId>bar</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>someGroup</groupId>
<artifactId>someArtifact</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
As in the above example, and as our projects grow, we may forget that the same version of dependencies are already transitive dependencies.
In my mind, for organization sake, I find it messy to leave these duplicate declarations, such as it is with someArtifact.
I could write a new maven-enforcer-plugin rule, but maybe there is already a solution.
Try with dependencyConvergence rule. Add this to your parent pom.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<dependencyConvergence/>
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>
Reference :: https://maven.apache.org/enforcer/enforcer-rules/dependencyConvergence.html

cobertura-maven-plugin cannot find my groovy source code

I am trying to use apache-aven to produce a code-coverage report for my Java/Groovy project. Attached is the pom file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hal_con</groupId>
<artifactId>scheduler</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.codehaus.groovy/groovy-all -->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.5</version>
<configuration>
<providerSelection>1.8</providerSelection>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<!-- https://mvnrepository.com/artifact/org.codehaus.mojo/cobertura-maven-plugin -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
</plugins>
</reporting>
</project>
I've tried both the following:
Adding the maven-source-plugin as suggested in: Maven + Cobertura : Unable to locate [Your Class]. Have you specified the source directory?
Adding the jxr-maven-plugin as suggested in:
maven-cobertura-plugion does not show the sources
In both cases the results were exactly the same:
Unable to locate com/hal_con/scheduler/FileParser.groovy. Have you specified the source directory?
I figure that the maven-cobertura-plugin needs to be told where to find my groovy sources, but I cannot find an example.
The Cobertura Maven Plugin doesn't provide a way to customize the location of the sources. By default, it then looks into the Maven standard folder, which is src/main/java. Since your Groovy classes are located inside src/main/groovy, they are not found.
There are 2 solutions depending on your project:
Add those sources to the project with the help of the build-helper-maven-plugin:add-source Mojo:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/groovy</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
This is helpful if the project is a mixed Java / Groovy project, because you can keep the Maven defaults, and add the Groovy specific folders.
Override the source directory of Maven with
<build>
<sourceDirectory>src/main/groovy</sourceDirectory>
<!-- rest of build configuration -->
</build>
This would be convenient if the project is a pure Groovy project, without any source Java files.
With any of those two changes, running mvn clean site will generate a Cobertura report where the Groovy sources will be correctly found.

How to "maven unpack-dependencies" to an absolute path?

How can I use the maven dependency plugin, unpack-dependecies goal to unpack to an absolute path, that is, NOT relative inside the generated target folder in the project tree? For example, I want to unpack the artifacts of the two dependencies below in /usr/local/*
<dependencies>
<dependency>
<groupId>package.org.apache.apr</groupId>
<artifactId>apr-bin</artifactId>
<version>1.4.6</version>
<classifier>bin</classifier>
<type>tar.gz</type>
</dependency>
<dependency>
<groupId>package.org.apache.apr-util</groupId>
<artifactId>apr-util-bin</artifactId>
<version>1.4.1</version>
<classifier>bin</classifier>
<type>tar.gz</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.7</version>
<executions>
<!-- Unpack header files and libraries for build -->
<execution>
<id>apr-bin-unpack</id>
<phase>generate-sources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeTransitive>true</excludeTransitive>
<!-- This element does NOT make a difference -->
<outputdirectory>/usr/local</outputdirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Check the capitalization. It should be:
<outputDirectory>/usr/local</outputDirectory>

maven-dependency-plugin unpack not being executed during phase

I'm packaging an ejb and I need to include some .classes from a dependency into the jar, I'm trying to use the maven-dependency-plugin to unpack the artifact and put the files in my ${project.build.directory}/classes directory during the package phase, but when I execute mvn package I dont see any log or reference to the maven-dependency-plugin (nothing happens), I even tried putting a invalid version of the plugin and It doesn't even throw exceptions.
Below my pom.xml
....
<packaging>ejb</packaging>
<name>myapp</name>
...repository and props
<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.myapp</groupId>
<artifactId>model</artifactId>
<version>1.0.0</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<includes>**/shared/*.class</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.0</ejbVersion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.myapp</groupId>
<artifactId>model</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
what am I missing?
PS: the artifact model is installed in the local repo and I have tried with other phases too.
If you remove the lines containing the text <pluginManagement> and </pluginManagement> the plugin should execute. Just those two lines, not the lines in between. pluginManagement is a marginally advanced feature.
PluginManagement provides configuration details to POMs that inherit from this POM. However this section provides only the configuration details. To actually be executed, the plugin must be explicitly referred to outside of a pluginManagement section.
See POM Reference

How do I execute simple ant call through maven?

My project runs perfectly fine with following commands:
C:\project\<project_name>\ant -lib ant\lib -buildfile applications/<sub-project-path>/ant/build.xml deploy
However, if I wrap this command either in maven-antrun-plugin or exec-maven-plugin in pom, I get all kinds of path issues.
For maven-antrun-plugin, it seems the certain properties can not be loaded due to path issue. In exec-maven-plugin, it seems that ant target never got passed in correctly.
Can someone please advice how I can apply this in a pom file? Much appreciated.
This is my pom for exec:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>ant</executable>
<workingDirectory>${basedir}</workingDirectory>
<arguments>
<argument>'-lib ant/lib'</argument>
<argument>'-buildfile $basedir/<project-path>/build.xml'</argument>
<argument>deploy</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Haven't tried it, but you could do something similar as documented in the maven antrun plugin example.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>ant</id>
<phase>process-resources</phase>
<configuration>
<target>
<ant antfile="${basedir}/<project-path>/build.xml">
<target name="deploy"/>
</ant>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Not sure what library you want to pass as argument in -lib in your snippet above, but the same can be declared as plugin dependencies.
Do note that this plugin does not care about the existence of an ant installation on your system. It downloads necessary ant libraries.
You should pass needed dependencies directly into antrun plugin declaration, right after <executions> element.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
...
</executions>
<dependencies>
<dependency>
<groupId>ant-contrib</groupId>
<artifactId>ant-contrib</artifactId>
<version>${ant-contrib.version}</version>
<exclusions>
<exclusion>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>jasper</artifactId>
<version>${tomcat.compile.version}</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}.0</version>
<scope>system</scope>
<systemPath>${jdk.home}/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
I've included some libraries that I use in our project, so that you have an example. Note, that if your build uses some non-standard ( i.e. something outside java.lang ) Java API classes, you have to pass tools.jar as a dependency.
Also, if you use ant-contrib do not forget to exclude ant as a dependency, because it is dependent on some ancient version of ant and you will get a version collision.
Another annoying thing is that dependency assigned directly to plugin execution are not part of POM's <dependencyManagement>, so you have to spell out precise versions. One workaround is to declare version properties in the same place as your central <dependencyManagement> and use the properties instead of hardcoded versions.

Resources