はじめに
あるOSSの解析のためにAspectJを利用した。
その際にMavenでアスペクトのビルドとテストを行ったので、その記録を残しておく。
ここでは、テストメソッドにログ出力を織り込むことにする。
$ tree
.
|-- pom.xml
`-- src
|-- main
| |-- java
| | `-- redj
| | `-- aspectj
| | `-- LoggingAspect.java
| `-- resources
`-- test
`-- java
`-- redj
`-- aspectj
`-- LoggingAspectTest.java
LoggingAspect.java
アスペクトを準備。
パッケージredj.aspectjの任意のクラスにおいて、testをプレフィックスに持つメソッドの実行前にログを出力する。
package redj.aspectj;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class LoggingAspect {
@Pointcut("execution(* redj.aspectj.*.test*(..))")
public void atTestMethod() {
}
@Before("atTestMethod()")
public void logBeforeTest() {
System.out.println("***** begin test");
}
}
LoggingAspectTest.java
テストクラスを準備。
アスペクトが織り込まれるように、testをプレフィックスに持つメソッドを定義しておく。
package redj.aspectj;
import org.junit.Test;
public class LoggingAspectTest {
@Test
public void testFoo() {
System.out.println("test foo");
}
@Test
public void testBar() {
System.out.println("test bar");
}
}
testフェーズでLoad-Time Weavingを利用するようにpom.xmlを構成。
かなり面倒。
maven-dependency-plugin:build-classpathを利用してaspectjweaverのJarファイルのパスを組み立てて、maven-surefire-plugin:testに引き渡しているところがポイント。
maven-surefire-plugin:testでは、プロパテイを遅延評価する必要があるので@{ }を利用している。
aspectj-maven-plugin:compileを利用してaop-ajc.xmlを生成する。
aop-ajc.xmlには、aspectjweaverに認識させるアスペクトの定義情報が書かれている。
ただし、aspectj-maven-pluginのcomplianceLevelのデフォルトは1.4なので、明示的に1.5以上に設定しないと、アノテーションを利用したアスペクトのコンパイルでエラーを起こす。
さらに、AspectJのバージョンがずれていると警告が出るので、aspectj-maven-pluginにaspectjtoolsへの依存を明示的に書いて、バージョンを合わせる。
xml version="1.0" encoding="UTF-8"
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlnsxsi="http://www.w3.org/2001/XMLSchema-instance" xsischemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>redj</groupId>
<artifactId>aspectj</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<properties>
<projectbuildsourceEncoding>UTF-8</projectbuildsourceEncoding>
<mavencompilersource>1.8</mavencompilersource>
<mavencompilertarget>1.8</mavencompilertarget>
<maven-dependency-pluginversion>3.0.0</maven-dependency-pluginversion>
<aspectj-maven-pluginversion>1.10</aspectj-maven-pluginversion>
<maven-surefire-pluginversion>2.20</maven-surefire-pluginversion>
<aspectjversion>1.8.10</aspectjversion>
<junitversion>4.12</junitversion>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputProperty>aspectj-weaver-path</outputProperty>
<includeGroupIds>org.aspectj</includeGroupIds>
<includeArtifactIds>aspectjweaver</includeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>${aspectj-maven-plugin.version}</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<complianceLevel>1.8</complianceLevel>
<outxml>true</outxml>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<executions>
<execution>
<id>default-test</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<argLine>-javaagent:@{aspectj-weaver-path}</argLine>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
ビルド
テストメソッドの実行前にログが出力されていることが確認できる。
$ mvn clean install
(略)
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running redj.aspectj.LoggingAspectTest
***** begin test
test bar
***** begin test
test foo
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.153 s - in redj.aspectj.LoggingAspectTest
(略)
参考