-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
2.14.3版本在JDK 21中遇到了类转换异常问题,TTL是否支持JDK 21? #555
Comments
从目前的CI构建中看,是覆盖了JDK21的,覆盖了JDK21环境的测试: 建议你反馈你在jdk21环境中你遇到了什么问题,提供相关有效的信息。 |
@wuwen5 异常信息如下, 这个问题在Idea中启动ttl 的 agent能够复现, 以命令方式挂载agent启动没有问题, 猜测是和idea的debug agent有冲突 2023-09-28 10:53:34.927 SEVERE [main] TtlTransformer: Fail to transform class sun/net/httpserver/ServerImpl$ReqRspTimeoutTask, cause: java.lang.NullPointerException: Cannot read field "string" because "utf" is null
java.lang.NullPointerException: Cannot read field "string" because "utf" is null
at com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.ConstPool.getUtf8Info(ConstPool.java:675)
at com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.MethodParametersAttribute.copy(MethodParametersAttribute.java:90)
at com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.AttributeInfo.copyAll(AttributeInfo.java:249)
at com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.MethodInfo.compact(MethodInfo.java:157)
at com.alibaba.ttl.threadpool.agent.internal.javassist.bytecode.ClassFile.compact(ClassFile.java:242)
at com.alibaba.ttl.threadpool.agent.internal.javassist.CtClassType.toBytecode(CtClassType.java:1583)
at com.alibaba.ttl.threadpool.agent.internal.javassist.CtClass.toBytecode(CtClass.java:1519)
at com.alibaba.ttl.threadpool.agent.TtlTransformer.transform(TtlTransformer.java:81)
at java.instrument/java.lang.instrument.ClassFileTransformer.transform(ClassFileTransformer.java:244)
at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:610)
at java.base/java.lang.ClassLoader.defineClass2(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1118)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:182)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:821)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:741)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:665)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at jdk.httpserver/sun.net.httpserver.HttpServerImpl.<init>(HttpServerImpl.java:50)
at jdk.httpserver/sun.net.httpserver.DefaultHttpServerProvider.createHttpServer(DefaultHttpServerProvider.java:35)
at jdk.httpserver/com.sun.net.httpserver.HttpServer.create(HttpServer.java:152)
at jdk.httpserver/com.sun.net.httpserver.HttpServer.create(HttpServer.java:126)
at io.prometheus.client.exporter.HTTPServer.<init>(HTTPServer.java:144)
at io.prometheus.client.exporter.HTTPServer.<init>(HTTPServer.java:165) |
应该是 已提交到 |
知道怎么回事了,问题出现在内部类的字节码发生了细微变化,在java8之后,当使用 使用 public void test(int, java.lang.String);
descriptor: (ILjava/lang/String;)V
flags: (0x0001) ACC_PUBLIC
Code:
stack=0, locals=3, args_size=3
0: return
LineNumberTable:
line 4: 0
MethodParameters:
Name Flags
i
s 默认在jdk中的class应该是没有携带 当使用 test4.MethodParamInnerClassTest$InnerClass(test4.MethodParamInnerClassTest);
descriptor: (Ltest4/MethodParamInnerClassTest;)V
flags: (0x0000)
Code:
(略)
MethodParameters:
Name Flags
this$0 final mandated 当未使用 test4.MethodParamInnerClassTest$InnerClass(test4.MethodParamInnerClassTest);
descriptor: (Ltest4/MethodParamInnerClassTest;)V
flags: (0x0000)
Code:
(略) 而java21如下,仍然携带了 test4.MethodParamInnerClassTest$InnerClass(test4.MethodParamInnerClassTest);
descriptor: (Ltest4/MethodParamInnerClassTest;)V
flags: (0x0000)
Code:
(略)
MethodParameters:
Name Flags
<no name> final mandated 所以,总结为,java21编译的内部类字节码发生了变化,引起的兼容性问题。
JVM规范: |
@wuwen5 是不是意味着即使用jdk8 在添加 |
不会 添加 现在问题是没使用 |
@wuwen5 目前看来只能在 |
先记录下可能与之相关的信息
|
进一步研究发现,影响范围为java21编译出来的非静态的内部类 非静态内部类, 包含 Java21InnerClassWithoutParameters$InnerClass(Java21InnerClassWithoutParameters);
descriptor: (LJava21InnerClassWithoutParameters;)V
flags: (0x0000)
Code:
stack=1, locals=2, args_size=2
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 2: 0
MethodParameters:
Name Flags
<no name> final mandated 静态内部类,不含 Java21InnerClassWithoutParameters$StaticInnerClass();
descriptor: ()V
flags: (0x0000)
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0 |
虚拟机规范允许MethodParameters里面项目名称指向0,表示参数没有名称。javaassist没有考虑这种情况,因为之前好像没有编译器在里面放0所以实际使用时javaassist没出过错。你可以编译个带Optional参数的enum: enum TestEnum {
INSTANCE(Optional.of("A"));
TestEnum(Optional<String> opt) {}
} 也会受影响,因为编译器加了name ordinal两个参数,类似inner class有个outer this参数。 |
当前已发布的 |
我也发现了 看到你在推进让 |
2.14.3版本是不是还不支持JDK21??
The text was updated successfully, but these errors were encountered: