Experiences with Lookup.defineClass

Rafael Winterhalter rafael.wth at gmail.com
Sat Mar 11 16:48:43 UTC 2017


I have implemented support for Lookup::defineClass in my library Byte Buddy
and my first impression is quite positive, I think this can offer a great
alternative for at least some use cases.

For this to work, I do however think it is crucial to add a parameter to
the ClassFileTransformer::transform method where a lookup object should be
provided as an additional argument in order to allow defining additional
classes in the instrumented class's loader and module. In practice, this is
often required in the same manner as javac needs to be able to define
anonymous classes when compiling source code. I checked my use of Unsafe in
Java agents and basically any use case breaks down to defining such classes
which can be replaced by Lookup::defineClass if a lookup object with the
instrumented class's context would be supplied to the class file
transformer. I do neither see that this could yield a security problem as
any such priviledge could already be abused by changing the instrumented
class.

As for the creation of runtime proxies by subclassing, I do not think that
this approach offers an alternative. As a library author, I do not normally
have an appropriate lookup context available. For use cases like Hibernate
or Spring, I think that it is therefore easiest to define a class in a
seperate class loader and to require users to export their types to enable
AOP. In the end, I do not think that might be a bad thing in the long run.

For testing libraries like Mockito, I would however prefer to use a
mechanism similar to Unsafe::defineClass. My prefered way would be to add a
test-specific module to any JDK installation that needs to be enabled by
some flag. It would be too bad if people had to open their modules just for
some test code to run where defining a class in a tested class's class
loader (for example because it is package-private) is a legitimate demand.
Requiring users to explicitly supply a lookup instance would yield an
awkward API where I would prefer a parameter (in a way, such a parameter
already exists by explicitly opening the Unsafe class via the command line
if that class became unavailable in Java 10). By adding a standard testing
module, we could however avoid to depend on internal packages and increase
stability of our libraries. In such a module, I would also like to see a
factory for getting hold of an instrumentation instance for the current VM.
I think that other tooling libraries and testing libraries would benefit of
such a priviledge module that needs explicit enabling.

Keep up the good work!
Best regards, Rafael


More information about the jigsaw-dev mailing list