Blocks :
|
|
Relates :
|
|
Relates :
|
The SystemProperty code used for VM argument parsing was reworked in Java 9 as part of the module system updates. In Java 8 the set_value() method was defined as follows: bool set_value(char *value) { if (writeable()) { if (_value != NULL) { FreeHeap(_value); } _value = AllocateHeap(strlen(value)+1, mtInternal); if (_value != NULL) { strcpy(_value, value); } return true; } return false; } so we can only update a writeable flag. In Java 9 this was refactored so that SystemProperty extends PathString, which contains a simple set_value method that always sets the value: bool PathString::set_value(const char *value) { if (_value != NULL) { FreeHeap(_value); } _value = AllocateHeap(strlen(value)+1, mtArguments); assert(_value != NULL, "Unable to allocate space for new path value"); if (_value != NULL) { strcpy(_value, value); } else { // not able to allocate return false; } return true; } and SystemProperty added a new method: // A system property should only have its value set // via an external interface if it is a writeable property. // The internal, non-writeable property jdk.boot.class.path.append // is the only exception to this rule. It can be set externally // via -Xbootclasspath/a or JVMTI OnLoad phase call to AddToBootstrapClassLoaderSearch. // In those cases for jdk.boot.class.path.append, the base class // set_value and append_value methods are called directly. bool set_writeable_value(const char *value) { if (writeable()) { return set_value(value); } return false; } The intent was obviously that in general set_writeable_value should be used to attempt to set the value, but the general property handling code was not updated: // This add maintains unique property key in the list. void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, PropertyAppendable append, PropertyWriteable writeable, PropertyInternal internal) { if (plist == NULL) return; // If property key exist then update with new value. SystemProperty* prop; for (prop = *plist; prop != NULL; prop = prop->next()) { if (strcmp(k, prop->key()) == 0) { if (append == AppendProperty) { prop->append_value(v); } else { prop->set_value(v); } return; } } PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty); } Consequently whether the flag is writeable or not is ignored and it will always be appended or set. As a result the user can override non-writable system properties on the command-line e.g: public class JavaProps { public static void main(String[] args) { System.out.println(System.getProperty(args[0])); } } > java9 JavaProps java.vm.name Java HotSpot(TM) 64-Bit Server VM > java9 -Djava.vm.name=MyVM JavaProps java.vm.name MyVM Property was re-defined by the user! Whereas in Java 8: > java JavaProps java.vm.name OpenJDK 64-Bit Server VM > java -Djava.vm.name=MyVM JavaProps java.vm.name OpenJDK 64-Bit Server VM
|