Note that there are some explanatory texts on larger screens.

plurals
  1. POAspectJ Load time weaver doesn't detect all classes
    text
    copied!<p>I am using Spring's declarative transactions (the @Transactional annotation) in "aspectj" mode. It works in most cases exactly like it should, but for one it doesn't. We can call it <code>Lang</code> (because that's what it's actually called).</p> <p>I have been able to pinpoint the problem to the load time weaver. By turning on debug and verbose logging in aop.xml, it lists all classes being woven. The problematic class <code>Lang</code> is indeed not mentioned in the logs at all.</p> <p>Then I put a breakpoint at the top of <code>Lang</code>, causing Eclipse to suspend the thread when the <code>Lang</code> class is loaded. This breakpoint is hit while the LTW weaving other classes! So I am guessing it either tries to weave <code>Lang</code> and fails and doesn't output that, or some other class has a reference that forces it to load <code>Lang</code> before it actually gets a chance to weave it.</p> <p>I am unsure however how to continue to debug this, since I am not able to reproduce it in smaller scale. Any suggestions on how to go on?</p> <hr> <p><em>Update:</em> Other clues are also welcome. For example, how does the LTW actually work? There appears to be a lot of magic happening. Are there any options to get even more debug output from the LTW? I currently have:</p> <pre><code>&lt;weaver options="-XnoInline -Xreweavable -verbose -debug -showWeaveInfo"&gt; </code></pre> <hr> <p>I forgot tom mention it before: <strong>spring-agent</strong> is being used to allow LTW, i.e., the <code>InstrumentationLoadTimeWeaver</code>.</p> <hr> <p>Based on the suggestions of Andy Clement I decided to inspect whether the AspectJ transformer is ever even passed the class. I put a breakpoint in <code>ClassPreProcessorAgent.transform(..)</code>, and it seems that the <code>Lang</code> class never even reaches that method, despite it being loaded by the same class loader as other classes (an instance of Jetty's WebAppClassLoader).</p> <p>I then went on to put a breakpoint in <code>InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(..)</code>. Not even that one is hit for <code>Lang</code>. And I believe that method should be invoked for <em>all</em> loaded classes, regardless of what class loader they are using. This is starting to look like:</p> <ol> <li>A problem with my debugging. Possibly <code>Lang</code> is not loaded at the time when Eclipse reports it is</li> <li>Java bug? Far-fetched, but I suppose it does happen.</li> </ol> <hr> <p>Next clue: I turned on <code>-verbose:class</code> and it appears as if <code>Lang</code> <em>is</em> being loaded prematurely - probably before the transformer is added to Instrumentation. Oddly, my Eclipse breakpoint does not catch this loading.</p> <p>This means that Spring is new suspect. there appears to be some processing in <code>ConfigurationClassPostProcessor</code> that loads classes to inspect them. This could be related to my problem.</p> <hr> <p>These lines in <code>ConfigurationClassBeanDefinitionReader</code> causes the <code>Lang</code> class to be read:</p> <pre><code>else if (metadata.isAnnotated(Component.class.getName()) || metadata.hasAnnotatedMethods(Bean.class.getName())) { beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); return true; } </code></pre> <p>In particular, <code>metadata.hasAnnotatedMethods()</code> calls <code>getDeclaredMethods()</code> on the class, which loads all parameter classes of all methods in that class. I am guessing that this might not be the end of the problem though, because I think the classes are supposed to be unloaded. Could the JVM be caching the class instance for unknowable reasons?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload