I need to add a variable in java.lang.string for some instrumentation purpose. Is it possible to do ? I am getting the following exception when i do:
java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)
at sun.instrument.InstrumentationImpl.redefineClasses0(Native Method)
at sun.instrument.InstrumentationImpl.redefineClasses(InstrumentationImpl.java:170)
at com.javapapers.java.instrumentation.DurationAgent.premain(DurationAgent.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Actually, the exception does already contain all relevant information. The exception’s type name java.lang.UnsupportedOperationException
contains the term “unsupport operation” and its message does name the unsupported operation: “attempted to change the schema (add/remove fields)”.
In other words, adding or removing fields during a class redefinition is not supported by the HotSpot JVM, whether attempted on a core class or any other class. As the documentation states:
The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions.
For other classes, load time Instrumentation may help, changing the declared fields before its first definition in the runtime, however, for a crucial class like java.lang.String
, which must be present before even Agents can be loaded, that is not an option.
The only possible way to change the String
class is to prepend an alternative implementation to the bootstrap class path on JVM startup, however, I strongly discourage from altering the configuration in such a way. You can break the entire JVM too easily when playing with such a fundamental class, it’s even that, what happen to work with one JVM (version), may break the other (or next version)…