Does JAXB use bytecode instrumentation?
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 ins开发者_如何转开发trumentation when it is available? Where can i read more about this functionality?
Thanks, Yuval
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.
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.
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/.
As mentioned by skaffman you can turn off the generation of all those inner classes by setting the system property : com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot=true
Of course it's not documented, but it hasn't changed for years.
精彩评论