-
-
Notifications
You must be signed in to change notification settings - Fork 808
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
Comments
The same happens when trying to instrument the type initializer. Instrumenting any other method of that class doesn't result in this issue. |
I've tried to load this with a This is the diff of the constant pool, compared to the original class file (as shown by javap)
And the BootstrapMethod attachments:
I think the issue this BootstrapMethod entry:
This is invalid because there's no explicit constructor defined in |
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. |
I'm not sure that's the issue. It only seems to be a problem when the constructor is private. Instrumenting the constructor of The thing with Because of that referencing the non-existing constructor in a bootstrap method seems to cause the verifier error. |
Also check out the SO post from this smart dude: https://stackoverflow.com/questions/29478139/is-it-valid-to-have-a-jvm-bytecode-class-without-any-constructor |
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:
Did you run javap with -p? Without the flag, it's hiding any private members. |
I still think it's a verifier issue not allowing the "special naming" convention that normally applies to constructors. The entry in question is:
I'll try a patch on a branch for you to try out. |
Oh boy, I did not add the |
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? |
Almost there. There's the same problem with https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.4.8
https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.10.1.9.invokedynamic
Not sure what the right reference kind for |
True, obviously, it is not possible to create a handle to You can check the latest master version to test this. |
Some are currently failing see raphw/byte-buddy#880
I get this exception now:
I suppose |
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. |
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 |
Works great, thanks. Looking forward to the release 🙂 |
When instrumenting
org.slf4j.LoggerFactory<init>
with a simple enter advice that is dispatched with invokedynamic I get the following exception: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
The text was updated successfully, but these errors were encountered: