Skip to content

Commit 5bcb772

Browse files
committed
[GR-68047] Split up and rename future defaults.
PullRequest: graal/21636
2 parents 4ecddea + 7ab9363 commit 5bcb772

20 files changed

+204
-111
lines changed

docs/reference-manual/native-image/JCASecurityServices.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,17 @@ The report will detail all registered service classes, the API methods that trig
3838
3939
## Provider Initialization
4040

41-
Currently security providers are initialized at build time.
42-
To move their initialization to run time, use the option `--future-defaults=all` or `--future-defaults=run-time-initialized-jdk`.
43-
Provider verification will still occur at build time.
41+
Currently, security providers are initialized at build time.
42+
To move their initialization to run time, use the option `--future-defaults=run-time-initialize-security-providers`, `--future-defaults=all`, or `--future-defaults=run-time-initialize-jdk`.
43+
Provider verification will still occur at build time.
4444
Run-time initialization of security providers helps reduce image heap size.
45-
To move their initialization to run time, you can use the flag `--future-defaults=all` or `--future-defaults=run-time-initialized-jdk`.
4645

4746
## Provider Registration
4847

4948
The `native-image` builder captures the list of providers and their preference order from the underlying JVM.
5049
The provider order is specified in the `java.security` file under `<java-home>/conf/security/java.security`.
5150
New security providers cannot be registered at run time by default (see the section above); all providers must be statically configured at executable build time.
52-
If the user specifies `--future-defaults=all` or `--future-defaults=run-time-initialized-jdk` to move providers initialization to run time, then a specific properties file can be used via the command line option `-Djava.security.properties=<path>`.
51+
If the user specifies `--future-defaults=run-time-initialize-security-providers`, `--future-defaults=all`, or `--future-defaults=run-time-initialize-jdk` to move providers initialization to run time, then a specific properties file can be used via the command line option `-Djava.security.properties=<path>`.
5352

5453
## Providers Reordering at Run Time
5554

@@ -61,7 +60,7 @@ Security.removeProvider("BC");
6160
Security.insertProviderAt(bcProvider, 1);
6261
```
6362

64-
If `--future-defaults=all` or `--future-defaults=run-time-initialized-jdk` is enabled, the list of providers is constructed at run time.
63+
If `--future-defaults=all` or `--future-defaults=run-time-initialize-jdk` is enabled, the list of providers is constructed at run time.
6564
The same approach to manipulating providers can then be used.
6665

6766
## SecureRandom

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import java.util.Collections;
2828
import java.util.LinkedHashSet;
29+
import java.util.List;
2930
import java.util.Objects;
3031
import java.util.Set;
3132

@@ -54,26 +55,36 @@
5455
* rolled back. The changes must be aligning native image with the Java spec and must be thoroughly
5556
* reviewed.
5657
* </p>
57-
* Note 2: future defaults can not be simply removed as user code can depend on the system property
58+
* Note 2: future defaults can depend on each other. For example, if some functionality depends on
59+
* <code>run-time-security-providers</code> it can enable it similarly to <code>all</code> that
60+
* enables all future defaults.
61+
* </p>
62+
* Note 3: future defaults can not be simply removed as user code can depend on the system property
5863
* values that are set by the option. When removing a future-default option, one has to leave the
5964
* system property both a build time and at run time set to <code>true</code>.
6065
*/
6166
public class FutureDefaultsOptions {
6267
private static final String OPTION_NAME = "future-defaults";
6368

64-
private static final String DEFAULT_NAME = "<default-value>";
6569
private static final String ALL_NAME = "all";
70+
private static final String RUN_TIME_INITIALIZE_JDK = "run-time-initialize-jdk";
6671
private static final String NONE_NAME = "none";
67-
private static final String RUN_TIME_INITIALIZE_JDK_NAME = "run-time-initialized-jdk";
68-
private static final String TREAT_NAME_AS_TYPE_NAME = "treat-name-as-type";
69-
70-
public static final String RUN_TIME_INITIALIZE_JDK_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_JDK_NAME + ")";
71-
72+
/**
73+
* Macro commands: They enable or disable other defaults, but they are not future defaults
74+
* themselves.
75+
*/
76+
private static final Set<String> ALL_COMMANDS = Set.of(ALL_NAME, RUN_TIME_INITIALIZE_JDK, NONE_NAME);
77+
78+
private static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS = "run-time-initialize-security-providers";
79+
private static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS = "run-time-initialize-file-system-providers";
80+
private static final String COMPLETE_REFLECTION_TYPES = "complete-reflection-types";
81+
private static final Set<String> ALL_FUTURE_DEFAULTS = Set.of(RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS, RUN_TIME_INITIALIZE_SECURITY_PROVIDERS, COMPLETE_REFLECTION_TYPES);
82+
83+
public static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_SECURITY_PROVIDERS + ")";
84+
public static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS + ")";
85+
private static final String DEFAULT_NAME = "<default-value>";
7286
public static final String SYSTEM_PROPERTY_PREFIX = ImageInfo.PROPERTY_NATIVE_IMAGE_PREFIX + OPTION_NAME + ".";
7387

74-
private static final Set<String> ALL_FUTURE_DEFAULTS = Set.of(RUN_TIME_INITIALIZE_JDK_NAME, TREAT_NAME_AS_TYPE_NAME);
75-
private static final Set<String> ALL_COMMANDS = Set.of(ALL_NAME, NONE_NAME);
76-
7788
private static String futureDefaultsAllValues() {
7889
return StringUtil.joinSingleQuoted(getAllValues());
7990
}
@@ -128,6 +139,8 @@ public static void parseAndVerifyOptions() {
128139

129140
if (value.equals(ALL_NAME)) {
130141
futureDefaults.addAll(ALL_FUTURE_DEFAULTS);
142+
} else if (value.equals(RUN_TIME_INITIALIZE_JDK)) {
143+
futureDefaults.addAll(List.of(RUN_TIME_INITIALIZE_SECURITY_PROVIDERS, RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS));
131144
} else {
132145
futureDefaults.add(value);
133146
}
@@ -143,15 +156,31 @@ public static Set<String> getFutureDefaults() {
143156
return Collections.unmodifiableSet(Objects.requireNonNull(futureDefaults, "must be initialized before usage"));
144157
}
145158

159+
/**
160+
* @see FutureDefaultsOptions#FutureDefaults
161+
*/
146162
public static boolean allFutureDefaults() {
147163
return getFutureDefaults().containsAll(ALL_FUTURE_DEFAULTS);
148164
}
149165

150-
public static boolean isJDKInitializedAtRunTime() {
151-
return getFutureDefaults().contains(RUN_TIME_INITIALIZE_JDK_NAME);
166+
/**
167+
* @see FutureDefaultsOptions#FutureDefaults
168+
*/
169+
public static boolean completeReflectionTypes() {
170+
return getFutureDefaults().contains(COMPLETE_REFLECTION_TYPES);
171+
}
172+
173+
/**
174+
* @see FutureDefaultsOptions#FutureDefaults
175+
*/
176+
public static boolean securityProvidersInitializedAtRunTime() {
177+
return getFutureDefaults().contains(RUN_TIME_INITIALIZE_SECURITY_PROVIDERS);
152178
}
153179

154-
public static boolean treatNameAsType() {
155-
return getFutureDefaults().contains(TREAT_NAME_AS_TYPE_NAME);
180+
/**
181+
* @see FutureDefaultsOptions#FutureDefaults
182+
*/
183+
public static boolean fileSystemProvidersInitializedAtRunTime() {
184+
return getFutureDefaults().contains(RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS);
156185
}
157186
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public static EnumSet<ConfigurationParserOption> getConfigurationParserOptions()
181181
if (TreatAllTypeReachableConditionsAsTypeReached.getValue()) {
182182
result.add(ConfigurationParserOption.TREAT_ALL_TYPE_REACHABLE_CONDITIONS_AS_TYPE_REACHED);
183183
}
184-
if (TreatAllNameEntriesAsType.getValue() || FutureDefaultsOptions.treatNameAsType()) {
184+
if (TreatAllNameEntriesAsType.getValue() || FutureDefaultsOptions.completeReflectionTypes()) {
185185
result.add(ConfigurationParserOption.TREAT_ALL_NAME_ENTRIES_AS_TYPE);
186186
}
187187
return result;
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
Enable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'run-time-initialized-jdk', 'none'.
1+
Enable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'treat-name-as-type', 'run-time-initialize-security-providers', 'run-time-initialize-file-system-providers', and 'none'.
22

33
The preferred way to use this option is '--future-defaults=all'. The meaning of each possible option is as follows:
44
1. 'all' is the preferred option, and it enables all other behaviors.
5-
2. 'run-time-initialized-jdk' shifts away from build-time initialization of the JDK, instead initializing most of it at run time. This transition is gradual, with individual components of the JDK becoming run-time initialized in each release. This process should complete with JDK 29 when this option should not be needed anymore. Unless you store classes from the JDK in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
6-
3. 'none' forcefully disables all enabled options. This can be used only on the command line to override choices taken by inaccessible parts of the build process.
5+
2. 'complete-reflection-types' reflective registration of a type, via metadata files or the Feature API, always includes all type metadata. Now, all registered types behave the same as types defined in 'reachability-metadata.json'.
6+
3. 'run-time-initialize-security-providers' shifts away from build-time initialization for 'java.security.Provider'. Unless you store 'java.security.Provider'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
7+
4. 'run-time-initialize-file-system-providers' shifts away from build-time initialization for 'java.nio.file.spi.FileSystemProvider'. Unless you store 'FileSystemProvider'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
8+
5. 'none' forcefully disables all enabled options. This can be used only on the command line to override choices taken by inaccessible parts of the build process.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/FileSystemProviderSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public final class FileSystemProviderSupport {
4444

4545
@Platforms(Platform.HOSTED_ONLY.class)
4646
public static void register(FileSystemProvider provider) {
47-
VMError.guarantee(!FutureDefaultsOptions.isJDKInitializedAtRunTime(), "No need to register FileSystemProvider if the JDK is initialized at run time.");
47+
VMError.guarantee(!FutureDefaultsOptions.fileSystemProvidersInitializedAtRunTime(), "No need to register FileSystemProvider if the JDK is initialized at run time.");
4848
FileSystemProviderBuildTimeInitSupport.register(provider);
4949
}
5050

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jdk;
26+
27+
import java.util.function.BooleanSupplier;
28+
29+
import com.oracle.svm.core.FutureDefaultsOptions;
30+
31+
public class FileSystemProvidersInitializedAtBuildTime implements BooleanSupplier {
32+
@Override
33+
public boolean getAsBoolean() {
34+
return !FutureDefaultsOptions.fileSystemProvidersInitializedAtRunTime();
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.jdk;
26+
27+
import java.util.function.BooleanSupplier;
28+
29+
import com.oracle.svm.core.FutureDefaultsOptions;
30+
31+
public class FileSystemProvidersInitializedAtRunTime implements BooleanSupplier {
32+
@Override
33+
public boolean getAsBoolean() {
34+
return FutureDefaultsOptions.fileSystemProvidersInitializedAtRunTime();
35+
}
36+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDKInitializedAtRunTime.java renamed to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecurityProvidersInitializedAtBuildTime.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828

2929
import com.oracle.svm.core.FutureDefaultsOptions;
3030

31-
public class JDKInitializedAtRunTime implements BooleanSupplier {
31+
public class SecurityProvidersInitializedAtBuildTime implements BooleanSupplier {
3232
@Override
3333
public boolean getAsBoolean() {
34-
return FutureDefaultsOptions.isJDKInitializedAtRunTime();
34+
return !FutureDefaultsOptions.securityProvidersInitializedAtRunTime();
3535
}
3636
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JDKInitializedAtBuildTime.java renamed to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecurityProvidersInitializedAtRunTime.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828

2929
import com.oracle.svm.core.FutureDefaultsOptions;
3030

31-
public class JDKInitializedAtBuildTime implements BooleanSupplier {
31+
public class SecurityProvidersInitializedAtRunTime implements BooleanSupplier {
3232
@Override
3333
public boolean getAsBoolean() {
34-
return !FutureDefaultsOptions.isJDKInitializedAtRunTime();
34+
return FutureDefaultsOptions.securityProvidersInitializedAtRunTime();
3535
}
3636
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SecuritySubstitutions.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ private static void setJavaHome(String newJavaHome) {
250250
* properly signed and can be used by JCE. It does that via jar verification which we cannot
251251
* support.
252252
*/
253-
@TargetClass(className = "javax.crypto.JceSecurity", onlyWith = JDKInitializedAtBuildTime.class)
253+
@TargetClass(className = "javax.crypto.JceSecurity", onlyWith = SecurityProvidersInitializedAtBuildTime.class)
254254
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+27/src/java.base/share/classes/javax/crypto/JceSecurity.java.template")
255255
@SuppressWarnings({"unused"})
256256
final class Target_javax_crypto_JceSecurity {
@@ -303,7 +303,7 @@ static Exception getVerificationResult(Provider p) {
303303
}
304304
}
305305

306-
@TargetClass(className = "javax.crypto.JceSecurity", innerClass = "WeakIdentityWrapper", onlyWith = JDKInitializedAtBuildTime.class)
306+
@TargetClass(className = "javax.crypto.JceSecurity", innerClass = "WeakIdentityWrapper", onlyWith = SecurityProvidersInitializedAtBuildTime.class)
307307
@SuppressWarnings({"unused"})
308308
final class Target_javax_crypto_JceSecurity_WeakIdentityWrapper {
309309

@@ -377,7 +377,7 @@ public boolean implies(ProtectionDomain domain, Permission permission) {
377377
}
378378
}
379379

380-
@TargetClass(className = "sun.security.jca.ProviderConfig", onlyWith = JDKInitializedAtBuildTime.class)
380+
@TargetClass(className = "sun.security.jca.ProviderConfig", onlyWith = SecurityProvidersInitializedAtBuildTime.class)
381381
@SuppressWarnings({"unused", "static-method"})
382382
final class Target_sun_security_jca_ProviderConfig {
383383

0 commit comments

Comments
 (0)