Compare commits

...

7 Commits

Author SHA1 Message Date
eabdullin
45671bd301 Portable build 2026-07-23 07:43:48 +00:00
eabdullin
466d55c435 Portable build 2026-04-22 21:38:45 +00:00
eabdullin
ef44154d4a Portable build 2026-04-16 08:54:48 +00:00
eabdullin
0c5840784e Portable build 2026-03-30 09:48:30 +00:00
eabdullin
ebd11d7edf Portable build 2026-01-28 07:38:57 +00:00
b91e4dee39 import UBI java-25-openjdk-25.0.2.0.10-1.el9 2026-01-28 07:01:20 +00:00
be73aaae60 Import from CS git 2025-12-23 08:10:37 +00:00
47 changed files with 3546 additions and 4920 deletions

49
.gitignore vendored
View File

@ -1,46 +1,3 @@
/openjdk-jdk17u-jdk-17.0.7+7.tar.xz SOURCES/nssadapter-0.1.1.tar.xz
/tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz SOURCES/openjdk-25.0.4+7.tar.xz
/openjdk-jdk18u-jdk-18.0.1+0.tar.xz SOURCES/tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz
/openjdk-jdk18u-jdk-18.0.1+10.tar.xz
/openjdk-jdk18u-jdk-18.0.1.1+2.tar.xz
/openjdk-jdk18u-jdk-18.0.2+9.tar.xz
/openjdk-jdk19u-jdk-19+36.tar.xz
/openjdk-jdk19u-jdk-19.0.1+10.tar.xz
/openjdk-jdk19u-jdk-19.0.2+7.tar.xz
/openjdk-jdk20u-jdk-20+36.tar.xz
/openjdk-jdk20u-jdk-20.0.1+9.tar.xz
/openjdk-jdk20u-jdk-20.0.2+9.tar.xz
/openjdk-jdk21u-jdk-21+35.tar.xz
/openjdk-21.0.1+12.tar.xz
/openjdk-21.0.2+11.tar.xz
/openjdk-21.0.2+12.tar.xz
/openjdk-21.0.2+13.tar.xz
/openjdk-21.0.3+1-ea.tar.xz
/openjdk-21.0.3+7-ea.tar.xz
/openjdk-21.0.3+9.tar.xz
/openjdk-21.0.4+1-ea.tar.xz
/openjdk-21.0.4+5-ea.tar.xz
/openjdk-21.0.4+7.tar.xz
/openjdk-21.0.5+1-ea.tar.xz
/openjdk-21.0.5+5-ea.tar.xz
/openjdk-21.0.5+9-ea.tar.xz
/openjdk-21.0.5+10.tar.xz
/openjdk-21.0.5+11.tar.xz
/openjdk-21.0.6+6-ea.tar.xz
/openjdk-21.0.6+7.tar.xz
/openjdk-21.0.7+1-ea.tar.xz
/openjdk-21.0.7+2-ea.tar.xz
/openjdk-21.0.7+3-ea.tar.xz
/openjdk-21.0.7+4-ea.tar.xz
/openjdk-21.0.7+5-ea.tar.xz
/openjdk-21.0.7+6.tar.xz
/openjdk-21.0.8+1-ea.tar.xz
/openjdk-21.0.8+2-ea.tar.xz
/openjdk-21.0.8+8-ea.tar.xz
/openjdk-21.0.8+9.tar.xz
/openjdk-22.0.2+9.tar.xz
/openjdk-23.0.2+7.tar.xz
/openjdk-24.0.2+12.tar.xz
/openjdk-25+36.tar.xz
/openjdk-25.0.1+8.tar.xz
/nssadapter-0.1.0.tar.xz

View File

@ -0,0 +1,3 @@
c37273ae74270c39736b04acd9a1935990d29fe1 SOURCES/nssadapter-0.1.1.tar.xz
9132e9960758327b96ed34e863e2766effe4af9f SOURCES/openjdk-25.0.4+7.tar.xz
c8281ee37b77d535c9c1af86609a531958ff7b34 SOURCES/tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz

670
NEWS
View File

@ -1,670 +0,0 @@
Key:
JDK-X - https://bugs.openjdk.java.net/browse/JDK-X
CVE-XXXX-YYYY: https://cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY
New in release OpenJDK 25.0.1 (2025-10-21):
===========================================
* CVEs
- CVE-2025-53057
- CVE-2025-53066
- CVE-2025-61748
* Changes
- JDK-8315131: Clarify VarHandle set/get access on 32-bit platforms
- JDK-8352637: Enhance bytecode verification
- JDK-8356294: Enhance Path Factories
- JDK-8356587: Missing object ID X in pool jdk.types.Method
- JDK-8357826: Avoid running some jtreg tests when asan is configured
- JDK-8358452: JNI exception pending in Java_sun_awt_screencast_ScreencastHelper_remoteDesktopKeyImpl of screencast_pipewire.c:1214 (ID: 51119)
- JDK-8358577: Test serviceability/jvmti/thread/GetCurrentContendedMonitor/contmon01/contmon01.java failed: unexpexcted monitor object
- JDK-8358819: The first year is not displayed correctly in Japanese Calendar
- JDK-8359059: Bump version numbers for 25.0.1
- JDK-8359218: RISC-V: Only enable CRC32 intrinsic when AvoidUnalignedAccess == false
- JDK-8359270: C2: alignment check should consider base offset when emitting arraycopy runtime call
- JDK-8359454: Enhance String handling
- JDK-8359596: Behavior change when both -Xlint:options and -Xlint:-options flags are given
- JDK-8360179: RISC-V: Only enable BigInteger intrinsics when AvoidUnalignedAccess == false
- JDK-8360533: ContainerRuntimeVersionTestUtils fromVersionString fails with some docker versions
- JDK-8360647: [XWayland] [OL10] NumPad keys are not triggered
- JDK-8360679: Shenandoah: AOT saved adapter calls into broken GC barrier stub
- JDK-8360937: Enhance certificate handling
- JDK-8361212: Remove AffirmTrust root CAs
- JDK-8361532: RISC-V: Several vector tests fail after JDK-8354383
- JDK-8361829: [TESTBUG] RISC-V: compiler/vectorization/runner/BasicIntOpTest.java fails with RVV but not Zvbb
- JDK-8362109: Change milestone to fcs for all releases
- JDK-8362882: Update SubmissionPublisher() specification to reflect use of ForkJoinPool.asyncCommonPool()
- JDK-8366223: ZGC: ZPageAllocator::cleanup_failed_commit_multi_partition is broken
- JDK-8367031: [backout] Change java.time month/day field types to 'byte'
- JDK-8368308: ISO 4217 Amendment 180 Update
Notes on individual issues:
===========================
core-libs/java.io:serialization:
JDK-8367031: [backout] Change java.time month/day field types to 'byte'
=======================================================================
In the initial release of OpenJDK 25, attempting to read serialised
Class objects created by earlier versions of OpenJDK for several of
the `java.time` classes would fail with a
`InvalidClassException`. Similarly, `java.time` Class objects
serialised with OpenJDK 25 could not be read by older OpenJDK
versions. This was due to the type of the day and month fields in
these classes being changed to `byte`. This change has now been
reverted and compatibility between OpenJDK 25 and older versions
restored.
Note that this incompatibility occurred with the `Class` object and
not an instance of the object i.e. `writeObject(LocalDate.class)`
would produce incompatible serialised data, but
`writeObject(LocalDate.now())` would not.
security-libs/java.security:
JDK-8361212: Remove AffirmTrust root CAs
========================================
The following root certificates from AffirmTrust, which were
deactivated in the 21.0.5 release of October 2024, have been removed
from the `cacerts` keystore:
Alias name: affirmtrustcommercialca [jdk]
CN=AffirmTrust Commercial
O=AffirmTrust
C=US
SHA256: 03:76:AB:1D:54:C5:F9:80:3C:E4:B2:E2:01:A0:EE:7E:EF:7B:57:B6:36:E8:A9:3C:9B:8D:48:60:C9:6F:5F:A7
Alias name: affirmtrustnetworkingca [jdk]
CN=AffirmTrust Networking
O=AffirmTrust
C=US
SHA256: 0A:81:EC:5A:92:97:77:F1:45:90:4A:F3:8D:5D:50:9F:66:B5:E2:C5:8F:CD:B5:31:05:8B:0E:17:F3:F0B4:1B
Alias name: affirmtrustpremiumca [jdk]
CN=AffirmTrust Premium
O=AffirmTrust
C=US
SHA256: 70:A7:3F:7F:37:6B:60:07:42:48:90:45:34:B1:14:82:D5:BF:0E:69:8E:CC:49:8D:F5:25:77:EB:F2:E9:3B:9A
Alias name: affirmtrustpremiumeccca [jdk]
CN=AffirmTrust Premium ECC
O=AffirmTrust
C=US
SHA256: BD:71:FD:F6:DA:97:E4:CF:62:D1:64:7A:DD:25:81:B0:7D:79:AD:F8:39:7E:B4:EC:BA:9C:5E:84:88:82:14:23
New in release OpenJDK 25.0.0 (2025-09-16):
===========================================
Major changes are listed below. Some changes may have been backported
to earlier releases following their first appearance in OpenJDK 22
through to 25.
NEW FEATURES
============
Language Features
=================
Flexible Constructor Bodies
============================
https://openjdk.org/jeps/447
https://openjdk.org/jeps/482
https://openjdk.org/jeps/492
https://openjdk.org/jeps/513
In constructors in the Java programming language, allow statements to
appear before an explicit constructor invocation, i.e., super(..) or
this(..). The statements cannot reference the instance under
construction, but they can initialize its fields. Initializing fields
before invoking another constructor makes a class more reliable when
methods are overridden.
This language feature is now finalised (JEP 513). It was first
introduced as a preview language feature
(http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP 447) under the
name "Statements before super(...)". It reached a second preview in
OpenJDK 23 (JEP 482) with the addition of allowing fields to be
initialized before invoking another constructor. It reached a third
preview in OpenJDK 24 (JEP 492).
Unnamed Patterns and Variables
==============================
https://openjdk.org/jeps/443
https://openjdk.org/jeps/456
Enhance the Java language with unnamed patterns, which match a record
component without stating the component's name or type, and unnamed
variables, which can be initialized but not used. Both are denoted by
an underscore character, _.
This feature is now finalised (JEP 456). It was a preview feature
(http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP 443).
Primitive Types in Patterns, instanceof, and switch
===================================================
https://openjdk.org/jeps/455
https://openjdk.org/jeps/488
https://openjdk.org/jeps/507
Enhance pattern matching by allowing primitive type patterns in all
pattern contexts, and extend instanceof and switch to work with all
primitive types.
This is a preview language feature (http://openjdk.java.net/jeps/12)
introduced in OpenJDK 23 (JEP 455) with a second preview in OpenJDK 24
(JEP 488) and reaching a third in OpenJDK 25 (JEP 507).
Module Import Declarations
==========================
https://openjdk.org/jeps/476
https://openjdk.org/jeps/494
https://openjdk.org/jeps/511
Enhance the Java programming language with the ability to succinctly
import all of the packages exported by a module. This simplifies the
reuse of modular libraries, but does not require the importing code to
be in a module itself.
This language feature is now finalised (JEP 511). It was introduced as
a preview language feature (http://openjdk.java.net/jeps/12) in
OpenJDK 23 (JEP 476) and had a second preview in OpenJDK 24 (JEP 494).
Library Features
================
Foreign Function & Memory API
=============================
https://openjdk.org/jeps/412
https://openjdk.org/jeps/419
https://openjdk.org/jeps/424
https://openjdk.org/jeps/434
https://openjdk.org/jeps/442
https://openjdk.org/jeps/454
Introduce an API by which Java programs can interoperate with code and
data outside of the Java runtime. By efficiently invoking foreign
functions (i.e., code outside the JVM), and by safely accessing
foreign memory (i.e., memory not managed by the JVM), the API enables
Java programs to call native libraries and process native data without
the brittleness and danger of JNI.
This API is now finalised (JEP 454). It was first introduced in
incubation (https://openjdk.java.net/jeps/11) in OpenJDK 17 (JEP 412),
and is an evolution of the Foreign Memory Access API (OpenJDK 14
through 16) and Foreign Linker API (OpenJDK 16) (see release notes for
java-17-openjdk). OpenJDK 18 saw a second round of incubation (JEP
419) before its inclusion as a preview feature
(http://openjdk.java.net/jeps/12) in OpenJDK 19 (JEP 424). A second
preview took place in OpenJDK 20 (JEP 434) and a third and final
preview in OpenJDK 21 (JEP 442).
Prepare to Restrict the Use of JNI
==================================
https://openjdk.org/jeps/472
Issue warnings about uses of the Java Native Interface (JNI) and
adjust the Foreign Function & Memory (FFM) API to issue warnings in a
consistent manner. All such warnings aim to prepare developers for a
future release that ensures integrity by default by uniformly
restricting JNI and the FFM API. Application developers can avoid both
current warnings and future restrictions by selectively enabling these
interfaces where essential using the --enable-native-access
command-line option.
Class-File API
==============
https://openjdk.org/jeps/457
https://openjdk.org/jeps/466
https://openjdk.org/jeps/484
Provide a standard API for parsing, generating, and transforming Java
class files.
This API is now finalised (JEP 484). It was introduced as a preview
library feature (http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP
457) with a second preview in OpenJDK 23 (JEP 466).
Vector API
==========
https://openjdk.org/jeps/338
https://openjdk.org/jeps/414
https://openjdk.org/jeps/417
https://openjdk.org/jeps/426
https://openjdk.org/jeps/438
https://openjdk.org/jeps/448
https://openjdk.org/jeps/460
https://openjdk.org/jeps/469
https://openjdk.org/jeps/489
https://openjdk.org/jeps/508
Introduce an API to express vector computations that reliably compile
at runtime to optimal vector hardware instructions on supported CPU
architectures and thus achieve superior performance to equivalent
scalar computations.
This is an incubation feature (https://openjdk.java.net/jeps/11)
introduced in OpenJDK 16 (JEP 338). A second round of incubation took
place in OpenJDK 17 (JEP 414), OpenJDK 18 (JEP 417) saw a third,
OpenJDK 19 a fourth (JEP 426), OpenJDK 20 (JEP 438) a fifth, OpenJDK
21 a sixth (JEP 448), OpenJDK 22 a seventh (JEP 460), OpenJDK 23 an
eighth (JEP 469), OpenJDK 24 a ninth (JEP 489) and it reaches its
tenth in OpenJDK 25 (JEP 508).
Stream Gatherers
================
https://openjdk.org/jeps/461
https://openjdk.org/jeps/473
https://openjdk.org/jeps/485
Enhance the Stream API to support custom intermediate operations. This
will allow stream pipelines to transform data in ways that are not
easily achievable with the existing built-in intermediate operations.
This API is now finalised (JEP 485). It was introduced as a preview
library feature (http://openjdk.java.net/jeps/12) in OpenJDK 22 (JEP
461) with a second preview in OpenJDK 23 (JEP 473).
Structured Concurrency
======================
https://openjdk.org/jeps/428
https://openjdk.org/jeps/437
https://openjdk.org/jeps/453
https://openjdk.org/jeps/462
https://openjdk.org/jeps/480
https://openjdk.org/jeps/499
https://openjdk.org/jeps/505
Simplify multithreaded programming by introducing an API for
structured concurrency. Structured concurrency treats multiple tasks
running in different threads as a single unit of work, thereby
streamlining error handling and cancellation, improving reliability,
and enhancing observability.
This API was first introduced in incubation
(https://openjdk.java.net/jeps/11) in OpenJDK 19 (JEP 428) and had a
second round of incubation in OpenJDK 20 (JEP 437). It became a
preview feature (http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP
453), reached its second preview in OpenJDK 22 (JEP 462), had a third
preview in OpenJDK 23 (JEP 480), a fourth in OpenJDK 24 (JEP 499) and
reaches its fifth in OpenJDK 25 (JEP 505).
Compact Source Files and Instance Main Methods
==============================================
https://openjdk.org/jeps/445
https://openjdk.org/jeps/463
https://openjdk.org/jeps/477
https://openjdk.org/jeps/495
https://openjdk.org/jeps/512
Evolve the Java programming language so that beginners can write their
first programs without needing to understand language features
designed for large programs. Far from using a separate dialect of the
language, beginners can write streamlined declarations for
single-class programs and then seamlessly expand their programs to use
more advanced features as their skills grow. Experienced developers
can likewise enjoy writing small programs succinctly, without the need
for constructs intended for programming in the large.
This library feature is now finalised (JEP 512) with some minor
changes from the last release. It was first introduced as a preview
(http://openjdk.java.net/jeps/12) in OpenJDK 21 (JEP 445) under the
name "Unnamed Classes and Instance Main Methods". It reached a second
preview in OpenJDK 22 (JEP 463) and a third in OpenJDK 23 (JEP 477)
under the new name, "Implicitly Declared Classes and Instance Main
Methods", due to the move away from unnamed classes to an implicitly
declared name chosen by the host system. It had a fourth preview in
OpenJDK 24 (JEP 495) with new terminology and a revised title ("Simple
Source Files and Instance Main Methods"), but otherwise unchanged.
Scoped Values
=============
https://openjdk.org/jeps/429
https://openjdk.org/jeps/446
https://openjdk.org/jeps/464
https://openjdk.org/jeps/481
https://openjdk.org/jeps/487
https://openjdk.org/jeps/506
Introduce scoped values, which enable the sharing of immutable data
within and across threads. They are preferred to thread-local
variables, especially when using large numbers of virtual threads.
This API is now finalised (JEP 506). This API was first introduced in
incubation (https://openjdk.java.net/jeps/11) in OpenJDK 20 (JEP
429). It became a preview feature (http://openjdk.java.net/jeps/12) in
OpenJDK 21 (JEP 446), had a second preview in OpenJDK 22 (JEP 464), a
third in OpenJDK 23 (JEP 481) and a fourth in OpenJDK 24 (JEP 487).
Key Derivation Function API
===========================
https://openjdk.org/jeps/478
https://openjdk.org/jeps/510
Introduce an API for Key Derivation Functions (KDFs), which are
cryptographic algorithms for deriving additional keys from a secret
key and other data.
This API is now finalised (JEP 510). It was first introduced as a
preview library feature (http://openjdk.java.net/jeps/12) in OpenJDK
24 (JEP 478).
Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
==================================================================
https://openjdk.org/jeps/496
Enhance the security of Java applications by providing an
implementation of the quantum-resistant Module-Lattice-Based
Key-Encapsulation Mechanism (ML-KEM). Key encapsulation mechanisms
(KEMs) are used to secure symmetric keys over insecure communication
channels using public key cryptography. ML-KEM is designed to be
secure against future quantum computing attacks. It has been
standardized by the United States National Institute of Standards and
Technology (NIST) in FIPS 203 [0].
[0] https://csrc.nist.gov/pubs/fips/203/final
Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
==================================================================
https://openjdk.org/jeps/497
Enhance the security of Java applications by providing an
implementation of the quantum-resistant Module-Lattice-Based Digital
Signature Algorithm (ML-DSA). Digital signatures are used to detect
unauthorized modifications to data and to authenticate the identity of
signatories. ML-DSA is designed to be secure against future quantum
computing attacks. It has been standardized by the United States
National Institute of Standards and Technology (NIST) in FIPS 204 [0].
[0] https://csrc.nist.gov/pubs/fips/204/final
PEM Encodings of Cryptographic Objects
======================================
https://openjdk.org/jeps/470
Introduce an API for encoding objects that represent cryptographic
keys, certificates, and certificate revocation lists into the
widely-used Privacy-Enhanced Mail (PEM) transport format, and for
decoding from that format back into objects.
This is a preview library feature (http://openjdk.java.net/jeps/12)
introduced in OpenJDK 25 (JEP 470).
Stable Values
=============
https://openjdk.org/jeps/502
Introduce an API for stable values, which are objects that hold
immutable data. Stable values are treated as constants by the JVM,
enabling the same performance optimizations that are enabled by
declaring a field final. Compared to final fields, however, stable
values offer greater flexibility as to the timing of their
initialization.
This is a preview library feature (http://openjdk.java.net/jeps/12)
introduced in OpenJDK 25 (JEP 502).
Virtual Machine Enhancements
============================
Region Pinning for G1
=====================
https://openjdk.org/jeps/423
Reduce latency by implementing region pinning in G1, so that garbage
collection need not be disabled during Java Native Interface (JNI)
critical regions.
ZGC: Generational Mode by Default
=================================
https://openjdk.org/jeps/439
https://openjdk.org/jeps/474
Switch the default mode of the Z Garbage Collector (ZGC) to the
generational mode. Deprecate the non-generational mode, with the
intent to remove it in a future release.
Late Barrier Expansion for G1
=============================
https://openjdk.org/jeps/475
Simplify the implementation of the G1 garbage collector's barriers,
which record information about application memory accesses, by
shifting their expansion from early in the C2 JIT's compilation
pipeline to later.
Ahead-of-Time Class Loading & Linking
=====================================
https://openjdk.org/jeps/483
https://openjdk.org/jeps/514
Improve startup time by making the classes of an application instantly
available, in a loaded and linked state, when the HotSpot Java Virtual
Machine starts. Achieve this by monitoring the application during one
run and storing the loaded and linked forms of all classes in a cache
for use in subsequent runs. Lay a foundation for future improvements
to both startup and warmup time.
Using this feature requires a two stage process:
1. Create the Ahead-of-Time cache from a training run of the
application using the option `--XX:AOTCacheOutput=<cache name>` where
`<cache name>` is the cache reference to use in later runs.
2. When running the application in testing or production, use the
option `-XX:AOTCache=<cache name>` to run the application with the
cache generated in #2.
Previously, in OpenJDK 24 (JEP 483), the training run and cache
creation were handled by two separate steps:
1. Populate the Ahead-of-Time configuration data with a training run
of the application using the options `-XX:AOTMode=record
-XX:AOTConfiguration=<config name>` where `<config name>` is the
configuration reference to use in #2.
2. Create the Ahead-of-Time cache using the options
`-XX:AOTMode=create -XX:AOTConfiguration=<config name>
-XX:AOTCache=<cache name>` where `<config name>` is the configuration
reference from #1 and `<cache name>` is the cache reference to use in
later runs.
JEP 514 ("Ahead-of-Time Command-Line Ergonomics") in OpenJDK 25 adds
the option `--XX:AOTCacheOutput` which performs both the above steps
from a single command-line invocation using a temporary configuration
file. A new environment variable, `JDK_AOT_VM_OPTIONS`, can be used
to pass options to the cache creation step without affecting the
training run step.
Ahead-of-Time Method Profiling
==============================
https://openjdk.org/jeps/515
Improve warmup time by making method-execution profiles from a
previous run of an application instantly available, when the HotSpot
Java Virtual Machine starts. This will enable the JIT compiler to
generate native code immediately upon application startup, rather than
having to wait for profiles to be collected.
Synchronize Virtual Threads without Pinning
===========================================
https://openjdk.org/jeps/491
Improve the scalability of Java code that uses synchronized methods
and statements by arranging for virtual threads that block in such
constructs to release their underlying platform threads for use by
other virtual threads. This will eliminate nearly all cases of virtual
threads being pinned to platform threads, which severely restricts the
number of virtual threads available to handle an application's
workload.
Compact Object Headers
======================
https://openjdk.org/jeps/450
https://openjdk.org/jeps/519
Reduce the size of object headers in the HotSpot JVM from between 96
and 128 bits down to 64 bits on 64-bit architectures. This will reduce
heap size, improve deployment density, and increase data locality.
This is now a production feature in OpenJDK 25 (JEP 519) enabled using
`-XX:+UseCompactObjectHeaders`. It was first introduced as an
experimental feature (JEP 450) that also required the use of
`-XX:+UnlockExperimentalVMOptions`.
Generational Shenandoah
=======================
https://openjdk.org/jeps/404
https://openjdk.org/jeps/521
Enhance the Shenandoah garbage collector with experimental
generational collection capabilities to improve sustainable
throughput, load-spike resilience, and memory utilization.
This is now a production feature in OpenJDK 25 (JEP 521) enabled using
`-XX:ShenandoahGCMode=generational`. It was first introduced as an
experimental feature (JEP 404) that also required the use of
`-XX:+UnlockExperimentalVMOptions`.
JFR Cooperative Sampling
========================
https://openjdk.org/jeps/518
Improve the stability of the JDK Flight Recorder (JFR) when it
asynchronously samples Java thread stacks. Achieve this by walking
call stacks only at safepoints, while minimizing safepoint bias.
JFR Method Timing & Tracing
===========================
https://openjdk.org/jeps/520
Extend the JDK Flight Recorder (JFR) with facilities for method timing
and tracing via bytecode instrumentation.
JFR CPU-Time Profiling
======================
https://openjdk.org/jeps/509
Enhance the JDK Flight Recorder (JFR) to capture more accurate
CPU-time profiling information on Linux.
This is an experimental feature so its JFR events are tagged with the
`@Experimental` annotation. Unlike other experimental virtual machine
features, it does not need to be explicitly enabled with
`-XX:+UnlockExperimentalVMOptions`.
Tools
=====
Launch Multi-File Source-Code Programs
======================================
https://openjdk.org/jeps/458
Enhance the java application launcher to be able to run a program
supplied as multiple files of Java source code. This will make the
transition from small programs to larger ones more gradual, enabling
developers to choose whether and when to go to the trouble of
configuring a build tool.
Markdown Documentation Comments
===============================
https://openjdk.org/jeps/467
Enable JavaDoc documentation comments to be written in Markdown rather
than solely in a mixture of HTML and JavaDoc @-tags.
Linking Run-Time Images without JMODs
=====================================
https://openjdk.org/jeps/493
Reduce the size of the JDK by approximately 25% by enabling the jlink
tool to create custom run-time images without using the JDK's JMOD
files.
This feature must be enabled when the JDK is built using the
--enable-linkable-runtime option. It will not be enabled by default,
and some JDK vendors may choose not to enable it.
DEPRECATIONS
============
Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
==================================================================
https://openjdk.org/jeps/471
Deprecate the memory-access methods in sun.misc.Unsafe for removal in
a future release. These unsupported methods have been superseded by
standard APIs, namely the VarHandle API (JEP 193, OpenJDK 9) and the
Foreign Function & Memory API (JEP 454, OpenJDK 22). We strongly
encourage library developers to migrate from sun.misc.Unsafe to
supported replacements, so that applications can migrate smoothly to
modern JDK releases.
Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
=========================================================
https://openjdk.org/jeps/498
Issue a warning at run time on the first occasion that any
memory-access method in sun.misc.Unsafe is invoked. All of these
unsupported methods were terminally deprecated in JDK 23 (see JEP 471
above). They have been superseded by standard APIs, namely the
VarHandle API (JEP 193, OpenJDK 9) and the Foreign Function & Memory
API (JEP 454, OpenJDK 22). We strongly encourage library developers to
migrate from sun.misc.Unsafe to supported replacements, so that
applications can migrate smoothly to modern JDK releases.
Permanently Disable the Security Manager
========================================
https://openjdk.org/jeps/486
The Security Manager has not been the primary means of securing
client-side Java code for many years, it has rarely been used to
secure server-side code, and it is costly to maintain. We therefore
deprecated it for removal in OpenJDK 17 via JEP 411 (2021). As the
next step toward removing the Security Manager, we will revise the
Java Platform specification so that developers cannot enable it and
other Platform classes do not refer to it. This change will have no
impact on the vast majority of applications, libraries, and tools. We
will remove the Security Manager API in a future release.
REMOVALS
========
String Templates
================
https://openjdk.org/jeps/430
https://openjdk.org/jeps/459
https://openjdk.org/jeps/465
This was a preview feature (http://openjdk.java.net/jeps/12)
introduced in OpenJDK 21 (JEP 430) with a second preview in OpenJDK 22
(JEP 459). A third preview was proposed but ultimately withdrawn for
OpenJDK 23 (JEP 465) and the feature is no longer present. See [0]
for further explanation.
[0] https://mail.openjdk.org/pipermail/amber-spec-experts/2024-April/004106.html
Remove the Windows & Linux 32-bit x86 Ports
===========================================
https://openjdk.org/jeps/449
https://openjdk.org/jeps/479
https://openjdk.org/jeps/501
https://openjdk.org/jeps/503
Remove the source code and build support for the Windows (JEP 479) &
Linux (JEP 503) 32-bit x86 ports. The Windows port was deprecated for
removal in JDK 21 by JEP 449 and the Linux port was deprecated for
removal in JDK 24 by JEP 501. Both deprecations took place with the
express intent to remove the ports in a future release.
Following this removal of these 32-bit x86 ports, the
architecture-agnostic Zero port is the only way to run Java programs
on 32-bit x86 processors.
ZGC: Remove the Non-Generational Mode
=====================================
https://openjdk.org/jeps/439
https://openjdk.org/jeps/474
https://openjdk.org/jeps/490
Remove the non-generational mode of the Z Garbage Collector (ZGC),
keeping the generational mode as the default for ZGC (see JEP 439 &
474).

1860
SOURCES/NEWS Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* TestTranslations -- Ensure translations are available for new timezones /* TestTranslations -- Ensure translations are available for new timezones
Copyright (C) 2022 Red Hat, Inc. Copyright (C) 2026 Red Hat, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
@ -50,25 +50,38 @@ public class TestTranslations {
"Mountain Daylight Time", "MDT", "MDT", "Mountain Daylight Time", "MDT", "MDT",
"Mountain Time", "MT", "MT"}); "Mountain Time", "MT", "MT"});
map.put(Locale.FRANCE, new String[] { "heure normale des Rocheuses", "UTC\u221207:00", "MST", map.put(Locale.FRANCE, new String[] { "heure normale des Rocheuses", "UTC\u221207:00", "MST",
"heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MST", "heure d\u2019\u00e9t\u00e9 des Rocheuses", "UTC\u221206:00", "MDT",
"heure des Rocheuses", "UTC\u221207:00", "MST"}); "heure des Rocheuses", "UTC\u221207:00", "MT"});
map.put(Locale.GERMANY, new String[] { "Rocky-Mountains-Normalzeit", "GMT-07:00", "MST", map.put(Locale.GERMANY, new String[] { "Rocky-Mountains-Normalzeit", "GMT-07:00", "MST",
"Rocky-Mountains-Sommerzeit", "GMT-06:00", "MST", "Rocky-Mountains-Sommerzeit", "GMT-06:00", "MDT",
"Rocky-Mountains-Zeit", "GMT-07:00", "MST"}); "Rocky-Mountains-Zeit", "GMT-07:00", "MT"});
CIUDAD_JUAREZ = Collections.unmodifiableMap(map); CIUDAD_JUAREZ = Collections.unmodifiableMap(map);
} }
public static void main(String[] args) { public static void main(String[] args) {
if (args.length < 1) { boolean debug = false;
System.err.println("Test must be started with the name of the locale provider.");
System.exit(1); if (args.length > 0) {
debug = Boolean.parseBoolean(args[0]);
} }
System.err.printf("Debugging: %s\n", debug);
testZoneStrings(debug);
testZone(KYIV,
new String[] { "Europe/Kiev", "Europe/Kyiv", "Europe/Uzhgorod", "Europe/Zaporozhye" });
testZone(CIUDAD_JUAREZ,
new String[] { "America/Cambridge_Bay", "America/Ciudad_Juarez" });
}
private static void testZoneStrings(final boolean debug) {
System.out.println("Checking sanity of full zone string set..."); System.out.println("Checking sanity of full zone string set...");
boolean invalid = Arrays.stream(Locale.getAvailableLocales()) boolean invalid = Arrays.stream(Locale.getAvailableLocales())
.peek(l -> System.out.println("Locale: " + l)) .peek(l -> System.out.printf(debug ? "Locale: %s\n" : "", l))
.map(l -> DateFormatSymbols.getInstance(l).getZoneStrings()) .map(l -> DateFormatSymbols.getInstance(l).getZoneStrings())
.peek(df -> System.out.printf(debug ? "Zone string size: %s\n" : "", df.length))
.flatMap(zs -> Arrays.stream(zs)) .flatMap(zs -> Arrays.stream(zs))
.flatMap(names -> Arrays.stream(names)) .flatMap(names -> Arrays.stream(names))
.filter(name -> Objects.isNull(name) || name.isEmpty()) .filter(name -> Objects.isNull(name) || name.isEmpty())
@ -78,15 +91,9 @@ public class TestTranslations {
System.err.println("Zone string for a locale returned null or empty string"); System.err.println("Zone string for a locale returned null or empty string");
System.exit(2); System.exit(2);
} }
String localeProvider = args[0];
testZone(localeProvider, KYIV,
new String[] { "Europe/Kiev", "Europe/Kyiv", "Europe/Uzhgorod", "Europe/Zaporozhye" });
testZone(localeProvider, CIUDAD_JUAREZ,
new String[] { "America/Cambridge_Bay", "America/Ciudad_Juarez" });
} }
private static void testZone(String localeProvider, Map<Locale,String[]> exp, String[] ids) { private static void testZone(Map<Locale,String[]> exp, String[] ids) {
for (Locale l : exp.keySet()) { for (Locale l : exp.keySet()) {
String[] expected = exp.get(l); String[] expected = exp.get(l);
System.out.printf("Expected values for %s are %s\n", l, Arrays.toString(expected)); System.out.printf("Expected values for %s are %s\n", l, Arrays.toString(expected));
@ -97,16 +104,11 @@ public class TestTranslations {
System.out.printf("Checking locale %s for %s...\n", l, id); System.out.printf("Checking locale %s for %s...\n", l, id);
if ("JRE".equals(localeProvider) || "CLDR".equals(localeProvider)) { expectedShortStd = expected[2];
expectedShortStd = expected[2]; expectedShortDST = expected[5];
expectedShortDST = expected[5]; expectedShortGen = expected[8];
expectedShortGen = expected[8]; System.out.printf("Using short values %s, %s and %s\n",
} else { expectedShortStd, expectedShortDST, expectedShortGen);
System.err.printf("Invalid locale provider %s\n", localeProvider);
System.exit(3);
}
System.out.printf("Locale Provider is %s, using short values %s, %s and %s\n",
localeProvider, expectedShortStd, expectedShortDST, expectedShortGen);
String longStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.LONG, l); String longStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.LONG, l);
String shortStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.SHORT, l); String shortStd = TimeZone.getTimeZone(id).getDisplayName(false, TimeZone.SHORT, l);

View File

@ -109,6 +109,8 @@ security.provider.8=
keystore.type=pkcs12 keystore.type=pkcs12
EOF EOF
# Make sure java.security exists before appending
test -e "${SECURITY}"/java.security || ( echo "${SECURITY}/java.security not found" && false )
cat >> "${SECURITY}"/java.security <<'EOF' cat >> "${SECURITY}"/java.security <<'EOF'
# #

View File

@ -1,8 +1,8 @@
diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java
index de2845fb550..b1e416b90f4 100644 index de2845fb550..60eeab678ca 100644
--- a/src/java.base/share/classes/java/security/Provider.java --- a/src/java.base/share/classes/java/security/Provider.java
+++ b/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java
@@ -1203,6 +1203,39 @@ public Set<Service> getServices() { @@ -1203,6 +1203,34 @@ public Set<Service> getServices() {
return serviceSet; return serviceSet;
} }
@ -10,9 +10,7 @@ index de2845fb550..b1e416b90f4 100644
+ private static final class RedHatFIPSFilter { + private static final class RedHatFIPSFilter {
+ static final boolean IS_ON = Boolean.parseBoolean( + static final boolean IS_ON = Boolean.parseBoolean(
+ Security.getProperty("__redhat_fips_filter__")); + Security.getProperty("__redhat_fips_filter__"));
+ private static final Set<String> ANY_SERVICE_TYPE = Set.of();
+ private static final Map<String, Set<String>> ALLOW_LIST = Map.of( + private static final Map<String, Set<String>> ALLOW_LIST = Map.of(
+ "SunPKCS11-FIPS", ANY_SERVICE_TYPE,
+ "SUN", Set.of( + "SUN", Set.of(
+ "AlgorithmParameterGenerator", + "AlgorithmParameterGenerator",
+ "AlgorithmParameters", "CertificateFactory", + "AlgorithmParameters", "CertificateFactory",
@ -20,21 +18,18 @@ index de2845fb550..b1e416b90f4 100644
+ "Configuration", "KeyStore"), + "Configuration", "KeyStore"),
+ "SunEC", Set.of( + "SunEC", Set.of(
+ "AlgorithmParameters", "KeyFactory"), + "AlgorithmParameters", "KeyFactory"),
+ "SunJSSE", ANY_SERVICE_TYPE,
+ "SunJCE", Set.of( + "SunJCE", Set.of(
+ "AlgorithmParameters", + "AlgorithmParameters",
+ "AlgorithmParameterGenerator", "KeyFactory", + "AlgorithmParameterGenerator", "KeyFactory",
+ "SecretKeyFactory"), + "SecretKeyFactory"),
+ "SunRsaSign", Set.of( + "SunRsaSign", Set.of(
+ "KeyFactory", "AlgorithmParameters"), + "KeyFactory", "AlgorithmParameters")
+ "XMLDSig", ANY_SERVICE_TYPE
+ ); + );
+ +
+ static boolean isAllowed(String provName, String serviceType) { + static boolean isAllowed(String provName, String serviceType) {
+ Set<String> allowedServiceTypes = ALLOW_LIST.get(provName); + Set<String> allowedServiceTypes = ALLOW_LIST.get(provName);
+ return allowedServiceTypes != null && + return allowedServiceTypes == null ||
+ (allowedServiceTypes == ANY_SERVICE_TYPE || + allowedServiceTypes.contains(serviceType);
+ allowedServiceTypes.contains(serviceType));
+ } + }
+ } + }
+ /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FIPS PATCH ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
@ -42,7 +37,7 @@ index de2845fb550..b1e416b90f4 100644
/** /**
* Add a service. If a service of the same type with the same algorithm * Add a service. If a service of the same type with the same algorithm
* name exists, and it was added using {@link #putService putService()}, * name exists, and it was added using {@link #putService putService()},
@@ -1231,6 +1264,15 @@ protected void putService(Service s) { @@ -1231,6 +1259,15 @@ protected void putService(Service s) {
("service.getProvider() must match this Provider object"); ("service.getProvider() must match this Provider object");
} }
String type = s.getType(); String type = s.getType();

View File

@ -1,4 +1,97 @@
# debug_package %%{nil} is portable-jdks specific # New Version-String scheme-style defines
%global featurever 25
%global interimver 0
%global updatever 4
%global patchver 0
%global buildver 7
%global portablerelease 1
%global rpmrelease 0
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver 57722aab802
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
# Define an optional suffix for the OS this package is built on
%if 0%{?rhel} == 7
%global pkgos rhel7
%endif
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N.ea<dist> for EA releases,
# - N<dist> for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
%global compatiblename java-%{javaver}-%{origin}
Name: %{compatiblename}-portable%{?pkgos:-%{pkgos}}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{portablerelease}.%{rpmrelease}%{?extraver}%{?dist}
%global fullversion %{compatiblename}-%{version}-%{release}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment portable edition
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# We are producing RPMs containing only tarballs
# and checksums so there are no binaries outside
# the tarballs to be processed for debuginfo
%define debug_package %{nil} %define debug_package %{nil}
# RPM conditionals so as to be able to dynamically produce # RPM conditionals so as to be able to dynamically produce
@ -96,25 +189,6 @@
%global normal_build %{nil} %global normal_build %{nil}
%endif %endif
# We have hardcoded list of files, which is appearing in alternatives, and in files
# in alternatives those are slaves and master, very often triplicated by man pages
# in files all masters and slaves are ghosted
# the ghosts are here to allow installation via query like `dnf install /usr/bin/java`
# you can list those files, with appropriate sections: cat *.spec | grep -e --install -e --slave -e post_
# TODO - fix those hardcoded lists via single list
# Those files must *NOT* be ghosted for *slowdebug* packages
# FIXME - if you are moving jshell or jlink or similar, always modify all three sections
# you can check via headless and devels:
# rpm -ql --noghost java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# == rpm -ql java-11-openjdk-headless-slowdebug-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# != rpm -ql java-11-openjdk-headless-11.0.1.13-8.fc29.x86_64.rpm | grep bin
# similarly for other %%{_jvmdir}/{jre,java} and %%{_javadocdir}/{java,java-zip}
%define is_release_build() %( if [ "%{?1}" == "%{debug_suffix_unquoted}" -o "%{?1}" == "%{fastdebug_suffix_unquoted}" ]; then echo "0" ; else echo "1"; fi )
# while JDK is a techpreview(is_system_jdk=0), some provides are turned off. Once jdk stops to be an techpreview, move it to 1
# as sytem JDK, we mean any JDK which can run whole system java stack without issues (like bytecode issues, module issues, dependencies...)
%global is_system_jdk 0
%global aarch64 aarch64 arm64 armv8 %global aarch64 aarch64 arm64 armv8
# we need to distinguish between big and little endian PPC64 # we need to distinguish between big and little endian PPC64
%global ppc64le ppc64le %global ppc64le ppc64le
@ -333,17 +407,14 @@
%global with_systemtap 0 %global with_systemtap 0
%endif %endif
# New Version-String scheme-style defines
%global featurever 25 # buildjdkver is usually same as featurever,
%global interimver 0 # but at the time of bootstrap of the next jdk, it is featurever-1,
%global updatever 1
%global patchver 0
# buildjdkver is usually same as %%{featurever},
# but in time of bootstrap of next jdk, it is featurever-1,
# and this it is better to change it here, on single place # and this it is better to change it here, on single place
%global buildjdkver %{featurever} %global buildjdkver %{featurever}
# We don't add any LTS designator for STS packages (Fedora and EPEL). # We don't add any LTS designator for STS packages (Fedora and EPEL).
# We need to explicitly exclude EPEL as it would have the %%{rhel} macro defined. # We need to explicitly exclude EPEL as it has the rhel macro defined.
%if 0%{?rhel} && !0%{?epel} %if 0%{?rhel} && !0%{?epel}
%global lts_designator "LTS" %global lts_designator "LTS"
%global lts_designator_zip -%{lts_designator} %global lts_designator_zip -%{lts_designator}
@ -355,7 +426,8 @@
# Define vendor information used by OpenJDK # Define vendor information used by OpenJDK
%global oj_vendor Red Hat, Inc. %global oj_vendor Red Hat, Inc.
%global oj_vendor_url https://www.redhat.com/ %global oj_vendor_url https://www.redhat.com/
# Define what url should JVM offer in case of a crash report
# Define what url the JVM should offer in case of a crash report
# order may be important, epel may have rhel declared # order may be important, epel may have rhel declared
%if 0%{?epel} %if 0%{?epel}
%global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{name}&version=epel%{epel} %global oj_vendor_bug_url https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora%20EPEL&component=%{name}&version=epel%{epel}
@ -371,67 +443,13 @@
%endif %endif
%endif %endif
%endif %endif
%global oj_vendor_version (Red_Hat-%{version}-%{rpmrelease}) %global oj_vendor_version (Red_Hat-%{version}-%{portablerelease})
# Define IcedTea version used for SystemTap tapsets and desktop file
%global icedteaver 6.0.0pre00-c848b93a8598
# Define current Git revision for the FIPS support patches
%global fipsver df044414ef4
# Define JDK versions
%global newjavaver %{featurever}.%{interimver}.%{updatever}.%{patchver}
%global javaver %{featurever}
# Strip up to 6 trailing zeros in newjavaver, as the JDK does, to get the correct version used in filenames
%global filever %(svn=%{newjavaver}; for i in 1 2 3 4 5 6 ; do svn=${svn%%.0} ; done; echo ${svn})
# The tag used to create the OpenJDK tarball
%global vcstag jdk-%{filever}+%{buildver}%{?tagsuffix:-%{tagsuffix}}
# Standard JPackage naming and versioning defines
%global origin openjdk
%global origin_nice OpenJDK
%global top_level_dir_name %{vcstag}
%global top_level_dir_name_backup %{top_level_dir_name}-backup
%global buildver 8
%global rpmrelease 2
#%%global tagsuffix %%{nil}
# Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit
%if %is_system_jdk
# Using 10 digits may overflow the int used for priority, so we combine the patch and build versions
# It is very unlikely we will ever have a patch version > 4 or a build version > 20, so we combine as (patch * 20) + build.
# This means 11.0.9.0+11 would have had a priority of 11000911 as before
# A 11.0.9.1+1 would have had a priority of 11000921 (20 * 1 + 1), thus ensuring it is bigger than 11.0.9.0+11
%global combiver $( expr 20 '*' %{patchver} + %{buildver} )
%global priority %( printf '%02d%02d%02d%02d' %{featurever} %{interimver} %{updatever} %{combiver} )
%else
# for techpreview, using 1, so slowdebugs can have 0
%global priority %( printf '%08d' 1 )
%endif
# Define milestone (EA for pre-releases, GA for releases)
# Release will be (where N is usually a number starting at 1):
# - 0.N%%{?extraver}%%{?dist} for EA releases,
# - N%%{?extraver}{?dist} for GA releases
%global is_ga 1
%if %{is_ga}
%global build_type GA
%global ea_designator ""
%global ea_designator_zip %{nil}
%global extraver %{nil}
%global eaprefix %{nil}
%else
%global build_type EA
%global ea_designator ea
%global ea_designator_zip -%{ea_designator}
%global extraver .%{ea_designator}
%global eaprefix 0.
%endif
# parametrized macros are order-sensitive
%global compatiblename java-%{featurever}-%{origin}
%global fullversion %{compatiblename}-%{version}-%{release}
# images directories from upstream build # images directories from upstream build
%global jdkimage jdk %global jdkimage jdk
%global static_libs_image static-libs-graal %global static_libs_image static-libs-graal
# output dir stub # output dir stub
# Parameterised macros are order-sensitive
%define buildoutputdir() %{expand:build/jdk%{featurever}.build%{?1}} %define buildoutputdir() %{expand:build/jdk%{featurever}.build%{?1}}
%define installoutputdir() %{expand:install/jdk%{featurever}.install%{?1}} %define installoutputdir() %{expand:install/jdk%{featurever}.install%{?1}}
%global altjavaoutputdir install/altjava.install %global altjavaoutputdir install/altjava.install
@ -442,20 +460,29 @@
%define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}} %define uniquesuffix() %{expand:%{fullversion}.%{_arch}%{?1}}
# portable only declarations # portable only declarations
%global jreimage jre %global jreimage jre
%define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.jre;g") %define jreportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.jre;g")
%define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.jdk;g") %define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.jdk;g")
%define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable%{1}.static-libs;g") %define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable%{1}.static-libs;g")
# RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1}
# so we have to pass in "" but evaluate it, otherwise files will include it
%define jreportablearchive() %{expand:%{jreportablenameimpl -- %%{1}}.tar.xz} %define jreportablearchive() %{expand:%{jreportablenameimpl -- %%{1}}.tar.xz}
%define jreportablearchive_for_files() %(echo %{jreportablearchive -- ""})
%define jdkportablearchive() %{expand:%{jdkportablenameimpl -- %%{1}}.tar.xz} %define jdkportablearchive() %{expand:%{jdkportablenameimpl -- %%{1}}.tar.xz}
%define jdkportablearchive_for_files() %(echo %{jdkportablearchive -- ""})
%define staticlibsportablearchive() %{expand:%{staticlibsportablenameimpl -- %%{1}}.tar.xz} %define staticlibsportablearchive() %{expand:%{staticlibsportablenameimpl -- %%{1}}.tar.xz}
%define staticlibsportablearchive_for_files() %(echo %{staticlibsportablearchive -- ""})
%define jreportablename() %{expand:%{jreportablenameimpl -- %%{1}}} %define jreportablename() %{expand:%{jreportablenameimpl -- %%{1}}}
%define jdkportablename() %{expand:%{jdkportablenameimpl -- %%{1}}} %define jdkportablename() %{expand:%{jdkportablenameimpl -- %%{1}}}
# Intentionally use jdkportablenameimpl here since we want to have static-libs files overlayed on # We intentionally use jdkportablenameimpl here since we want to have
# top of the JDK archive # static-libs files overlayed on top of the JDK archive
%define staticlibsportablename() %{expand:%{jdkportablenameimpl -- %%{1}}} %define staticlibsportablename() %{expand:%{jdkportablenameimpl -- %%{1}}}
%define docportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable.docs;g")
# These macros are not parameterised as the same is shared by all builds
%define docportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable.docs;g")
%define docportablearchive() %{docportablename}.tar.xz %define docportablearchive() %{docportablename}.tar.xz
%define miscportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}\\(_[0-9]\\)*;portable.misc;g") %define miscportablename() %(echo %{uniquesuffix ""} | sed "s;el%{rhel}[^.]*;portable.misc;g")
%define miscportablearchive() %{miscportablename}.tar.xz %define miscportablearchive() %{miscportablename}.tar.xz
# JDK to use for bootstrapping # JDK to use for bootstrapping
@ -474,26 +501,6 @@
%global build_hotspot_first 0 %global build_hotspot_first 0
%endif %endif
#################################################################
# fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349
# https://bugzilla.redhat.com/show_bug.cgi?id=1590796#c14
# https://bugzilla.redhat.com/show_bug.cgi?id=1655938
%global _privatelibs libsplashscreen[.]so.*|libawt_xawt[.]so.*|libjli[.]so.*|libattach[.]so.*|libawt[.]so.*|libextnet[.]so.*|libawt_headless[.]so.*|libdt_socket[.]so.*|libfontmanager[.]so.*|libinstrument[.]so.*|libj2gss[.]so.*|libj2pcsc[.]so.*|libj2pkcs11[.]so.*|libjaas[.]so.*|libjavajpeg[.]so.*|libjdwp[.]so.*|libjimage[.]so.*|libjsound[.]so.*|liblcms[.]so.*|libmanagement[.]so.*|libmanagement_agent[.]so.*|libmanagement_ext[.]so.*|libmlib_image[.]so.*|libnet[.]so.*|libnio[.]so.*|libprefs[.]so.*|librmi[.]so.*|libsaproc[.]so.*|libsctp[.]so.*|libsystemconf[.]so.*|libzip[.]so.*%{freetype_lib}
%global _publiclibs libjawt[.]so.*|libjava[.]so.*|libjvm[.]so.*|libverify[.]so.*|libjsig[.]so.*
%if %is_system_jdk
%global __provides_exclude ^(%{_privatelibs})$
%global __requires_exclude ^(%{_privatelibs})$
# Never generate lib-style provides/requires for slowdebug packages
%global __provides_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
%global __requires_exclude_from ^.*/%{uniquesuffix -- %{debug_suffix_unquoted}}/.*$
%global __provides_exclude_from ^.*/%{uniquesuffix -- %{fastdebug_suffix_unquoted}}/.*$
%global __requires_exclude_from ^.*/%{uniquesuffix -- %{fastdebug_suffix_unquoted}}/.*$
%else
# Don't generate provides/requires for JDK provided shared libraries at all.
%global __provides_exclude ^(%{_privatelibs}|%{_publiclibs})$
%global __requires_exclude ^(%{_privatelibs}|%{_publiclibs})$
%endif
# VM variant being built # VM variant being built
%ifarch %{zero_arches} %ifarch %{zero_arches}
%global vm_variant zero %global vm_variant zero
@ -501,28 +508,11 @@
%global vm_variant server %global vm_variant server
%endif %endif
%global etcjavasubdir %{_sysconfdir}/java/java-%{javaver}-%{origin}
%define etcjavadir() %{expand:%{etcjavasubdir}/%{uniquesuffix -- %{?1}}}
# Standard JPackage directories and symbolic links.
%define sdkdir() %{expand:%{uniquesuffix -- %{?1}}}
%define jrelnk() %{expand:jre-%{javaver}-%{origin}-%{version}-%{release}.%{_arch}%{?1}}
%define sdkbindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin}
%define jrebindir() %{expand:%{_jvmdir}/%{sdkdir -- %{?1}}/bin}
%global alt_java_name alt-java %global alt_java_name alt-java
%global devkit_name %{origin}-devkit %global devkit_name %{origin}-devkit
%global rpm_state_dir %{_localstatedir}/lib/rpm-state/ %global rpm_state_dir %{_localstatedir}/lib/rpm-state/
# For flatpack builds hard-code /usr/sbin/alternatives,
# otherwise use %%{_sbindir} relative path.
%if 0%{?flatpak}
%global alternatives_requires /usr/sbin/alternatives
%else
%global alternatives_requires %{_sbindir}/alternatives
%endif
# Portables have no repo (requires/provides), but these are awesome for orientation in spec # Portables have no repo (requires/provides), but these are awesome for orientation in spec
# Also scriptlets are happily missing and files are handled old fashion # Also scriptlets are happily missing and files are handled old fashion
# not-duplicated requires/provides/obsoletes for normal/debug packages # not-duplicated requires/provides/obsoletes for normal/debug packages
@ -547,11 +537,6 @@
# Prevent brp-java-repack-jars from being run # Prevent brp-java-repack-jars from being run
%global __jar_repack 0 %global __jar_repack 0
# Define an optional suffix for the OS this package is built on
%if 0%{?rhel} == 7
%global pkgos rhel7
%endif
# Define the architectures on which we build # Define the architectures on which we build
# On RHEL, this should be the architectures with a devkit # On RHEL, this should be the architectures with a devkit
%if 0%{?centos} == 0 %if 0%{?centos} == 0
@ -560,43 +545,6 @@ ExclusiveArch: %{devkit_arches}
ExclusiveArch: %{aarch64} %{ppc64le} s390x x86_64 riscv64 ExclusiveArch: %{aarch64} %{ppc64le} s390x x86_64 riscv64
%endif %endif
Name: java-%{javaver}-%{origin}-portable%{?pkgos:-%{pkgos}}
Version: %{newjavaver}.%{buildver}
Release: %{?eaprefix}%{rpmrelease}%{?extraver}%{?dist}
# java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons
# and this change was brought into RHEL-4. java-1.5.0-ibm packages
# also included the epoch in their virtual provides. This created a
# situation where in-the-wild java-1.5.0-ibm packages provided "java =
# 1:1.5.0". In RPM terms, "1.6.0 < 1:1.5.0" since 1.6.0 is
# interpreted as 0:1.6.0. So the "java >= 1.6.0" requirement would be
# satisfied by the 1:1.5.0 packages. Thus we need to set the epoch in
# JDK package >= 1.6.0 to 1, and packages referring to JDK virtual
# provides >= 1.6.0 must specify the epoch, "java >= 1:1.6.0".
Epoch: 1
Summary: %{origin_nice} %{featurever} Runtime Environment portable edition
# Groups are only used up to RHEL 8 and on Fedora versions prior to F30
%if (0%{?rhel} > 0 && 0%{?rhel} <= 8) || (0%{?fedora} >= 0 && 0%{?fedora} < 30)
Group: Development/Languages
%endif
# HotSpot code is licensed under GPLv2
# JDK library code is licensed under GPLv2 with the Classpath exception
# The Apache license is used in code taken from Apache projects (primarily xalan & xerces)
# DOM levels 2 & 3 and the XML digital signature schemas are licensed under the W3C Software License
# The JSR166 concurrency code is in the public domain
# The BSD and MIT licenses are used for a number of third-party libraries (see ADDITIONAL_LICENSE_INFO)
# The OpenJDK source tree includes:
# - JPEG library (IJG), zlib & libpng (zlib), giflib (MIT), harfbuzz (ISC),
# - freetype (FTL), jline (BSD) and LCMS (MIT)
# - jquery (MIT), jdk.crypto.cryptoki PKCS 11 wrapper (RSA)
# - public_suffix_list.dat from publicsuffix.org (MPLv2.0)
# The test code includes copies of NSS under the Mozilla Public License v2.0
# The PCSClite headers are under a BSD with advertising license
# The elliptic curve cryptography (ECC) source code is licensed under the LGPLv2.1 or any later version
License: ASL 1.1 and ASL 2.0 and BSD and BSD with advertising and GPL+ and GPLv2 and GPLv2 with exceptions and IJG and LGPLv2+ and MIT and MPLv2.0 and Public Domain and W3C and zlib and ISC and FTL and RSA
URL: http://openjdk.java.net/
# The source tarball, generated using generate_source_tarball.sh # The source tarball, generated using generate_source_tarball.sh
Source0: https://openjdk-sources.osci.io/openjdk%{featurever}/open%{vcstag}%{ea_designator_zip}.tar.xz Source0: https://openjdk-sources.osci.io/openjdk%{featurever}/open%{vcstag}%{ea_designator_zip}.tar.xz
@ -638,42 +586,17 @@ Source18: TestTranslations.java
# RPM/distribution specific patches # RPM/distribution specific patches
# #
############################################ ############################################
# Crypto policy and FIPS support patches # Crypto policy and FIPS support patches
# Patch is generated from the fips-25u tree at https://github.com/rh-openjdk/jdk/tree/fips-25u # Patch is generated from the fips-25u tree at https://github.com/rh-openjdk/jdk/tree/fips-25u
# as follows: git diff %%{vcstag} src make test > fips-25u-$(git show -s --format=%h HEAD).patch # as follows: git diff <vcstag> src make test > fips-25u-$(git show -s --format=%h HEAD).patch
# Diff is limited to src and make subdirectories to exclude .github changes # Diff is limited to src and make subdirectories to exclude .github changes
# Fixes currently included: # Fixes currently included:
# PR3183, RH1340845: Follow system wide crypto policy # OPENJDK-2108: Internal __redhat_fips__ property
# PR3695: Allow use of system crypto policy to be disabled by the user # OPENJDK-2123: Algorithms lockdown
# RH1655466: Support RHEL FIPS mode using SunPKCS11 provider # OPENJDK-4559: Red Hat Build of OpenJDK 25 should not restrict all the providers in FIPS
# RH1818909: No ciphersuites availale for SSLSocket in FIPS mode
# RH1860986: Disable TLSv1.3 with the NSS-FIPS provider until PKCS#11 v3.0 support is available
# RH1915071: Always initialise JavaSecuritySystemConfiguratorAccess
# RH1929465: Improve system FIPS detection
# RH1995150: Disable non-FIPS crypto in SUN and SunEC security providers
# RH1996182: Login to the NSS software token in FIPS mode
# RH1991003: Allow plain key import unless com.redhat.fips.plainKeySupport is set to false
# RH2021263: Resolve outstanding FIPS issues
# RH2052819: Fix FIPS reliance on crypto policies
# RH2052829: Detect NSS at Runtime for FIPS detection
# RH2052070: Enable AlgorithmParameters and AlgorithmParameterGenerator services in FIPS mode
# RH2023467: Enable FIPS keys export
# RH2094027: SunEC runtime permission for FIPS
# RH2036462: sun.security.pkcs11.wrapper.PKCS11.getInstance breakage
# RH2090378: Revert to disabling system security properties and FIPS mode support together
# RH2104724: Avoid import/export of DH private keys
# RH2092507: P11Key.getEncoded does not work for DH keys in FIPS mode
# Build the systemconf library on all platforms
# RH2048582: Support PKCS#12 keystores [now part of JDK-8301553 upstream]
# RH2020290: Support TLS 1.3 in FIPS mode
# Add nss.fips.cfg support to OpenJDK tree
# RH2117972: Extend the support for NSS DBs (PKCS11) in FIPS mode
# Remove forgotten dead code from RH2020290 and RH2104724
# OJ1357: Fix issue on FIPS with a SecurityManager in place
# RH2134669: Add missing attributes when registering services in FIPS mode.
# test/jdk/sun/security/pkcs11/fips/VerifyMissingAttributes.java: fixed jtreg main class
# RH1940064: Enable XML Signature provider in FIPS mode
# RH2173781: Avoid calling C_GetInfo() too early, before cryptoki is initialized [now part of JDK-8301553 upstream]
Patch1001: fips-%{featurever}u-%{fipsver}.patch Patch1001: fips-%{featurever}u-%{fipsver}.patch
############################################# #############################################
@ -690,7 +613,10 @@ Patch1001: fips-%{featurever}u-%{fipsver}.patch
# #
############################################# #############################################
# Currently empty # JDK-8347901: C2 should remove unused leaf / pure runtime calls
Patch2002: jdk8347901-c2_unused_leaf_removal.patch
# JDK-83787313: C2: performance regression due to missing constant folding for Math.pow()
Patch2003: jdk8378713-c2_missing_pow_constant_folding.patch
############################################# #############################################
# #
@ -773,19 +699,19 @@ BuildRequires: libpng-devel
BuildRequires: zlib-devel BuildRequires: zlib-devel
%else %else
# Version in src/java.desktop/share/legal/freetype.md # Version in src/java.desktop/share/legal/freetype.md
Provides: bundled(freetype) = 2.13.3 Provides: bundled(freetype) = 2.14.3
# Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h # Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
Provides: bundled(giflib) = 5.2.2 Provides: bundled(giflib) = 6.1.3
# Version in src/java.desktop/share/native/libharfbuzz/hb-version.h # Version in src/java.desktop/share/native/libharfbuzz/hb-version.h
Provides: bundled(harfbuzz) = 10.4.0 Provides: bundled(harfbuzz) = 14.2.0
# Version in src/java.desktop/share/native/liblcms/lcms2.h # Version in src/java.desktop/share/native/liblcms/lcms2.h
Provides: bundled(lcms2) = 2.17.0 Provides: bundled(lcms2) = 2.19.1
# Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h # Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h
Provides: bundled(libjpeg) = 6b Provides: bundled(libjpeg) = 6b
# Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h # Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h
Provides: bundled(libpng) = 1.6.47 Provides: bundled(libpng) = 1.6.58
# Version in src/java.base/share/native/libzip/zlib/zlib.h # Version in src/java.base/share/native/libzip/zlib/zlib.h
Provides: bundled(zlib) = 1.3.1 Provides: bundled(zlib) = 1.3.2
# We link statically against libstdc++ to increase portability # We link statically against libstdc++ to increase portability
%ifnarch %{devkit_arches} %ifnarch %{devkit_arches}
BuildRequires: libstdc++-static BuildRequires: libstdc++-static
@ -974,11 +900,6 @@ fi
export XZ_OPT="-T0" export XZ_OPT="-T0"
%setup -q -c -n %{uniquesuffix ""} -T -a 0 %setup -q -c -n %{uniquesuffix ""} -T -a 0
# https://bugzilla.redhat.com/show_bug.cgi?id=1189084 # https://bugzilla.redhat.com/show_bug.cgi?id=1189084
prioritylength=`expr length %{priority}`
if [ $prioritylength -ne 8 ] ; then
echo "priority must be 8 digits in total, violated"
exit 14
fi
# OpenJDK patches # OpenJDK patches
@ -988,22 +909,13 @@ sh %{SOURCE12} %{top_level_dir_name}
%endif %endif
# Patch the JDK # Patch the JDK
# This syntax is deprecated:
# %patchN [...]
# and should be replaced with:
# %patch -PN [...]
# For example:
# %patch1001 -p1
# becomes:
# %patch -P1001 -p1
# The replacement format suggested by recent (circa Fedora 38) RPM
# deprecation messages:
# %patch N [...]
# is not backward-compatible with prior (circa RHEL-8) versions of
# rpmbuild.
pushd %{top_level_dir_name} pushd %{top_level_dir_name}
# Add crypto policy and FIPS support # Add crypto policy and FIPS support
%patch -P1001 -p1 %patch -P1001 -p1
# Add C2 patches
%patch -P2002 -p1
%patch -P2003 -p1
popd # openjdk popd # openjdk
echo "Generating %{alt_java_name} man page" echo "Generating %{alt_java_name} man page"
@ -1087,7 +999,6 @@ cat %{bootjdk}/release
export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :) export NUM_PROC=%(/usr/bin/getconf _NPROCESSORS_ONLN 2> /dev/null || :)
export NUM_PROC=${NUM_PROC:-1} export NUM_PROC=${NUM_PROC:-1}
%if 0%{?_smp_ncpus_max} %if 0%{?_smp_ncpus_max}
# Honor %%_smp_ncpus_max
[ ${NUM_PROC} -gt %{?_smp_ncpus_max} ] && export NUM_PROC=%{?_smp_ncpus_max} [ ${NUM_PROC} -gt %{?_smp_ncpus_max} ] && export NUM_PROC=%{?_smp_ncpus_max}
%endif %endif
export XZ_OPT="-T0" export XZ_OPT="-T0"
@ -1207,8 +1118,8 @@ function buildjdk() {
mkdir -p ${outputdir} mkdir -p ${outputdir}
pushd ${outputdir} pushd ${outputdir}
# Note: zlib and freetype use %{link_type} # Note: zlib and freetype use link_type (macro)
# rather than ${link_opt} as the system versions # rather than link_opt (shell var) as the system versions
# are always used in a system_libs build, even # are always used in a system_libs build, even
# for the static library build # for the static library build
LD_LIBRARY_PATH=${LIBPATH} \ LD_LIBRARY_PATH=${LIBPATH} \
@ -1717,12 +1628,14 @@ $JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -versi
# Check translations are available for new timezones (during flatpak builds, the # Check translations are available for new timezones (during flatpak builds, the
# tzdb.dat used by this test is not where the test expects it, so this is # tzdb.dat used by this test is not where the test expects it, so this is
# disabled for flatpak builds) # disabled for flatpak builds)
# Disable test until we are on the latest JDK $JAVA_HOME/bin/java %{SOURCE18}
$JAVA_HOME/bin/javac -d . %{SOURCE18}
$JAVA_HOME/bin/java $(echo $(basename %{SOURCE18})|sed "s|\.java||") JRE
$JAVA_HOME/bin/java -Djava.locale.providers=CLDR $(echo $(basename %{SOURCE18})|sed "s|\.java||") CLDR
%endif %endif
# Check blocked.certs is valid (OPENJDK-4362)
jtreg_test=$(pwd)/%{top_level_dir_name}/test/jdk/sun/security/lib/CheckBlockedCerts.java
jtreg_dir=$(dirname ${jtreg_test})
$JAVA_HOME/bin/java --add-exports java.base/sun.security.util=ALL-UNNAMED -Dtest.src=${jtreg_dir} ${jtreg_test}
# Check src.zip has all sources. See RHBZ#1130490 # Check src.zip has all sources. See RHBZ#1130490
unzip -l $JAVA_HOME/lib/src.zip | grep 'sun.misc.Unsafe' unzip -l $JAVA_HOME/lib/src.zip | grep 'sun.misc.Unsafe'
@ -1894,8 +1807,8 @@ done
%files %files
# main package builds always # main package builds always
%{_jvmdir}/%{jreportablearchive -- %%{nil}} %{_jvmdir}/%{jreportablearchive_for_files}
%{_jvmdir}/%{jreportablearchive -- %%{nil}}.sha256sum %{_jvmdir}/%{jreportablearchive_for_files}.sha256sum
%else %else
%files %files
# placeholder # placeholder
@ -1904,15 +1817,15 @@ done
%if %{include_normal_build} %if %{include_normal_build}
%files devel %files devel
%{_jvmdir}/%{jdkportablearchive -- %%{nil}} %{_jvmdir}/%{jdkportablearchive_for_files}
%{_jvmdir}/%{jdkportablearchive -- .debuginfo} %{_jvmdir}/%{jdkportablearchive -- .debuginfo}
%{_jvmdir}/%{jdkportablearchive -- %%{nil}}.sha256sum %{_jvmdir}/%{jdkportablearchive_for_files}.sha256sum
%{_jvmdir}/%{jdkportablearchive -- .debuginfo}.sha256sum %{_jvmdir}/%{jdkportablearchive -- .debuginfo}.sha256sum
%if %{include_staticlibs} %if %{include_staticlibs}
%files static-libs %files static-libs
%{_jvmdir}/%{staticlibsportablearchive -- %%{nil}} %{_jvmdir}/%{staticlibsportablearchive_for_files}
%{_jvmdir}/%{staticlibsportablearchive -- %%{nil}}.sha256sum %{_jvmdir}/%{staticlibsportablearchive_for_files}.sha256sum
%endif %endif
%files unstripped %files unstripped
@ -1966,6 +1879,97 @@ done
%endif %endif
%changelog %changelog
* Thu Jul 23 2026 eabdullin <eabdullin@almalinux.org> - 1:25.0.4.0.7-1.0
- Portable build
* Thu Jul 16 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.4.0.7-1.0
- Update to jdk-25.0.4+7 (GA)
- Update release notes to 25.0.4+7
- Bump freetype version to 2.14.3 following JDK-8385390
- Bump giflib version to 6.1.3 following JDK-8384902
- Bump HarfBuzz version to 14.2.0 following JDK-8385490
- Bump lcms2 version to 2.19.1 following JDK-8375065 & JDK-8383354
- Bump libpng version to 1.6.58 following JDK-8384495
- Drop local copy of JDK-8375294 EOPNOTSUPP patch
- Revert fr_FR and de_DE changes made in d43f0e6186370fdeb0ca2f3594f39783e20eef1c now JDK-8382020 is fixed
- Simplify TestTranslations run now there is only the CLDR provider and one set of data (JDK-8174269)
- Make zone string debug output optional in TestTranslations
- ** This tarball is embargoed until 2026-07-21 @ 1pm PT. **
- Resolves: OPENJDK-4865
- Resolves: OPENJDK-4902
* Mon Jul 13 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-3.0
- Add 25u backports of JDK-8347901 & JDK-8378713 C2 performance fixes
- Resolves: OPENJDK-4885
* Thu Jul 02 2026 Andrea Bolognani <abologna@redhat.com> - 1:25.0.3.0.9-3.0
- Strip %%{dist} more thoroughly
- Resolves: OPENJDK-4881
* Fri Jun 26 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-2.0
- Port ForFiles patch to RHEL and update to use standard function naming format
- Remove macro references in comments where possible (%dnl not compatible enough yet)
- Drop unused tagsuffix line which causes issues on older RPM versions without %dnl
- Cleanup RPM only macros unused in the portable spec file
- Move version information and core NVR definitions back towards the top of the file
- Specify portablerelease and rpmrelease (always 0 for portables) in the Release field
- Related: OPENJDK-4872
- Resolves: OPENJDK-4873
- Resolves: OPENJDK-4875
- Resolves: OPENJDK-4876
* Fri Jun 26 2026 Jiri Vanek <jvanek@redhat.com> - 1:25.0.3.0.9-2
- Redeclared ForFiles release sections as %%nil no longer works with %%1
- RPM 4.19 no longer accept our double percentaged %%{nil} passed to %%{1}
- so we have to pass in "" but evaluate it, otherwise files record will include it
- Resolves: OPENJDK-4872
* Sat Apr 18 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.3.0.9-1
- Update to jdk-25.0.3+9 (GA)
- Update release notes to 25.0.3+9
- Update FIPS patch to 57722aab802 version synced with 25.0.3+8
- Drop local libpng patches now JDK-8372534, JDK-8375063 & JDK-8377526 are included upstream
- Drop local HarfBuzz patch now JDK-8375057 is included upstream
- Bump freetype version to 2.14.2 following JDK-8373290 & JDK-8379158
- Bump giflib version to 6.1.2 following JDK-8379256 & JDK-8380078
- Bump libpng version to 1.6.57 following JDK-8380959 & JDK-8382047
- Bump zlib version to 1.3.2 following JDK-8378631
- Add JDK-8375294 EOPNOTSUPP patch ahead of 25.0.4
- ** This tarball is embargoed until 2026-04-21 @ 1pm PT. **
- Resolves: OPENJDK-4634
- Resolves: OPENJDK-4656
- Resolves: OPENJDK-4607
- Resolves: OPENJDK-4675
* Tue Mar 03 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-3
- Update FIPS patch to e55ada9353e to include the fix for the too restrictive provider lockdown
- Fix FIPS issue list to represent the new 25u version
- Add JDK-8375063 libpng 1.6.54 ahead of 25.0.3
- Add JDK-8375057 harfbuzz 12.3.2 ahead of 25.0.3
- Add JDK-8377526 libpng 1.6.55 ahead of 25.0.3
- Bump libpng version to 1.6.55 following JDK-8375063 & JDK-8377526
- Bump harfbuzz version to 12.3.2 following JDK-8375057
- Resolves: OPENJDK-4570
- Resolves: OPENJDK-4304
- Resolves: OPENJDK-4524
- Resolves: OPENJDK-4544
- Resolves: OPENJDK-4553
* Mon Jan 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-2
- Add JDK-8372534 libpng 1.6.51 ahead of 25.0.3
- Bump libpng version to 1.6.51 following JDK-8372534
- Add CVEs for 25.0.2 to NEWS
- Correct version and date for this upcoming release in NEWS
- Related: OPENJDK-4359
* Mon Jan 12 2026 Andrew Hughes <gnu.andrew@redhat.com> - 1:25.0.2.0.10-1
- Update to jdk-25.0.2+10 (GA)
- Update release notes to 25.0.2+10
- Add test to ensure blocked.certs is valid (OPENJDK-4362)
- ** This tarball is embargoed until 2026-01-20 @ 1pm PT. **
- Resolves: OPENJDK-4359
- Resolves: OPENJDK-4362
* Tue Dec 02 2025 Severin Gehwolf <sgehwolf@redhat.com> - 1:25.0.1.0.8-2 * Tue Dec 02 2025 Severin Gehwolf <sgehwolf@redhat.com> - 1:25.0.1.0.8-2
- Switch from static-libs-image to static-libs-graal-image to avoid large unneeded libjvm.a - Switch from static-libs-image to static-libs-graal-image to avoid large unneeded libjvm.a
- Resolves: OPENJDK-4197 - Resolves: OPENJDK-4197

View File

@ -0,0 +1,772 @@
From 09853461a6896ab1f15469c753c21ca212e7e650 Mon Sep 17 00:00:00 2001
From: duke <duke@openjdk.org>
Date: Tue, 7 Apr 2026 15:14:53 +0000
Subject: [PATCH 1/2] Backport ed70910b0f3e1b19d915ec13ac3434407d01bc5d
---
src/hotspot/share/opto/callnode.cpp | 53 +++++++-
src/hotspot/share/opto/callnode.hpp | 29 ++++-
src/hotspot/share/opto/classes.hpp | 2 +
src/hotspot/share/opto/compile.cpp | 19 +++
src/hotspot/share/opto/divnode.cpp | 158 ++++++++++--------------
src/hotspot/share/opto/divnode.hpp | 35 +++---
src/hotspot/share/opto/graphKit.cpp | 29 +++--
src/hotspot/share/opto/graphKit.hpp | 1 +
src/hotspot/share/opto/library_call.cpp | 2 +-
src/hotspot/share/opto/macro.cpp | 15 +--
src/hotspot/share/opto/multnode.cpp | 13 ++
src/hotspot/share/opto/multnode.hpp | 46 +++++++
src/hotspot/share/opto/node.cpp | 12 +-
src/hotspot/share/opto/node.hpp | 5 +-
src/hotspot/share/opto/parse2.cpp | 8 +-
15 files changed, 282 insertions(+), 145 deletions(-)
diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
index 6f13ce0f809..fc4b0c35dff 100644
--- a/src/hotspot/share/opto/callnode.cpp
+++ b/src/hotspot/share/opto/callnode.cpp
@@ -935,7 +935,7 @@ Node *CallNode::result_cast() {
}
-void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) {
+void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) const {
projs->fallthrough_proj = nullptr;
projs->fallthrough_catchproj = nullptr;
projs->fallthrough_ioproj = nullptr;
@@ -1319,6 +1319,57 @@ void CallLeafVectorNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_
//=============================================================================
+bool CallLeafPureNode::is_unused() const {
+ return proj_out_or_null(TypeFunc::Parms) == nullptr;
+}
+
+bool CallLeafPureNode::is_dead() const {
+ return proj_out_or_null(TypeFunc::Control) == nullptr;
+}
+
+/* We make a tuple of the global input state + TOP for the output values.
+ * We use this to delete a pure function that is not used: by replacing the call with
+ * such a tuple, we let output Proj's idealization pick the corresponding input of the
+ * pure call, so jumping over it, and effectively, removing the call from the graph.
+ * This avoids doing the graph surgery manually, but leaves that to IGVN
+ * that is specialized for doing that right. We need also tuple components for output
+ * values of the function to respect the return arity, and in case there is a projection
+ * that would pick an output (which shouldn't happen at the moment).
+ */
+TupleNode* CallLeafPureNode::make_tuple_of_input_state_and_top_return_values(const Compile* C) const {
+ // Transparently propagate input state but parameters
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ in(TypeFunc::Control),
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr));
+
+ // And add TOPs for the return values
+ for (uint i = TypeFunc::Parms; i < tf()->range()->cnt(); i++) {
+ tuple->set_req(i, C->top());
+ }
+
+ return tuple;
+}
+
+Node* CallLeafPureNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (is_dead()) {
+ return nullptr;
+ }
+
+ // We need to wait until IGVN because during parsing, usages might still be missing
+ // and we would remove the call immediately.
+ if (can_reshape && is_unused()) {
+ // The result is not used. We remove the call by replacing it with a tuple, that
+ // is later disintegrated by the projections.
+ return make_tuple_of_input_state_and_top_return_values(phase->C);
+ }
+
+ return CallRuntimeNode::Ideal(phase, can_reshape);
+}
+
#ifndef PRODUCT
void CallLeafNode::dump_spec(outputStream *st) const {
st->print("# ");
diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp
index 213fbda4e89..2462a88143f 100644
--- a/src/hotspot/share/opto/callnode.hpp
+++ b/src/hotspot/share/opto/callnode.hpp
@@ -752,7 +752,7 @@ class CallNode : public SafePointNode {
// Collect all the interesting edges from a call for use in
// replacing the call by something else. Used by macro expansion
// and the late inlining support.
- void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true);
+ void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true) const;
virtual uint match_edge(uint idx) const;
@@ -928,6 +928,33 @@ class CallLeafNode : public CallRuntimeNode {
#endif
};
+/* A pure function call, they are assumed not to be safepoints, not to read or write memory,
+ * have no exception... They just take parameters, return a value without side effect. It is
+ * always correct to create some, or remove them, if the result is not used.
+ *
+ * They still have control input to allow easy lowering into other kind of calls that require
+ * a control, but this is more a technical than a moral constraint.
+ *
+ * Pure calls must have only control and data input and output: I/O, Memory and so on must be top.
+ * Nevertheless, pure calls can typically be expensive math operations so care must be taken
+ * when letting the node float.
+ */
+class CallLeafPureNode : public CallLeafNode {
+protected:
+ bool is_unused() const;
+ bool is_dead() const;
+ TupleNode* make_tuple_of_input_state_and_top_return_values(const Compile* C) const;
+
+public:
+ CallLeafPureNode(const TypeFunc* tf, address addr, const char* name,
+ const TypePtr* adr_type)
+ : CallLeafNode(tf, addr, name, adr_type) {
+ init_class_id(Class_CallLeafPure);
+ }
+ int Opcode() const override;
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+};
+
//------------------------------CallLeafNoFPNode-------------------------------
// CallLeafNode, not using floating point or using it in the same manner as
// the generated code
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index bc259eed2d1..587d5fad8f2 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -61,6 +61,7 @@ macro(CallDynamicJava)
macro(CallJava)
macro(CallLeaf)
macro(CallLeafNoFP)
+macro(CallLeafPure)
macro(CallLeafVector)
macro(CallRuntime)
macro(CallStaticJava)
@@ -372,6 +373,7 @@ macro(SubI)
macro(SubL)
macro(TailCall)
macro(TailJump)
+macro(Tuple)
macro(MacroLogicV)
macro(ThreadLocal)
macro(Unlock)
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 2b956dcb5d8..9f7f48b9a34 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -3298,6 +3298,25 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f
case Op_Opaque1: // Remove Opaque Nodes before matching
n->subsume_by(n->in(1), this);
break;
+ case Op_CallLeafPure: {
+ // If the pure call is not supported, then lower to a CallLeaf.
+ if (!Matcher::match_rule_supported(Op_CallLeafPure)) {
+ CallNode* call = n->as_Call();
+ CallNode* new_call = new CallLeafNode(call->tf(), call->entry_point(),
+ call->_name, TypeRawPtr::BOTTOM);
+ new_call->init_req(TypeFunc::Control, call->in(TypeFunc::Control));
+ new_call->init_req(TypeFunc::I_O, C->top());
+ new_call->init_req(TypeFunc::Memory, C->top());
+ new_call->init_req(TypeFunc::ReturnAdr, C->top());
+ new_call->init_req(TypeFunc::FramePtr, C->top());
+ for (unsigned int i = TypeFunc::Parms; i < call->tf()->domain()->cnt(); i++) {
+ new_call->init_req(i, call->in(i));
+ }
+ n->subsume_by(new_call, this);
+ }
+ frc.inc_call_count();
+ break;
+ }
case Op_CallStaticJava:
case Op_CallJava:
case Op_CallDynamicJava:
diff --git a/src/hotspot/share/opto/divnode.cpp b/src/hotspot/share/opto/divnode.cpp
index a70194274a7..5dd8be877ff 100644
--- a/src/hotspot/share/opto/divnode.cpp
+++ b/src/hotspot/share/opto/divnode.cpp
@@ -42,19 +42,19 @@
#include <math.h>
-ModFloatingNode::ModFloatingNode(Compile* C, const TypeFunc* tf, const char* name) : CallLeafNode(tf, nullptr, name, TypeRawPtr::BOTTOM) {
+ModFloatingNode::ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name) : CallLeafPureNode(tf, addr, name, TypeRawPtr::BOTTOM) {
add_flag(Flag_is_macro);
C->add_macro_node(this);
}
-ModDNode::ModDNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::Math_DD_D_Type(), "drem") {
+ModDNode::ModDNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::drem), "drem") {
init_req(TypeFunc::Parms + 0, a);
init_req(TypeFunc::Parms + 1, C->top());
init_req(TypeFunc::Parms + 2, b);
init_req(TypeFunc::Parms + 3, C->top());
}
-ModFNode::ModFNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::modf_Type(), "frem") {
+ModFNode::ModFNode(Compile* C, Node* a, Node* b) : ModFloatingNode(C, OptoRuntime::modf_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::frem), "frem") {
init_req(TypeFunc::Parms + 0, a);
init_req(TypeFunc::Parms + 1, b);
}
@@ -1516,137 +1516,109 @@ const Type* UModLNode::Value(PhaseGVN* phase) const {
return unsigned_mod_value<TypeLong, julong, jlong>(phase, this);
}
-Node* ModFNode::Ideal(PhaseGVN* phase, bool can_reshape) {
- if (!can_reshape) {
- return nullptr;
- }
- PhaseIterGVN* igvn = phase->is_IterGVN();
-
- bool result_is_unused = proj_out_or_null(TypeFunc::Parms) == nullptr;
- bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr;
- if (result_is_unused && not_dead) {
- return replace_with_con(igvn, TypeF::make(0.));
- }
-
- // Either input is TOP ==> the result is TOP
- const Type* t1 = phase->type(dividend());
- const Type* t2 = phase->type(divisor());
- if (t1 == Type::TOP || t2 == Type::TOP) {
- return phase->C->top();
- }
-
+const Type* ModFNode::get_result_if_constant(const Type* dividend, const Type* divisor) const {
// If either number is not a constant, we know nothing.
- if ((t1->base() != Type::FloatCon) || (t2->base() != Type::FloatCon)) {
+ if ((dividend->base() != Type::FloatCon) || (divisor->base() != Type::FloatCon)) {
return nullptr; // note: x%x can be either NaN or 0
}
- float f1 = t1->getf();
- float f2 = t2->getf();
- jint x1 = jint_cast(f1); // note: *(int*)&f1, not just (int)f1
- jint x2 = jint_cast(f2);
+ float dividend_f = dividend->getf();
+ float divisor_f = divisor->getf();
+ jint dividend_i = jint_cast(dividend_f); // note: *(int*)&f1, not just (int)f1
+ jint divisor_i = jint_cast(divisor_f);
// If either is a NaN, return an input NaN
- if (g_isnan(f1)) {
- return replace_with_con(igvn, t1);
+ if (g_isnan(dividend_f)) {
+ return dividend;
}
- if (g_isnan(f2)) {
- return replace_with_con(igvn, t2);
+ if (g_isnan(divisor_f)) {
+ return divisor;
}
// If an operand is infinity or the divisor is +/- zero, punt.
- if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jint) {
+ if (!g_isfinite(dividend_f) || !g_isfinite(divisor_f) || divisor_i == 0 || divisor_i == min_jint) {
return nullptr;
}
// We must be modulo'ing 2 float constants.
// Make sure that the sign of the fmod is equal to the sign of the dividend
- jint xr = jint_cast(fmod(f1, f2));
- if ((x1 ^ xr) < 0) {
+ jint xr = jint_cast(fmod(dividend_f, divisor_f));
+ if ((dividend_i ^ xr) < 0) {
xr ^= min_jint;
}
- return replace_with_con(igvn, TypeF::make(jfloat_cast(xr)));
+ return TypeF::make(jfloat_cast(xr));
}
-Node* ModDNode::Ideal(PhaseGVN* phase, bool can_reshape) {
- if (!can_reshape) {
- return nullptr;
- }
- PhaseIterGVN* igvn = phase->is_IterGVN();
-
- bool result_is_unused = proj_out_or_null(TypeFunc::Parms) == nullptr;
- bool not_dead = proj_out_or_null(TypeFunc::Control) != nullptr;
- if (result_is_unused && not_dead) {
- return replace_with_con(igvn, TypeD::make(0.));
- }
-
- // Either input is TOP ==> the result is TOP
- const Type* t1 = phase->type(dividend());
- const Type* t2 = phase->type(divisor());
- if (t1 == Type::TOP || t2 == Type::TOP) {
- return nullptr;
- }
-
+const Type* ModDNode::get_result_if_constant(const Type* dividend, const Type* divisor) const {
// If either number is not a constant, we know nothing.
- if ((t1->base() != Type::DoubleCon) || (t2->base() != Type::DoubleCon)) {
+ if ((dividend->base() != Type::DoubleCon) || (divisor->base() != Type::DoubleCon)) {
return nullptr; // note: x%x can be either NaN or 0
}
- double f1 = t1->getd();
- double f2 = t2->getd();
- jlong x1 = jlong_cast(f1); // note: *(long*)&f1, not just (long)f1
- jlong x2 = jlong_cast(f2);
+ double dividend_d = dividend->getd();
+ double divisor_d = divisor->getd();
+ jlong dividend_l = jlong_cast(dividend_d); // note: *(long*)&f1, not just (long)f1
+ jlong divisor_l = jlong_cast(divisor_d);
// If either is a NaN, return an input NaN
- if (g_isnan(f1)) {
- return replace_with_con(igvn, t1);
+ if (g_isnan(dividend_d)) {
+ return dividend;
}
- if (g_isnan(f2)) {
- return replace_with_con(igvn, t2);
+ if (g_isnan(divisor_d)) {
+ return divisor;
}
// If an operand is infinity or the divisor is +/- zero, punt.
- if (!g_isfinite(f1) || !g_isfinite(f2) || x2 == 0 || x2 == min_jlong) {
+ if (!g_isfinite(dividend_d) || !g_isfinite(divisor_d) || divisor_l == 0 || divisor_l == min_jlong) {
return nullptr;
}
// We must be modulo'ing 2 double constants.
// Make sure that the sign of the fmod is equal to the sign of the dividend
- jlong xr = jlong_cast(fmod(f1, f2));
- if ((x1 ^ xr) < 0) {
+ jlong xr = jlong_cast(fmod(dividend_d, divisor_d));
+ if ((dividend_l ^ xr) < 0) {
xr ^= min_jlong;
}
- return replace_with_con(igvn, TypeD::make(jdouble_cast(xr)));
+ return TypeD::make(jdouble_cast(xr));
}
-Node* ModFloatingNode::replace_with_con(PhaseIterGVN* phase, const Type* con) {
- Compile* C = phase->C;
- Node* con_node = phase->makecon(con);
- CallProjections projs;
- extract_projections(&projs, false, false);
- phase->replace_node(projs.fallthrough_proj, in(TypeFunc::Control));
- if (projs.fallthrough_catchproj != nullptr) {
- phase->replace_node(projs.fallthrough_catchproj, in(TypeFunc::Control));
- }
- if (projs.fallthrough_memproj != nullptr) {
- phase->replace_node(projs.fallthrough_memproj, in(TypeFunc::Memory));
- }
- if (projs.catchall_memproj != nullptr) {
- phase->replace_node(projs.catchall_memproj, C->top());
- }
- if (projs.fallthrough_ioproj != nullptr) {
- phase->replace_node(projs.fallthrough_ioproj, in(TypeFunc::I_O));
- }
- assert(projs.catchall_ioproj == nullptr, "no exceptions from floating mod");
- assert(projs.catchall_catchproj == nullptr, "no exceptions from floating mod");
- if (projs.resproj != nullptr) {
- phase->replace_node(projs.resproj, con_node);
+Node* ModFloatingNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (can_reshape) {
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+
+ // Either input is TOP ==> the result is TOP
+ const Type* dividend_type = phase->type(dividend());
+ const Type* divisor_type = phase->type(divisor());
+ if (dividend_type == Type::TOP || divisor_type == Type::TOP) {
+ return phase->C->top();
+ }
+ const Type* constant_result = get_result_if_constant(dividend_type, divisor_type);
+ if (constant_result != nullptr) {
+ return make_tuple_of_input_state_and_constant_result(igvn, constant_result);
+ }
}
- phase->replace_node(this, C->top());
- C->remove_macro_node(this);
- disconnect_inputs(C);
- return nullptr;
+
+ return CallLeafPureNode::Ideal(phase, can_reshape);
+}
+
+/* Give a tuple node for ::Ideal to return, made of the input state (control to return addr)
+ * and the given constant result. Idealization of projections will make sure to transparently
+ * propagate the input state and replace the result by the said constant.
+ */
+TupleNode* ModFloatingNode::make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const {
+ Node* con_node = phase->makecon(con);
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ in(TypeFunc::Control),
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr),
+ con_node);
+
+ return tuple;
}
//=============================================================================
diff --git a/src/hotspot/share/opto/divnode.hpp b/src/hotspot/share/opto/divnode.hpp
index 127e2431b0b..b13460c89f5 100644
--- a/src/hotspot/share/opto/divnode.hpp
+++ b/src/hotspot/share/opto/divnode.hpp
@@ -156,40 +156,45 @@ class ModLNode : public Node {
};
// Base class for float and double modulus
-class ModFloatingNode : public CallLeafNode {
+class ModFloatingNode : public CallLeafPureNode {
+ TupleNode* make_tuple_of_input_state_and_constant_result(PhaseIterGVN* phase, const Type* con) const;
+
protected:
- Node* replace_with_con(PhaseIterGVN* phase, const Type* con);
+ virtual Node* dividend() const = 0;
+ virtual Node* divisor() const = 0;
+ virtual const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const = 0;
public:
- ModFloatingNode(Compile* C, const TypeFunc* tf, const char *name);
+ ModFloatingNode(Compile* C, const TypeFunc* tf, address addr, const char* name);
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
};
// Float Modulus
class ModFNode : public ModFloatingNode {
private:
- Node* dividend() const { return in(TypeFunc::Parms + 0); }
- Node* divisor() const { return in(TypeFunc::Parms + 1); }
+ Node* dividend() const override { return in(TypeFunc::Parms + 0); }
+ Node* divisor() const override { return in(TypeFunc::Parms + 1); }
+ const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
public:
ModFNode(Compile* C, Node* a, Node* b);
- virtual int Opcode() const;
- virtual uint ideal_reg() const { return Op_RegF; }
- virtual uint size_of() const { return sizeof(*this); }
- virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ int Opcode() const override;
+ uint ideal_reg() const override { return Op_RegF; }
+ uint size_of() const override { return sizeof(*this); }
};
// Double Modulus
class ModDNode : public ModFloatingNode {
private:
- Node* dividend() const { return in(TypeFunc::Parms + 0); }
- Node* divisor() const { return in(TypeFunc::Parms + 2); }
+ Node* dividend() const override { return in(TypeFunc::Parms + 0); }
+ Node* divisor() const override { return in(TypeFunc::Parms + 2); }
+ const Type* get_result_if_constant(const Type* dividend, const Type* divisor) const override;
public:
ModDNode(Compile* C, Node* a, Node* b);
- virtual int Opcode() const;
- virtual uint ideal_reg() const { return Op_RegD; }
- virtual uint size_of() const { return sizeof(*this); }
- virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ int Opcode() const override;
+ uint ideal_reg() const override { return Op_RegD; }
+ uint size_of() const override { return sizeof(*this); }
};
//------------------------------UModINode---------------------------------------
diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp
index 20feca26ede..1b8b7008578 100644
--- a/src/hotspot/share/opto/graphKit.cpp
+++ b/src/hotspot/share/opto/graphKit.cpp
@@ -1880,14 +1880,20 @@ Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_p
// after the call, if this call has restricted memory effects.
Node* GraphKit::set_predefined_input_for_runtime_call(SafePointNode* call, Node* narrow_mem) {
// Set fixed predefined input arguments
- Node* memory = reset_memory();
- Node* m = narrow_mem == nullptr ? memory : narrow_mem;
- call->init_req( TypeFunc::Control, control() );
- call->init_req( TypeFunc::I_O, top() ); // does no i/o
- call->init_req( TypeFunc::Memory, m ); // may gc ptrs
- call->init_req( TypeFunc::FramePtr, frameptr() );
- call->init_req( TypeFunc::ReturnAdr, top() );
- return memory;
+ call->init_req(TypeFunc::Control, control());
+ call->init_req(TypeFunc::I_O, top()); // does no i/o
+ call->init_req(TypeFunc::ReturnAdr, top());
+ if (call->is_CallLeafPure()) {
+ call->init_req(TypeFunc::Memory, top());
+ call->init_req(TypeFunc::FramePtr, top());
+ return nullptr;
+ } else {
+ Node* memory = reset_memory();
+ Node* m = narrow_mem == nullptr ? memory : narrow_mem;
+ call->init_req(TypeFunc::Memory, m); // may gc ptrs
+ call->init_req(TypeFunc::FramePtr, frameptr());
+ return memory;
+ }
}
//-------------------set_predefined_output_for_runtime_call--------------------
@@ -1905,6 +1911,11 @@ void GraphKit::set_predefined_output_for_runtime_call(Node* call,
const TypePtr* hook_mem) {
// no i/o
set_control(_gvn.transform( new ProjNode(call,TypeFunc::Control) ));
+ if (call->is_CallLeafPure()) {
+ // Pure function have only control (for now) and data output, in particular
+ // they don't touch the memory, so we don't want a memory proj that is set after.
+ return;
+ }
if (keep_mem) {
// First clone the existing memory state
set_all_memory(keep_mem);
@@ -2491,6 +2502,8 @@ Node* GraphKit::make_runtime_call(int flags,
} else if (flags & RC_VECTOR){
uint num_bits = call_type->range()->field_at(TypeFunc::Parms)->is_vect()->length_in_bytes() * BitsPerByte;
call = new CallLeafVectorNode(call_type, call_addr, call_name, adr_type, num_bits);
+ } else if (flags & RC_PURE) {
+ call = new CallLeafPureNode(call_type, call_addr, call_name, adr_type);
} else {
call = new CallLeafNode(call_type, call_addr, call_name, adr_type);
}
diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp
index 28773d75333..806a211d7e2 100644
--- a/src/hotspot/share/opto/graphKit.hpp
+++ b/src/hotspot/share/opto/graphKit.hpp
@@ -784,6 +784,7 @@ class GraphKit : public Phase {
RC_NARROW_MEM = 16, // input memory is same as output
RC_UNCOMMON = 32, // freq. expected to be like uncommon trap
RC_VECTOR = 64, // CallLeafVectorNode
+ RC_PURE = 128, // CallLeaf is pure
RC_LEAF = 0 // null value: no flags set
};
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index f74af38387c..12960d101a8 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -1802,7 +1802,7 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
Node* b = (call_type == OptoRuntime::Math_DD_D_Type()) ? argument(2) : nullptr;
const TypePtr* no_memory_effects = nullptr;
- Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
+ Node* trig = make_runtime_call(RC_LEAF | RC_PURE, call_type, funcAddr, funcName,
no_memory_effects,
a, top(), b, b ? top() : nullptr);
Node* value = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index acf1dbabf19..aafc5d3c170 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -2638,17 +2638,14 @@ bool PhaseMacroExpand::expand_macro_nodes() {
switch (n->Opcode()) {
case Op_ModD:
case Op_ModF: {
- bool is_drem = n->Opcode() == Op_ModD;
CallNode* mod_macro = n->as_Call();
- CallNode* call = new CallLeafNode(mod_macro->tf(),
- is_drem ? CAST_FROM_FN_PTR(address, SharedRuntime::drem)
- : CAST_FROM_FN_PTR(address, SharedRuntime::frem),
- is_drem ? "drem" : "frem", TypeRawPtr::BOTTOM);
+ CallNode* call = new CallLeafPureNode(mod_macro->tf(), mod_macro->entry_point(),
+ mod_macro->_name, TypeRawPtr::BOTTOM);
call->init_req(TypeFunc::Control, mod_macro->in(TypeFunc::Control));
- call->init_req(TypeFunc::I_O, mod_macro->in(TypeFunc::I_O));
- call->init_req(TypeFunc::Memory, mod_macro->in(TypeFunc::Memory));
- call->init_req(TypeFunc::ReturnAdr, mod_macro->in(TypeFunc::ReturnAdr));
- call->init_req(TypeFunc::FramePtr, mod_macro->in(TypeFunc::FramePtr));
+ call->init_req(TypeFunc::I_O, C->top());
+ call->init_req(TypeFunc::Memory, C->top());
+ call->init_req(TypeFunc::ReturnAdr, C->top());
+ call->init_req(TypeFunc::FramePtr, C->top());
for (unsigned int i = 0; i < mod_macro->tf()->domain()->cnt() - TypeFunc::Parms; i++) {
call->init_req(TypeFunc::Parms + i, mod_macro->in(TypeFunc::Parms + i));
}
diff --git a/src/hotspot/share/opto/multnode.cpp b/src/hotspot/share/opto/multnode.cpp
index 736e84315ee..f429d5daac0 100644
--- a/src/hotspot/share/opto/multnode.cpp
+++ b/src/hotspot/share/opto/multnode.cpp
@@ -120,6 +120,10 @@ const TypePtr *ProjNode::adr_type() const {
if (bottom_type() == Type::MEMORY) {
// in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
Node* ctrl = in(0);
+ if (ctrl->Opcode() == Op_Tuple) {
+ // Jumping over Tuples: the i-th projection of a Tuple is the i-th input of the Tuple.
+ ctrl = ctrl->in(_con);
+ }
if (ctrl == nullptr) return nullptr; // node is dead
const TypePtr* adr_type = ctrl->adr_type();
#ifdef ASSERT
@@ -163,6 +167,15 @@ void ProjNode::check_con() const {
assert(_con < t->is_tuple()->cnt(), "ProjNode::_con must be in range");
}
+//------------------------------Identity---------------------------------------
+Node* ProjNode::Identity(PhaseGVN* phase) {
+ if (in(0) != nullptr && in(0)->Opcode() == Op_Tuple) {
+ // Jumping over Tuples: the i-th projection of a Tuple is the i-th input of the Tuple.
+ return in(0)->in(_con);
+ }
+ return this;
+}
+
//------------------------------Value------------------------------------------
const Type* ProjNode::Value(PhaseGVN* phase) const {
if (in(0) == nullptr) return Type::TOP;
diff --git a/src/hotspot/share/opto/multnode.hpp b/src/hotspot/share/opto/multnode.hpp
index dff2caed38d..834dcfdca6d 100644
--- a/src/hotspot/share/opto/multnode.hpp
+++ b/src/hotspot/share/opto/multnode.hpp
@@ -82,6 +82,7 @@ class ProjNode : public Node {
virtual const Type *bottom_type() const;
virtual const TypePtr *adr_type() const;
virtual bool pinned() const;
+ virtual Node* Identity(PhaseGVN* phase);
virtual const Type* Value(PhaseGVN* phase) const;
virtual uint ideal_reg() const;
virtual const RegMask &out_RegMask() const;
@@ -105,4 +106,49 @@ class ProjNode : public Node {
ProjNode* other_if_proj() const;
};
+/* Tuples are used to avoid manual graph surgery. When a node with Proj outputs (such as a call)
+ * must be removed and its ouputs replaced by its input, or some other value, we can make its
+ * ::Ideal return a tuple of what we want for each output: the ::Identity of output Proj will
+ * take care to jump over the Tuple and directly pick up the right input of the Tuple.
+ *
+ * For instance, if a function call is proven to have no side effect and return the constant 0,
+ * we can replace it with the 6-tuple:
+ * (control input, IO input, memory input, frame ptr input, return addr input, Con:0)
+ * all the output projections will pick up the input of the now gone call, except for the result
+ * projection that is replaced by 0.
+ *
+ * Using TupleNode avoid manual graph surgery and leave that to our expert surgeon: IGVN.
+ * Since the user of a Tuple are expected to be Proj, when creating a tuple during idealization,
+ * the output Proj should be enqueued for IGVN immediately after, and the tuple should not survive
+ * after the current IGVN.
+ */
+class TupleNode : public MultiNode {
+ const TypeTuple* _tf;
+
+ template <typename... NN>
+ static void make_helper(TupleNode* tn, uint i, Node* node, NN... nn) {
+ tn->set_req(i, node);
+ make_helper(tn, i + 1, nn...);
+ }
+
+ static void make_helper(TupleNode*, uint) {}
+
+public:
+ TupleNode(const TypeTuple* tf) : MultiNode(tf->cnt()), _tf(tf) {}
+
+ int Opcode() const override;
+ const Type* bottom_type() const override { return _tf; }
+
+ /* Give as many `Node*` as you want in the `nn` pack:
+ * TupleNode::make(tf, input1)
+ * TupleNode::make(tf, input1, input2, input3, input4)
+ */
+ template <typename... NN>
+ static TupleNode* make(const TypeTuple* tf, NN... nn) {
+ TupleNode* tn = new TupleNode(tf);
+ make_helper(tn, 0, nn...);
+ return tn;
+ }
+};
+
#endif // SHARE_OPTO_MULTNODE_HPP
diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp
index 8f6c67c16f5..5ecc038954d 100644
--- a/src/hotspot/share/opto/node.cpp
+++ b/src/hotspot/share/opto/node.cpp
@@ -2946,23 +2946,13 @@ bool Node::is_dead_loop_safe() const {
bool Node::is_div_or_mod(BasicType bt) const { return Opcode() == Op_Div(bt) || Opcode() == Op_Mod(bt) ||
Opcode() == Op_UDiv(bt) || Opcode() == Op_UMod(bt); }
-bool Node::is_pure_function() const {
- switch (Opcode()) {
- case Op_ModD:
- case Op_ModF:
- return true;
- default:
- return false;
- }
-}
-
// `maybe_pure_function` is assumed to be the input of `this`. This is a bit redundant,
// but we already have and need maybe_pure_function in all the call sites, so
// it makes it obvious that the `maybe_pure_function` is the same node as in the caller,
// while it takes more thinking to realize that a locally computed in(0) must be equal to
// the local in the caller.
bool Node::is_data_proj_of_pure_function(const Node* maybe_pure_function) const {
- return Opcode() == Op_Proj && as_Proj()->_con == TypeFunc::Parms && maybe_pure_function->is_pure_function();
+ return Opcode() == Op_Proj && as_Proj()->_con == TypeFunc::Parms && maybe_pure_function->is_CallLeafPure();
}
//=============================================================================
diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp
index 2bbb10879f5..dc0ac474c4b 100644
--- a/src/hotspot/share/opto/node.hpp
+++ b/src/hotspot/share/opto/node.hpp
@@ -54,6 +54,7 @@ class CallDynamicJavaNode;
class CallJavaNode;
class CallLeafNode;
class CallLeafNoFPNode;
+class CallLeafPureNode;
class CallNode;
class CallRuntimeNode;
class CallStaticJavaNode;
@@ -673,6 +674,7 @@ class Node {
DEFINE_CLASS_ID(CallRuntime, Call, 1)
DEFINE_CLASS_ID(CallLeaf, CallRuntime, 0)
DEFINE_CLASS_ID(CallLeafNoFP, CallLeaf, 0)
+ DEFINE_CLASS_ID(CallLeafPure, CallLeaf, 1)
DEFINE_CLASS_ID(Allocate, Call, 2)
DEFINE_CLASS_ID(AllocateArray, Allocate, 0)
DEFINE_CLASS_ID(AbstractLock, Call, 3)
@@ -907,6 +909,7 @@ class Node {
DEFINE_CLASS_QUERY(CallJava)
DEFINE_CLASS_QUERY(CallLeaf)
DEFINE_CLASS_QUERY(CallLeafNoFP)
+ DEFINE_CLASS_QUERY(CallLeafPure)
DEFINE_CLASS_QUERY(CallRuntime)
DEFINE_CLASS_QUERY(CallStaticJava)
DEFINE_CLASS_QUERY(Catch)
@@ -1289,8 +1292,6 @@ class Node {
bool is_div_or_mod(BasicType bt) const;
- bool is_pure_function() const;
-
bool is_data_proj_of_pure_function(const Node* maybe_pure_function) const;
//----------------- Printing, etc
diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp
index 1a4c3c91c4f..04b6e49b620 100644
--- a/src/hotspot/share/opto/parse2.cpp
+++ b/src/hotspot/share/opto/parse2.cpp
@@ -1097,11 +1097,11 @@ void Parse::jump_switch_ranges(Node* key_val, SwitchRange *lo, SwitchRange *hi,
Node* Parse::floating_point_mod(Node* a, Node* b, BasicType type) {
assert(type == BasicType::T_FLOAT || type == BasicType::T_DOUBLE, "only float and double are floating points");
- CallNode* mod = type == BasicType::T_DOUBLE ? static_cast<CallNode*>(new ModDNode(C, a, b)) : new ModFNode(C, a, b);
+ CallLeafPureNode* mod = type == BasicType::T_DOUBLE ? static_cast<CallLeafPureNode*>(new ModDNode(C, a, b)) : new ModFNode(C, a, b);
- Node* prev_mem = set_predefined_input_for_runtime_call(mod);
- mod = _gvn.transform(mod)->as_Call();
- set_predefined_output_for_runtime_call(mod, prev_mem, TypeRawPtr::BOTTOM);
+ set_predefined_input_for_runtime_call(mod);
+ mod = _gvn.transform(mod)->as_CallLeafPure();
+ set_predefined_output_for_runtime_call(mod);
Node* result = _gvn.transform(new ProjNode(mod, TypeFunc::Parms + 0));
record_for_igvn(mod);
return result;
--
2.53.0

View File

@ -0,0 +1,626 @@
From 1f61b6754b5abce07db45fd385a19c2cf9296a08 Mon Sep 17 00:00:00 2001
From: Kangcheng Xu <kxu@redhat.com>
Date: Mon, 27 Apr 2026 10:14:39 -0400
Subject: [PATCH 2/2] Backport 7f631ea958e30246b927f3524f0fbf37334422b9
---
src/hotspot/share/opto/callnode.cpp | 175 ++++++++++++++
src/hotspot/share/opto/callnode.hpp | 17 ++
src/hotspot/share/opto/classes.hpp | 1 +
src/hotspot/share/opto/library_call.cpp | 62 +----
src/hotspot/share/opto/macro.cpp | 19 +-
.../intrinsics/math/PowDNodeTests.java | 218 ++++++++++++++++++
.../compiler/lib/ir_framework/IRNode.java | 11 +
7 files changed, 437 insertions(+), 66 deletions(-)
create mode 100644 test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
diff --git a/src/hotspot/share/opto/callnode.cpp b/src/hotspot/share/opto/callnode.cpp
index fc4b0c35dff..cb6cc2082b3 100644
--- a/src/hotspot/share/opto/callnode.cpp
+++ b/src/hotspot/share/opto/callnode.cpp
@@ -42,6 +42,7 @@
#include "opto/rootnode.hpp"
#include "opto/runtime.hpp"
#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
#include "utilities/powerOfTwo.hpp"
#include "code/vmreg.hpp"
@@ -1354,6 +1355,25 @@ TupleNode* CallLeafPureNode::make_tuple_of_input_state_and_top_return_values(con
return tuple;
}
+CallLeafPureNode* CallLeafPureNode::inline_call_leaf_pure_node(Node* control) const {
+ Node* top = Compile::current()->top();
+ if (control == nullptr) {
+ control = in(TypeFunc::Control);
+ }
+
+ CallLeafPureNode* call = new CallLeafPureNode(tf(), entry_point(), _name, nullptr);
+ call->init_req(TypeFunc::Control, control);
+ call->init_req(TypeFunc::I_O, top);
+ call->init_req(TypeFunc::Memory, top);
+ call->init_req(TypeFunc::ReturnAdr, top);
+ call->init_req(TypeFunc::FramePtr, top);
+ for (unsigned int i = 0; i < tf()->domain()->cnt() - TypeFunc::Parms; i++) {
+ call->init_req(TypeFunc::Parms + i, in(TypeFunc::Parms + i));
+ }
+
+ return call;
+}
+
Node* CallLeafPureNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (is_dead()) {
return nullptr;
@@ -2424,3 +2444,158 @@ bool CallNode::may_modify_arraycopy_helper(const TypeOopPtr* dest_t, const TypeO
return true;
}
+
+PowDNode::PowDNode(Compile* C, Node* base, Node* exp)
+ : CallLeafPureNode(
+ OptoRuntime::Math_DD_D_Type(),
+ StubRoutines::dpow() != nullptr ? StubRoutines::dpow() : CAST_FROM_FN_PTR(address, SharedRuntime::dpow),
+ "pow",
+ nullptr) {
+ add_flag(Flag_is_macro);
+ C->add_macro_node(this);
+
+ init_req(TypeFunc::Parms + 0, base);
+ init_req(TypeFunc::Parms + 1, C->top()); // double slot padding
+ init_req(TypeFunc::Parms + 2, exp);
+ init_req(TypeFunc::Parms + 3, C->top()); // double slot padding
+}
+
+const Type* PowDNode::Value(PhaseGVN* phase) const {
+ const Type* t_base = phase->type(base());
+ const Type* t_exp = phase->type(exp());
+
+ if (t_base == Type::TOP || t_exp == Type::TOP) {
+ return Type::TOP;
+ }
+
+ const TypeD* base_con = t_base->isa_double_constant();
+ const TypeD* exp_con = t_exp->isa_double_constant();
+ const TypeD* result_t = nullptr;
+
+ // constant folding: both inputs are constants
+ if (base_con != nullptr && exp_con != nullptr) {
+ result_t = TypeD::make(SharedRuntime::dpow(base_con->getd(), exp_con->getd()));
+ }
+
+ // Special cases when only the exponent is known:
+ if (exp_con != nullptr) {
+ double e = exp_con->getd();
+
+ // If the second argument is positive or negative zero, then the result is 1.0.
+ // i.e., pow(x, +/-0.0D) => 1.0
+ if (e == 0.0) { // true for both -0.0 and +0.0
+ result_t = TypeD::ONE;
+ }
+
+ // If the second argument is NaN, then the result is NaN.
+ // i.e., pow(x, NaN) => NaN
+ if (g_isnan(e)) {
+ result_t = TypeD::make(NAN);
+ }
+ }
+
+ if (result_t != nullptr) {
+ // We can't simply return a TypeD here, it must be a tuple type to be compatible with call nodes.
+ const Type** fields = TypeTuple::fields(2);
+ fields[TypeFunc::Parms + 0] = result_t;
+ fields[TypeFunc::Parms + 1] = Type::HALF;
+ return TypeTuple::make(TypeFunc::Parms + 2, fields);
+ }
+
+ return tf()->range();
+}
+
+Node* PowDNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (!can_reshape) {
+ return nullptr; // wait for igvn
+ }
+
+ PhaseIterGVN* igvn = phase->is_IterGVN();
+ Node* base = this->base();
+ Node* exp = this->exp();
+
+ const Type* t_exp = phase->type(exp);
+ const TypeD* exp_con = t_exp->isa_double_constant();
+
+ // Special cases when only the exponent is known:
+ if (exp_con != nullptr) {
+ double e = exp_con->getd();
+
+ // If the second argument is 1.0, then the result is the same as the first argument.
+ // i.e., pow(x, 1.0) => x
+ if (e == 1.0) {
+ return make_tuple_of_input_state_and_result(igvn, base);
+ }
+
+ // If the second argument is 2.0, then strength reduce to multiplications.
+ // i.e., pow(x, 2.0) => x * x
+ if (e == 2.0) {
+ Node* mul = igvn->transform(new MulDNode(base, base));
+ return make_tuple_of_input_state_and_result(igvn, mul);
+ }
+
+ // If the second argument is 0.5, the strength reduce to square roots.
+ // i.e., pow(x, 0.5) => sqrt(x) iff x > 0
+ if (e == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
+ Node* ctrl = in(TypeFunc::Control);
+ Node* zero = igvn->zerocon(T_DOUBLE);
+
+ // According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
+ // So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
+ // -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
+ Node* cmp = igvn->register_new_node_with_optimizer(new CmpDNode(base, zero));
+ Node* test = igvn->register_new_node_with_optimizer(new BoolNode(cmp, BoolTest::le));
+
+ IfNode* iff = new IfNode(ctrl, test, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
+ igvn->register_new_node_with_optimizer(iff);
+ Node* if_slow = igvn->register_new_node_with_optimizer(new IfTrueNode(iff)); // x <= 0
+ Node* if_fast = igvn->register_new_node_with_optimizer(new IfFalseNode(iff)); // x > 0
+
+ // slow path: call pow(x, 0.5)
+ Node* call = igvn->register_new_node_with_optimizer(inline_call_leaf_pure_node(if_slow));
+ Node* call_ctrl = igvn->register_new_node_with_optimizer(new ProjNode(call, TypeFunc::Control));
+ Node* call_result = igvn->register_new_node_with_optimizer(new ProjNode(call, TypeFunc::Parms + 0));
+
+ // fast path: sqrt(x)
+ Node* sqrt = igvn->register_new_node_with_optimizer(new SqrtDNode(igvn->C, if_fast, base));
+
+ // merge paths
+ RegionNode* region = new RegionNode(3);
+ igvn->register_new_node_with_optimizer(region);
+ region->init_req(1, call_ctrl); // slow path
+ region->init_req(2, if_fast); // fast path
+
+ PhiNode* phi = new PhiNode(region, Type::DOUBLE);
+ igvn->register_new_node_with_optimizer(phi);
+ phi->init_req(1, call_result); // slow: pow() result
+ phi->init_req(2, sqrt); // fast: sqrt() result
+
+ igvn->C->set_has_split_ifs(true); // Has chance for split-if optimization
+
+ return make_tuple_of_input_state_and_result(igvn, phi, region);
+ }
+ }
+
+ return CallLeafPureNode::Ideal(phase, can_reshape);
+}
+
+// We can't simply have Ideal() returning a Con or MulNode since the users are still expecting a Call node, but we could
+// produce a tuple that follows the same pattern so users can still get control, io, memory, etc..
+TupleNode* PowDNode::make_tuple_of_input_state_and_result(PhaseIterGVN* phase, Node* result, Node* control) {
+ if (control == nullptr) {
+ control = in(TypeFunc::Control);
+ }
+
+ Compile* C = phase->C;
+ C->remove_macro_node(this);
+ TupleNode* tuple = TupleNode::make(
+ tf()->range(),
+ control,
+ in(TypeFunc::I_O),
+ in(TypeFunc::Memory),
+ in(TypeFunc::FramePtr),
+ in(TypeFunc::ReturnAdr),
+ result,
+ C->top());
+ return tuple;
+}
diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp
index 2462a88143f..bb87746a3f6 100644
--- a/src/hotspot/share/opto/callnode.hpp
+++ b/src/hotspot/share/opto/callnode.hpp
@@ -953,6 +953,8 @@ class CallLeafPureNode : public CallLeafNode {
}
int Opcode() const override;
Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+
+ CallLeafPureNode* inline_call_leaf_pure_node(Node* control = nullptr) const;
};
//------------------------------CallLeafNoFPNode-------------------------------
@@ -1304,4 +1306,19 @@ class UnlockNode : public AbstractLockNode {
JVMState* dbg_jvms() const { return nullptr; }
#endif
};
+
+//------------------------------PowDNode--------------------------------------
+class PowDNode : public CallLeafPureNode {
+ TupleNode* make_tuple_of_input_state_and_result(PhaseIterGVN* phase, Node* result, Node* control = nullptr);
+
+public:
+ PowDNode(Compile* C, Node* base, Node* exp);
+ int Opcode() const override;
+ const Type* Value(PhaseGVN* phase) const override;
+ Node* Ideal(PhaseGVN* phase, bool can_reshape) override;
+
+ Node* base() const { return in(TypeFunc::Parms + 0); }
+ Node* exp() const { return in(TypeFunc::Parms + 2); }
+};
+
#endif // SHARE_OPTO_CALLNODE_HPP
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index 587d5fad8f2..b7ba16e99a0 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -283,6 +283,7 @@ macro(OpaqueZeroTripGuard)
macro(OpaqueNotNull)
macro(OpaqueInitializedAssertionPredicate)
macro(OpaqueTemplateAssertionPredicate)
+macro(PowD)
macro(ProfileBoolean)
macro(OrI)
macro(OrL)
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index 12960d101a8..6c71a61ba75 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -1817,61 +1817,17 @@ bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, c
//------------------------------inline_math_pow-----------------------------
bool LibraryCallKit::inline_math_pow() {
+ Node* base = argument(0);
Node* exp = argument(2);
- const TypeD* d = _gvn.type(exp)->isa_double_constant();
- if (d != nullptr) {
- if (d->getd() == 2.0) {
- // Special case: pow(x, 2.0) => x * x
- Node* base = argument(0);
- set_result(_gvn.transform(new MulDNode(base, base)));
- return true;
- } else if (d->getd() == 0.5 && Matcher::match_rule_supported(Op_SqrtD)) {
- // Special case: pow(x, 0.5) => sqrt(x)
- Node* base = argument(0);
- Node* zero = _gvn.zerocon(T_DOUBLE);
-
- RegionNode* region = new RegionNode(3);
- Node* phi = new PhiNode(region, Type::DOUBLE);
-
- Node* cmp = _gvn.transform(new CmpDNode(base, zero));
- // According to the API specs, pow(-0.0, 0.5) = 0.0 and sqrt(-0.0) = -0.0.
- // So pow(-0.0, 0.5) shouldn't be replaced with sqrt(-0.0).
- // -0.0/+0.0 are both excluded since floating-point comparison doesn't distinguish -0.0 from +0.0.
- Node* test = _gvn.transform(new BoolNode(cmp, BoolTest::le));
-
- Node* if_pow = generate_slow_guard(test, nullptr);
- Node* value_sqrt = _gvn.transform(new SqrtDNode(C, control(), base));
- phi->init_req(1, value_sqrt);
- region->init_req(1, control());
-
- if (if_pow != nullptr) {
- set_control(if_pow);
- address target = StubRoutines::dpow() != nullptr ? StubRoutines::dpow() :
- CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
- const TypePtr* no_memory_effects = nullptr;
- Node* trig = make_runtime_call(RC_LEAF, OptoRuntime::Math_DD_D_Type(), target, "POW",
- no_memory_effects, base, top(), exp, top());
- Node* value_pow = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+0));
-#ifdef ASSERT
- Node* value_top = _gvn.transform(new ProjNode(trig, TypeFunc::Parms+1));
- assert(value_top == top(), "second value must be top");
-#endif
- phi->init_req(2, value_pow);
- region->init_req(2, _gvn.transform(new ProjNode(trig, TypeFunc::Control)));
- }
-
- C->set_has_split_ifs(true); // Has chance for split-if optimization
- set_control(_gvn.transform(region));
- record_for_igvn(region);
- set_result(_gvn.transform(phi));
- return true;
- }
- }
-
- return StubRoutines::dpow() != nullptr ?
- runtime_math(OptoRuntime::Math_DD_D_Type(), StubRoutines::dpow(), "dpow") :
- runtime_math(OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
+ CallNode* pow = new PowDNode(C, base, exp);
+ set_predefined_input_for_runtime_call(pow);
+ pow = _gvn.transform(pow)->as_CallLeafPure();
+ set_predefined_output_for_runtime_call(pow);
+ Node* result = _gvn.transform(new ProjNode(pow, TypeFunc::Parms + 0));
+ record_for_igvn(pow);
+ set_result(result);
+ return true;
}
//------------------------------inline_math_native-----------------------------
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index aafc5d3c170..a28043c8d8f 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -2484,6 +2484,7 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_ModD ||
n->Opcode() == Op_ModF ||
+ n->Opcode() == Op_PowD ||
n->is_OpaqueNotNull() ||
n->is_OpaqueInitializedAssertionPredicate() ||
n->Opcode() == Op_MaxL ||
@@ -2637,19 +2638,11 @@ bool PhaseMacroExpand::expand_macro_nodes() {
default:
switch (n->Opcode()) {
case Op_ModD:
- case Op_ModF: {
- CallNode* mod_macro = n->as_Call();
- CallNode* call = new CallLeafPureNode(mod_macro->tf(), mod_macro->entry_point(),
- mod_macro->_name, TypeRawPtr::BOTTOM);
- call->init_req(TypeFunc::Control, mod_macro->in(TypeFunc::Control));
- call->init_req(TypeFunc::I_O, C->top());
- call->init_req(TypeFunc::Memory, C->top());
- call->init_req(TypeFunc::ReturnAdr, C->top());
- call->init_req(TypeFunc::FramePtr, C->top());
- for (unsigned int i = 0; i < mod_macro->tf()->domain()->cnt() - TypeFunc::Parms; i++) {
- call->init_req(TypeFunc::Parms + i, mod_macro->in(TypeFunc::Parms + i));
- }
- _igvn.replace_node(mod_macro, call);
+ case Op_ModF:
+ case Op_PowD: {
+ CallLeafPureNode* call_macro = n->as_CallLeafPure();
+ CallLeafPureNode* call = call_macro->inline_call_leaf_pure_node();
+ _igvn.replace_node(call_macro, call);
transform_later(call);
break;
}
diff --git a/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java b/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
new file mode 100644
index 00000000000..e28cc5ab346
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/intrinsics/math/PowDNodeTests.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2026, IBM and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package compiler.intrinsics.math;
+
+import jdk.test.lib.Asserts;
+
+import compiler.lib.ir_framework.*;
+import compiler.lib.generators.*;
+import static compiler.lib.generators.Generators.*;
+
+import java.util.Random;
+
+/*
+ * @test
+ * @bug 8378713
+ * @key randomness
+ * @summary Math.pow(base, exp) should constant propagate
+ * @library /test/lib /
+ * @run driver ${test.main.class}
+ */
+public class PowDNodeTests {
+ public static final Generator<Double> UNIFORMS = G.uniformDoubles(); // [0, 1)
+
+ public static final double B = UNIFORMS.next() * 1000.0d;
+ public static final double E = UNIFORMS.next() * 1000.0d + 3.0d; // e >= 3 to avoid strength reduction code
+
+ public static void main(String[] args) {
+ TestFramework.run();
+
+ testCorrectness();
+ }
+
+ // Test 1: pow(2.0, 10.0) -> 1024.0
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ public static double constantLiteralFolding() {
+ return Math.pow(2.0, 10.0); // should fold to 1024.0
+ }
+
+ // Test 2: pow(final B, final E) -> B^E
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ public static double constantStaticFolding() {
+ return Math.pow(B, E); // should fold to B^E
+ }
+
+ // Test 3: pow(b, 0.0) -> 1.0
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expZero(double b) {
+ return Math.pow(b, 0.0);
+ }
+
+ // Test 4: pow(b, 1.0) -> b (identity)
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expOne(double b) {
+ return Math.pow(b, 1.0);
+ }
+
+ // Test 5: pow(b, NaN) -> NaN
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expNaN(double b) {
+ return Math.pow(b, Double.NaN);
+ }
+
+ // Test 6: pow(b, 2.0) -> b * b
+ // More tests in TestPow2Opt.java
+ @Test
+ @IR(failOn = {IRNode.POW_D})
+ @IR(counts = {IRNode.MUL_D, "1"})
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expTwo(double b) {
+ return Math.pow(b, 2.0);
+ }
+
+ // Test 7: pow(b, 0.5) -> b <= 0.0 ? pow(b, 0.5) : sqrt(b)
+ // More tests in TestPow0Dot5Opt.java
+ @Test
+ @IR(counts = {IRNode.IF, "1"})
+ @IR(counts = {IRNode.SQRT_D, "1"})
+ @IR(counts = {".*CallLeaf.*pow.*", "1"}, phase = CompilePhase.BEFORE_MATCHING)
+ @Arguments(values = {Argument.RANDOM_EACH})
+ public static double expDot5(double b) {
+ return Math.pow(b, 0.5); // expand to: if (b > 0) { sqrt(b) } else { call(b) }
+ }
+
+ // Test 8: non-constant exponent stays as call
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"})
+ @Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
+ public static double nonConstant(double b, double e) {
+ return Math.pow(b, e);
+ }
+
+ // Test 9: late constant discovery on base (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateBaseConstant() {
+ double base = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ base = B;
+ }
+ }
+ // After loop opts, base == B (constant), so pow(B, E) folds
+ return Math.pow(base, E);
+ }
+
+ // Test 10: late constant discovery on exp (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateExpConstant() {
+ double exp = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ exp = E;
+ }
+ }
+ // After loop opts, exp == E (constant), so pow(B, E) folds
+ return Math.pow(B, exp);
+ }
+
+ // Test 11: late constant discoveries on both base and exp (after loop opts)
+ @Test
+ @IR(counts = {IRNode.POW_D, "1"}, phase = CompilePhase.AFTER_PARSING)
+ @IR(failOn = {IRNode.POW_D})
+ public static double lateBothConstant() {
+ double base = 0, exp = 0;
+ for (int i = 0; i < 4; i++) {
+ if ((i % 2) == 0) {
+ base = B;
+ exp = E;
+ }
+ }
+ // After loop opts, base = B, exp == E, so pow(B, E) folds
+ return Math.pow(base, exp);
+ }
+
+ private static void assertEQWithinOneUlp(double expected, double observed) {
+ if (Double.isNaN(expected) && Double.isNaN(observed)) return;
+
+ // Math.pow() requires result must be within 1 ulp of the respective magnitude
+ double ulp = Math.max(Math.ulp(expected), Math.ulp(observed));
+ if (Math.abs(expected - observed) > ulp) {
+ throw new AssertionError(String.format(
+ "expect = %x, observed = %x, ulp = %x",
+ Double.doubleToRawLongBits(expected), Double.doubleToRawLongBits(observed), Double.doubleToRawLongBits(ulp)
+ ));
+ }
+ }
+
+ private static void testCorrectness() {
+ // No need to warm up for intrinsics
+ Asserts.assertEQ(1024.0d, constantLiteralFolding());
+
+ double BE = StrictMath.pow(B, E);
+ assertEQWithinOneUlp(BE, constantStaticFolding());
+ assertEQWithinOneUlp(BE, lateBaseConstant());
+ assertEQWithinOneUlp(BE, lateExpConstant());
+ assertEQWithinOneUlp(BE, lateBothConstant());
+
+ Generator<Double> anyBits = G.anyBitsDouble();
+ Generator<Double> largeDoubles = G.uniformDoubles(Long.MAX_VALUE, Double.MAX_VALUE);
+ Generator<Double> doubles = G.doubles();
+ double[] values = {
+ Double.MIN_VALUE, Double.MIN_NORMAL, -42.0d, -1.0d, -0.0d, +0.0d, 0.5d, 1.0d, 2.0d, 123d, Double.MAX_VALUE,
+ Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
+ UNIFORMS.next(), UNIFORMS.next(),
+ largeDoubles.next(), -largeDoubles.next(), // some sufficiently large magnitudes
+ anyBits.next(), anyBits.next(), // any bits with potentially more NaN representation
+ doubles.next(), doubles.next() // a healthy sprinkle of whatever else is possible
+ };
+
+ for (double b : values) {
+ // Strength reduced, so we know the bits matches exactly
+ Asserts.assertEQ(1.0d, expZero(b));
+ Asserts.assertEQ(b, expOne(b));
+ Asserts.assertEQ(b * b, expTwo(b));
+
+ assertEQWithinOneUlp(Double.NaN, expNaN(b));
+
+ // Runtime calls, so make sure the result is within 1 ulp
+ assertEQWithinOneUlp(StrictMath.pow(b, 0.5d), expDot5(b));
+
+ for (double e : values) {
+ assertEQWithinOneUlp(StrictMath.pow(b, e), nonConstant(b, e));
+ }
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
index 7b751f1a72c..6a95a2b5da7 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
@@ -1858,6 +1858,11 @@ public class IRNode {
beforeMatchingNameRegex(SQRT_HF, "SqrtHF");
}
+ public static final String SQRT_D = PREFIX + "SQRT_D" + POSTFIX;
+ static {
+ beforeMatchingNameRegex(SQRT_D, "SqrtD");
+ }
+
public static final String SQRT_F = PREFIX + "SQRT_F" + POSTFIX;
static {
beforeMatchingNameRegex(SQRT_F, "SqrtF");
@@ -2825,6 +2830,12 @@ public class IRNode {
macroNodes(MOD_D, regex);
}
+ public static final String POW_D = PREFIX + "POW_D" + POSTFIX;
+ static {
+ String regex = START + "PowD" + MID + END;
+ macroNodes(POW_D, regex);
+ }
+
public static final String BLACKHOLE = PREFIX + "BLACKHOLE" + POSTFIX;
static {
fromBeforeRemoveUselessToFinalCode(BLACKHOLE, "Blackhole");
--
2.53.0

1
SPECS/java-25-openjdk.spec Symbolic link
View File

@ -0,0 +1 @@
../SOURCES/java-25-openjdk-portable.specfile

View File

@ -1,7 +0,0 @@
# recipients: java-qa
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +0,0 @@
diff --git a/Makefile b/Makefile
index 5175f21..571748a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,12 +13,12 @@ DEVEL_PKGS = nss nss-softokn
LIB_DIR = $(shell pkg-config --variable=libdir nss-softokn)
SHARED_LIBS = pthread softokn3 nss3
STATIC_LIBS = freebl
-SHR_CFLAGS = -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL \
- $(addprefix -l,$(SHARED_LIBS)) \
+SHR_CFLAGS = -shared -fPIC -fvisibility=hidden \
$(strip $(shell pkg-config --cflags $(DEVEL_PKGS))) \
-Wpedantic -Wall -Wextra -Wconversion -Werror
DBG_CFLAGS = -Wno-error=unused-variable -Wno-error=unused-parameter -DDEBUG \
-O0 -g
+SHR_LDFLAGS = -Wl,--exclude-libs,ALL $(addprefix -l,$(SHARED_LIBS))
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
CLANG_FORMAT_STYLE = { \
@@ -53,10 +53,12 @@ endif
.PHONY: release ## Build the library in RELEASE mode (default)
release: BLD_CFLAGS = $(SHR_CFLAGS) $(CFLAGS)
+release: BLD_LDFLAGS = $(SHR_LDFLAGS) $(LDFLAGS)
release: $(CLEAN_IF_PREVIOUS_BUILD_MODE_IS_DEBUG) $(OUTPUT)
.PHONY: debug ## Build the library in DEBUG mode
debug: BLD_CFLAGS = $(SHR_CFLAGS) $(DBG_CFLAGS) $(CFLAGS)
+debug: BLD_LDFLAGS = $(SHR_LDFLAGS) $(LDFLAGS)
debug: CREATE_DBG_SENTINEL_IF_NEEDED = touch $(DBG_SENTINEL)
debug: $(CLEAN_IF_PREVIOUS_BUILD_MODE_IS_RELEASE) $(OUTPUT)
@@ -73,7 +75,7 @@ $(BIN_DIR):
$(OUTPUT): $(BIN_DIR) $(SRC_FILES)
@$(CREATE_DBG_SENTINEL_IF_NEEDED)
- $(CC) $(BLD_CFLAGS) $(filter %.c, $+) \
+ $(CC) $(BLD_CFLAGS) $(filter %.c, $+) $(BLD_LDFLAGS) \
$(addprefix $(LIB_DIR)/lib,$(addsuffix .a,$(STATIC_LIBS))) -o $@

View File

@ -1,3 +0,0 @@
---
inspections:
javabytecode: off

View File

@ -1,29 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the RPM on CentOS 9 or 10
centpkg -v build
# Local Variables:
# compile-command: "shellcheck build_centos.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,29 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the portable on CentOS
centpkg -v build --target java-openjdk-portable-build --rhel-target none
# Local Variables:
# compile-command: "shellcheck build_centos_portable_build.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,43 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the RPM on RHEL 10
NVR=${1}
USER=${2}
if test "${NVR}" = ""; then
echo "${0} <NVR> <USER>";
exit 1;
fi
if test "${USER}" = ""; then
echo "${0} <NVR> <USER>";
exit 2;
fi
METADATA="{\"osci\": {\"upstream_nvr\": \"${NVR}\", \"upstream_owner_name\": \"${USER}\"}, \"rhel-target\": \"latest\"}"
rhpkg -v build --target=java-openjdk-rhel-10-build --custom-user-metadata "${METADATA}"
# Local Variables:
# compile-command: "shellcheck build_rhel_10.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,29 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the portable on RHEL 7
rhpkg -v build --target=java-openjdk-rhel-7-build --skip-nvr-check
# Local Variables:
# compile-command: "shellcheck build_rhel_7_portable_build.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,43 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the RPM on RHEL 8
NVR=${1}
USER=${2}
if test "${NVR}" = ""; then
echo "${0} <NVR> <USER>";
exit 1;
fi
if test "${USER}" = ""; then
echo "${0} <NVR> <USER>";
exit 2;
fi
METADATA="{\"osci\": {\"upstream_nvr\": \"${NVR}\", \"upstream_owner_name\": \"${USER}\"}, \"rhel-target\": \"latest\"}"
rhpkg -v build --target=java-openjdk-rhel-8-build --custom-user-metadata "${METADATA}"
# Local Variables:
# compile-command: "shellcheck build_rhel_8.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,43 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the RPM on RHEL 9
NVR=${1}
USER=${2}
if test "${NVR}" = ""; then
echo "${0} <NVR> <USER>";
exit 1;
fi
if test "${USER}" = ""; then
echo "${0} <NVR> <USER>";
exit 2;
fi
METADATA="{\"osci\": {\"upstream_nvr\": \"${NVR}\", \"upstream_owner_name\": \"${USER}\"}, \"rhel-target\": \"latest\"}"
rhpkg -v build --target=java-openjdk-rhel-9-build --custom-user-metadata "${METADATA}"
# Local Variables:
# compile-command: "shellcheck build_rhel_9.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,29 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds the portable on RHEL 8
rhpkg -v build --target=java-openjdk-rhel-8-build --skip-nvr-check
# Local Variables:
# compile-command: "shellcheck build_rhel_portable_build.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,43 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Builds a scratch build of vanilla OpenJDK with no local patches
SEPARATE_ARCHES=${1}
CMD="--target java-openjdk-rhel-8-build --skip-nvr-check --nowait";
SUPPORTED_ARCHES="aarch64 ppc64le s390x x86_64";
if [ "x${SEPARATE_ARCHES}" = "x" ] ; then
SEPARATE_ARCHES=0;
fi
if [ ${SEPARATE_ARCHES} -eq 1 ] ; then
for arch in ${SUPPORTED_ARCHES}; do \
rhpkg -v build --arches ${arch} --scratch ${CMD} ; \
done && brew watch-task --mine
else
rhpkg -v build ${CMD} && brew watch-task --mine
fi
# Local Variables:
# compile-command: "shellcheck build_vanilla.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,61 +0,0 @@
#!/bin/sh
# Copyright (C) 2024 Red Hat, Inc.
# Written by Andrew John Hughes <gnu.andrew@redhat.com>.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
TREE=${1}
if test "${TREE}" = ""; then
TREE=${PWD}
fi
if [ -e "${TREE}"/nashorn/.hg ] || [ -e "${TREE}"/nashorn/merge.changeset ] ; then
NASHORN="nashorn" ;
fi
if [ -e "${TREE}"/corba/.hg ] || [ -e "${TREE}"/corba/merge.changeset ] ; then
CORBA="corba";
fi
if [ -e "${TREE}"/jaxp/.hg ] || [ -e "${TREE}"/jaxp/merge.changeset ] ; then
JAXP="jaxp";
fi
if [ -e "${TREE}"/jaxws/.hg ] || [ -e "${TREE}"/jaxws/merge.changeset ] ; then
JAXWS="jaxws";
fi
if [ -e "${TREE}"/langtools/.hg ] || [ -e "${TREE}"/langtools/merge.changeset ] ; then
LANGTOOLS="langtools";
fi
if [ -e "${TREE}"/jdk/.hg ] || [ -e "${TREE}"/jdk/merge.changeset ] ; then
JDK="jdk";
fi
if [ -e "${TREE}"/hotspot/.hg ] || [ -e "${TREE}"/hotspot/merge.changeset ] ; then
HOTSPOT="hotspot";
fi
SUBTREES="${CORBA} ${JAXP} ${JAXWS} ${LANGTOOLS} ${NASHORN} ${JDK} ${HOTSPOT}";
echo "${SUBTREES}"
# Local Variables:
# compile-command: "shellcheck discover_trees.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,294 +0,0 @@
#!/bin/bash
# Copyright (C) 2024 Red Hat, Inc.
# Written by:
# Andrew John Hughes <gnu.andrew@redhat.com>
# Thomas Fitzsimmons <fitzsim@redhat.com>
# Jiri Vanek <jvanek@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Generates the source tarball for OpenJDK projects.
#
# There are multiple ways to specify the source code location and version:
#
# 1. Specify the version (VERSION), the location of the Git repository
# (REPO_ROOT) and the root of the output tarball name (FILE_NAME_ROOT)
# 2. Specify the version (VERSION) along with an upstream project name
# (PROJECT_NAME) and repository name (REPO_NAME) that can be used
# to construct the URL of the upstream OpenJDK repository.
# 3. Specify OPENJDK_LATEST=1 and allow the script to obtain the JDK
# feature version from the spec file, which is then used to
# obtain the latest build promotion from the upstream repository.
#
# An appropriate bootstrap JDK is also required for when ./configure
# is run within the checked out repository to generate the .src-rev.
# file. This can be specified by setting BOOT_JDK.
#
# Example 1:
# This will check out the specified version from the specified
# repository and construct a tarball called openjdk-17.0.3+5.tar.xz:
#
# $ VERSION=jdk-17.0.3+5 FILE_NAME_ROOT=open${VERSION} \
# REPO_ROOT=$HOME/projects/openjdk/upstream/17u \
# BOOT_JDK=/usr/lib/jvm/java-17-openjdk ./generate_source_tarball.sh
#
# Example 2:
# This will check out the same version as example 1, but from the
# upstream repository:
#
# $ VERSION=jdk-17.0.3+5 PROJECT_NAME=openjdk REPO_NAME=jdk17u \
# BOOT_JDK=/usr/lib/jvm/java-17-openjdk ./generate_source_tarball.sh
#
# Example 3:
# This will read the OpenJDK feature version from the spec file, then create a
# tarball from the most recent tag for that version in the upstream Git
# repository.
#
# $ OPENJDK_LATEST=1 \
# BOOT_JDK=/usr/lib/jvm/java-17-openjdk ./generate_source_tarball.sh
#
set -e
OPENJDK_URL_DEFAULT=https://github.com
COMPRESSION_DEFAULT=xz
if [ "$1" = "help" ] ; then
echo "Behaviour may be specified by setting the following variables:"
echo
echo "VERSION - the version of the specified OpenJDK project"
echo " (required unless OPENJDK_LATEST is set)"
echo "PROJECT_NAME - the name of the OpenJDK project being archived"
echo " (needed to compute REPO_ROOT and/or"
echo " FILE_NAME_ROOT automatically;"
echo " optional if they are set explicitly)"
echo "REPO_NAME - the name of the OpenJDK repository"
echo " (needed to compute REPO_ROOT automatically;"
echo " optional if REPO_ROOT is set explicitly)"
echo "OPENJDK_URL - the URL to retrieve code from"
echo " (defaults to ${OPENJDK_URL_DEFAULT})"
echo "COMPRESSION - the compression type to use"
echo " (defaults to ${COMPRESSION_DEFAULT})"
echo "FILE_NAME_ROOT - name of the archive, minus extensions"
echo " (defaults to PROJECT_NAME-VERSION)"
echo "REPO_ROOT - the location of the Git repository to archive"
echo " (defaults to OPENJDK_URL/PROJECT_NAME/REPO_NAME.git)"
echo "TO_COMPRESS - what part of clone to pack"
echo " (defaults to ${VERSION})"
echo "BOOT_JDK - the bootstrap JDK to satisfy the configure run"
echo " (defaults to packaged JDK version)"
echo "WITH_TEMP - run in a temporary directory"
echo " (defaults to disabled)"
echo "OPENJDK_LATEST - deduce VERSION from most recent upstream tag"
echo " (implies WITH_TEMP, computes everything else"
echo " automatically; Note: accesses network to read"
echo " tag list from remote Git repository)"
exit 1;
fi
if [ "$OPENJDK_LATEST" != "" ] ; then
FEATURE_VERSION=$(echo '%featurever' \
| rpmspec --shell ./*.spec 2>/dev/null \
| grep --after-context 1 featurever \
| tail --lines 1)
PROJECT_NAME=openjdk
REPO_NAME=jdk"${FEATURE_VERSION}"u
# Skip -ga tags since those are the same as the most recent non-ga tag, and
# the non-ga tag is the one that is used to generated the official source
# tarball. For example:
# ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10-ga^{}
# 25a2e6c20c9a96853714284cabc6b456eb095070 refs/tags/jdk-17.0.10-ga
# ca760c86642aa2e0d9b571aaabac054c0239fbdc refs/tags/jdk-17.0.10+7^{}
# e49c5749b10f3e90274b72e9279f794fdd191d27 refs/tags/jdk-17.0.10+7
VERSION=$(git ls-remote --tags --refs --sort=-version:refname \
"${OPENJDK_URL_DEFAULT}/${PROJECT_NAME}/${REPO_NAME}.git" \
"jdk-${FEATURE_VERSION}*" \
| grep --invert-match '\-ga$' \
| head --lines 1 | cut --characters 52-)
FILE_NAME_ROOT=open${VERSION}
WITH_TEMP=1
fi
if [ "$WITH_TEMP" != "" ] ; then
pushd "$(mktemp --directory --tmpdir temp-generated-source-tarball-XXX)"
fi
if [ "$VERSION" = "" ] ; then
echo "No VERSION specified"
exit 2
fi
echo "Version: ${VERSION}"
NUM_VER=${VERSION##jdk-}
RELEASE_VER=${NUM_VER%%+*}
BUILD_VER=${NUM_VER##*+}
MAJOR_VER=${RELEASE_VER%%.*}
echo "Major version is ${MAJOR_VER}, release ${RELEASE_VER}, build ${BUILD_VER}"
if [ "$BOOT_JDK" = "" ] ; then
echo "No boot JDK specified".
BOOT_JDK=/usr/lib/jvm/java-${MAJOR_VER}-openjdk;
echo -n "Checking for ${BOOT_JDK}...";
if [ -d "${BOOT_JDK}" ] && [ -x "${BOOT_JDK}"/bin/java ] ; then
echo "Boot JDK found at ${BOOT_JDK}";
else
echo "Not found";
PREV_VER=$((MAJOR_VER - 1));
BOOT_JDK=/usr/lib/jvm/java-${PREV_VER}-openjdk;
echo -n "Checking for ${BOOT_JDK}...";
if [ -d ${BOOT_JDK} ] && [ -x ${BOOT_JDK}/bin/java ] ; then
echo "Boot JDK found at ${BOOT_JDK}";
else
echo "Not found";
exit 4;
fi
fi
else
echo "Boot JDK: ${BOOT_JDK}";
fi
if [ "$OPENJDK_URL" = "" ] ; then
OPENJDK_URL=${OPENJDK_URL_DEFAULT}
echo "No OpenJDK URL specified; defaulting to ${OPENJDK_URL}"
else
echo "OpenJDK URL: ${OPENJDK_URL}"
fi
if [ "$COMPRESSION" = "" ] ; then
# rhel 5 needs tar.gz
COMPRESSION=${COMPRESSION_DEFAULT}
fi
echo "Creating a tar.${COMPRESSION} archive"
if [ "$FILE_NAME_ROOT" = "" ] ; then
if [ "$PROJECT_NAME" = "" ] ; then
echo "No PROJECT_NAME specified, needed by FILE_NAME_ROOT"
exit 1
fi
FILE_NAME_ROOT=${PROJECT_NAME}-${VERSION}
echo "No file name root specified; default to ${FILE_NAME_ROOT}"
fi
if [ "$REPO_ROOT" = "" ] ; then
if [ "$PROJECT_NAME" = "" ] ; then
echo "No PROJECT_NAME specified, needed by REPO_ROOT"
exit 1
fi
if [ "$REPO_NAME" = "" ] ; then
echo "No REPO_NAME specified, needed by REPO_ROOT"
exit 3
fi
REPO_ROOT="${OPENJDK_URL}/${PROJECT_NAME}/${REPO_NAME}.git"
echo "No repository root specified; default to ${REPO_ROOT}"
fi;
if [ "$TO_COMPRESS" = "" ] ; then
TO_COMPRESS="${VERSION}"
echo "No targets to be compressed specified ; default to ${TO_COMPRESS}"
fi;
echo -e "Settings:"
echo -e "\tVERSION: ${VERSION}"
echo -e "\tPROJECT_NAME: ${PROJECT_NAME}"
echo -e "\tREPO_NAME: ${REPO_NAME}"
echo -e "\tOPENJDK_URL: ${OPENJDK_URL}"
echo -e "\tCOMPRESSION: ${COMPRESSION}"
echo -e "\tFILE_NAME_ROOT: ${FILE_NAME_ROOT}"
echo -e "\tREPO_ROOT: ${REPO_ROOT}"
echo -e "\tTO_COMPRESS: ${TO_COMPRESS}"
echo -e "\tBOOT_JDK: ${BOOT_JDK}"
echo -e "\tWITH_TEMP: ${WITH_TEMP}"
echo -e "\tOPENJDK_LATEST: ${OPENJDK_LATEST}"
if [ -d "${FILE_NAME_ROOT}" ] ; then
echo "Reusing existing ${FILE_NAME_ROOT}"
STAT_TIME="$(stat --format=%Y "${FILE_NAME_ROOT}")"
TAR_TIME="$(date --date=@"${STAT_TIME}" --iso-8601=seconds)"
else
mkdir "${FILE_NAME_ROOT}"
pushd "${FILE_NAME_ROOT}"
echo "Cloning ${VERSION} root repository from ${REPO_ROOT}"
if realpath -q "${REPO_ROOT}"; then
echo "Local path detected; not adding depth argument";
DEPTH="--";
else
DEPTH="--depth=1";
echo "Remote repository detected; adding ${DEPTH}";
fi
git clone -b "${VERSION}" "${DEPTH}" "${REPO_ROOT}" "${VERSION}"
pushd "${VERSION}"
TAR_TIME="$(git log --max-count 1 --format=%cI)"
popd
popd
fi
pushd "${FILE_NAME_ROOT}"
# Generate .src-rev so build has knowledge of the revision the tarball was
# created from
mkdir build
pushd build
sh "${PWD}"/../"${VERSION}"/configure --with-boot-jdk="${BOOT_JDK}"
make store-source-revision
popd
rm -rf build
# Remove commit checks
echo "Removing $(find "${VERSION}" -name '.jcheck' -print)"
find "${VERSION}" -name '.jcheck' -print0 | xargs -0 rm -r
# Remove history and GHA
echo "find ${VERSION} -name '.hgtags'"
find "${VERSION}" -name '.hgtags' -exec rm -v '{}' '+'
echo "find ${VERSION} -name '.hgignore'"
find "${VERSION}" -name '.hgignore' -exec rm -v '{}' '+'
echo "find ${VERSION} -name '.gitattributes'"
find "${VERSION}" -name '.gitattributes' -exec rm -v '{}' '+'
echo "find ${VERSION} -name '.gitignore'"
find "${VERSION}" -name '.gitignore' -exec rm -v '{}' '+'
# Work around some Git objects not having write permissions.
echo "chmod --recursive u+w ${VERSION}/.git"
chmod --recursive u+w "${VERSION}"/.git
echo "find ${VERSION} -name '.git'"
find "${VERSION}" -name '.git' -exec rm -rv '{}' '+'
echo "find ${VERSION} -name '.github'"
find "${VERSION}" -name '.github' -exec rm -rv '{}' '+'
echo "Compressing remaining forest"
if [ "$COMPRESSION" = "xz" ] ; then
SWITCH=cJf
else
SWITCH=czf
fi
EA_PART="$(awk -F= \
'/^DEFAULT_PROMOTED_VERSION_PRE/ { if ($2) print "-"$2 }' \
"${VERSION}"/make/conf/version-numbers.conf)"
TARBALL_NAME=${FILE_NAME_ROOT}${EA_PART}.tar.${COMPRESSION}
XZ_OPT=${XZ_OPT-"-T0"} \
tar --mtime="${TAR_TIME}" --owner=root --group=root --sort=name \
--exclude-vcs -$SWITCH "${TARBALL_NAME}" "${TO_COMPRESS}"
mv "${TARBALL_NAME}" ..
popd
if [ "$WITH_TEMP" != "" ] ; then
echo "Tarball is: $(realpath .)/${TARBALL_NAME}"
popd
else
echo -n "Done. You may want to remove the uncompressed version"
echo " - $FILE_NAME_ROOT"
fi
# Local Variables:
# compile-command: "shellcheck generate_source_tarball.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,172 +0,0 @@
#!/usr/bin/env sh
# Copyright (C) 2025 Red Hat, Inc.
# Original written by Antonio Vieiro <avieirov@redhat.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
if [ $# -ne 1 ]; then
echo "Usage: $0 openjdk-root-directory"
exit 1
fi
JDKROOT=$1
if [ ! -d "${JDKROOT}" ] ; then
echo "${JDKROOT} is not a directory.";
exit 2
fi
# Work out the OpenJDK version
# OpenJDK >= 10 has its version in the build machinery
# OpenJDK >= 17 stores it in a new location (JDK-8258246)
VERSION_FILE="${JDKROOT}"/make/conf/version-numbers.conf
printf "Checking for %s..." "${VERSION_FILE}";
if [ ! -f "${VERSION_FILE}" ] ; then
VERSION_FILE="${JDKROOT}"/make/autoconf/version-numbers
echo "Not found; using old version file ${VERSION_FILE}";
else
echo "found.";
fi
if [ -e "${VERSION_FILE}" ] ; then
openjdk_version=$(grep '^DEFAULT_VERSION_FEATURE' "${VERSION_FILE}" | cut -d '=' -f 2)
elif [ -e "${JDKROOT}"/jdk/src/java.base/share/classes/java/lang/Object.java ] ; then
openjdk_version=9;
elif [ -e "${JDKROOT}"/common/autoconf ] ; then
openjdk_version=8;
else
openjdk_version=7;
fi
echo "OpenJDK version: ${openjdk_version}";
#
# Freetype
#
if [ "${openjdk_version}" -gt 8 ] ; then
FREETYPE=src/java.desktop/share/native/libfreetype/include/freetype/freetype.h
ABS_FREETYPE="${JDKROOT}"/"${FREETYPE}"
if [ ! -f "${ABS_FREETYPE}" ]; then
echo "Freetype header not found!"
exit 2
fi
FREETYPE_VERSION=$(awk '/#define FREETYPE_MAJOR/ {MAJOR=$3} /#define FREETYPE_MINOR/ {MINOR=$3} /#define FREETYPE_PATCH/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_FREETYPE}")
else
echo "No bundled FreeType on ${openjdk_version}";
fi
# giflib
if [ "${openjdk_version}" -gt 8 ] ; then
GIFLIB=src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h
else
GIFLIB=jdk/src/share/native/sun/awt/giflib/gif_lib.h
fi
ABS_GIFLIB="${JDKROOT}"/"${GIFLIB}"
if [ ! -f "${ABS_GIFLIB}" ]; then
echo "giflib header not found!"
exit 3
fi
GIFLIB_VERSION=$(awk '/#define GIFLIB_MAJOR/ {MAJOR=$3} /#define GIFLIB_MINOR/ {MINOR=$3} /#define GIFLIB_RELEASE/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_GIFLIB}")
# harfbuzz
if [ "${openjdk_version}" -gt 8 ] ; then
HARFBUZZ=src/java.desktop/share/native/libharfbuzz/hb-version.h
ABS_HARFBUZZ="${JDKROOT}/${HARFBUZZ}"
if [ ! -f "${ABS_HARFBUZZ}" ]; then
echo "HarfBuzz header not found!"
exit 4
fi
HARFBUZZ_VERSION=$(awk '/#define HB_VERSION_MAJOR/ {MAJOR=$3} /#define HB_VERSION_MINOR/ {MINOR=$3} /#define HB_VERSION_MICRO/ {PATCH=$3} END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_HARFBUZZ}")
else
echo "No HarfBuzz on ${openjdk_version}";
fi
# lcms
if [ "${openjdk_version}" -gt 8 ] ; then
LCMS=src/java.desktop/share/native/liblcms/lcms2.h
else
LCMS=jdk/src/share/native/sun/java2d/cmm/lcms/lcms2.h
fi
ABS_LCMS="${JDKROOT}"/"${LCMS}"
if [ ! -f "${ABS_LCMS}" ]; then
echo "lcms header not found!"
exit 5
fi
LCMS_VERSION=$(awk '/#define LCMS_VERSION/ { MAJOR=int($3 / 1000); REST=$3 % 1000; MINOR=int(REST / 10); PATCH=REST % 10; } END {printf "%s.%s.%s", MAJOR, MINOR, PATCH}' "${ABS_LCMS}")
# jpeg
if [ "${openjdk_version}" -gt 8 ] ; then
JPEG=src/java.desktop/share/native/libjavajpeg/jpeglib.h
else
JPEG=jdk/src/share/native/sun/awt/image/jpeg/jpeglib.h
fi
ABS_JPEG="${JDKROOT}"/"${JPEG}"
if [ ! -f "${ABS_JPEG}" ]; then
echo "jpeg header not found!"
exit 6
fi
JPEG_VERSION=$(awk '/#define JPEG_LIB_VERSION/ { VERSION=$3; MAJOR=int(VERSION / 10); MINOR=VERSION%10; } END {printf "%s%c", MAJOR, (MINOR+96)}' "${ABS_JPEG}")
# png
if [ "${openjdk_version}" -gt 8 ] ; then
PNG=src/java.desktop/share/native/libsplashscreen/libpng/png.h
else
PNG=jdk/src/share/native/sun/awt/libpng/png.h
fi
ABS_PNG="${JDKROOT}"/"${PNG}"
if [ ! -f "${ABS_PNG}" ]; then
echo "png header not found!"
exit 7
fi
PNG_VERSION=$(awk '/#define PNG_LIBPNG_VER_STRING/ { VERSION=$3; gsub("\"", "", VERSION) } END {print VERSION}' "${ABS_PNG}")
# zlib
if [ "${openjdk_version}" -gt 8 ] ; then
ZLIB=src/java.base/share/native/libzip/zlib/zlib.h
else
ZLIB=jdk/src/share/native/java/util/zip/zlib/zlib.h
fi
ABS_ZLIB="${JDKROOT}"/"${ZLIB}"
if [ ! -f "${ABS_ZLIB}" ]; then
echo "zlib header not found!"
exit 8
fi
ZLIB_VERSION=$(awk '/#define ZLIB_VERSION/ { VERSION=$3; gsub("\"", "", VERSION) } END {print VERSION}' "${ABS_ZLIB}")
# Print output
printf "\nRPM definitions:\n"
if [ "${openjdk_version}" -gt 8 ] ; then
echo "# Version in ${FREETYPE}"
echo "Provides: bundled(freetype) = ${FREETYPE_VERSION}"
fi
echo "# Version in ${GIFLIB}"
echo "Provides: bundled(giflib) = ${GIFLIB_VERSION}"
if [ "${openjdk_version}" -gt 8 ] ; then
echo "# Version in ${HARFBUZZ}"
echo "Provides: bundled(harfbuzz) = ${HARFBUZZ_VERSION}"
fi
echo "# Version in ${LCMS}"
echo "Provides: bundled(lcms2) = ${LCMS_VERSION}"
echo "# Version in ${JPEG}"
echo "Provides: bundled(libjpeg) = ${JPEG_VERSION}"
echo "# Version in ${PNG}"
echo "Provides: bundled(libpng) = ${PNG_VERSION}"
echo "# Version in ${ZLIB}"
echo "Provides: bundled(zlib) = ${ZLIB_VERSION}"
# Local Variables:
# compile-command: "shellcheck get_bundle_versions.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,198 +0,0 @@
#!/bin/bash
# Copyright (C) 2024 Red Hat, Inc.
# Written by Andrew John Hughes <gnu.andrew@redhat.com>.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
ICEDTEA_USE_VCS=true
ICEDTEA_VERSION=3.15.0
ICEDTEA_URL=https://icedtea.classpath.org/download/source
ICEDTEA_SIGNING_KEY=CFDA0F9B35964222
ICEDTEA_HG_URL=https://icedtea.classpath.org/hg/icedtea11
set -e
RPM_DIR=${PWD}
if [ ! -f "${RPM_DIR}/jconsole.desktop.in" ] ; then
echo "Not in RPM source tree.";
exit 1;
fi
if test "${TMPDIR}" = ""; then
TMPDIR=/tmp;
fi
WORKDIR=${TMPDIR}/it.sync
echo "Using working directory ${WORKDIR}"
mkdir "${WORKDIR}"
pushd "${WORKDIR}"
if test "${WGET}" = ""; then
WGET=$(which wget);
if test "${WGET}" = ""; then
echo "wget not found";
exit 1;
fi
fi
if test "${TAR}" = ""; then
TAR=$(which tar)
if test "${TAR}" = ""; then
echo "tar not found";
exit 2;
fi
fi
echo "Dependencies:";
echo -e "\tWGET: ${WGET}";
echo -e "\tTAR: ${TAR}\n";
if test "${ICEDTEA_USE_VCS}" = "true"; then
echo "Mode: Using VCS";
if test "${GREP}" = ""; then
GREP=$(which grep);
if test "${GREP}" = ""; then
echo "grep not found";
exit 3;
fi
fi
if test "${CUT}" = ""; then
CUT=$(which cut);
if test "${CUT}" = ""; then
echo "cut not found";
exit 4;
fi
fi
if test "${TR}" = ""; then
TR=$(which tr);
if test "${TR}" = ""; then
echo "tr not found";
exit 5;
fi
fi
if test "${HG}" = ""; then
HG=$(which hg);
if test "${HG}" = ""; then
echo "hg not found";
exit 6;
fi
fi
echo "Dependencies:";
echo -e "\tGREP: ${GREP}";
echo -e "\tCUT: ${CUT}";
echo -e "\tTR: ${TR}";
echo -e "\tHG: ${HG}";
echo "Checking out repository from VCS...";
${HG} clone ${ICEDTEA_HG_URL} icedtea
echo "Obtaining version from configure.ac...";
ROOT_VER=$(${GREP} '^AC_INIT' icedtea/configure.ac|${CUT} -d ',' -f 2|${TR} -d '[][:space:]')
echo "Root version from configure: ${ROOT_VER}";
VCS_REV=$(${HG} log -R icedtea --template '{node|short}' -r tip)
echo "VCS revision: ${VCS_REV}";
ICEDTEA_VERSION="${ROOT_VER}-${VCS_REV}"
echo "Creating icedtea-${ICEDTEA_VERSION}";
mkdir "icedtea-${ICEDTEA_VERSION}"
echo "Copying required files from checkout to icedtea-${ICEDTEA_VERSION}";
# Commented out for now as IcedTea 6's jconsole.desktop.in is outdated
#cp -a icedtea/jconsole.desktop.in ../icedtea-${ICEDTEA_VERSION}
cp -a "${RPM_DIR}/jconsole.desktop.in" "icedtea-${ICEDTEA_VERSION}"
cp -a icedtea/tapset "icedtea-${ICEDTEA_VERSION}"
rm -rf icedtea
else
echo "Mode: Using tarball";
if test "${ICEDTEA_VERSION}" = ""; then
echo "No IcedTea version specified for tarball download.";
exit 3;
fi
if test "${CHECKSUM}" = ""; then
CHECKSUM=$(which sha256sum)
if test "${CHECKSUM}" = ""; then
echo "sha256sum not found";
exit 4;
fi
fi
if test "${PGP}" = ""; then
PGP=$(which gpg)
if test "${PGP}" = ""; then
echo "gpg not found";
exit 5;
fi
fi
echo "Dependencies:";
echo -e "\tCHECKSUM: ${CHECKSUM}";
echo -e "\tPGP: ${PGP}\n";
echo "Checking for IcedTea signing key ${ICEDTEA_SIGNING_KEY}...";
if ! gpg --list-keys ${ICEDTEA_SIGNING_KEY}; then
echo "IcedTea signing key ${ICEDTEA_SIGNING_KEY} not installed.";
exit 6;
fi
echo "Downloading IcedTea release tarball...";
${WGET} -v ${ICEDTEA_URL}/icedtea-${ICEDTEA_VERSION}.tar.xz
echo "Downloading IcedTea tarball signature...";
${WGET} -v ${ICEDTEA_URL}/icedtea-${ICEDTEA_VERSION}.tar.xz.sig
echo "Downloading IcedTea tarball checksums...";
${WGET} -v ${ICEDTEA_URL}/icedtea-${ICEDTEA_VERSION}.sha256
echo "Verifying checksums...";
${CHECKSUM} --check --ignore-missing icedtea-${ICEDTEA_VERSION}.sha256
echo "Checking signature...";
${PGP} --verify icedtea-${ICEDTEA_VERSION}.tar.xz.sig
echo "Extracting files...";
${TAR} xJf icedtea-${ICEDTEA_VERSION}.tar.xz \
icedtea-${ICEDTEA_VERSION}/tapset \
icedtea-${ICEDTEA_VERSION}/jconsole.desktop.in
rm -vf icedtea-${ICEDTEA_VERSION}.tar.xz
rm -vf icedtea-${ICEDTEA_VERSION}.tar.xz.sig
rm -vf icedtea-${ICEDTEA_VERSION}.sha256
fi
echo "Replacing desktop files...";
mv -v "icedtea-${ICEDTEA_VERSION}/jconsole.desktop.in" "${RPM_DIR}"
echo "Creating new tapset tarball...";
mv -v "icedtea-${ICEDTEA_VERSION}" openjdk
${TAR} cJf "${RPM_DIR}/tapsets-icedtea-${ICEDTEA_VERSION}.tar.xz" openjdk
rm -rvf openjdk
popd
rm -rf "${WORKDIR}"
# Local Variables:
# compile-command: "shellcheck icedtea_sync.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,114 +0,0 @@
#!/bin/bash
# Copyright (C) 2024 Red Hat, Inc.
# Written by Andrew John Hughes <gnu.andrew@redhat.com>, 2012-2022
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
OLD_RELEASE=$1
NEW_RELEASE=$2
REPO=$3
SUBDIR=$4
SCRIPT_DIR=$(dirname "${0}")
if test "${SUBDIR}" = ""; then
echo "No subdirectory specified; using .";
SUBDIR=".";
fi
if test "$REPO" = ""; then
echo "No repository specified; using ${PWD}"
REPO=${PWD}
fi
if test "${TMPDIR}" = ""; then
TMPDIR=/tmp;
fi
echo "Repository: ${REPO}"
if [ -e "${REPO}/.git" ] ; then
TYPE=git;
elif [ -e "${REPO}/.hg" ] ; then
TYPE=hg;
else
echo "No Mercurial or Git repository detected.";
exit 1;
fi
if test "$OLD_RELEASE" = "" || test "$NEW_RELEASE" = ""; then
echo "ERROR: Need to specify old and new release";
exit 2;
fi
echo "Listing fixes between $OLD_RELEASE and $NEW_RELEASE in $REPO"
rm -f "${TMPDIR}/fixes2" "${TMPDIR}/fixes3" "${TMPDIR}/fixes"
for repos in . $("${SCRIPT_DIR}/discover_trees.sh" "${REPO}");
do
if test "$TYPE" = "hg"; then
hg log -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R "$REPO/$repos" -G -M "${REPO}/${SUBDIR}" | \
grep -E '^[o:| ]*summary'|grep -v 'Added tag'|sed -r 's#^[o:| ]*summary:\W*([0-9])# - JDK-\1#'| \
sed 's#^[o:| ]*summary:\W*# - #' >> "${TMPDIR}/fixes2";
hg log -v -r "tag('$NEW_RELEASE'):tag('$OLD_RELEASE') - tag('$OLD_RELEASE')" -R "$REPO/$repos" -G -M "${REPO}/${SUBDIR}" | \
grep -E '^[o:| ]*[0-9]{7}'|sed -r 's#^[o:| ]*([0-9]{7})# - JDK-\1#' >> "${TMPDIR}/fixes3";
else
git -C "${REPO}" log --no-merges --pretty=format:%B "${NEW_RELEASE}...${OLD_RELEASE}" -- "${SUBDIR}" |grep -E '^[0-9]{7}' | \
sed -r 's#^([0-9])# - JDK-\1#' >> "${TMPDIR}/fixes2";
touch "${TMPDIR}/fixes3" ; # unused
fi
done
sort "${TMPDIR}/fixes2" "${TMPDIR}/fixes3" > "${TMPDIR}/fixes4"
uniq "${TMPDIR}/fixes4" > "${TMPDIR}/fixes"
rm -f "${TMPDIR}/fixes2" "${TMPDIR}/fixes3"
if ! [ -s "${TMPDIR}/fixes" ] ; then
echo "Failed to obtain fixes.";
exit 3;
fi
echo "In ${TMPDIR}/fixes:"
cat "${TMPDIR}/fixes"
printf "\nChecking for duplicates...";
if uniq -d "${TMPDIR}/fixes4" | grep 'JDK' > "${TMPDIR}/dupes"; then
printf "found.\nWARNING: Review the following duplicates:\n";
cat "${TMPDIR}/dupes";
else
echo "No apparent duplicates.";
fi
rm -f "${TMPDIR}/fixes4";
printf "\nChecking for backouts...";
if grep -i 'backout' "${TMPDIR}/fixes" > "${TMPDIR}/backouts"; then
printf "found.\nWARNING: Review the following backouts:\n"
cat "${TMPDIR}/backouts";
else
echo "No apparent backouts.";
fi
printf "\nChecking for bundled library updates...";
if grep -iE ':( \(tz\))? update.*(freetype|gif|harfbuzz|lcms|jpeg|png|timezone|zlib)' "${TMPDIR}/fixes" > "${TMPDIR}/bundles"; then
printf "found.\nWARNING: Review the following with respect to bundled provides:\n";
cat "${TMPDIR}/bundles";
echo "Compare the output of $(dirname "${0}")/get_bundle_versions.sh with the RPM using the JDK source tree"
else
echo "No apparent library updates.";
fi
# Local Variables:
# compile-command: "shellcheck openjdk_news.sh"
# fill-column: 80
# indent-tabs-mode: nil
# sh-basic-offset: 4
# End:

View File

@ -1,3 +0,0 @@
SHA512 (tapsets-icedtea-6.0.0pre00-c848b93a8598.tar.xz) = 97d026212363b3c83f6a04100ad7f6fdde833d16579717f8756e2b8c2eb70e144a41a330cb9ccde9c3badd37a2d54fdf4650a950ec21d8b686d545ecb2a64d30
SHA512 (openjdk-25.0.1+8.tar.xz) = eb84d876f81ca02803283e8294c89b6acbed3753426811c3bcc228615c9618deefc85da4aa702800cac2feb103e628ee8b92292b316e9d7e12a58b6de69c5085
SHA512 (nssadapter-0.1.0.tar.xz) = 581f49d1a27550e3a2fa0a9d407f43c507627a8439827904d14daaf24e071d9f73884a2abe4cb3d36d26f1af09ef7d20724b2d40c9bac202e0316fac6c1a636b

View File

@ -1,21 +0,0 @@
---
- hosts: localhost
roles:
- role: standard-test-source
tags:
- always
- role: standard-test-basic
tags:
- classic
- atomic
required_packages:
- java-21-openjdk-devel
tests:
- javaVersion1:
dir: ~
run: set -ex; useradd franta1; su franta1 -c 'java -version';
run: set -ex; useradd franta4; su franta4 -c 'javac -version';
run: ls -l /usr/lib/jvm;
- javaVersion2:
dir: ~
run: set -ex; useradd franta2; su franta2 -c 'java --version'