-
-
Notifications
You must be signed in to change notification settings - Fork 809
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
IllegalAccessError when loading a class generated with a NamingStrategy #1
Comments
Hi Jonathan, you are defining a package-private class Thank you for using Byte Buddy! You are somewhat an early adopter and I hope to improve this behavior in later versions. A future version of Byte Buddy will definitely come with an (optional) validator that will throw an appropriate exception. Today's version does not yet catch all validation errors with a detailed error message because this validation generates some run time overhead. Also note that I am planing to release a version 0.2 of Byte Buddy in only a couple of weeks. It comes with several bug fixes, some new functionality to better support Java 8 and improved support for creating proxy classes. Best regards, Rafael |
Ah, I assumed that the package was always the same as the superclass and that the naming strategy was just for the class name. Good to know. So using a fully qualified subclass name, things work well, but only if I use |
Java is a quite tricky language when it comes to package-private access. Package-private access is also rather an invention for being used by compilers rather then by users since they have strange semantics. You might have heard before that two classes are only consider equal by the Java run time if they were loaded with the same class loader even if they otherwise represent an identical class. The same is true for Java packages. If a class is loaded with a different class loader, it cannot get private-package access to any classes (or class members) that belong to another class loader. The injection strategy uses reflection to load a class into a given class loader. The wrapper class loader on the other hand, creates a new child class loader for loading a given class. The former strategy is more efficient since a class loader is a rather expensive object to Java (takes about 70 nanoseconds to create it in my benchmarks). However, it does not need to call internal methods. Also, the wrapper class loader allows the unloading of the generated class if none of its instances and its class and class loader are not longer reachable. This is handy when creating classes that are only needed for a limited amount of time such as in bootstrap procedures. One specific use case of this strategy would be mocking for example as for creating type safe DSLs. This allows to keep the perm gen requirements of an application down as the injector strategy often targets the system class loader what makes loaded classes invincible for the application's life time. The injector strategy is equivalent to Javassist and cglib's approaches. |
Good info. I recalled that Guice uses a separate class loader for instrumenting/proxying classes/methods that are not private/package-private and the user classloader for everything else. A hybrid strategy like that is something I might need to look into. |
I thought about predefining such a strategy for Byte Buddy 0.2. However, this would require you to resolve any invokable method of a class in order to check if any of those methods is package-private relatively to the generated class in order to determine its necessity. Such reflective look-ups are unfortunately expensive. I might still just add the strategy and add an explicit warning of its costs. |
I have a simple scenario where I receive an IllegalAccessError when loading a generated class that uses a NamingStrategy.
Here's the complete test:
The text was updated successfully, but these errors were encountered: