Currently Existing Solutions With Maven 3

The current solution to create a multi release jar is not very convenient. An examples https://github.com/khmarbaise/mrelease or others (please add them if you have some?) The issue with those setups is that you have to go a bit tricky way to resolve that.

  • XXX

Current Impediments

  • Currently IDE's do not support having different JDK version based code in a single module/project; for example one directory with JDK 11 source and another with JDK 17 source code. The current state is that the support of such setup is a non usual setup which is more or less only required for library producer. 
  • The convenience of the solutions is not good.. 

Possible Future Solution

Model Enhancements 

Related discussion about that topic: https://lists.apache.org/thread/08f9o0k9b4wrqgrfjqptrzfflr2r6gfs https://github.com/OpenElements/maven-support-care/discussions/37

<build>
  <sources>
    <source scope="main">src/main/java</source>
    <source scope="main" multi-release="11">src/main/java11</source>
    <source scope="test">src/test/java</source>
  </sources>
  <resources>
  <resource type="main">
  ...
  </resource>
  <resource type="test">
  ...
  </resource>
</resources>
..

Base on the directory idea it could be assumed, that such setup to automatically detects a versioned based directory something like src/main/java21 which triggers the usage of --release 21 for compiling as well as for the testing area and also for resources. But based on this assumption the question arises: How to limit the tests for a particular JDK version? And also things like code coverage (running surefire for different versions? or all together?) and maybe other tools like static code analyzers?  Another part is: What about generators who generate code? How to separate them? Currently we have things like target/generated-sources/ ... that would require a change as well to generate targeted to a particular JDK version? (What about those plugins? How to configure them? for each version different?)

Questions

  • How should the above setup being triggered that we want to build a multi release jar?
  • Do we need a particular maven plugin for that purpose? 

Consequences

  • That means that for each version based part the plugins like compiler, resources, surefire/failsafe, others needed to executed... 
  • ???

The following needs to be summarized (TBD):
Furthermore if you have several JDK versions for example; you have one non-version dependendat maybe just JDK 8 based and version dependant parts for version 11,17,21,22 so you need for each version separated test/main code + resources and also you might require different deps for different jdk versions... (as already suggested)
But on the other hand we could think about a packaging type "multi-release" which automatically defines a default directory layout (as suggested src/main/java/.. base version.. and "src/main/java11/ for JDK 11 etc. also the resources like src/main/resources11/.. and for src/test/java11 etc. the same way)...
Those diretories could automatically trigger the appropriate --release option (The default is defined by the usual configuration of maven-compiler-plugin --release also associated with src/main/java;) so if you create a directory src/main/java21 it will be compiled via --release 21...That would just remove the requirement to define all those things in your pom file by hand..(and might be more following the idea convention over configuration)..
The same way for the the src/test/java21 ...A not trivial thing is about things like code coverage how to handle things in that setup? Also how to run tests only limited to a JDK 21 code area which might be require code from the default area (src/main/java). And how could it be handled to have different deps in different code areas (JDK 21 requires for testing a different library?) and in case of code coverage we require the agents (or even other tools?) ? and let later combine them into a single one...Those thoughs are bringing me at the moment to go into the multi module setup which solves already a lot of those issues...(current setup not convenient of course)... and also keep the flexibility ...

Packaging Type - multirelease

The assumption is to have a multi module build setup where one module is responsible for producing the final multi release jar which is based on the new packaging type multirelease.  This type binds the maven-compiler-plugin to the life cycle which is required to compile the module-info.java file which is located in the usual src/main/java/ location.

We create a maven-multi-release-plugin which handles the final packaging into the resulting jar file. This combines the compiles module-info.class file and also from the other modules the code and of course only picks up the right files (it's bit like maven-shade-plugin with filters?) The dependencies given are put into the resulting multi release jar ... (maybe those needed to be identified by a particular scope? Not sure about that). (Needs more thourougly thinking/trying about it). Based on the usage of plugin supplemental requirements like defining OSGi enhancements could be done easier?

The issues like creating code coverage or having different dependencies in the different version based modules can be done with the existing mechanisms and also code generators can easily be configured in the appropriate module without even chaning existing plugins... (Maven 4 itself is a different story?) 

Questions

  • ??

Consequences

  • The triggering for building a multi release jar is done by the packaging type
  • The work is done mainly by a new plugin?
  • No labels