Estoy usando las transacciones declarativas de Spring (la anotación @Transactional) en el modo "aspectj". Funciona en la mayoría de los casos exactamente como debería, pero para uno no. Podemos llamarlo Lang
(porque así se llama en realidad).AspectJ Tiempo de carga weaver no detecta todas las clases
He podido identificar el problema con el telar del tiempo de carga. Al activar el registro de depuración y detallado en aop.xml, se enumeran todas las clases que se tejen. La clase problemática Lang
de hecho no se menciona en los registros.
Luego puse un punto de interrupción en la parte superior de Lang
, haciendo que Eclipse suspenda el hilo cuando se carga la clase Lang
. ¡Este punto de ruptura se golpea mientras el LTW teje otras clases! Así que supongo que o bien trata de tejer Lang
y falla y no produce eso, o alguna otra clase tiene una referencia que lo fuerza a cargar Lang
antes de que realmente tenga la posibilidad de tejerlo.
No estoy seguro de cómo seguir para depurar esto, ya que no puedo reproducirlo en menor escala. ¿Alguna sugerencia sobre cómo continuar?
Actualización: Otras pistas también son bienvenidos. Por ejemplo, ¿cómo funciona LTW en realidad? Parece que hay mucha magia sucediendo. ¿Hay alguna opción para obtener aún más resultados de depuración del LTW? Actualmente tengo:
<weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo">
olvidé tom mencionó antes: primavera-agente está siendo utilizado para permitir LTW, es decir, la InstrumentationLoadTimeWeaver
.
Basado en las sugerencias de Andy Clement, decidí inspeccionar si el transformador AspectJ alguna vez pasó la clase. Puse un punto de interrupción en ClassPreProcessorAgent.transform(..)
, y parece que la clase Lang
nunca llega a ese método, a pesar de que lo carga el mismo cargador de clases que otras clases (una instancia de Jetty's WebAppClassLoader).
Luego pasé a poner un punto de interrupción en InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..)
. Ni siquiera ese es golpeado por Lang
. Y creo que se debe invocar ese método para todas las clases cargadas, independientemente de qué cargador de clase estén usando. Esto comienza a verse así:
- Un problema con mi depuración. Posiblemente
Lang
no se carga en el momento en que Eclipse informa que es - ¿Error de Java? Extraordinario, pero supongo que sucede.
siguiente pista: Me enciende -verbose:class
y parece como si Lang
es se carga antes de tiempo - probablemente antes de añadir el transformador a la Instrumentación. Curiosamente, mi punto de corte Eclipse no capta esta carga.
Esto significa que Spring es un nuevo sospechoso. parece haber algún procesamiento en ConfigurationClassPostProcessor
que carga clases para inspeccionarlas. Esto podría estar relacionado con mi problema.
Estas líneas en ConfigurationClassBeanDefinitionReader
hace que la clase Lang
para ser leído:
else if (metadata.isAnnotated(Component.class.getName()) ||
metadata.hasAnnotatedMethods(Bean.class.getName())) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
return true;
}
En particular, metadata.hasAnnotatedMethods()
llamadas getDeclaredMethods()
en la clase, que carga todas las clases de parámetros de todos los métodos de esa clase. Supongo que este podría no ser el final del problema, porque creo que se supone que las clases están descargadas. ¿Podría la JVM almacenar en caché la instancia de clase por razones desconocidas?
Gracias por la respuesta. Interesante idea de que la cadena "Lang" podría causar un problema. Pero debería haber mencionado, hay otras clases (al menos una) que tampoco se tejen. El otro conocido se llama CommServer. Entonces dudo que ese sea el problema. Puede que tenga que empezar a buscar en la fuente de AspectJ. – waxwing