no problem to move it to this thread. It is indeed about "The Maven
Way", although we may need to start from the beginning, explaining
the
issue we're facing.
Let's use ASM as an example, their 6.0_ALPHA has been built like
this,
although without Maven.
ASM is an all purpose Java bytecode manipulation and analysis
framework.
IIRC their code is compatible with Java 1.2, but they've also added
a
module-info for those who want to use this dependency within a
Java9/Jigsaw project.
module-info MUST be built with Java9 with source/target or release =
9.
Other sources must be built with an older JDK with source/target 1.2
There are several ways to solve this:
- multi-module project and multi release jar like Paul suggest.
However,
IIRC the specs say that the module-info MUST exist in the root.
- 2 source folders, src/main/java and src/main/jigsaw, both writing
to
target/classes. Here it is quite clear what happens per
source-folder.
- 1 source folder and all the magic of calling javac twice in the
maven-compiler-plugin. I started with this, but I don't like it.
Details
are below.
- 1 source folder and 2 execution blocks (one excluding module-info,
one
only including module-info).
We shouldn't be looking at Maven alone, but also at IDE support.
AFAIK
Netbeans and IntelliJ simply call Maven. Eclipse is probably hard
due to
the m2eclipse extensions.
Now back to Pauls suggestion. I don't think we make developers very
happy if they are advised to have a multimodule project just to be
able
to compile the module-info file.
I am aware that this is mainly an issue for library builders, end
users
simply build everything with Java9, no problems there. From library
builders you can expect that they don't mind adding extra
configuration to
build their jar, but forcing them to set up a Maven multimodule
project is
not really nice.
I would expect the module-info close to the related sourcefiles, so
I
would prefer in the same (single) MavenProject.
*Unless* IDEs are so strong with handling multi release jars that it
looks like I'm adjusting the module-info, even though it is
actually
located somewhere else.
So let's see the opinions from others.
thanks,
Robert
On Wed, 31 Aug 2016 15:59:04 +0200, Paul Benedict
<[email protected]>
wrote:
Robert, I'm responding to dev@maven so we can discuss Maven
philosophies...
I believe the pattern should be based on a multi-module project.
Each
module should target the expected JDK version. Then introduce a new
"mrjar"
type for the parent that knows how to bind them all together into a
Multi-Release JAR.
Cheers,
Paul
On Wed, Aug 31, 2016 at 6:10 AM, Robert Scholte
<[email protected]>
wrote:
I've been working on the implementation of this in the
maven-compiler-plugin, but I'm not really pleased with the result.
The problem is that in the worst case scenario we have to work
with 3
different versions of Java:
- The Maven Runtime (set as JAVA_HOME)
- JDK for the module-info.java
- JDK for all other source files.
The example below worked because all three were set to JDK9.
But based on the source/target of 1.6 I cannot predict which JDK
is
used,
only that it is at least JDK6. Should the plugin switch to another
JDK?
And if you want to compile with source/target 1.5 or less, you're
in
trouble. There's something called toolchain, where you can specify
the
JavaHome per version, but in case of maven-compiler-plugin it
assumes
that
all java-related plugins and execution blocks want to use the same
toolchain through the whole Maven project.
The good news is that for the maven-jdeps-plugin I improved this
part in
Maven 3.3.1, since this plugin only works with Java8 and above,
which
doesn't have to be the same JDK to compile the sources with. Now
you can
simple say: I want the toolchain for version X. This feature needs
to be
added to the plugin.
That said I think I will write a recipe for this. This is first of
all
an
issue for library writers who want to have their jar compatible
with
multiple Java versions for their end users.
Result: One javac call per execution block as it was meant to be.
thanks,
Robert
On Fri, 26 Aug 2016 15:31:07 +0200, Oliver Gondža
<[email protected]>
wrote:
Thank you all for your suggestions. I managed to get the project
to
build
with following maven setup:
```
<!--
When using compiler from java 8 and older, ignore module
files
altogether.
Otherwise, use 2 phase compilation to build
- all classes for target version and
- module-info.java with 9+ source and target level
-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<configuration>
<excludes>
<exclude>**/module-info.java</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>jigsaw</id>
<activation>
<jdk>[1.9,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
<executions>
<execution>
<id>module-infos</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<includes>
<include>**/module-info.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
```
It does compile with older javac versions as a bonus. Given this
is
nothing else than using `-source 9 -target 9` for
module-info.java if
present, I dare to say maven-compiler-plugin can be adapted to
figure
this
out on its own.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]