In my project, we are going to use Java 7 for maven-compiler-plugin
and we assume that after Maven compile, all the code which is using Java 8 should not compile successfully.
However, in my case, there is a file using Arrays.stream(T[] array)
which can be used from Java 8 and it still compiles successfully. Below is some of the pom.xml
file which configure the Java version. Would you please have a look and give me any idea why my files can still compile successfully although I configure it to be Java 7?
For the pom.xml
, I skip the dependencies and so on and only list the properties and the build.
<properties>
<java.version>1.7</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>
And for the file I use a method in Java 8, the line is something like this:
buffer.append(Arrays.stream(arg).collect(Collectors.joining("/")));
And what I want is that since I configure the Java version to be 7 in Maven and after compile, the file which use the Java 8 should not compile successfully and show the errors like "... are allowed only at source level 1.8 or above".
2.1. The Maven compiler accepts this command with –target and –source versions. If we want to use the Java 8 language features, the –source should be set to 1.8. Also, for the compiled classes to be compatible with JVM 1.8, the –target value should be 1.8. The default value for both of them is the 1.6 version.
Show activity on this post. Create a pom-only ( <packaging>pom</packaging> ) project that has the compiler settings (and any other default settings) you want. You give treat it like any other project (release it; deploy it to your Maven repo, etc.). It doesn't help much if all you want to set is compiler settings.
The default Java compiler version used by Maven is Java 1.5 .
Maven JDK 1.8 use in Eclipse As soon as a new Maven build takes place, the JDK version reverts back to 1.5. The only way to make this a permanent change is to edit the Maven compiler plugin POM entry and force Eclipse and Maven to use Java 1.8.
The <source>
and <target>
flags of the Compiler Plugin, which maps directly to the -source
and -target
options of the Java compiler javac
(when it is the one used), are generally misunderstood.
source
does not instruct javac
to compile the Java source files with the specified JDK version. It instructs javac
to check the version of the accepted source code, which is very different. A major version of Java sometimes brings changes to the syntax of the source code. For example, in Java 1.4, you could not write source code containing generics, like List<String>
; it wasn't valid. But with Java 5, you can, which means that a new kind of Java source code was now accepted by the JDK 5 compiler. A JDK 1.4 compiler, faced with a List<String>
, can only error because it doesn't know that, when the JDK 5 compiler accepts it perfectly. Setting the -source 1.4
option would tell the JDK 5 compiler to interpret the source code as JDK 1.4 source code; therefore, if that code did contain generics, it would fail, because that source code isn't valid in that version. What this also means, is that if the source code doesn't contain any Java 5 specific source code, it would compile just fine with -source 1.4
.
In the example here, you have a case where the javac
compiler of JDK 8 is instructed to check the source code with regard to Java 7. And actually, the line
buffer.append(Arrays.stream(arg).collect(Collectors.joining("/")));
does not use any Java 8 specific source code. Sure, it uses Java 8 specific classes, but the source code itself would perfectly be understandable by a JDK 7 compiler.
There are no lambda expressions. Add a simple map(i -> i)
in your pipeline, and then javac
will error, telling you:
lambda expressions are not supported in
-source 1.7
It detected that the source code used a specific feature that isn't available in the set of the JDK 7 source code features.
There are no invocations of static methods on interfaces. Replace your Stream pipeline with Stream.of(arg)
instead of Arrays.stream(arg)
. This time, you'll get an error:
static interface method invocations are not supported in
-source 1.7
Arrays
is not an interface, so invoking a static method stream
on that class is perfectly valid JDK 7 source code. However, Stream
is an interface (which is, of course, known to the JDK 8 compiler you're using), and, before Java 8, interfaces couldn't contain static methods. As such, it isn't valid Java 7 source code.
There are more like that, but the point isn't to describe them all here (type annotations, repeated annotations, method references, intersection types in cast... you can see all of them in javac
source code for example). All in all, there is no reason for javac
to fail with that source code and the -source 7
option.
target
is another beast entirely; this isn't the issue here, so suffice it to say that it instructs javac
to generate byte code that targets the specified version the VM. It does not ensure in any way, that the byte code produced will actually run with said version of the VM. If you want to ensure that, the -bootclasspath
option is to be used.
Coming back to the task at hand here, which is actually to make compilation fail here. With Maven, you have 2 solutions:
javadoc
tool of the JDK installation).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With