Move Fedora JDKs to become single-built, portable, ordinary JDKs, while keeping comfortable, usual system integration
Motivation
To introduce properly working dynamically linked JDK to Fedora took several excellent engineers several years. Even after a decade, there are remaining unfixed issues. And new issues are appearing. All that is simply saying - JDK is designed to be portable, it is not possible to provide dynamic jdk behaving like usual dynamic jdk. Stop introducing features which are from "normal" portable JDK point of view bugs.
To be able to call some build of JDK, an binary have to pass severe certification. We are trying to keep all live JDKs in all fedoras - jdk8,jdk11, jdk17 and latest STS - jdk18 now (19 in half a year). We would like to keep this. Testing each of the four JDKs in 2-3 live Fedora versions is time consuming and leads to delayed releases. After this change is in air, we will certificate each binary only once, and redistribute.
Non goals
It is important to highlight that it is not a goal to change how current rpms works. All current rpms should remain in place. Only the way how the binary got to build, and how it got into rpms will change.
It is also not a goal, to pack third party blob. Jdk will still continue to build in koji as it should.
It is not goal to embed any security libraries. JDK is using several security providers, and all are currently loaded dynamically in runtime. Still there is remaining issue with cacerts: https://fedoraproject.org/wiki/MoveFedoraJDKsToBecomePortableJDKs#cacerts
Main Steps
- Move JDKs in RPMs to become portable details
- Introduce new portable rpms, which will provide just packed standalone tarball details
- Make the normal rpms to not built jdk, but to repack the portable rpms with all integration details
Dates
- first steps should be taken in f37
- the repack-able base pkg wil be introduced asynchronously
- whole repack should be finished in f38
- the changes will affect also older fedoras
Side effects
- affected packages: java-1.8.0-openjdk, java-11-openjdk, java-17-openjdk and java-latest-openjdk (with all subpkgs)
Dynamical JDK links all libraries from OS. Proper portable-like linked jdk is using in-tree (custom built) libraries (eg lcms2, jpeg, png, zip), eg image or font rendering might by slightly different. Bundled libraries will be properly treated:
- https://docs.fedoraproject.org/en-US/fesco/Bundled_Software_policy/
- https://fedoraproject.org/wiki/Bundled_Libraries
- https://docs.fedoraproject.org/en-US/packaging-guidelines/#bundling
Details
Move JDKs in RPMs to become portable
proposed for f37 as: https://fedoraproject.org/wiki/Changes/JdkInTreeLibsAndStdclibStatic
For f37 a new system wide change (which will actually backport to older fedoras once verified as completely ok. The patch which have to go to each JDK (8,11,17, latest) is as simple as:
https://src.fedoraproject.org/rpms/java-latest-openjdk/pull-request/98#request_diff
This patch will move to use intree libraries where possible and move stdc++ to static linking We have already tested such jdk deeply, and we know it is working fine in Fedora. Still unknown surprise may occure.
Tha patch currently lacks:
- embedded libraries spec file definitions
- tzdata handling
- cacerts hadling
Where embedded libraries will be handled in initial commit, the tzdata and cacerts may arrive later.
Introduce new portable rpms, which will provide just packed standalone tarball
This will introduce 4 new packages to jdk, as usual packages via pkg review.
- java-1.8.0-openjdk-portable
- java-11-openjdk-portable
- java-17-openjdk-portable
- java-latest-openjdk-portable
Each of them will build jdk and jre in all three release,slowdebug,fastdebug. Release with zipped debuginfo, others with embedded. The resulting images will contain only tarball, and wide usage of them alone is not expected None of them will have any virtual provides.
In ideal world, we will build this only for oldest live Fedora, but tag for each version up.
Make the normal rpms to not built jdk, but to repack the portable rpms with all integration
This is most important step, without which it can be most likely dropped. We will stop building OpenJDK binary in java-x-openjdk packages %build. Instead we will BuildRequires: java-x-openjdk-portable, and we will just repack its content into java-x-openjdk to achieve full system integration. Such jdk rpms shodl be identical of those after step1.
At the end, it is essential, that only portables from oldest live fedora are used. Otherwise it would somehow work, but would be moreover useless.
The repacking of same portable package in all Fedoras will again be system wide change, but with impact to all live fedoras once done.
Build each portables only once, in oldest live Fedora xor epel and repack everywhere
https://fedoraproject.org/wiki/Changes/BuildJdkOncePackEverywhere
Known issues
debuginfo
JDK is able to build with all necessary debuginfo and currently openjdk packages builds with proper debuginfo packages. In case of portable tarball, we can produce correct external or internal debuginfo, but we are currenly unable to reuse this for debuginfo packages.
As for future, we will most likely build slow and full debuginfo pkgs with embedded debuginfo. The release build may go out with ziped external debuginfo, or we wil find a way how to use that for creation of debuginfo rpms. If the reproducible builds will work in that time, we may use fourth build cycle to provide also release packages with embedded debuginfo, and then reuse this during repacking to create proper debuginfo
tzdata
Current JDKs in Fedora uses system TZDATA. This is actually cauisng buggy behavior - in some corenrcase - when tzdata in system are so much newer, jdk is not ready for them.
Portable JDK should use its intree-copy of tzdata. That will make it more "other-javas" aligned, but in paralle it will make it Fedora misaligned.
Possible workarounds:
- fully manual - in tree data will be used, and there will be switch to use system tzdata
- system tzdata will be used if found, and there will be switch to move to in-tree
- as portable rpms will be repacked by normal packages, normal packages cen set up some integration (eg via bashrc) to set expected default (but as system JDK is one of mostly installed pkg, it may be to intrusive)
It is possible, that non of those will be viable, and just in tree will be used
cacerts
Current JDKs in Fedora uses system cacerts. This is better the in-tree cacerts, as they are usually more fresh, and they do not cause issues as tzdata does. But sometime user experience is weird as jdk works differently on various OSes, where identical behavior is expected.
Portable JDK should use be able to use both in tree-copy of cacers and the System one. That will make it to take better form both worlds, but the correct implementation is not yet known, most likely, similar -D/system variable switch with sane default as in case of tzdata
Possible workarounds:
- fully manual - in tree cacerts will be used, and there will be switch to use system cacert
- system cacerts will be used if found, and there will be switch to move to in-tree
- as portable rpms will be repacked by normal packages, normal packages cen set up some integration (eg via bashrc) to set expected default (but as system JDK is one of mostly installed pkg, it may be to intrusive)
system crypto policy and FIPs
We are able to test and keep Fedora's crypto policies working. But unexpected surprise or delayed release may occur if the JDK's crypto engine get changed to much.
Similar to tzdata and cacerts, a dynamic mechanism whether to fedora specific crypto policies will have to be done
tapsets and desktop icons/files
Current rpms have desktop icons, desktop files and tapset files. Those are processed in %prep
and full path to future installed jdk is included in the file.
As it have sense to keep both tapsets, desktop icons and files in the portable tarball, the portable build will just provide tapsets and desktop icons/files as separate tarballs, which will be then processed by integration repack. Maybe something better will be figured out
Rawhide GCC
Every update of GCC is actually making troubles to JDK, but usually it is that GCC finds old hidden issue in java. Sometimes we found that GCC itself is buggy. By repacking portables from oldest live Fedora, we are delaying this feature by 2 years.
We may keep building portbales also in rawhide, but not to ship them. Or maybe we can be building them in all fedoras, but again not to ship them (ship only those from oldest live Fedora). Or maybe it just do not metter. TBH, IDK:)
Report bug URL
Current bug url is generated in build time.
- it is not possibel to cosntruct it in runtime
- possible workarounds
- generate partial url without os
- generate url pointing to "source of the truth" - the portables
- make native URL (and friends) logic to understand some environment variables
- patch hotspot to generate the url from system metadata
Rotting of JDK
This is highlight, that we will be rebuilding JDK at least four times per year, but most likely much more often. And if older Fedora dies, we will rebuild in newer asap. No rotting of JDK should ever happen.
Removed ECC
A side goal of this proposal, is to build binary identical JDK as Adoptium Temurin. We remvoe ECC which are illegal in Fedora from sources. Temurin does not