Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure explicit Java module descriptors #359

Merged
merged 1 commit into from Mar 20, 2023

Conversation

aalmiray
Copy link
Contributor

@aalmiray aalmiray commented Mar 1, 2023

Use the ModiTect plugin to add module descriptors while retaining Java 8 compatibility.

Fix for #358

NOTE: The release must be run with Java9+ or else it will fail to generate module descriptors. The CI workflow runs tests with 8, 11, and 17 which is fine as long as the package phase is not invoked.

Use the ModiTect plugin to add module descriptors while
retaining Java 8 compatibility.
@aalmiray
Copy link
Contributor Author

aalmiray commented Mar 1, 2023

$ jarviz bytecode show --file core/target/failsafe-3.3.1-SNAPSHOT.jar 
subject: failsafe-3.3.1-SNAPSHOT.jar
Unversioned classes. Bytecode version: 52 (Java 8) total: 114
Versioned classes 9. Bytecode version: 53 (Java 9) total: 1

$ jarviz module descriptor --file core/target/failsafe-3.3.1-SNAPSHOT.jar 
subject: failsafe-3.3.1-SNAPSHOT.jar
name: dev.failsafe.core
version: 3.3.1-SNAPSHOT
open: false
automatic: false
exports:
  dev.failsafe
  dev.failsafe.event
  dev.failsafe.function
  dev.failsafe.internal
  dev.failsafe.internal.util
  dev.failsafe.spi
requires:
  java.base mandated

$ jarviz module descriptor --file modules/okhttp/target/failsafe-okhttp-3.3.1-SNAPSHOT.jar 
subject: failsafe-okhttp-3.3.1-SNAPSHOT.jar
name: dev.failsafe.okhttp
version: 3.3.1-SNAPSHOT
open: false
automatic: false
exports:
  dev.failsafe.okhttp
requires:
  dev.failsafe.core
  java.base mandated
  okhttp3

$ jarviz module descriptor --file modules/retrofit/target/failsafe-retrofit-3.3.1-SNAPSHOT.jar 
subject: failsafe-retrofit-3.3.1-SNAPSHOT.jar
name: dev.failsafe.retrofit
version: 3.3.1-SNAPSHOT
open: false
automatic: false
exports:
  dev.failsafe.retrofit
requires:
  dev.failsafe.core
  java.base mandated
  retrofit2

<goal>add-module-info</goal>
</goals>
<configuration>
<jvmVersion>9</jvmVersion>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you confirm how this and the --multi-release=9 line below interacts with the 1.8 compiler target? I just want to be sure we don't break 1.8 compatibility.

@jhalterman
Copy link
Member

Thanks for this @aalmiray. My only comment (above) is wanting to ensure that we don't break 1.8 compatibility.

@aalmiray
Copy link
Contributor Author

Understood. This is how classes would look like once packaged:

$ jarviz bytecode show --file core/target/failsafe-3.3.1-SNAPSHOT.jar 
subject: failsafe-3.3.1-SNAPSHOT.jar
Unversioned classes. Bytecode version: 52 (Java 8) total: 114
Versioned classes 9. Bytecode version: 53 (Java 9) total: 1

The build was run with Java 11. The single class with bytecode 53 is module-info.class which is placed in the versioned space:

$ unzip -l core/target/failsafe-3.3.1-SNAPSHOT.jar 
Archive:  core/target/failsafe-3.3.1-SNAPSHOT.jar
  Length      Date    Time    Name
---------  ---------- -----   ----
     1359  03-16-2023 08:07   META-INF/MANIFEST.MF
        0  03-16-2023 08:07   META-INF/
        0  03-16-2023 08:07   dev/
        0  03-16-2023 08:07   dev/failsafe/
        0  03-16-2023 08:07   dev/failsafe/internal/
        0  03-16-2023 08:07   dev/failsafe/internal/util/
        0  03-16-2023 08:07   dev/failsafe/function/
        0  03-16-2023 08:07   dev/failsafe/spi/
        0  03-16-2023 08:07   dev/failsafe/event/
        0  03-16-2023 08:07   META-INF/maven/
        0  03-16-2023 08:07   META-INF/maven/dev.failsafe/
        0  03-16-2023 08:07   META-INF/maven/dev.failsafe/failsafe/
     1511  03-16-2023 08:07   dev/failsafe/RateLimiterConfig.class
...
     1845  03-16-2023 08:07   dev/failsafe/Failsafe.class
     1371  03-16-2023 08:07   dev/failsafe/FailurePolicyConfig.class
        0  03-16-2023 08:07   META-INF/versions/
        0  03-16-2023 08:07   META-INF/versions/9/
      319  03-16-2023 08:07   META-INF/versions/9/module-info.class

@Tembrel
Copy link
Contributor

Tembrel commented Mar 16, 2023

Understood. This is how classes would look like once packaged:

I have had multi-release packaging of other dependencies break my Java 8 builds (of my system that uses Failsafe), not because the multi-release jar was incompatible with Java 8, but because the published pom.xml didn't work well with Apache Ivy.

I have been able to work around this using special Ivy configurations, and would probably be able to figure out how to do the same in this case, but it almsot certainly will be a hit. I want proponents of Java modules to recognize that keeping compatibility is a lot harder than it appears at first blush.

@aalmiray
Copy link
Contributor Author

Do you happen to know why the pom.xml was not compatible with Ivy? In the case of this PR the change is found inside the <build> section which has no bearing on how dependencies are resolved from a consumer's point of view.

@Tembrel
Copy link
Contributor

Tembrel commented Mar 16, 2023

I don't know enough about Maven pom files to give an authoritative answer, but here's the line I had to change in my ivy.xml file (for the StreamEx library):

    <dependency org="one.util" name="streamex" rev="0.8.1"/>

This stopped working until I changed it to:

    <dependency org="one.util" name="streamex" rev="0.8.1">
      <!-- Distributed as multi-release-jar; ask for jar explicitly -->
      <artifact name="streamex" type="jar" />
    </dependency>

You could reasonably say that it's not such a big deal, but it took me a long time to figure this out, and until I did, I was shut out of updating to the latest release of StreamEx.

I am reasonably confident that a similar transformation would work if Failsafe goes this route, but I don't know for sure. There are probably others who, for various reasons, are stuck on Java 8 and who don't directly use Maven but depend on its ecosystem.

@aalmiray
Copy link
Contributor Author

It looks like streamex-0.8.0 explicitly changed its packaging go "multirelease-jar" https://central.sonatype.com/artifact/one.util/streamex/0.8.0
Version 0.8.1 went back to default "jar" packaging.

This was a conscious decision of the author to modify the companion metadata (pom.xml) and has nothing to do with the actual JAR contents.

ModiTect does not alter in any way the chosen packaging, rest assured the fix you had to put in place for streamex was explicit for that version alone.

@Tembrel
Copy link
Contributor

Tembrel commented Mar 16, 2023

Fingers crossed.

@jhalterman jhalterman merged commit 907c4b1 into failsafe-lib:master Mar 20, 2023
6 checks passed
@jhalterman
Copy link
Member

Thanks for this @aalmiray! Also, jarviz is a great little tool!

@jhalterman
Copy link
Member

This was released in Failsafe 3.3.1.

@aalmiray aalmiray deleted the java-modules branch March 20, 2023 21:52
@aalmiray
Copy link
Contributor Author

Thank you for merging and releasing 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants