2010-01-25 17 views
8

Alguien en el que trabajo notó (en stacktrace) que cuando ejecuto el jvm con -javaagent: spring-instrumentation.jar mis clases comentadas JAXB tienen extraños métodos nuevos que no escribimos: p. SomeJaxbAnnotatedClass $ JaxbAccessorM_getFields_setFields_java_util_Set.get¿JAXB utiliza instrumentación de bytecode?

¿Esto significa que jaxb utiliza instrumentación de bytecode cuando está disponible? ¿Dónde puedo leer más acerca de esta funcionalidad?

Gracias, Yuval

Respuesta

12

Sólo un además del puesto de skaffman:

Lo que se ve (SomeJaxbAnnotatedClass $ JaxbAccessor ...) es una clase interna, que se genera dinámicamente mediante la implementación de referencia JAXB. Para evitar la sobrecarga de reflexión en tiempo de ejecución, se generan bytecode para las implementaciones concretas de la clase com.sun.xml.bind.v2.runtime.reflect.Accessor y se inyectan en el cargador de clases actual invocando ClassLoader.defineClass (String, byte [], int, int), después de usar reflection para eludir el modificador de acceso protegido del método defineClass.

Por lo tanto, la implementación de la referencia JAXB no está instrumentando bytecode en el sentido de que está modificando las clases existentes, sino que genera nuevas clases para optimizar el rendimiento en el tiempo de ejecución.

+0

(+1) buena adición. – skaffman

+0

Gracias por dejar esto en claro, supuse que confundí las clases internas con métodos adicionales e imaginé que la instrumentación de primavera podría tener algo que ver con esto. Lo que describes tiene mucho más sentido :) –

1

yo sepa, JAXB utiliza la reflexión para generar clases basadas en el XML que proporcione (aunque yo no lo he utilizado en algún momento, por lo que pueden haber cambiado su metodología).

Sé que JiBX, por otro lado, usa BCEL para realizar instrumentación de bytecode. Aquí hay un artículo sobre eso: http://www.ibm.com/developerworks/java/library/j-cwt09065/.

+0

Sé todo sobre JIBX lo usó y sufrí cada minuto de tener que ejecutar la compilación de publicaciones, estaba sorprendido de ver a JAXB haciendo algo que se parecía a la inyección de código byte, pero creo que estaba equivocado ... –

8

Cuando se inicia el JaxbContext, realiza una gran cantidad de operaciones de reflexión, para almacenar previamente todas las cosas que necesitará más adelante. Esto se hace por motivos de rendimiento. No estoy seguro de lo que hace exactamente, pero espero que realice algún tipo de lógica de generación de clase de tiempo de ejecución, ya que será más rápido en tiempo de ejecución que la reflexión en bruto.

Curiosamente, puede desactivar este comportamiento estableciendo una propiedad del sistema no documentada, que mejora el inicio del contexto, a expensas del rendimiento en tiempo de ejecución.

edit: Debo recalcar que esto es lo que hace la implementación de referencia de Sun JAXB bajo las coberturas, no es parte de la especificación JAXB. Otras implementaciones son libres de hacer lo que elijan.

+1

+1 por mencionar que podría haber diferentes implementaciones que se implementan de manera diferente! –

0

Como se ha mencionado por skaffman puede desactivar la generación de todas esas clases internas mediante el establecimiento de la propiedad del sistema: com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.fastBoot = true

Por supuesto no está documentado, pero no ha cambiado durante años.