Skip to content

Commit c08980a

Browse files
authored
Merge pull request #50591 from zakkak/2025-10-16-deprecate-runtime-reinitialization
Refactorings and deprecations related to obsolete runtime (re)initialization configuration in native-image
2 parents e2b8f8c + 527e5a0 commit c08980a

File tree

21 files changed

+110
-142
lines changed

21 files changed

+110
-142
lines changed

core/deployment/src/main/java/io/quarkus/deployment/NioSocketImplProcessor.java

Lines changed: 0 additions & 14 deletions
This file was deleted.

core/deployment/src/main/java/io/quarkus/deployment/SslProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import io.quarkus.deployment.annotations.BuildProducer;
66
import io.quarkus.deployment.annotations.BuildStep;
77
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
8-
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
8+
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
99
import io.quarkus.runtime.annotations.ConfigPhase;
1010
import io.quarkus.runtime.annotations.ConfigRoot;
1111
import io.smallrye.config.ConfigMapping;
@@ -36,7 +36,7 @@ SslNativeConfigBuildItem setupNativeSsl() {
3636
}
3737

3838
@BuildStep
39-
void runtime(BuildProducer<RuntimeReinitializedClassBuildItem> reinitialized) {
40-
reinitialized.produce(new RuntimeReinitializedClassBuildItem(JAVA_11_PLUS_SSL_LOGGER));
39+
void runtime(BuildProducer<RuntimeInitializedClassBuildItem> reinitialized) {
40+
reinitialized.produce(new RuntimeInitializedClassBuildItem(JAVA_11_PLUS_SSL_LOGGER));
4141
}
4242
}

core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/NativeImageConfigBuildItem.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,23 @@
1717
* during the build process.
1818
* It collects information such as:
1919
* <ul>
20-
* <li>Classes to be initialized at runtime ({@link #runtimeInitializedClasses})</li>
21-
* <li>Classes to be re-initialized at runtime ({@link #runtimeReinitializedClasses})</li>
22-
* <li>Resource bundles to include ({@link #resourceBundles})</li>
23-
* <li>Dynamic proxy definitions ({@link #proxyDefinitions})</li>
24-
* <li>System properties to be set within the native image ({@link #nativeImageSystemProperties})</li>
20+
* <li>Classes to be (re-)initialized at runtime</li>
21+
* <li>Resource bundles to include</li>
22+
* <li>Dynamic proxy definitions</li>
23+
* <li>System properties to be set within the native image</li>
2524
* </ul>
2625
* The final native image configuration is assembled by combining all produced instances of this build item.
2726
* Use the {@link #builder()} method to construct instances.
2827
*/
2928
public final class NativeImageConfigBuildItem extends MultiBuildItem {
3029

3130
private final Set<String> runtimeInitializedClasses;
32-
private final Set<String> runtimeReinitializedClasses;
3331
private final Set<String> resourceBundles;
3432
private final Set<List<String>> proxyDefinitions;
3533
private final Map<String, String> nativeImageSystemProperties;
3634

3735
public NativeImageConfigBuildItem(Builder builder) {
3836
this.runtimeInitializedClasses = Collections.unmodifiableSet(builder.runtimeInitializedClasses);
39-
this.runtimeReinitializedClasses = Collections.unmodifiableSet(builder.runtimeReinitializedClasses);
4037
this.resourceBundles = Collections.unmodifiableSet(builder.resourceBundles);
4138
this.proxyDefinitions = Collections.unmodifiableSet(builder.proxyDefinitions);
4239
this.nativeImageSystemProperties = Collections.unmodifiableMap(builder.nativeImageSystemProperties);
@@ -46,8 +43,13 @@ public Iterable<String> getRuntimeInitializedClasses() {
4643
return runtimeInitializedClasses;
4744
}
4845

46+
/**
47+
* @deprecated Starting with Mandrel/GraalVM 23.1 for JDK 21 this is functionally the same with
48+
* {@link #getRuntimeInitializedClasses()}.
49+
*/
50+
@Deprecated(since = "3.30", forRemoval = true)
4951
public Iterable<String> getRuntimeReinitializedClasses() {
50-
return runtimeReinitializedClasses;
52+
return getRuntimeInitializedClasses();
5153
}
5254

5355
public Iterable<String> getResourceBundles() {
@@ -69,7 +71,6 @@ public static Builder builder() {
6971
public static class Builder {
7072

7173
final Set<String> runtimeInitializedClasses = new HashSet<>();
72-
final Set<String> runtimeReinitializedClasses = new HashSet<>();
7374
final Set<String> resourceBundles = new HashSet<>();
7475
final Set<List<String>> proxyDefinitions = new HashSet<>();
7576
final Map<String, String> nativeImageSystemProperties = new HashMap<>();
@@ -79,9 +80,13 @@ public Builder addRuntimeInitializedClass(String className) {
7980
return this;
8081
}
8182

83+
/**
84+
* @deprecated Starting with Mandrel/GraalVM 23.1 for JDK 21 this is functionally the same with
85+
* {@link Builder#addRuntimeInitializedClass(String)}.
86+
*/
87+
@Deprecated(since = "3.30", forRemoval = true)
8288
public Builder addRuntimeReinitializedClass(String className) {
83-
runtimeReinitializedClasses.add(className);
84-
return this;
89+
return addRuntimeInitializedClass(className);
8590
}
8691

8792
public Builder addResourceBundle(String className) {

core/deployment/src/main/java/io/quarkus/deployment/builditem/nativeimage/RuntimeReinitializedClassBuildItem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* @deprecated Starting with Mandrel/GraalVM 23.1 for JDK 21 this is functionally the same with
1010
* {@link RuntimeInitializedClassBuildItem}.
1111
*/
12-
@Deprecated(since = "3.18")
12+
@Deprecated(since = "3.18", forRemoval = true)
1313
public final class RuntimeReinitializedClassBuildItem extends MultiBuildItem {
1414

1515
private final String className;

core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
import io.quarkus.deployment.builditem.SystemPropertyBuildItem;
9292
import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem;
9393
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
94-
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
94+
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
9595
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
9696
import io.quarkus.deployment.console.ConsoleInstalledBuildItem;
9797
import io.quarkus.deployment.console.QuarkusCommand;
@@ -232,12 +232,12 @@ void setUpDefaultLogCleanupFilters(List<LogCleanupFilterBuildItem> logCleanupFil
232232

233233
@BuildStep
234234
void miscSetup(
235-
Consumer<RuntimeReinitializedClassBuildItem> runtimeInit,
235+
Consumer<RuntimeInitializedClassBuildItem> runtimeInit,
236236
Consumer<NativeImageSystemPropertyBuildItem> systemProp,
237237
Consumer<ServiceProviderBuildItem> provider) {
238-
runtimeInit.accept(new RuntimeReinitializedClassBuildItem(ConsoleHandler.class.getName()));
239-
runtimeInit.accept(new RuntimeReinitializedClassBuildItem("io.smallrye.common.ref.References$ReaperThread"));
240-
runtimeInit.accept(new RuntimeReinitializedClassBuildItem("io.smallrye.common.os.Process"));
238+
runtimeInit.accept(new RuntimeInitializedClassBuildItem(ConsoleHandler.class.getName()));
239+
runtimeInit.accept(new RuntimeInitializedClassBuildItem("io.smallrye.common.ref.References$ReaperThread"));
240+
runtimeInit.accept(new RuntimeInitializedClassBuildItem("io.smallrye.common.os.Process"));
241241
systemProp
242242
.accept(new NativeImageSystemPropertyBuildItem("java.util.logging.manager", "org.jboss.logmanager.LogManager"));
243243
provider.accept(

core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageConfigBuildStep.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem;
2323
import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem;
2424
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
25-
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
2625
import io.quarkus.deployment.pkg.NativeConfig;
2726
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
2827
import io.quarkus.runtime.ssl.SslContextConfigurationRecorder;
@@ -45,17 +44,13 @@ void build(NativeConfig nativeConfig,
4544
BuildProducer<NativeImageProxyDefinitionBuildItem> proxy,
4645
BuildProducer<NativeImageResourceBundleBuildItem> resourceBundle,
4746
BuildProducer<RuntimeInitializedClassBuildItem> runtimeInit,
48-
BuildProducer<RuntimeReinitializedClassBuildItem> runtimeReinit,
4947
BuildProducer<NativeImageSystemPropertyBuildItem> nativeImage,
5048
BuildProducer<SystemPropertyBuildItem> systemProperty,
5149
BuildProducer<JavaLibraryPathAdditionalPathBuildItem> javaLibraryPathAdditionalPath) {
5250
for (NativeImageConfigBuildItem nativeImageConfigBuildItem : nativeImageConfigBuildItems) {
5351
for (String i : nativeImageConfigBuildItem.getRuntimeInitializedClasses()) {
5452
runtimeInit.produce(new RuntimeInitializedClassBuildItem(i));
5553
}
56-
for (String i : nativeImageConfigBuildItem.getRuntimeReinitializedClasses()) {
57-
runtimeReinit.produce(new RuntimeReinitializedClassBuildItem(i));
58-
}
5954
for (Map.Entry<String, String> e : nativeImageConfigBuildItem.getNativeImageSystemProperties().entrySet()) {
6055
nativeImage.produce(new NativeImageSystemPropertyBuildItem(e.getKey(), e.getValue()));
6156
}
@@ -98,13 +93,13 @@ void build(NativeConfig nativeConfig,
9893
}
9994

10095
@BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
101-
void reinitHostNameUtil(BuildProducer<RuntimeReinitializedClassBuildItem> runtimeReInitClass) {
96+
void reinitHostNameUtil(BuildProducer<RuntimeInitializedClassBuildItem> runtimeReInitClass) {
10297
// certain libraries like JBoss logging internally use this class to determine the hostname
10398
// of the system. This HostName class computes and stores the hostname as a static field in a class,
10499
// so we reinitialize this to re-compute the field (and other related fields) during native application's
105100
// runtime
106-
runtimeReInitClass.produce(new RuntimeReinitializedClassBuildItem("org.wildfly.common.net.HostName"));
107-
runtimeReInitClass.produce(new RuntimeReinitializedClassBuildItem("io.smallrye.common.net.HostName"));
101+
runtimeReInitClass.produce(new RuntimeInitializedClassBuildItem("org.wildfly.common.net.HostName"));
102+
runtimeReInitClass.produce(new RuntimeInitializedClassBuildItem("io.smallrye.common.net.HostName"));
108103
}
109104

110105
private Boolean isSslNativeEnabled(SslNativeConfigBuildItem sslNativeConfig,

core/deployment/src/main/java/io/quarkus/deployment/steps/NativeImageFeatureStep.java

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void write(String s, byte[] bytes) {
112112
}
113113
}
114114

115-
if (!runtimeInitializedClassBuildItems.isEmpty()) {
115+
if (!runtimeInitializedClassBuildItems.isEmpty() || !runtimeReinitializedClassBuildItems.isEmpty()) {
116116
// Class[] runtimeInitializedClasses()
117117
MethodCreator runtimeInitializedClasses = file
118118
.getMethodCreator("runtimeInitializedClasses", Class[].class)
@@ -123,7 +123,8 @@ public void write(String s, byte[] bytes) {
123123
ofMethod(Class.class, "getClassLoader", ClassLoader.class),
124124
thisClass);
125125
ResultHandle classesArray = runtimeInitializedClasses.newArray(Class.class,
126-
runtimeInitializedClasses.load(runtimeInitializedClassBuildItems.size()));
126+
runtimeInitializedClasses
127+
.load(runtimeInitializedClassBuildItems.size() + runtimeReinitializedClassBuildItems.size()));
127128
for (int i = 0; i < runtimeInitializedClassBuildItems.size(); i++) {
128129
TryBlock tc = runtimeInitializedClasses.tryBlock();
129130
ResultHandle clazz = tc.invokeStaticMethod(
@@ -133,6 +134,15 @@ public void write(String s, byte[] bytes) {
133134
CatchBlockCreator cc = tc.addCatch(Throwable.class);
134135
cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException());
135136
}
137+
for (int i = 0; i < runtimeReinitializedClassBuildItems.size(); i++) {
138+
TryBlock tc = runtimeInitializedClasses.tryBlock();
139+
ResultHandle clazz = tc.invokeStaticMethod(
140+
ofMethod(Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class),
141+
tc.load(runtimeReinitializedClassBuildItems.get(i).getClassName()), tc.load(false), cl);
142+
tc.writeArrayValue(classesArray, i, clazz);
143+
CatchBlockCreator cc = tc.addCatch(Throwable.class);
144+
cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException());
145+
}
136146
runtimeInitializedClasses.returnValue(classesArray);
137147

138148
ResultHandle classes = overallCatch.invokeStaticMethod(runtimeInitializedClasses.getMethodDescriptor());
@@ -160,33 +170,6 @@ public void write(String s, byte[] bytes) {
160170
overallCatch.invokeStaticMethod(INITIALIZE_PACKAGES_AT_RUN_TIME, packages);
161171
}
162172

163-
// hack in reinitialization of process info classes
164-
if (!runtimeReinitializedClassBuildItems.isEmpty()) {
165-
MethodCreator runtimeReinitializedClasses = file
166-
.getMethodCreator("runtimeReinitializedClasses", Class[].class)
167-
.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
168-
169-
ResultHandle thisClass = runtimeReinitializedClasses.loadClassFromTCCL(GRAAL_FEATURE);
170-
ResultHandle cl = runtimeReinitializedClasses.invokeVirtualMethod(
171-
ofMethod(Class.class, "getClassLoader", ClassLoader.class),
172-
thisClass);
173-
ResultHandle classesArray = runtimeReinitializedClasses.newArray(Class.class,
174-
runtimeReinitializedClasses.load(runtimeReinitializedClassBuildItems.size()));
175-
for (int i = 0; i < runtimeReinitializedClassBuildItems.size(); i++) {
176-
TryBlock tc = runtimeReinitializedClasses.tryBlock();
177-
ResultHandle clazz = tc.invokeStaticMethod(
178-
ofMethod(Class.class, "forName", Class.class, String.class, boolean.class, ClassLoader.class),
179-
tc.load(runtimeReinitializedClassBuildItems.get(i).getClassName()), tc.load(false), cl);
180-
tc.writeArrayValue(classesArray, i, clazz);
181-
CatchBlockCreator cc = tc.addCatch(Throwable.class);
182-
cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException());
183-
}
184-
runtimeReinitializedClasses.returnValue(classesArray);
185-
186-
ResultHandle classes = overallCatch.invokeStaticMethod(runtimeReinitializedClasses.getMethodDescriptor());
187-
overallCatch.invokeStaticMethod(INITIALIZE_CLASSES_AT_RUN_TIME, classes);
188-
}
189-
190173
// Ensure registration of fields being accessed through unsafe is done last to ensure that the class
191174
// initialization configuration is done first. Registering the fields before configuring class initialization
192175
// may results in classes being marked for runtime initialization even if not explicitly requested.

extensions/flyway/deployment/src/main/java/io/quarkus/flyway/deployment/FlywayAlwaysEnabledProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import io.quarkus.deployment.builditem.FeatureBuildItem;
99
import io.quarkus.deployment.builditem.IndexDependencyBuildItem;
1010
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
11-
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
11+
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
1212
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
1313

1414
public class FlywayAlwaysEnabledProcessor {
@@ -22,8 +22,8 @@ void build(BuildProducer<FeatureBuildItem> featureProducer) {
2222
* Reinitialize {@code InsertRowLock} to avoid using a cached seed when invoking {@code getNextRandomString}
2323
*/
2424
@BuildStep
25-
public RuntimeReinitializedClassBuildItem reinitInsertRowLock() {
26-
return new RuntimeReinitializedClassBuildItem(
25+
public RuntimeInitializedClassBuildItem reinitInsertRowLock() {
26+
return new RuntimeInitializedClassBuildItem(
2727
"org.flywaydb.core.internal.database.InsertRowLock");
2828
}
2929

extensions/grpc-common/deployment/src/main/java/io/quarkus/grpc/common/deployment/GrpcCommonProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ NativeImageConfigBuildItem nativeImageConfiguration() {
9090
.addRuntimeInitializedClass("io.grpc.netty.NettyServerBuilder")
9191
.addRuntimeInitializedClass("io.grpc.netty.NettyChannelBuilder")
9292
.addRuntimeInitializedClass("io.grpc.internal.RetriableStream")
93-
.addRuntimeReinitializedClass("com.google.protobuf.UnsafeUtil");
93+
.addRuntimeInitializedClass("com.google.protobuf.UnsafeUtil");
9494
return builder.build();
9595
}
9696

extensions/hibernate-validator/deployment/src/main/java/io/quarkus/hibernate/validator/deployment/HibernateValidatorProcessor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
9797
import io.quarkus.deployment.builditem.nativeimage.ReflectiveFieldBuildItem;
9898
import io.quarkus.deployment.builditem.nativeimage.ReflectiveMethodBuildItem;
99-
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
99+
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
100100
import io.quarkus.deployment.logging.LogCleanupFilterBuildItem;
101101
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
102102
import io.quarkus.deployment.recording.RecorderContext;
@@ -645,8 +645,8 @@ public void init(BeanContainerBuildItem beanContainerBuildItem, HibernateValidat
645645
}
646646

647647
@BuildStep
648-
public RuntimeReinitializedClassBuildItem reinitClockProviderSystemTimezone() {
649-
return new RuntimeReinitializedClassBuildItem(
648+
public RuntimeInitializedClassBuildItem reinitClockProviderSystemTimezone() {
649+
return new RuntimeInitializedClassBuildItem(
650650
"io.quarkus.hibernate.validator.runtime.clockprovider.HibernateValidatorClockProviderSystemZoneIdHolder");
651651
}
652652

0 commit comments

Comments
 (0)