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

java.lang.VerifyError in bytebuddy when installing agent jar to bootstrap classloader #1731

Open
ziyilin opened this issue Dec 4, 2024 · 3 comments
Assignees
Labels
Milestone

Comments

@ziyilin
Copy link

ziyilin commented Dec 4, 2024

The type pollution agent is used to detect a JDK performance bug.
We tried to apply for our application. But we need to modify it a little to install the agent jar to the bootstrap classloader to fit our application's requirement. One of our middleware loads all the classes with its own classloader. The agent classes should be installed to the bootstrap classloader, otherwise the middleware issues an ClassNotFoundException.
But the agent reports the VerifyError from bytebuddy once is installed to bootstrap classloader. The stack trace is:

[Byte Buddy] ERROR io.type.pollution.example.C [jdk.internal.loader.ClassLoaders$AppClassLoader@21588809, unnamed module @51891008, Thread[main,5,main], loaded=false]
java.lang.VerifyError: (class: agent/net/bytebuddy/pool/TypePool$Default$TypeExtractor, method: visitRecordComponent signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lagent/net/bytebuddy/jar/asm/RecordComponentVisitor;) Wrong return type in function
        at agent.net.bytebuddy.pool.TypePool$Default.parse(TypePool.java:856)
        at agent.net.bytebuddy.pool.TypePool$Default.doDescribe(TypePool.java:841)
        at agent.net.bytebuddy.pool.TypePool$Default$WithLazyResolution.access$001(TypePool.java:921)
        at agent.net.bytebuddy.pool.TypePool$Default$WithLazyResolution.doResolve(TypePool.java:1019)
        at agent.net.bytebuddy.pool.TypePool$Default$WithLazyResolution$LazyTypeDescription.delegate(TypePool.java:1088)
        at agent.net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getModifiers(TypeDescription.java:8453)
        at agent.net.bytebuddy.matcher.ModifierMatcher.doMatch(ModifierMatcher.java:60)
        at agent.net.bytebuddy.matcher.ModifierMatcher.doMatch(ModifierMatcher.java:27)
        at agent.net.bytebuddy.matcher.ElementMatcher$Junction$ForNonNullValues.matches(ElementMatcher.java:249)
        at agent.net.bytebuddy.matcher.ElementMatcher$Junction$Disjunction.matches(ElementMatcher.java:214)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$RawMatcher$ForElementMatchers.matches(AgentBuilder.java:1833)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$RawMatcher$Disjunction.matches(AgentBuilder.java:1721)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:11878)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:11838)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1700(AgentBuilder.java:11555)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12318)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:12250)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doPrivileged(AgentBuilder.java)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:11781)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.transform(Unknown Source)
        at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563)
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1022)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)
        at io.type.pollution.example.Main.main(Main.java:62)

I know it might not an issue of bytebuddy. But I have no idea how to get it work with bytebuddy. Any help will be appreciated.

How to Reproduce:
Our modification for the agent is here. The JDK version is 11.

  1. git clone [email protected]:ziyilin/type-pollution-agent.git
  2. git checkout install-bootstrap -b install-bootstrap
  3. mvn clean package
  4. Run without installing to bootstrap classloader. It works well. java -javaagent:agent/target/type-pollution-agent-0.1-SNAPSHOT.jar -jar example/target/type-pollution-example-0.1-SNAPSHOT.jar
  5. Run with installing to boostrap classloader. It reports VerifyError. java -javaagent:agent/target/type-pollution-agent-0.1-SNAPSHOT.jar -Dio.type.pollution.bootstrap=true -jar example/target/type-pollution-example-0.1-SNAPSHOT.jar
@raphw
Copy link
Owner

raphw commented Dec 4, 2024

Could you try bumping Byte Buddy to the latest version first: https://github.com/ziyilin/type-pollution-agent/blob/install-bootstrap/agent/pom.xml#L16

@raphw raphw self-assigned this Dec 4, 2024
@raphw raphw added the question label Dec 4, 2024
@raphw raphw added this to the 1.15.10 milestone Dec 4, 2024
@ziyilin
Copy link
Author

ziyilin commented Dec 5, 2024

Updated Byte Buddy to the latest(1.15.10). The VerifyError is gone, and now reports the following exception:

[Byte Buddy] ERROR io.type.pollution.example.C [jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7, unnamed module @7e774085, Thread[main,5,main], loaded=false]
java.lang.IllegalAccessError: class agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw tried to access protected method 'agent.net.bytebuddy.description.type.TypeList$Generic agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw$RawAnnotatedType$LazyRawAnnotatedTypeList.of(agent.net.bytebuddy.pool.TypePool, java.util.Map, java.util.List)' (agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw is in unnamed module of loader 'app'; agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw$RawAnnotatedType$LazyRawAnnotatedTypeList is in unnamed module of loader 'bootstrap')
        at agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription$GenericTypeToken$Resolution$Raw.resolveInterfaceTypes(TypePool.java:3717)
        at agent.net.bytebuddy.pool.TypePool$Default$LazyTypeDescription.getInterfaces(TypePool.java:2862)
        at agent.net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getInterfaces(TypeDescription.java:8451)
        at agent.net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getInterfaces(TypeDescription.java:8451)
        at agent.net.bytebuddy.dynamic.scaffold.InstrumentedType$Factory$Default$1.represent(InstrumentedType.java:436)
        at agent.net.bytebuddy.ByteBuddy.rebase(ByteBuddy.java:1030)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$TypeStrategy$Default$1.builder(AgentBuilder.java:2820)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:12715)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:12661)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1800(AgentBuilder.java:12370)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:13152)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:13082)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doPrivileged(AgentBuilder.java)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:12604)
        at agent.net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.transform(Unknown Source)
        at java.instrument/sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at java.instrument/sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:541)
        at java.base/java.lang.ClassLoader.defineClass1(Native Method)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        at io.type.pollution.example.Main.main(Main.java:62)

@raphw
Copy link
Owner

raphw commented Dec 5, 2024

It seems like Byte Buddy is both on the class path and on the boot loader in the same namespace. That will not work as the class loader version will query downwards and resolve classes on a different class loader.

You will have to shade Byte Buddy for this during your build, that is move the classes to a different namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants