аспект j - объявление метода Intertype не работает с Maven

У меня проблемы с компиляцией проекта с Maven и AspectJ.

Это выдержка из POM для aspectj-maven-plugin (взято из действующего POM):

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.7</version>
    <executions>
        <execution>
            <id>default-aj-compile</id>
            <phase>compile</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-core</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-persistence</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <Xlint>ignore</Xlint>
                <forceAjcCompile>true</forceAjcCompile>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <aspectDirectory>src/main/aspects</aspectDirectory>
                <testAspectDirectory>src/test/aspects</testAspectDirectory>
            </configuration>
        </execution>
        <execution>
            <id>default-aj-test-compile</id>
            <phase>test-compile</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-core</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-test</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-persistence</artifactId>
                    </aspectLibrary>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <Xlint>ignore</Xlint>
                <forceAjcCompile>true</forceAjcCompile>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <aspectDirectory>src/main/aspects</aspectDirectory>
                <testAspectDirectory>src/test/aspects</testAspectDirectory>
            </configuration>
        </execution>
        <execution>
            <id>default-aj-generate-sources</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>compile</goal>
            </goals>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-persistence</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <Xlint>ignore</Xlint>
                <forceAjcCompile>true</forceAjcCompile>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <aspectDirectory>src/main/aspects</aspectDirectory>
                <testAspectDirectory>src/test/aspects</testAspectDirectory>
            </configuration>
        </execution>
        <execution>
            <id>default-aj-generate-test-sources</id>
            <phase>generate-test-sources</phase>
            <goals>
                <goal>test-compile</goal>
            </goals>
            <configuration>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.jcz</groupId>
                        <artifactId>jcz-persistence</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
                <showWeaveInfo>true</showWeaveInfo>
                <verbose>true</verbose>
                <Xlint>ignore</Xlint>
                <forceAjcCompile>true</forceAjcCompile>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <aspectDirectory>src/main/aspects</aspectDirectory>
                <testAspectDirectory>src/test/aspects</testAspectDirectory>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.5</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.5</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>1.8.5</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <configuration>
        <showWeaveInfo>true</showWeaveInfo>
        <verbose>true</verbose>
        <Xlint>ignore</Xlint>
        <forceAjcCompile>true</forceAjcCompile>
        <complianceLevel>1.8</complianceLevel>
        <source>1.8</source>
        <target>1.8</target>
        <aspectDirectory>src/main/aspects</aspectDirectory>
        <testAspectDirectory>src/test/aspects</testAspectDirectory>
    </configuration>
</plugin>

При запуске mvn clean deploy я получил эти строки:

[INFO] --- aspectj-maven-plugin:1.7:test-compile (default-aj-generate-test-sources) @ jcz-persistence-jpa ---
[INFO] 'org.jcz.persistence.jpa.model.Band' (Band.java:45) is annotated with @Entity type annotation from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:79)
[INFO] 'org.jcz.persistence.jpa.model.Band' (Band.java:45) is annotated with @UUID type annotation from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:80)
[INFO] Extending interface set for type 'org.jcz.persistence.jpa.model.Band' (Band.java) to include 'org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID' (UUIDSupportAspect.aj)
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'boolean org.jcz.persistence.EntitySupport.equals(java.lang.Object)')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'java.lang.String org.jcz.persistence.EntitySupport.toSuperString()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'java.lang.String org.jcz.persistence.EntitySupport.toString()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'org.jcz.persistence.UniqueIdentifier org.jcz.persistence.EntitySupport.uniqueIdentifier()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'java.util.Comparator<java.lang.reflect.Method> org.jcz.persistence.EntitySupport.retrieveComparatorForAction(java.lang.Class<? extends java.lang.annotation.Annotation>)')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'java.lang.String org.jcz.persistence.EntitySupport.retrieveDescriptionForAction(java.lang.annotation.Annotation)')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.invokeActions(java.lang.Class<? extends java.lang.annotation.Annotation>)')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPrePersist()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPostPersist()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPreUpate()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPostUpdate()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPreRemove()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.EntitySupportAspect' (EntitySupportAspect.aj:'void org.jcz.persistence.EntitySupport.doPostRemove()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped field from 'org.jcz.aspects.persistence.UUIDSupportAspect' (UUIDSupportAspect.aj:'java.lang.String org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID.id')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.UUIDSupportAspect' (UUIDSupportAspect.aj:'java.io.Serializable org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID.getId()')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.UUIDSupportAspect' (UUIDSupportAspect.aj:'void org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID.setId(java.io.Serializable)')
[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.UUIDSupportAspect' (UUIDSupportAspect.aj:'void org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID.ensureId()')

Просто чтобы уменьшить область до одного случая:

[INFO] Type 'org.jcz.persistence.jpa.model.Band' (Band.java) has intertyped method from 'org.jcz.aspects.persistence.UUIDSupportAspect' (UUIDSupportAspect.aj:'java.io.Serializable org.jcz.aspects.persistence.UUIDSupportAspect$WithUUID.getId()')

Итак, похоже, что метод getId() правильно внедрен в класс Band. Но когда Maven переходит к компиляции тестов и модульному тестированию:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project jcz-persistence-jpa: Compilation failure: Compilation failure:

и, среди других деталей ошибки, я получил

[ERROR] /home/stefano/projects/java/jcz-persistence-jpa/src/test/java/org/jcz/persistence/jpa/ServiceTestCase.java:[182,45] cannot find symbol
[ERROR] symbol:   method getId()
[ERROR] location: variable persisted of type org.jcz.persistence.jpa.model.Band
[ERROR] /home/stefano/projects/java/jcz-persistence-jpa/src/test/java/org/jcz/persistence/jpa/ServiceTestCase.java:[182,60]

как будто все мои объявления интертипа не были введены, в конце концов.

Чтобы проверить, нет ли ошибки в коде, я попытался запустить тесты JUnit из Eclipse, и все заработало нормально.

Итак, я предполагаю, что в процессе компиляции maven есть что-то, что я не настроил правильно.

Может ли кто-нибудь помочь мне понять, что вызывает проблему?


person Stefano Cazzola    schedule 15.11.2015    source источник


Ответы (2)


Наконец придумал решение. Оставив след здесь.

Чтобы решить эту проблему, я настроил maven-compiler-plugin следующим образом:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${maven-compiler-plugin.version}</version>
    <configuration>
        <source>1.${java.version}</source>
        <target>1.${java.version}</target>
        <useIncrementalCompilation>false</useIncrementalCompilation>
    </configuration>
</plugin>

где наиболее важной частью является <useIncrementalCompilation>false</useIncrementalCompilation>

person Stefano Cazzola    schedule 15.11.2015
comment
На самом деле это известная, но не исправленная проблема в плагине компилятора Maven, потому что переключатель делает противоположное тому, что он рекламировал. На самом деле он использует инкрементную компиляцию, если вы установите переключатель в положение false. Очень надоедливый. Я упомянул, что во многих ответах здесь, на SO, просто не было некоторое время, но вы узнали сами. :-) Кстати, вы можете принять свой ответ, чтобы закрыть вопрос. - person kriegaex; 21.11.2015
comment
большое спасибо @kriegaex! Даже если я решил проблему тогда, я никогда не интересовался причиной, почему это произошло. Теперь, когда я знаю, я также решил проблему, которая возникла у меня при компиляции в последних выпусках Eclipse (начиная с конца 2019 года) :-) - person Stefano Cazzola; 25.07.2020

Чтобы межтиповое объявление работало с аспектом j-maven-plugin, необходимо настроить maven-compiler-plugin, добавив параметр failOnError:

            <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <failOnError>false</failOnError>
            </configuration>
        </plugin>

Решение взято с https://fw-geekycoder.blogspot.com/2010/05/aspectj-inter-type-declaration.html

person Marian    schedule 24.07.2020