I'm afraid this will be long story, but this might be the moment to share the details.
https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html describes already several topics: - why MultiRelease Jars - how to build them? There are several patterns, each with its pro's and con's. But it doesn't explain the technical problems, so I guess we need to explain it a bit better. I will also take the time to describes things that you might already know. So you want to build a jar? You take the minimum pom (modelVersion + groupId + artifactId + version) and you can set the packaging to jar (or omit it, as it is the default value). You will call "package", which matches a phase of the default lifecycle. Maven must first figure out the matching lifecycle, by looping over all the available.[1] It will pick up all mapped Lifecycle components and will search in its phases. The result will be the "default" Lifecycle. Based on this Maven will look for "jar" named LifecycleMapper and the configuration for the "default" lifecycle [2] Now it knows which plugins, versions and goals must be called. (it is possible to call multiple calls within one phase) There is no explicit executionId (I'm actually not sure if you can use it here, I think so), so default-<goal> will be used as executionId. You can see this in the console output of Maven. You can use this executionId for explicit configuration. Keep in mind that plugins are very isolated. They have their own classloader during execution. They don't share configuration or instances with other plugins(*), you could treat the pom as the shared configuration. For the creation of a Multirelease jar we have sepatare challenges for the following phases: compile, test and packaging. The simplest of the three is probably packaging: you need to ensure that the manifest has the attribute Multi-Release: true Depending on in which folder/package structure the classes are available you need to build up the right structure, putting classes in their matching META-INF/versions/${release}/ -folder Now the compiling part: My first approach is close to what everybody wants: no additional configuration in the pom (the minimal pom should be enough), use src/main/java<release>/ as predefined folder template. I did a POC, and it looks promising: the plugin would loop over the folders, extracted the release value and executed javac a couple of times, but the classes in the matching directory. Well, I was wrong: tests started to fail. I discovered that several parameters should only be used for a subset of a javac calls, or just exactly for one. Especially the includes/excludes caused trouble. I could try to find a configuration for includes/excludes per release value within the same execution, but I knew there were other properties needing similar features. And then I came to the conclusion the an "executionblock" should match exactly one javac call, it is already named like that! It does mean, that you must define multiple execution-blocks. And because execution blocks aren't context aware you need to configure them a little bit. Right now that is: <release>11</release> <multiReleaseOutput>true</multiReleaseOutput> <compileSourceRoots> <compileSourceRoot>${project.basedir}/src/main/java11</compileSourceRoot> </compileSourceRoots> Multirelease is quite a specific feature that is only useful for a specific kind of libraries, so needing extra configuration for a reliable result was acceptable for me. Testing is by far the hardest part and the most underestimated part: you can only test multirelease jar a a jar (so you cannot test it with surefire, you must use failsafe) and must test it separately with all targeted JDK release versions. Or you must make multiple test-jars, stripping of every release layer, but that means that you are actually not testing the deliverable. https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html shows a matrix with all kind of approaches. My preferred solution is the test it with a CI server with multiple JDKs and use profiles to decide which mulitirelease sources should be compiled, but it all depends on your way of work. github.com/codehaus-plexus/plexus-languages/blob/master/plexus-java/pom.xml#L105-L151 The way you want to test has effect on how you can compile and vice versa. I have my doubt there's a solution that covers it all. Should Maven be changed for this? Well, maybe. The key is that you need to add executions dynamically, and the first plugin that can inform Maven about that is the maven-compiler-plugin. I'm saying dynamically, because you don't want to have a static list like <compile> org.apache.maven.plugins:maven-compiler-plugin:3.1:compile@default-compile, org.apache.maven.plugins:maven-compiler-plugin:3.1:compile@default-compile_java11, org.apache.maven.plugins:maven-compiler-plugin:3.1:compile@default-compile_java14, org.apache.maven.plugins:maven-compiler-plugin:3.1:compile@default-compile_java15 </compile> It is possible to create MRJARs for several years, but it requires additional configuration. And I don't mind, because even though the specs are quite simple, developing them is hard, so it should not be too easy to make them. That said, I'm not sure if this is the topic I want to spend more valuable time and energy on. IMO You're only helping a very, very small group of people with something that already works in general Developers just need to configure the pom to the style they want to build, test and package the MRJAR. thanks, Robert [1] https://github.com/apache/maven/blob/master/maven-core/src/main/resources/META-INF/plexus/components.xml [2] https://github.com/apache/maven/blob/master/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml#L56-L98 On 24-4-2020 18:06:34, Christian Stein <sormu...@gmail.com> wrote: Robert (?) wrote this page [0] about supporting MR-JAR files. There're several approaches to the topic. It'd be nice, if the compiler- and the jar-plugin would pick one by default or based on a directory layout convention. [0]: https://maven.apache.org/plugins/maven-compiler-plugin/multirelease.html On Fri, Apr 24, 2020 at 5:26 PM Elliotte Rusty Harold wrote: > I've been thinking about multirelease jars. First step is source layout. > Here's a strawman modeled after the jar layout. > > We add a versions directory to the existing src directory. Inside the > versions directory one can have directories named 9, 10, 11, etc. for each > major Java version that has custom code. Each numbered directory is a full > src folder that contains main, test, etc. > > > Can anyone poke holes in this? Is there a reason why this wouldn't suffice? > > -- > Elliotte Rusty Harold > elh...@ibiblio.org >