检测 java 核心 类

Instrumenting java core classes

出于某些检测目的,我需要在 java.lang.string 中添加一个变量。有可能吗?当我这样做时出现以下异常:

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)

实际上,异常已经包含了所有相关信息。异常的类型名称 java.lang.UnsupportedOperationException 包含术语“ 不支持操作 ”,其消息确实命名了不受支持的操作:“ 试图更改模式(add/remove 字段)”.

换句话说,HotSpot JVM 不支持在 class 重新定义期间添加或删除字段,无论是在核心 class 还是任何其他 class 上尝试。正如 the documentation 所述:

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.

对于其他 classes,加载时间 Instrumentation 可能会有所帮助,在运行时的第一个定义之前更改声明的字段,但是,对于像 java.lang.String 这样的关键 class,它必须在代理可以加载之前存在,这不是一个选项。

更改 String class 的唯一可能方法是在 JVM 启动时为 bootstrap class 路径添加一个替代实现,但是,我强烈反对以这种方式改变配置。在使用这样一个基础 class 时,您可能会很容易地破坏整个 JVM,甚至,在一个 JVM(版本)上发生的事情,可能会破坏另一个(或下一个版本)......