Update 5: I've downloaded the latest Spring ToolsSuite IDE based on the latest Eclipse. When I import my project as a Maven project, Eclipse/STS appears to use the Maven goals for building my project. This means AspectJ finally works correctly in Eclipse.
Update 4: I have ended up just using Maven + AspectJ plugin for compile-time weaving, effectively bypassing Eclipse's mechanism.
Update 3: It seems AspectJ's Eclipse plug-in breaks Eclipse's ability to correctly Publish to Tomcat. Only by removing the AspectJ capability on a project can I get it to properly Publish again. Very annoying.
Update 2: I have this now working in Eclipse. It makes me very uncomfortable to say this, but I have no idea how I got it working from either Eclipse or Maven builds. It appears to be a compile issue rather than a run-time issue.
Update 1: It appears I've gotten this to work via Maven builds, but I have no idea how. Eclipse still doesn't work. The only thing I changed in the pom.xml was adding these (insignificant?) configuration parameters:
<source>1.6</source>
<complianceLevel>1.6</complianceLevel>
<verbose>true</verbose>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>
I'm actually worried that I have a repeat of this problem, where everything works inconsistently. I will keep this question updated as I learn more.
With regards to Eclipse, I made some progress by taking the binary aspects I wish to weave - in this case spring-aspects.jar - and copying it out of my classpath. I then add this now external jar to my Aspect Path. After doing this, Eclipse properly shows me AspectJ markers in my code. It's annoying that I can't just leave spring-aspects.jar in my Java Build Path which is maintained by Maven for me via the Maven plug-in. For some reason, however, the AspectJ plug-in doesn't see the binary aspects unless they're explicitly added to the Aspect Path.
Original Post: @Configurable is a Spring annotation that allows dependencies to be injected into objects instantiated external to Spring (for example, by Hibernate or some Factory class).
I was using this annotation previously with load-time weaving and it mostly worked. Occasionally I would boot up and nothing would get injected. This issue spawned this StackOverflow question. There weren't many answers, but most suggested that I try compile-time weaving instead due to greater reliability.
I installed the AspectJ plug-in for Eclipse and Maven. Both of these produce what appears to be properly compiled classes. I've opened up one of the classes in a text editor before AspectJ compilation and found no references to AspectJ. I opened it up after AspectJ compilation and both Eclipse and Maven generated versions have a reference to org.aspectj.weaver.MethodDeclarationLineNumber. This is why I assume it's being properly compiled. The problem is that once deployed, no dependencies get injected.
My Spring applicationContext.xml does include the following:
<context:spring-configured />
<context:component-scan base-package="com.myapp" />
Is the above all that's needed for classes marked @Configurable to have DI done? During the conversion from load-time weaving to compile-time weaving, I removed META-INF/aop.xml, <context:load-time-weaver /> from my applicationContext.xml, and Spring's Tomcat weaver from my context.xml.
How can I investigate this problem further? What are possible causes?
It works for us on maven using compile time weaving, try adding the following plugins:
Its done as two separate execution steps to allow you to add different aspect libraries for unit testing and compilation.
You'll also need the following dependency added for the spring-aspects library:
making a field of a @configurable class Autowired throws NullPointerException if you do not configure your spring properly for this annotation. follow these steps to make @configurable annotations work properly
This method is called AspectJ build time weaving to inject spring beans to your non-spring-made classes.
First step is to install these plugins in eclipse:
From these two update sites install whatever eclipse suggests:
After installing,right-click on project and Do:
Next, you need to add these to your pom.xml:
Under Dependencies Add:
Under Plugins Add:
Important: DO NOT use any
<pluginManagment>
tag under<build>
tag. your pom.xml needs to be something like this:finally add
<context:spring-configured />
to your spring application context config file.Now you can annotate a POJO class as
@Configurable
and inject spring beans in it using@Autowired
annotation. this way whenever you make a new instance of that POJO it will be configured (e.g. injected with dependencies) automatically.I successfully configured load-time weaving in my app, if this is an alternative for you.
My environment:
Configuration details:
Spring XML configuration:
Spring annotations
Java VM Parameter
Instances of historyHandler and baseEntitty are created by ecliselink. historyHandler in baseEntitty and historyDao in historyHandler is set by load-timeweaving.
You can set the VM Parameter in Eclipse run configuration or in Tomcats catalina.sh/bat.
As far as your Eclipse classpath issues are concerned, you might find this useful.
The m2eclipse plugin has an optional AJDT integration. The integration reads the aspectLibraries section of the aspectj-maven-plugin's configuration, and contributes the jars to Eclipse's Aspect Path.