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

ClassFormatError when using indy dispatch #880

Closed
felixbarny opened this issue Jun 12, 2020 · 15 comments
Closed

ClassFormatError when using indy dispatch #880

felixbarny opened this issue Jun 12, 2020 · 15 comments
Assignees
Labels
Milestone

Comments

@felixbarny
Copy link
Contributor

When instrumenting org.slf4j.LoggerFactory<init> with a simple enter advice that is dispatched with invokedynamic I get the following exception:

java.lang.IllegalStateException: Error invoking java.lang.instrument.Instrumentation#retransformClasses
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(AgentBuilder.java:6877) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector$ForRetransformation.doApply(AgentBuilder.java:7148) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector.apply(AgentBuilder.java:6993) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy.apply(AgentBuilder.java:4855) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default.doInstall(AgentBuilder.java:9463) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:9384) ~[byte-buddy-dep-1.10.11.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$Delegator.installOn(AgentBuilder.java:10986) ~[byte-buddy-dep-1.10.11.jar:?]
	at co.elastic.apm.agent.bci.ElasticApmAgent.initInstrumentation(ElasticApmAgent.java:173) ~[classes/:?]
	at co.elastic.apm.agent.bci.ElasticApmAgent.initInstrumentation(ElasticApmAgent.java:152) ~[classes/:?]
	at co.elastic.apm.agent.bci.InstrumentationTest.testPatchClassFileVersionToJava7(InstrumentationTest.java:292) ~[test-classes/:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628) ~[junit-platform-commons-1.4.2.jar:1.4.2]
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at java.util.ArrayList.forEach(ArrayList.java:1540) ~[?:?]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at java.util.ArrayList.forEach(ArrayList.java:1540) ~[?:?]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) ~[junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) ~[junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69) [junit5-rt.jar:?]
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) [junit-rt.jar:?]
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) [junit-rt.jar:?]
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) [junit-rt.jar:?]
Caused by: java.lang.ClassFormatError
	at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method) ~[?:?]
	at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(AgentBuilder.java:6869) ~[byte-buddy-dep-1.10.11.jar:?]
	... 60 more

Note that the target class file version of this class is 49 and I'm patching it to 51 in order to be able to insert the invokedynamic. But the patching seems to work fine as dispatching via a static method call works as expected.

Note that the constructor is private, empty, and doesn't appear in the output of javap at all.

There's a dump of the instrumented and original class:
LoggerFactory.zip

@felixbarny
Copy link
Contributor Author

The same happens when trying to instrument the type initializer. Instrumenting any other method of that class doesn't result in this issue.

@felixbarny
Copy link
Contributor Author

I've tried to load this with a ByteArrayClassLaoder and the error message is more descriptive: java.lang.ClassFormatError: Bad method name at constant pool index 187 in class file org/slf4j/LoggerFactory

This is the diff of the constant pool, compared to the original class file (as shown by javap)

  #519 = Utf8               co.elastic.apm.agent.bci.InstrumentationTest$CommonsLangInstrumentation
  #520 = String             #519          // co.elastic.apm.agent.bci.InstrumentationTest$CommonsLangInstrumentation
  #521 = Methodref          #91.#294      // org/slf4j/LoggerFactory."<init>":()V
  #522 = MethodHandle       7:#521        // REF_invokeSpecial org/slf4j/LoggerFactory."<init>":()V
  #523 = String             #187          // <init>
  #524 = Utf8               java/lang/IndyBootstrapDispatcher
  #525 = Class              #524          // java/lang/IndyBootstrapDispatcher
  #526 = Utf8               bootstrap
  #527 = Utf8               (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;I)Ljava/lang/invoke/CallSite;
  #528 = NameAndType        #526:#527     // bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;I)Ljava/lang/invoke/CallSite;
  #529 = Methodref          #525.#528     // java/lang/IndyBootstrapDispatcher.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;I)Ljava/lang/invoke/CallSite;
  #530 = MethodHandle       6:#529        // REF_invokeStatic java/lang/IndyBootstrapDispatcher.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;I)Ljava/lang/invoke/CallSite;
  #531 = Utf8               onEnter
  #532 = NameAndType        #531:#188     // onEnter:()V
  #533 = InvokeDynamic      #0:#532       // #0:onEnter:()V
  #534 = Class              #185          // "[Ljava/lang/String;"
  #535 = Utf8               StackMapTable
  #536 = Utf8               BootstrapMethods

And the BootstrapMethod attachments:

SourceFile: "LoggerFactory.java"
BootstrapMethods:
  0: #530 REF_invokeStatic java/lang/IndyBootstrapDispatcher.bootstrap:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;I)Ljava/lang/invoke/CallSite;
    Method arguments:
      #520 co.elastic.apm.agent.bci.InstrumentationTest$CommonsLangInstrumentation
      #91 org/slf4j/LoggerFactory
      #522 REF_invokeSpecial org/slf4j/LoggerFactory."<init>":()V
      #523 <init>
      #166 0

I think the issue this BootstrapMethod entry:

      #522 REF_invokeSpecial org/slf4j/LoggerFactory."<init>":()V

This is invalid because there's no explicit constructor defined in LoggerFactory. Not sure if it has something to do with the patching from bytecode version 49 to 51?

@raphw
Copy link
Owner

raphw commented Jun 13, 2020

I know what it is then. Bootstrap methods require a method name argument, if you use it or not. Constructors and type initializers have special names, and which probably cause the verifier to reject the argument. I'll just pass an empty string instead.

I'll fix it in the next days and release a new version.

@felixbarny
Copy link
Contributor Author

I'm not sure that's the issue. It only seems to be a problem when the constructor is private. Instrumenting the constructor of org.slf4j.event.SubstituteLoggingEvent, for example, works as expected.

