Anand Sunderraman Anand Sunderraman - 6 months ago 114
Java Question

maven multi module project, compile one of the modules with a different java version

I am trying to build a maven multimodule project, where I want two of the modules to build on java 8 and one of them to build on java 7

EDIT: I also looked at this SO question

So I tried the solutions provided at Maven and Java multi-version modules

So my parent pom looks like

<?xml version="1.0" encoding="UTF-8"?>
<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.example</groupId>
<artifactId>parent</artifactId>
<name>parent</name>
<version>1.0.0-SNAPSHOT</version>
<description>Parent pom </description>
<packaging>pom</packaging>

<properties>
<aspectj.version>1.8.5</aspectj.version>
<jackson.version>2.4.0</jackson.version>
<java.version>1.8</java.version>
<java.source.version>${java.version}</java.source.version>
<java.target.version>${java.version}</java.target.version>
<jdk.version>8</jdk.version>
<jdk>${env.JAVA_HOME_8}</jdk>
<jersey.version>2.9</jersey.version>
<groovy.version>2.4.3</groovy.version>
<slf4j.version>1.7.9</slf4j.version>
<spock.version>1.0-groovy-2.4</spock.version>
<spring.boot.version>1.3.5.RELEASE</spring.boot.version>
<spring.version>4.2.6.RELEASE</spring.version>
<spring.security.version>3.1.7.RELEASE</spring.security.version>
<spring.data.version>1.7.0.RELEASE</spring.data.version>
</properties>

<dependencyManagement>

</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<executions>
<execution>
<id>unit-tests</id>
<goals>
<goal>test</goal>
</goals>
<phase>test</phase>
<configuration>
<includes>
<include>**/*Test.*</include>
<include>**/*Spec.*</include>
</includes>
<excludes>
<exclude>**/*IntegrationTest.*</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/groovy</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/test/groovy</source>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
<source>${java.source.version}</source>
<target>${java.target.version}</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<verbose>true</verbose>
<executable>${jdk}/bin/javac</executable>
<fork>true</fork>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.4.3-01</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
<outputDirectory>${project.build.directory}/surefire-reports/cobertura</outputDirectory>
<instrumentation>
<ignoreTrivial>true</ignoreTrivial>
<ignores>
<ignore>org.slf4j.Logger.*</ignore>
</ignores>
<excludes>
<exclude>**/Application.class</exclude>
<exclude>**/ApplicationConfig.class</exclude>
<exclude>**/JerseyConfig.class</exclude>
</excludes>
</instrumentation>
<check />
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>cobertura</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<modules>
<module>model</module>
<module>persistence</module>
<module>service</module>
</modules>
</project>


And the pom in the module looks like:

<?xml version="1.0" encoding="UTF-8"?>
<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.example</groupId>
<artifactId>model</artifactId>
<name>model</name>
<description>Model forservices</description>
<packaging>jar</packaging>

<parent>
<artifactId>parent</artifactId>
<groupId>com.example</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

<properties>
<java.version>1.7</java.version>
<java.source.version>${java.version}</java.source.version>
<java.target.version>${java.version}</java.target.version>
<jdk.version>7</jdk.version>
<jdk>${env.JAVA_HOME_7}</jdk>
</properties>

<build>
<plugins>
<plugin>
<groupId>org.raml.plugins</groupId>
<artifactId>raml-jaxrs-maven-plugin</artifactId>
<version>1.3.3</version>
<configuration>
<jaxrsVersion>2.0</jaxrsVersion>
<jsonMapper>jackson2</jsonMapper>
<jsonMapperConfiguration>
<generateBuilders>true</generateBuilders>
<includeHashcodeAndEquals>true</includeHashcodeAndEquals>
<includeToStringuseLongIntegers>true</includeToStringuseLongIntegers>
</jsonMapperConfiguration>
</configuration>
<executions>
<execution>
<id>generate-model</id>
<goals>
<goal>generate</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<sourcePaths>
<sourcePath>${basedir}/src/main/raml/services.raml</sourcePath>
</sourcePaths>
<basePackageName>com.example.app</basePackageName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>


However on compilation I get the following error:

[INFO] Found location </Users/someuser/.m2/repository/org/codehaus/groovy/groovy-eclipse-batch/2.4.3-01/groovy-eclipse-batch-2.4.3-01.jar> for className <org.eclipse.jdt.internal.compiler.batch.Main>
[INFO] no javaAgentClass seems to be set
[INFO] Compiling in a forked process using /Users/someuser/.m2/repository/org/codehaus/groovy/groovy-eclipse-batch/2.4.3-01/groovy-eclipse-batch-2.4.3-01.jar
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] Failure executing groovy-eclipse compiler:
javac: invalid flag: -jar
Usage: javac <options> <source files>
use -help for a list of possible options

[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.687s
[INFO] Finished at: Thu May 26 10:04:15 EDT 2016
[INFO] Final Memory: 21M/320M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project model: Compilation failure
[ERROR] Failure executing groovy-eclipse compiler:
[ERROR] javac: invalid flag: -jar
[ERROR] Usage: javac <options> <source files>
[ERROR] use -help for a list of possible options


EDIT::

So based on A. Di Matteo answer I tried


  1. removing the fork and executable options from the config section of the maven-compiler-plugin

  2. Setting the source and target version to 1.7 on my module that needed a different version of java



It builds successfully. But when I read the build manifest it says Build-Jdk: 1.8.0_40. So what does that mean

Manifest-Version: 1.0
Implementation-Title: model
Build-Date: 2016-05-26 10:44:16
Implementation-Version: 1.0.0-SNAPSHOT
Archiver-Version: Plexus Archiver
Built-By:
Specification-Vendor: my org
Repo-Name: model
Specification-Title: model
Implementation-Vendor-Id: com.org
Git-Hash: xxx
Implementation-Vendor: my org
App-Name: model
Version-Number: 1.0.0-SNAPSHOT
Created-By: Apache Maven 3.0.5
Build-Jdk: 1.8.0_40
Specification-Version: 1.0.0-SNAPSHOT

Answer

Looking at this old thread concerning the groovy compiler:

Are you by any chance explicitly specifying 'javac' as an executable somewhere in your pom? The only way that I can reproduce your problem is by using a configuration like this:

<configuration>
  <compilerId>groovy-eclipse-compiler</compilerId>
  <executable>javac</executable>
  <fork>true</fork>
</configuration>

When I remove the {{javac}} option, then things work fine.

This is a small bug in the groovy-eclipse-compiler since we should never be looking at the executable option (and I'll fix this), but the workaround is easy.

And this old one

Now fixed locally. Please re-open if this is not the problem that you were having.

When using the Groovy Eclipse Compiler within a Maven build, setting maven-compiler-plugin option forked = true causes "invalid flag: -jar" error

It seems like the issue is related to the usage of fork and executable and even though it concerned an old version of the groovy compiler, it is still (partially?) there.

Using the minimal POM below:

<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sample</groupId>
    <artifactId>sample-project</artifactId>
    <version>0.0.2-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <compilerId>groovy-eclipse-compiler</compilerId>
                    <source>1.7</source>
                    <target>1.7</target>
                    <showDeprecation>true</showDeprecation>
                    <showWarnings>true</showWarnings>
                    <verbose>true</verbose>
                    <executable>path_to_java8\bin\javac.exe</executable>
                    <fork>true</fork>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-compiler</artifactId>
                        <version>2.9.2-01</version>
                    </dependency>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-batch</artifactId>
                        <version>2.4.3-01</version>
                    </dependency>
                    <dependency>
                        <groupId>junit</groupId>
                        <artifactId>junit</artifactId>
                        <version>4.11</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

We can already reproduce the issue and the misleading invalid flag error.

Removing the <fork>true</fork> configuration entry, the build would then be SUCCESSFUL, but it would also skip the executable element which, from official documentation, is used to

Sets the executable of the compiler to use when fork is true.


A suggestion to then overcome the issue would be:

  • Remove the fork and executable option
  • Use the major Java version, in this case 8 as default JDK for all modules
  • Set the source/target to the minor version where required, in this case 7 in certain modules
  • Configure the animal-maven-sniffer accordingly in the concerned modules to make sure you adhere to Java 7 cross compilation.

Concerning cross-compilation, I would also hightly recommend to read this StackOverflow post.