24
24
*/
25
25
package com .oracle .svm .core .jdk ;
26
26
27
+ import java .util .ArrayList ;
28
+ import java .util .Arrays ;
27
29
import java .util .Collections ;
28
30
import java .util .HashMap ;
31
+ import java .util .HashSet ;
32
+ import java .util .List ;
29
33
import java .util .Map ;
30
34
import java .util .Properties ;
35
+ import java .util .Set ;
36
+ import java .util .concurrent .ConcurrentHashMap ;
31
37
import java .util .function .Supplier ;
32
38
39
+ import com .oracle .svm .core .option .RuntimeOptionKey ;
40
+ import org .graalvm .compiler .options .Option ;
41
+ import org .graalvm .compiler .serviceprovider .JavaVersionUtil ;
33
42
import org .graalvm .nativeimage .ImageInfo ;
34
43
import org .graalvm .nativeimage .Platform ;
35
44
import org .graalvm .nativeimage .Platforms ;
48
57
*/
49
58
public abstract class SystemPropertiesSupport {
50
59
60
+ public static class SystemPropertyFeatureOptions {
61
+ @ Option (help = "Report the usage of undefined property as exception when it is not explicitly set)" )//
62
+ public static final RuntimeOptionKey <Boolean > ReportUndefinedSystemPropertyError = new RuntimeOptionKey <>(false );
63
+ }
64
+
65
+ private enum ChangedType {
66
+ Removed , Added
67
+ }
68
+
69
+ private static class PropertyInfo {
70
+ public PropertyInfo (String name , int version , ChangedType changed ) {
71
+ this (name , version , changed , false , null );
72
+ }
73
+
74
+ public PropertyInfo (String name , int version , ChangedType changed , boolean sameAsHosted ){
75
+ this (name , version , changed , sameAsHosted , null );
76
+ }
77
+
78
+ public PropertyInfo (String name , int version , ChangedType changed , boolean sameAsHosted , String initValue ) {
79
+ this .name = name ;
80
+ this .version = version ;
81
+ this .changed = changed ;
82
+ this .sameAsHosted = sameAsHosted ;
83
+ this .initValue = initValue ;
84
+ }
85
+
86
+ public String name ;
87
+ public int version ;
88
+ public ChangedType changed ;
89
+ public boolean sameAsHosted ;
90
+ public String initValue ;
91
+ }
92
+
51
93
/** System properties that are taken from the VM hosting the image generator. */
52
- private static final String [] HOSTED_PROPERTIES = {
53
- "java.version" ,
54
- ImageInfo .PROPERTY_IMAGE_KIND_KEY ,
55
- /*
56
- * We do not support cross-compilation for now. Separator might also be cached
57
- * in other classes, so changing them would be tricky.
58
- */
59
- "line.separator" , "path.separator" , "file.separator" ,
60
- /* For our convenience for now. */
61
- "file.encoding" , "sun.jnu.encoding" ,
62
- "java.class.version" ,
63
- "java.specification.name" ,
64
- "java.specification.vendor" ,
65
- "java.specification.version" ,
66
- "java.vm.specification.name" ,
67
- "java.vm.specification.vendor" ,
68
- "java.vm.specification.version"
69
- };
94
+ private static final Set <String > HOSTED_PROPERTIES = new HashSet <>(Arrays .asList (
95
+ "java.version" ,
96
+ ImageInfo .PROPERTY_IMAGE_KIND_KEY ,
97
+ /*
98
+ * We do not support cross-compilation for now. Separator might also be cached
99
+ * in other classes, so changing them would be tricky.
100
+ */
101
+ "line.separator" , "path.separator" , "file.separator" ,
102
+ /* For our convenience for now. */
103
+ "file.encoding" , "sun.jnu.encoding" ,
104
+ "java.class.version" ,
105
+ "java.specification.name" ,
106
+ "java.specification.vendor" ,
107
+ "java.specification.version" ,
108
+ "java.vm.specification.name" ,
109
+ "java.vm.specification.vendor" ,
110
+ "java.vm.specification.version" ,
111
+ "java.runtime.version" ,
112
+ "sun.cpu.endian" ,
113
+ "sun.cpu.isalist" ,
114
+ "sun.io.unicode.encoding" ));
115
+
116
+ /** Undefined properties that are not changed since JDK8.
117
+ * This collection is used as baseline*/
118
+ private static final String [] UNDEFINED_UNCHANGED_PROPERTIES_8 = {
119
+ "awt.toolkit" ,
120
+ "java.awt.graphicsenv" ,
121
+ "java.awt.printerjob" ,
122
+ "java.home" ,
123
+ "sun.java.command" ,
124
+ "sun.java.launcher" ,
125
+ "sun.os.patch.level" ,
126
+ "user.country" ,
127
+ "user.language" ,
128
+ "user.timezone" };
129
+
130
+ /** Properties are removed or added since JDK8*/
131
+ private static final List <PropertyInfo > CHANGED_PROPERTIES_SINCE_8 = new ArrayList <>(
132
+ Arrays .asList (
133
+ // http://openjdk.java.net/jeps/261 http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/c558850fac57
134
+ new PropertyInfo ("sun.boot.class.path" , 9 , ChangedType .Removed , false , "" ),
135
+ // http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/e336cbd8b15e
136
+ new PropertyInfo ("java.ext.dirs" , 9 , ChangedType .Removed , false , "" ),
137
+ new PropertyInfo ("java.endorsed.dirs" , 9 , ChangedType .Removed , false , "" ),
138
+ // http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/3b241fb72b89
139
+ new PropertyInfo ("java.vm.compressedOopsMode" , 9 , ChangedType .Added ),
140
+ // http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/39c579b50006
141
+ new PropertyInfo ("jdk.debug" , 9 , ChangedType .Added ),
142
+ // https://openjdk.java.net/jeps/322
143
+ new PropertyInfo ("java.version.date" , 10 , ChangedType .Added , true ),
144
+ new PropertyInfo ("java.vendor.version" , 10 , ChangedType .Added , true ),
145
+ // https://github.com/openjdk/jdk/commit/d4941f14af150fb81db7cff5394192637be701dd
146
+ new PropertyInfo ("file.encoding.pkg" , 11 , ChangedType .Removed , true )
147
+ )
148
+ );
149
+
150
+ /** Properties can be initiated at build time and are available at build time's JDK version */
151
+ private static final List <PropertyInfo > CUR_VERSION_INIT_PROPERTIES = new ArrayList <>();
152
+
153
+ /** Undefined properties for JDK version got from JavaVersionUtil.JAVA_SPEC */
154
+ private static final Set <String > UNDEFINED_PROPERTIES = ConcurrentHashMap .newKeySet ();
155
+
156
+ static {
157
+ UNDEFINED_PROPERTIES .addAll (Arrays .asList (UNDEFINED_UNCHANGED_PROPERTIES_8 ));
158
+
159
+ for (PropertyInfo propertyInfo : CHANGED_PROPERTIES_SINCE_8 ) {
160
+ // Add properties introduced at current and lower JDK versions
161
+ if (JavaVersionUtil .JAVA_SPEC >= propertyInfo .version && propertyInfo .changed == ChangedType .Added ) {
162
+ addProperty (propertyInfo );
163
+ }
164
+ // Add back properties that are removed in higher JDK version
165
+ if (JavaVersionUtil .JAVA_SPEC < propertyInfo .version && propertyInfo .changed == ChangedType .Removed ) {
166
+ addProperty (propertyInfo );
167
+ }
168
+ }
169
+ }
170
+
171
+ private static void addProperty (PropertyInfo propertyInfo ) {
172
+ if (!propertyInfo .sameAsHosted && propertyInfo .initValue == null ) {
173
+ UNDEFINED_PROPERTIES .add (propertyInfo .name );
174
+ } else if (propertyInfo .sameAsHosted ) {
175
+ HOSTED_PROPERTIES .add (propertyInfo .name );
176
+ } else {
177
+ CUR_VERSION_INIT_PROPERTIES .add (propertyInfo );
178
+ }
179
+ }
70
180
71
181
/** System properties that are lazily computed at run time on first access. */
72
182
private final Map <String , Supplier <String >> lazyRuntimeValues ;
@@ -95,9 +205,10 @@ protected SystemPropertiesSupport() {
95
205
initializeProperty ("java.vendor.url" , "https://www.graalvm.org/" );
96
206
97
207
initializeProperty ("java.class.path" , "" );
98
- initializeProperty ("java.endorsed.dirs" , "" );
99
- initializeProperty ("java.ext.dirs" , "" );
100
- initializeProperty ("java.library.path" , "" );
208
+ initializeProperty ("java.runtime.name" , "Substrate VM Runtime Environment" );
209
+ initializeProperty ("sun.management.compiler" , "GraalVM Compiler" );
210
+ initializeProperty ("java.vendor.url.bug" , "https://github.com/oracle/graal/issues" );
211
+ initializeProperty ("java.vm.info" , "static mode" );
101
212
initializeProperty ("sun.arch.data.model" , Integer .toString (ConfigurationValues .getTarget ().wordJavaKind .getBitCount ()));
102
213
103
214
String targetName = System .getProperty ("svm.targetName" );
@@ -107,6 +218,10 @@ protected SystemPropertiesSupport() {
107
218
108
219
initializeProperty (ImageInfo .PROPERTY_IMAGE_CODE_KEY , ImageInfo .PROPERTY_IMAGE_CODE_VALUE_RUNTIME );
109
220
221
+ for (PropertyInfo propertyInfo : CUR_VERSION_INIT_PROPERTIES ){
222
+ initializeProperty (propertyInfo .name , propertyInfo .initValue );
223
+ }
224
+
110
225
lazyRuntimeValues = new HashMap <>();
111
226
lazyRuntimeValues .put ("user.name" , this ::userName );
112
227
lazyRuntimeValues .put ("user.home" , this ::userHome );
@@ -141,7 +256,15 @@ public Properties getProperties() {
141
256
142
257
protected String getProperty (String key ) {
143
258
initializeLazyValue (key );
144
- return properties .getProperty (key );
259
+ String ret = properties .getProperty (key );
260
+ if (ret == null && isUndefined (key ) && SystemPropertyFeatureOptions .ReportUndefinedSystemPropertyError .getValue ()) {
261
+ throw new UndefinedSystemPropertyException ("Java system property " + key + " is incompatible in native image. Please explicitly assign the expected value via -D" + key + "=, or avoid using this property." );
262
+ }
263
+ return ret ;
264
+ }
265
+
266
+ public static boolean isUndefined (String key ) {
267
+ return UNDEFINED_PROPERTIES .contains (key );
145
268
}
146
269
147
270
public void setProperties (Properties props ) {
0 commit comments