OpenClover - Начало работы с AspectJ

Я пытаюсь использовать Openclover с проектом, который использует AspectJ и инструменты аспекты в своем коде.

pom.xml имеет эти зависимости по отношению к AspectJ:

...
<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.9</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
...

И эти плагины:

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.openclover</groupId>
            <artifactId>clover-aspectj-compiler</artifactId>
            <version>1.0.0</version>
        </plugin>

        <plugin>
            <groupId>org.openclover</groupId>
            <artifactId>clover-maven-plugin</artifactId>
            <version>4.2.0</version>
            <executions>
                <execution>
                    <id>clover</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>instrument</goal>
                        <goal>clover</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>

Я использую два плагина для этого: clover-maven-plugin который является инструментом покрытия кода и clover-aspectj-compiler, обертка для компилятора AspectJ, которая позволяет инструментарий кода с использованием OpenClover.

Я получаю следующие ошибки:

[ERROR] QueryAspect.java:48:0::0 The type QueryAspect is already defined
[ERROR] LogAspect.java:35:0::0 The type LogAspect is already defined

Документации по этому поводу слишком мало (или, что лучше, нет), и я не могу заставить AspectJ работать с OpenClover, и в Интернете нет большой помощи.

Спасибо

1 ответ

Решение

Как обсуждалось в наших комментариях, вы можете просто использовать AspectJ Maven вместо Clover AspectJ. Вам просто нужно принять несколько мер предосторожности, чтобы заставить его работать:

  • Мне нравится помещать казни AspectJ Maven в process-sources фаза, чтобы убедиться, что компилятор AspectJ запускается до того, как плагин Maven Compiler запускает обычный компилятор Java. Вы также можете отключить Maven Compiler, поскольку Ajc - полная замена Javac. На самом деле эта фаза использовалась по умолчанию в более старых версиях плагинов, но она была изменена давно, что также упоминается в ответе на SO.

  • В Maven Compiler есть проблема, а именно - переключатель useIncrementalCompilation кажется, изменила логику. Вот почему вам нужно установить его false чтобы заставить это работать. В противном случае он пытается перекомпилировать материал, уже скомпилированный AspectJ, нарушая переплетение аспектов. См. MCOMPILER-209 и MCOMPILER-194, я объяснил проблему и ее решение там в моих сообщениях.

  • Теперь единственная проблема, фактически связанная с OpenClover (OC): AspectJ (AJ) ничего не знает о том, что OC добавляет исходный код к каждому методу для включения покрытия кода. К сожалению, OC также не знает об AJ, а также добавляет код в pointcots в стиле аннотаций, определенных как пустые методы с @Pointcut аннотаций. Поскольку OC должен сделать свою магию перед компиляцией AJ, компилятор AJ жалуется на неожиданный код, найденный в pointcut, и останавливает компиляцию с ошибкой. Есть как минимум два способа избежать этого:

    • Вы можете вставить все pointcut в соответствующие @Before, @After, @Around и т. д. советует использовать их, что обычно работает, но не всегда возможно в тех случаях, когда вам требуется привязка аргумента в pointcut для реализации шаблона червоточины, например execution(pointcutA()) && cflow(execution(pointcutB(myArgument))),

    • Или вы можете исключить все аспекты из инструментария OC, что проще всего, если они находятся в одном пакете, где нет других классов Java, которые должны быть инструментированы. Тогда вы можете использовать простое исключение, как в вашем случае <exclude>codeaspects/**</exclude>, Это то, что я делал в своем запросе на удаление, исправляя ваш проект.

    • Самый простой способ - просто переименовать все аспекты из *.java в *.aj, который является каноническим способом присвоения им имен в любом случае. Я только что попробовал в вашем проекте, и он прекрасно работает. AspectJ Maven ищет эти файлы в любом случае, но OC будет игнорировать их, даже не вычисляя их строки кода для пропущенного покрытия. Вы также можете избавиться от <exclude> упомянуто выше, смотрите этот коммит.

Возможно, обо всем этом автоматически позаботится Clover AspectJ, я никогда не пробовал. Может быть, автор этой обертки компилятора должен на самом деле объяснить, что он делает и как он работает, в документации, особенно о том, как использовать его с Maven. В противном случае нет смысла его использовать.

Другие вопросы по тегам