views:

198

answers:

3

Someone where i work noticed (in stacktrace) that when running the jvm with -javaagent:spring-instrumentation.jar my JAXB annotated classes have strange new methods in them which we didn't write: e.g. SomeJaxbAnnotatedClass$JaxbAccessorM_getFields_setFields_java_util_Set.get

Does this mean that jaxb uses bytecode instrumentation when it is available? Where can i read more about this functionality?

Thanks, Yuval

+1  A: 

Last I checked, JAXB uses reflection to generate classes based on the XML you provide (though I haven't used it in some time, so they may have changed their methodology).

I know that JiBX, on the other hand, uses BCEL to perform bytecode instrumentation. Here is an article about that: http://www.ibm.com/developerworks/java/library/j-cwt09065/.

danben
I know all about JIBX used it and suffered every minute from having to run the post compilation, I was just surprised to see JAXB doing something that looked like bytecode injection but I guess i was wrong...
Yuval Rimar
+3  A: 

When the JaxbContext starts up, it performs a large amount of reflection operations, to pre-cache all of the stuff it will later need. This is done for performance reasons. I'm not sure what it does exactly, but I would expect it to perform some kind of runtime class generation logic, since that will be faster at runtime than raw reflection.

Interestingly, you can turn this behaviour off by setting a non-documented system property, which improves the startup of the context, at the expense of runtime performance.

edit: I should stress that this is what the Sun JAXB reference implementation does under the covers, it's not part of the JAXB spec. Other implementations are free to do whatever they choose.

skaffman
+1 for mentioning that there might be different implementations that are implemented differently!
Tom Hawtin - tackline
+4  A: 

Just an addition to skaffman's post:

What you see (SomeJaxbAnnotatedClass$JaxbAccessor...) is an inner class, which is generated dynamically by the JAXB reference implementation. To prevent reflection overhead at runtime, bytecode for the concrete implementations of the class com.sun.xml.bind.v2.runtime.reflect.Accessor are generated and injected into the current classloader by invoking ClassLoader.defineClass(String, byte[], int, int), after using reflection to circumvent the protected access modifier of the defineClass method.

So, the JAXB reference implementation is not instrumenting bytecode in the sense that it's modifying existing classes, but generates new classes for optimized runtime performance.

jarnbjo
(+1) nice addition.
skaffman
Thanks for making this clear, I supposed i confused the inner classes with added methods and imagined that spring-instrumentation might have something to do with this. What you describe makes much more sense :)
Yuval Rimar