The thing with LogFactory's constructor is that it's private and the constructor method is not even in the bytecode of the class file. This seems to be the case even for classes compiled with bytecode level 51 (Java 7) (I've checked org.apache.commons.pool2.impl.CallStackUtils)

Because of that referencing the non-existing constructor in a bootstrap method seems to cause the verifier error.

@felixbarny
Copy link
Contributor Author

@raphw
Copy link
Owner

raphw commented Jun 14, 2020

The constructor is part of the class file. Or what did you mean by it's "not even in the bytecode"? I found it in the zip you sent as an empty implementation simply calling down the class hierarchy chain:

private org.slf4j.LoggerFactory();
  descriptor: ()V
  flags: ACC_PRIVATE
  Code:
    stack=1, locals=1, args_size=1
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
    LineNumberTable:
      line 105: 0
      line 106: 4
    LocalVariableTable:
      Start  Length  Slot  Name   Signature
          0       5     0  this   Lorg/slf4j/LoggerFactory;

Did you run javap with -p? Without the flag, it's hiding any private members.

@raphw
Copy link
Owner

raphw commented Jun 14, 2020

I still think it's a verifier issue not allowing the "special naming" convention that normally applies to constructors. The entry in question is:

#187 = Utf8               <init>

I'll try a patch on a branch for you to try out.

@felixbarny
Copy link
Contributor Author

Oh boy, I did not add the -p option 🤦

@raphw
Copy link
Owner

raphw commented Jun 14, 2020

I found the problem. Constructors require a special handle type when being added as a bootstrap method, invokespacial_new rather then invokespecial which is required for private methods. Private constructors were incorrectly resolved with the latter handle type.

I fixed this on master. Can you try again with the master thread?

@raphw raphw self-assigned this Jun 14, 2020
@raphw raphw added the bug label Jun 14, 2020
@raphw raphw added this to the 1.10.11 milestone Jun 14, 2020
@felixbarny
Copy link
Contributor Author

felixbarny commented Jun 15, 2020

Almost there. There's the same problem with <clinit> now. See also this section of the JVM spec:

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8

If the value of the reference_kind item is 5 (REF_invokeVirtual), 6 (REF_invokeStatic), 7 (REF_invokeSpecial), or 9 (REF_invokeInterface), the name of the method represented by a CONSTANT_Methodref_info structure or a CONSTANT_InterfaceMethodref_info structure must not be <init> or <clinit>.

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.1.9.invokedynamic

An invokedynamic instruction is type safe iff all of the following are true:

  • Its first operand, CP, refers to a constant pool entry denoting an dynamic call site with name
  • CallSiteName with descriptor Descriptor.
  • CallSiteName is not <init>.
  • CallSiteName is not <clinit>.
  • One can validly replace types matching the argument types given in Descriptor on the incoming operand stack with the return type given in Descriptor, yielding the outgoing type state.

Not sure what the right reference kind for <clinit> is though.

@raphw
Copy link
Owner

raphw commented Jun 15, 2020

True, obviously, it is not possible to create a handle to <clinit> as it can only be invoked by the VM itself but nor from code. For this to work, the handle argument needs to be dropped. Since null is not a possible constant value, you need to overload the method to avoid the handle argument.

You can check the latest master version to test this.

felixbarny added a commit to felixbarny/apm-agent-java that referenced this issue Jun 15, 2020
@felixbarny
Copy link
Contributor Author

I get this exception now:

java.lang.IllegalArgumentException: value [Ljava.lang.Object;@66a5755
	at org.objectweb.asm.SymbolTable.addConstant(SymbolTable.java:501) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.SymbolTable.addBootstrapMethod(SymbolTable.java:1052) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.SymbolTable.addConstantInvokeDynamic(SymbolTable.java:905) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodWriter.visitInvokeDynamicInsn(MethodWriter.java:1072) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodVisitor.visitInvokeDynamicInsn(MethodVisitor.java:461) ~[asm-8.0.1.jar:8.0.1]
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ValidatingClassVisitor$ValidatingMethodVisitor.visitInvokeDynamicInsn(TypeWriter.java:3694) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at org.objectweb.asm.tree.InvokeDynamicInsnNode.accept(InvokeDynamicInsnNode.java:84) ~[asm-tree-8.0.1.jar:8.0.1]
	at org.objectweb.asm.tree.InsnList.accept(InsnList.java:144) ~[asm-tree-8.0.1.jar:8.0.1]
	at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:751) ~[asm-tree-8.0.1.jar:8.0.1]
	at org.objectweb.asm.commons.JSRInlinerAdapter.visitEnd(JSRInlinerAdapter.java:158) ~[asm-commons-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:782) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:782) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:782) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:782) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1492) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:718) ~[asm-8.0.1.jar:8.0.1]
	at org.objectweb.asm.ClassReader.accept(ClassReader.java:401) ~[asm-8.0.1.jar:8.0.1]
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3827) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:224) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:10327) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10263) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1600(AgentBuilder.java:10029) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:10722) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$Java9CapableVmDispatcher.run(AgentBuilder.java:10660) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at java.security.AccessController.doPrivileged(Native Method) ~[?:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:10219) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$ByteBuddy$ModuleSupport.transform(Unknown Source) ~[?:?]
	at sun.instrument.TransformerManager.transform(TransformerManager.java:188) ~[?:?]
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:563) ~[?:?]
	at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method) ~[?:?]
	at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:167) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Dispatcher$ForJava6CapableVm.retransformClasses(AgentBuilder.java:6869) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector$ForRetransformation.doApply(AgentBuilder.java:7148) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy$Collector.apply(AgentBuilder.java:6993) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$RedefinitionStrategy.apply(AgentBuilder.java:4855) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default.doInstall(AgentBuilder.java:9463) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default.installOn(AgentBuilder.java:9384) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at net.bytebuddy.agent.builder.AgentBuilder$Default$Delegator.installOn(AgentBuilder.java:10986) ~[byte-buddy-dep-1.10.12-SNAPSHOT.jar:?]
	at co.elastic.apm.agent.bci.ElasticApmAgent.initInstrumentation(ElasticApmAgent.java:168) ~[classes/:?]
	at co.elastic.apm.agent.bci.ElasticApmAgent.initInstrumentation(ElasticApmAgent.java:147) ~[classes/:?]
	at co.elastic.apm.agent.bci.InstrumentationTest.testPatchClassFileVersionJava5ToJava7CommonsMath(InstrumentationTest.java:327) ~[test-classes/:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628) ~[junit-platform-commons-1.4.2.jar:1.4.2]
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68) ~[junit-jupiter-engine-5.4.2.jar:5.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at java.util.ArrayList.forEach(ArrayList.java:1540) ~[?:?]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at java.util.ArrayList.forEach(ArrayList.java:1540) ~[?:?]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) ~[junit-platform-engine-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229) ~[junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197) ~[junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) [junit-platform-launcher-1.4.2.jar:1.4.2]
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69) [junit5-rt.jar:?]
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) [junit-rt.jar:?]
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230) [junit-rt.jar:?]
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) [junit-rt.jar:?]

I suppose adviceMethod.getDeclaringType().getName() needs to be part of the Object[]

@raphw
Copy link
Owner

raphw commented Jun 15, 2020

Yes, indeed. I'll fix it up some time this week. I need to add proper validation to check that a supplied bootstrap method fits the signature and some tests, of course.

@raphw
Copy link
Owner

raphw commented Jun 15, 2020

Alright, I used my lunch break on this since it was a rather easy fix. Can you check master? I had to rearrange the order of the bootstrap arguments to allow for supporting the type initializer. Note that you can replace the last argument type with Object... if you want the type initializer to be provided optionally.

@felixbarny
Copy link
Contributor Author

Works great, thanks. Looking forward to the release 🙂

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

Successfully merging a pull request may close this issue.

2 participants