20 juin 2018

multi-release jar with Maven

Java 9 is here, and comes with some "surprises". So does Java 10, 11 ...

A recurrent problem I have as a library developer is I'd like to use some recent APIs but still need to support users on a not-so-recent JRE. Java 9 makes this even harder with the introduction of java modules, and a very common issue is getting such a warning at runtime :

WARNING: Illegal reflective access by com.foo.Bar to field org.Zot.qix

The issue here is that Java 9 doesn't just deprecate a method, it makes reflection model obsolete and warn you because this will be strictly unsupported in a future release. This has impacts on many popular frameworks : Spring, Hibernate, Guava ... (and Jenkins for sure). This is such a backward incompatible change we will need to live with, as more will come with future versions of Java platform.

There's a workaround for such issues, relying on a fresh new API introduced by Java 9 (VarHandles for this specific reflection problem) but does this mean your favourite framework will only support Java 9+ for new releases ?

So for sample, this code was used by Jenkins for a while :

public class ProcessUtil {
  public static long getPid(Process p) {
    try {  
        Field f = p.getClass().getDeclaredField("pid");
    return (long)f.get(p);
    } catch (ReflectiveOperationException e) {
        return -1; 

(ab)use of reflection to access Process pid attribute can be replaced in Java 9 with a fresh new API.

public class ProcessUtil {
  public static long getPid(Process p) {
    try {
 return p.getPid();
    } catch (UnsupportedOperationException e) {
        return -1; 

If we want Jenkins to run on Java 9 we need to replace ProcessUtil legacy implementation with this new code. But on the other side we still want Jenkins to run on Java 8.

Here comes JEP 238 "Multi Release Jar". The idea is to bundle in a Jar implementations of the exact same class targeting distinct Java releases. Anything before Java 9 will pick the plain old class file, but Java 9 will also look into META-INF/versions/9, Java 10 to look into META-INF/versions/10, and so on. So web can write the ProcessUtil class twice for Java 8 and Java 9, and get both included in the Jar, and used according to the platform which actually run the code.

Looks good, but now comes the funny part : how to write and bundle a class file twice in a Jar ?

Jetbrains' IDE Intellij Idea I'm using doesn't support setting distinct java level per source-folder, neither does Maven (see MCOMPILER-323), so I can't adopt a maven project structure like this one :

So I had to convert the library into a multi-module maven project, one of the sub-module being specific to re-implementing some classes for Java 9 :

And here comes a maven chicken-egg issue. The class we want to re-implement with Java 9 APIs do rely on some classes defined by the main library as type references. So core has to be built first by maven, then java9. But we still want to distribute a single Jar, with a single POM deployed to public repositories.

My current setup for this scenario is to let Maven think I'm building a multi-module Jar, then hack the build lifecycle to get Java 9 classes bundled into the "core" Jar. For this purpose, I had to rely on some ant-task in my pom.xml :

                ⟨mkdir dir="${project.build.outputDirectory}/META-INF/versions/9"/⟩
                ⟨javac classpath="${project.build.outputDirectory}" destdir="${project.build.outputDirectory}/META-INF/versions/9" includeantruntime="false" source="9" srcdir="../java9/src/main/java" target="9"/⟩

This hack do run java 9 compilation on sibling "java9" source directory from within the core maven module. As a result I can deploy artifacts from this single module without polluting my pom.xml with unnecessary sub-modules dependencies.

java9 module is configured as a java 9 jar module so my IDE will detect it accordingly, and depends on core module, so I can access all types to re-implement the class I want to replace.

Yes, this is a hack, but as it took me some time to get this running I thought it could be useful to others. You can see this in action on a tiny-library I created to offer a java 9 compliant way to access private fields by reflexion, on all versions of Java : https://github.com/ndeloof/fields

19 commentaires:

harry a dit…

My brother studies programming language and all these java related codes which I have never understood. I’m a sociology student who finds difficulty even in the simplest of projects and he makes fun of me especially about the fact that I take essay help from online sites like https://www.usessaywriter.com/essay-writing-service-in-chicago/ and can’t do it on my own.

Phuwadon a dit…

Video Slot อัพเดทใหม่ล่าสุดจากทาง JOKER GAMING ได้เปิดโอกาสให้ทุกท่านได้เข้าทำเงินกับเกมสล็อตอัพเดทใหม่ล่าสุด Blackbeard Legacy หนวดดำแห่งท้องทะเล อันดำมืดออกล่าเงินรางวัล แห่งท้องทะเลที่หลับใหลอยู่.

Nameeman555 a dit…

Thanks for fantastic information I was looking for this information for my mission.
play game for relax and win get money

JAke Leonel a dit…

This is cute, I'm sure kids will love this! Thanks for sharing.Way cool!
electric masturbator cup
water based lubricant

Henryjones a dit…

That's fantastic! I discovered to write my dissertation cheap about a month ago and have already used the service for three assignments. The reaction to each paper has been fantastic. I strongly suggest editing services to anyone in need!

Marry New a dit…

What a beautiful post, I've never seen a post that helpful before. I appreciate you telling me about the multi-release jar and I also appreciate your knowledge and would like to pass it along to a friend because it is very helpful. While looking for the greatest financial accounting homework help to do my accounting assignment, I came across your website today. Please continue your fantastic work on your website.

EvelynAdam a dit…

A multi-release jar is a jar file that contains code that is compatible with multiple versions of Java. This allows code to be written once and run on multiple versions of Java without needing to be recompiled. Maven is a build Denmark vs Tunisia Live Stream and enjoy the matches.

David01 a dit…

java 9 is difficult language for programming i known very well but don't take it serious about your health. Because it very effect to your 360 lipo abdominoplasty tummy tuck so kindly care fully doing your job feel free to go the doctor Cornerstone clinic.

issabella a dit…

A interested in programming languages and java-related codes, which I have never understood. I'm a Swansea university student who struggles with even the simplest assignments, and he makes fun of me, especially when I need essay assistance from web services like https://writemyassignmentforme.uk/swansea-university-assignment-help.php and can't accomplish it on my own.

David01 a dit…

A multi-release jar is a jar file containing code that is compatible with different Java versions. This enables code to be written once and execute on multiple Java versions without having to be recompiled. https://cornerstoneclinic.ae/veneers-dubai/

anajame a dit…

Maven is a great tool for managing multi-release jar files. It makes it easy to create and maintain different versions of the same jar file, which is particularly useful when there are multiple projects that depend on the same jar. By using Maven, you can easily package and deploy multiple versions of the same jar, so you don't have to worry about any compatibility issues. Plus, it's much cheap assignment writing services.

Lucy Carvin a dit…

I recently read about multi-release jar with Maven and it seems like a great way to help manage the different versions of a project. It's a great way to make sure you don't have to manually update multiple versions of an application. If you're pay someone to do my assignment UK, I would definitely recommend looking into this option. It can help save you time and money in the long run.

เกม สล็อต pg a dit…

PG SLOT จะมาแนะนำวิธีการ เลือกเล่นเกมสล็อตออนไลน์ อยากได้เงิน ว่าควรเลือกเล่นเกมแบบไหนถึงจะสามารถทำกำไรจากการเล่นสล็อต pgslot ได้อย่างเป็นกอบเป็นกำบางคนอาจเล่นเกมเพื่อการรีวิวเกม

ayesha a dit…

Thank you for providing a blog on the multi-jar feature. Can you please do this on eclipse and provide the link in this best masssage center in karachi
remark since I'm having trouble using Eclipse?

Harryjames a dit…

Multi-release jars are an incredibly useful tool for optimizing Java code for different Java versions. They allow developers to create a single jar file that targets different Java versions, making it easier to maintain compatibility across multiple platforms the best blogs & articles.

Scilife Pharma Pvt (Limited) a dit…

Scilife Pharma is a dynamic and progressive Branded-Generic and healthcare solution company. We are a leading player in the Pakistan Pharmaceutical industry for over 23 years with presence in over 50 countries around the world.

Wilson a dit…

Thanks for this useful information. I truly appreciated your efforts that you have done in this article.
average cost of uncontested divorce in virginia
cost of uncontested divorce in virginia

Jasper a dit…

Thanks for sharing interesting article keep share more like that, Abogado De Trafico En Virginia

Craftsmenmedia a dit…

We are a team of Designer and Digital in Marketing agency. We work with businesses who want to connect with their customers in a meaningful way through design, digital and marketing services. Our goal is to make sure your business grows by helping you understand the needs of your clients, then creating experiences that connect them with your brand.