检测java核心类

时间:2017-11-11 22:52:28

标签: java instrumentation

我需要在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)

1 个答案:

答案 0 :(得分:1)

实际上,例外已包含所有相关信息。异常的类型名称java.lang.UnsupportedOperationException包含术语“不支持操作”,其消息确实命名了不受支持的操作:“尝试更改架构(添加/删除字段)

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

  

重新定义可能会更改方法体,常量池和属性。重定义不得添加,删除或重命名字段或方法,更改方法的签名或更改继承。在将来的版本中可能会取消这些限制。

对于其他类,加载时间检测可能会有所帮助,在运行时第一次定义之前更改声明的字段,但是,对于像java.lang.String这样的关键类,必须在甚至可以加载代理之前存在,不是一种选择。

更改String类的唯一可能方法是在JVM启动时为bootstrap类路径添加替代实现,但是,我强烈反对以这种方式更改配置。在使用这样一个基础类时,你可以轻松地打破整个JVM,甚至可以使用一个JVM(版本),可能会破坏另一个(或下一个版本)......