Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

当jdk 14启用 --enable-preview 时,复杂的类 watch/trace出错 #1526

Closed
hengyunabc opened this issue Sep 24, 2020 · 5 comments
Closed
Labels
bug Something isn't working
Milestone

Comments

@hengyunabc
Copy link
Collaborator

java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the class NestHost, NestMembers, or Record attribute
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
        at com.taobao.arthas.core.advisor.Enhancer.enhance(Enhancer.java:371)
        at com.taobao.arthas.core.command.monitor200.EnhancerCommand.enhance(EnhancerCommand.java:149)
        at com.taobao.arthas.core.command.monitor200.EnhancerCommand.process(EnhancerCommand.java:96)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
        at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:832)

asm已升级为最新版本 9.0,并且使用了最新的API ASM9 。


复现demo:

public class BBB {
    public String test() {
        return "hello";
    }
}
public class FFF {
    public String test() {
        
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                System.err.println("ttt");
            }
            
        });
        t.start();
        return "hello";
    }
}
import java.io.IOException;

public class TTT {
    
    public static void main(String[] args) throws  IOException {
        
        System.err.println(new FFF());
        System.err.println(new BBB());
        System.in.read();
        
    }

}
  • 建立上面三个文件
  • 使用jdk 14来编译:jdk-14.0.2.jdk/Contents/Home/bin/javac --enable-preview --release 14 ./*.java
  • 启动: jdk-14.0.2.jdk/Contents/Home/bin/java --enable-preview TTT
  • 启动 arthas attach
  • watch BBB test ,这个是正常结果
  • watch FFF test ,会抛出上面的异常
@hengyunabc
Copy link
Collaborator Author

另外,在一个复杂的应用上,使用jdk 14,启用了 --enable-preview ,在watch时抛出下面的异常:

2020-09-24 15:38:41 [arthas-command-execute] INFO  c.t.arthas.core.advisor.Enhancer -enhance matched classes: [class com.aliyun.apsaradb.perfv4.store.dbdao.LogDbDao$$EnhancerBySpringCGLIB$$16733ee1, class com.aliyun.apsaradb.perfv4.store.dbdao.LogDbDao]
2020-09-24 15:38:41 [arthas-command-execute] ERROR c.t.arthas.core.advisor.Enhancer -Enhancer error, matchingClasses: [class com.aliyun.apsaradb.perfv4.store.dbdao.LogDbDao$$EnhancerBySpringCGLIB$$16733ee1, class com.aliyun.apsaradb.perfv4.store.dbdao.LogDbDao]
java.lang.ClassFormatError: null
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
        at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167)
        at com.taobao.arthas.core.advisor.Enhancer.enhance(Enhancer.java:371)
        at com.taobao.arthas.core.command.monitor200.EnhancerCommand.enhance(EnhancerCommand.java:149)
        at com.taobao.arthas.core.command.monitor200.EnhancerCommand.process(EnhancerCommand.java:96)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111)
        at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108)
        at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:385)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
        at java.base/java.lang.Thread.run(Thread.java:832)

可以发现有spring aop增强的类: EnhancerBySpringCGLIB ,但和这个类无关。

因为,如果直接 watch 这个spring aop类,结果是正常的。

如果打开 options disable-sub-class true,再次 watch com.aliyun.apsaradb.perfv4.store.dbdao.LogDbDao ,则只会匹配到一个类(没有spring aop类),还是会报错。

本地未能复现,也许和上面的错误类似。

@hengyunabc
Copy link
Collaborator Author

另外,加上-noverify参数,仍然会出错。

@hengyunabc
Copy link
Collaborator Author

options dump true ,打开dump开关,检查下生成的增强的字节码,发现

public class FFF
  minor version: 0
  major version: 49

再检查下代码,是这个commit引起的: 25c5fb7 ,关联issue: #1223

@hengyunabc hengyunabc added the bug Something isn't working label Sep 24, 2020
hengyunabc added a commit that referenced this issue Sep 24, 2020
@hengyunabc hengyunabc added this to the 3.4.3 milestone Sep 24, 2020
@hengyunabc
Copy link
Collaborator Author

原因是 .class 文件里的 java version是两部分组成的,高位是 minor ,通常是0, 低位是 major。 当启动 --enable-preview 时,编译出来的 .class 文件 的 minor version 是 65535 。 之前的代码只是简单的认为 classNode.version 就是 major version,导致出错。

@hengyunabc
Copy link
Collaborator Author

修复包测试: arthas-bin.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant