6

I want to configure compile time weaving for classes marked with @Configurable annotation to be able to inject spring dependencies to classes instatiated with new operator. I don't want to use load-time weaving because I don't have access to run script of application server, so I can't modify it. Also I want to be able to use this classes in tests, I mean to run test cases from IDE . I found information only about load time weaving on the web and spring reference and nothing about configuration of compile-time weaving.

PS. I use spring with maven

maks
  • 5,911
  • 17
  • 79
  • 123

2 Answers2

4

So the other answer is also valid but I thought i'd cover in a little more detail some of the implications of this approach.

The setup I use is at a basic level this :-

      <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.4</version>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjrt</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
            <configuration>
                <outxmlfile>META-INF/aop.xml</outxmlfile>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <source>1.7</source>
                <target>1.7</target>
                 <forceAjcCompile>true</forceAjcCompile>
            </configuration>
        </plugin>

Now, some additional information about the dependencies :-

 <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${dep.spring}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>${dep.spring}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>persistence-api</artifactId>
        <version>1.0</version>
        <scope>provided</scope>
    </dependency>

I suppose that you miss the persistence api, which is used for weaving.

Edit : related to https://jira.springsource.org/browse/SPR-6819 bug in spring. That seems to be why you need the persistence API.

Also helpful can be to create a maven job to weave if classes get unweaved in the ide (this happens a lot for me).

aspectj:compile

Finally if you intend to unit test your classes, it can be useful to weave classes after this phase. We weave in the prepare-package phase. If you would like to do this add

      <executions>
                <execution>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>

To your plugin.

I hope that helps because it can be tricky to get this approach to play nice in the IDE.

MikePatel
  • 2,593
  • 2
  • 24
  • 38
  • why do I need persistance api? I don't use it. And I can not imagine how it can be used for weaving. I have an assumption that some aspect in spring-aspects work with this api, so aspectj-maven-pluging must have an option to select concrete aspects from aspectjLibraries to be used in weaving process. Also, why do I need aspectjrt dependency, I don't use load-time weaving – maks Jul 31 '13 at 11:59
  • 1
    Hi, I added the jira issue for the persistence thing. – MikePatel Jul 31 '13 at 12:35
  • Also the aspect runtime isn't coupled to compile time weaving. You can minimize the need for its use by avoiding cflow pointcut designators and thisJoinPoint operations ( I have read ). Are you in a situation where you can't introduce any more dependencies to your project or something ? – MikePatel Aug 03 '13 at 09:01
  • Maybe you know when it going to be fixed? Yes, I can't introduce more dependencies. – maks Aug 03 '13 at 11:17
  • What version of spring are you on ? 3.2.1.RELEASE seems to have a fix ( though the bug is still open :S ) – MikePatel Aug 03 '13 at 11:28
  • Should be a dependency provided already in that version. jvm version ? – MikePatel Aug 03 '13 at 12:00
  • currently it is 1.6 hotspot, but planning to migrate to 1.7 – maks Aug 03 '13 at 12:12
1

Something like this in your pom should work...

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.4</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <configuration>
                            <source>${source}</source>
                            <target>${target}</target>
                            <verbose>true</verbose>
                            <aspectLibraries>
                                <aspectLibrary>
                                    <groupId>org.springframework</groupId>
                                    <artifactId>spring-aspects</artifactId>
                                </aspectLibrary>
                            </aspectLibraries>
                        </configuration>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <configuration>
                            <source>${source}</source>
                            <target>${target}</target>
                            <verbose>false</verbose>
                            <aspectLibraries>
                                <aspectLibrary>
                                    <groupId>org.springframework</groupId>
                                    <artifactId>spring-aspects</artifactId>
                                </aspectLibrary>
                            </aspectLibraries>
                        </configuration>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <!-- Ensure aspectj tools version used by compiler is the same version used as dependency. Avoids warning -->
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjweaver</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

Then make sure you have spring-aspects on your class path.

And for aspecting in Eclipse - install the AJDT

Michael Wiles
  • 20,902
  • 18
  • 71
  • 101
  • I have spring-aspects on classpath, but when I try to compile(mvn compile) the project I get nest error: `can't determine annotations of missing type javax.persistence.Entity`. However I even don't use it in my project(I don't have neither hibernate nor other jpa compatible tool) – maks Jul 26 '13 at 17:19
  • Also I've noticed that it tries to weave all my classes(even if they are not marked as `@Configurable') – maks Jul 26 '13 at 17:21
  • Also, what is `${aspectj.version}`. Version of what it implies? – maks Jul 26 '13 at 17:23
  • I just use a property to specify my aspectj version. So I think it's 1.7.2. I also get that can't determine annotations of missing type javax.persistence.Entity message. Don't think it is significant. And yes, it needs to at least scan everything in case it may contain an annotation that it is interested in. – Michael Wiles Jul 27 '13 at 00:42
  • Do you mean aspectjweaver version under aspectj or aspectjrt? Maybe there is some way to tell aspectj-maven-plugin to skip some packages, classes? – maks Jul 27 '13 at 11:26