I am new to maven, and I find that though I change the facet of the jdk of the project to 1.8, every time I "update maven",it will get back to jdk 1.6.
Why is that?
I installed jdk 1.8 in my windows, and I am using eclipse.
I read Specify JDK for Maven to use and add the following but it does not work.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.8</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
The version of the JDK that maven will use is set in the maven-compiler-plugin like so:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source> <!-- use java 8 -->
<target>1.8</target>
</configuration>
</plugin>
See Setting the -source and -target of the Java Compiler for more information.
Check the maven compiler plugin to specify source and target java version,
http://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html
Regards,
Prasanna
maybe too late, but it works for me:
<!-- we want JDK 1.8 source and binary compatiblility -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- ... -->
<!-- we want sources to be processed by a specific 1.8 javac -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA_1_8_HOME}/bin/javac</executable>
</configuration>
</plugin>
Your question help me a lot anyway :) Thanks :)
In a comment you asked:
So what about maven-enforcer-plugin, what is this to do?
According to that documentation for the plugin:
"This goal is meant to be bound to a lifecycle phase and configured in your pom.xml. The enforcers execute the configured rules to check for certain constraints."
In other words, it checks that certain constraints have been satisfied. It does not cause them to be satisfied.
In your example, the effect of the plugin should be to cause the build to fail if the Java version is not Java 1.8.
... and why it solves the thread "Specify JDK for Maven to use"?
The answer you are referring to says this:
"And it never harms to ... add maven-enforce-plugin to make sure the right jdk is used. This is a good practice for your pom."
As you can see, it does not state that maven-enforce-plugin "solves" the problem. It is actually providing a way to ensure that the problem has been solved ... and fail the build if it hasn't.
Related
I couldn't understand for some time why my Maven project wasn't building in Eclipse and presented me with "Bad version number in .class file" errors.
I checked all my dependencies and ensured they were built for Java 6 or lower (using this handy JAR version checking tool).
I opened my project properties and confirmed I had project-specific compiler settings, set to compliance level 1.6.
I also confirmed I had the Java 6 libraries on my build path.
Finally, I discovered the cause was related to the default JRE selected for my workspace. This was set to jdk1.5 for some reason. Setting this to something higher than this (I chose jdk1.8) solved the issue. In the end, I had to select jdk1.7 to allow my AspectJ weaving to work correctly.
My question is: why did this solve it? According to the preferences page, this setting only influences which JRE is added to the build path of newly created Java projects. I can't fathom why this would affect my ability to build my project. Any suggestions? It seems as though Eclipse uses the default JRE selection to influence what type of compiler is used.
I'm using m2e to bind Eclipse and Maven. My POM build section is as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<!-- http://maven.apache.org/plugins/maven-compiler-plugin/ -->
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<complianceLevel>1.6</complianceLevel>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I have a problem with CTW aspects using aspectj-maven-plugin. I get the following error (execution entry is being highlighted):
Multiple annotations found at this line:
- Execution default of goal org.codehaus.mojo:aspectj-maven-plugin:1.5:compile failed: Plugin
org.codehaus.mojo:aspectj-maven-plugin:1.5 or one of its dependencies could not be resolved: Could not find artifact
com.sun:tools:jar:1.7.0_21 at specified path C:\Program Files\Java\jre7/../lib/tools.jar (org.codehaus.mojo:aspectj-maven-
plugin:1.5:compile:default:compile)
- Execution default of goal org.codehaus.mojo:aspectj-maven-plugin:1.5:test-compile failed: Plugin
org.codehaus.mojo:aspectj-maven-plugin:1.5 or one of its dependencies could not be resolved: Could not find artifact
com.sun:tools:jar:1.7.0_21 at specified path C:\Program Files\Java\jre7/../lib/tools.jar (org.codehaus.mojo:aspectj-maven-
plugin:1.5:test-compile:default:test-compile)
On the configuration:
<build>
<plugins>
<!-- http://mojo.codehaus.org/aspectj-maven-plugin/usage.html -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>
<source>1.7</source>
<target>1.7</target>
<sources>
<source>
<basedir>src/main/java</basedir>
<includes>
<include>**/*Aspect.java</include>
</includes>
</source>
</sources>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
What am I doing wrong? It looks like as if this plugin was unable to find jdk? But why?
Is your JAVA_HOME set properly? Please check that. It worked perfectly for me. So I think you should add below mentioned plugin and try:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
Run mvn compile after that.
Please check the JAVA_HOME env variable. This happened to me when JAVA_HOME is pointed to JRE folder rather than jdk folder.
I had this problem running with java 11, seems like it is only compatible with java 8.
Looking into the project, aspectj-maven-plugin it looks like the update was committed but never actually merged.
I would like to use java 7 in my tests and java 6 for the code. How to achieve this?
You can also set source and target in the execution phase testCompile of the maven-compiler-plugin. So try something like this
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>testCompileWithJDK7</id>
<phase>test-compile</phase>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</execution>
</executions>
</plugin>
You can set the jvm that is used by the maven-surefire-plugin to point to the java 7 executable.
See http://maven.apache.org/surefire/maven-surefire-plugin/test-mojo.html#jvm
I have projects that need to be build with a specific version of the JDK.
The problem isn't in the source and target parameters but in the jars of the runtime used during compilation.
In some cases I get a compilation error if I try to compile with the wrong JDK, but sometimes the build is successful and I get runtime errors when using the jars.
For example in eclipse I have the ability to establish the execution enviroment for the project in the .classpath file.
Is there a way to handle such situation in maven?
What I would like to have is the ability to handle JRE dependency like other dependencies of the project in the POM file.
UPDATE:
The accepted solution was the best one when I asked this question, so I won't change it. Meanwhile a new solution to this kind of problems has been introduced: Maven Toolchain. Follow the link for further details.
I've found this article:
http://maven.apache.org/plugins/maven-compiler-plugin/examples/compile-using-different-jdk.html
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${JAVA_1_4_HOME}/bin/javac</executable>
<compilerVersion>1.3</compilerVersion>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
I have projects that need to be build with a specific version of the JDK.
You can use the Maven Enforcer plugin to enforce the use of a particular version of the JDK:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.5</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
But I'm not sure I really understood the question. If this is not what you want, maybe you could declare your JDK specific dependencies in profiles and use an activation trigger based on the JDK version. For example:
<profiles>
<profile>
<activation>
<jdk>1.5</jdk>
</activation>
...
</profile>
</profiles>
This configuration will trigger the profile when the JDK's version starts with "1.5".
I believe that this can be solved with following plugin in your pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
Here you target version 1.6 , or write your own version
How can I configure the maven compiler to use java 5 for my test code and java 1.4 for my main code?
If you want to set compliance to the relevant Java version, you can configure the compiler plugin for each execution. Assuming Maven is using a JDK at least as current as the highest version you specify. By using properties you can override that configuration on the commandline or in a child if needed:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compileSource}</source>
<target>${compileSource}</target>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<source>${testCompileSource}</source>
<target>${testCompileSource}</target>
</configuration>
</execution>
</executions>
</plugin>
...
<properties>
<compileSource>1.4</compileSource>
<testCompileSource>1.5</testCompileSource>
</properties>
If you mean using different compilers, that's a bit more involved. as you need to specify the path to the JDK and what compiler version you're using. Again these can be defined in properties. Though you may want to define them in your settings.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${compileSource}</source>
<target>${compileSource}</target>
<executable>${compileJdkPath}/bin/javac</executable>
<compilerVersion>${compileSource}</compilerVersion>
</configuration>
<executions>
<execution>
<id>test-compile</id>
<phase>process-test-sources</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<source>${testCompileSource}</source>
<target>${testCompileSource}</target>
<executable>${testCompileJdkPath}/bin/javac</executable>
<compilerVersion>${testCompileSource}</compilerVersion>
</configuration>
</execution>
</executions>
</plugin>
...
<properties>
<compileSource>1.4</compileSource>
<testCompileSource>1.5</testCompileSource>
<compileJdkPath>path/to/jdk</compileJdkPath>
<testCompileJdkPath>path/to/test/jdk<testCompileJdkPath>
</properties>
Note it might make sense to define the compiler configurations in profiles, one for each JDK you support, so that your normal builds don't rely on properties being set.
Also, in Maven 3.x, you need to include the fork parameter when specifying the executable, e.g.:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
<configuration>
<fork>true</fork>
<executable>${testCompileJdkPath}/bin/javac</executable>
<source>1.8</source>
<target>1.8</target>
</configuration>
</execution>
</executions>
</plugin>
I had no luck with the accepted answer compiling java 7 source and java 8 test sources using the maven-compiler-plugin, version 3.5.1. Because the compile plugin used the source / target parameter for both, main and test sources.
But I found out, there are separate configuration parameters for the test source and target.
So for me the solution that worked was
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<testSource>1.8</testSource>
<testTarget>1.8</testTarget>
</configuration>
</plugin>
</plugins>
</build>
I found a solution at least for my case.
I am writing a library that needs to be Java 1.7 compatible but relies on the nashorn engine in JDK 8 to test some of its features, which is a perfect reason for using different compiler/jdk version for main and test.
When talking about using different compiler/JRE version for main and test, say version A for main and version B for test and A is strictly smaller than B, we really want to achieve the following:
Make the IDE (in my case, the Eclipse) use the JDK version B during development for not introducing compilation error (red cross on your project icon).
Make JUnit tests runnable from within your IDE.
Make JUnit tests runnable from command line through mvn clean test which is required for releasing.
Compile sources in main using JRE A, which enables automatic detection of using new features from JDK B.
Free use of new features / new APIs from JDK B in test cases codes.
And the following pom declaration works (for example let A = 1.7 and B = 1.8):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<fork>true</fork>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<compilerArguments>
<source>1.7</source>
<target>1.7</target>
</compilerArguments>
</configuration>
</execution>
<execution>
<id>default-testCompile</id>
<configuration>
<compilerArguments>
<source>1.8</source>
<target>1.8</target>
</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
Firstly, <source>1.8</source> <target>1.8</target> is a must to make Eclipse happy and using 1.8 for the project itself, as others pointed out that Eclipse has a still pending bug and does not support different JDK version in a single project natively.
Secondly, use <execution> to override the source and target arguments during source compilation and test source compilation. default-compile and default-testCompile are special names for compiler plugin.
Thirdly, be sure to use compilerArguments but not compilerArgs. As far as I know, only compilerArguments can be used to override argument settings during runtime.