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");
        f.setAccessible(true);
    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 :

  
  ⟨build⟩
    ⟨plugins⟩
      ⟨plugin⟩
        ⟨artifactid⟩maven-antrun-plugin⟨/artifactid⟩
        ⟨executions⟩
          ⟨execution⟩
            ⟨id⟩bundle_java9⟨/id⟩
            ⟨goals⟩
              ⟨goal⟩run⟨/goal⟩
            ⟨/goals⟩
            ⟨phase⟩prepare-package⟨/phase⟩
            ⟨configuration⟩
              ⟨tasks⟩
                ⟨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"/⟩
              ⟨/tasks⟩
            ⟨/configuration⟩
          ⟨/execution⟩
        ⟨/executions⟩
      ⟨/plugin⟩
      ⟨plugin⟩
        ⟨artifactid⟩maven-jar-plugin⟨/artifactid⟩
        ⟨configuration⟩
          ⟨archive⟩
            ⟨manifestentries⟩
              ⟨multi-release⟩true⟨/multi-release⟩
            ⟨/manifestentries⟩
          ⟨/archive⟩
        ⟨/configuration⟩
      ⟨/plugin⟩
    ⟨/plugins⟩
  ⟨/build⟩


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




24 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 หนวดดำแห่งท้องทะเล อันดำมืดออกล่าเงินรางวัล แห่งท้องทะเลที่หลับใหลอยู่.

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

munnaza a dit…

You may produce more executable jars by adding extra execution> tags if you wish. The pom.xml file configurations listed above will create numerous executable jar files for the many primary classes contained in the spa massage center in karachi Java-based application.

Anonyme a dit…

Choosing an Assignment Helper can be a daunting task, especially with the abundance of online services available. However, taking the right steps can ensure that you find a reputable and reliable provider that will deliver quality work and help you achieve your academic goals. Here are some steps to take while choosing an assignment helper:


Do your research: Start by researching online and reading reviews and testimonials from previous clients. This will give you an idea of the quality of work and customer service provided by the service provider.


Check the credentials: Ensure that the service provider has a team of qualified and experienced experts with relevant academic backgrounds. This will guarantee that they have the necessary knowledge and skills to handle your assignments.


Look for plagiarism-free guarantee: Plagiarism can lead to severe academic consequences, so it's essential to choose a service provider that guarantees 100% original work.


Check the pricing: While price shouldn't be the only factor in your decision, it's essential to choose a provider that offers competitive rates without compromising quality.


Consider the turnaround time: Ensure that the service provider can deliver your assignment within the deadline, especially if you have a tight schedule.


Check the customer support: Choose a service provider that offers 24/7 customer support to ensure that you can reach out to them at any time for assistance or queries.


In conclusion, choosing an Assignment Helper requires careful consideration, research, and analysis. By following these steps, you can find a reputable and reliable service provider that will help you achieve your academic goals and enhance your learning experience.

johns a dit…

Your blogs are really good and interesting. It is very great and informative. 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:Bankruptcy lawyers in virginia, I got a lots of useful information in your blog. Keeps sharing more useful blogs..

srisri a dit…

Multi-Release JAR with Maven simplifies Java development by enabling seamless compatibility across multiple Java versions. Its streamlined integration into Maven projects facilitates efficient management of cross-version dependencies. This plugin ensures smoother deployment and runtime behavior, allowing developers to embrace the latest Java features while maintaining compatibility with older runtime environments. A must-have tool for modern Java projects seeking optimal performance and compatibility.
Accidente de Camionero Conductor
Accidentes de Camioneros Conductor

ทดลองpg รับฟรีเครดิต a dit…

เว็บไซต์พนัน บาคาร่า88 บนเว็บของพวกเรานั้นง่ายและก็สบาย เปิดบริการให้ท่านเล่นได้จากทุกหนทุกแห่งแล้วก็ทุกเมื่อแค่เพียง PG SLOT เชื่อมต่ออินเทอร์เน็ตเพื่อไปสู่เว็บ อีกทั้งพวกเรายังเสนอ

shane a dit…

New blog perso" translates to "New personal blog" in English. It typically refers to an individual's newly created online platform where they share personal thoughts, experiences, interests, or creative work. Personal blogs serve as a medium for self-expression, storytelling, and connecting with readers on a more personal level.
abogado inmobiliario
trucking accident lawyer near me

Robin a dit…

Awesome! Its genuinely remarkable post, I have got much clear idea regarding from this post. abogado transito arlington va