Closed aalmiray closed 1 year ago
$ 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
Thanks for this @aalmiray. My only comment (above) is wanting to ensure that we don't break 1.8 compatibility.
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
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.
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.
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.
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.
Fingers crossed.
Thanks for this @aalmiray! Also, jarviz is a great little tool!
This was released in Failsafe 3.3.1.
Thank you for merging and releasing 😁
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
, and17
which is fine as long as thepackage
phase is not invoked.