Как использовать AspectJ Maven для бинарного плетения после фазы Javac + Lombok - PullRequest
0 голосов
/ 11 июля 2019

У меня есть проект, который использует скомпилированные аспекты и ткет их во время компиляции.Я хочу добавить Lombok, но, к сожалению, AJC не поддерживается Lombok.Поскольку этот проект сам по себе не имеет источников аспектов, я настроил плагин AspectJ Maven для выполнения ткачества после компиляции, после компиляции с использованием Javac + Lombok.

Вот конфигурация для плагина AspectJ Maven:

<forceAjcCompile>true</forceAjcCompile>
<sources/>
<weaveDirectory>${project.build.outputDirectory}</weaveDirectory>

Он присоединяется к фазе компиляции сразу после компиляции плагина Maven Compiler.Таким образом, сначала будет вызываться Lombok + Javac, а затем AJC будет выполнять переплетение сгенерированных файлов классов Javac.

Есть ли какие-либо ограничения / недостатки при выполнении переплетения байт-кода над сгенерированными javac классами?

Может быть, естьлучший способ заставить Maven + Ломбок + Аспекты + Идея работать вместе без проблем.

Вот минимальный пример проекта: https://github.com/Psimage/aspectj-and-lombok

1 Ответ

0 голосов
/ 12 июля 2019

Когда в другом вопросе вы задали мне комментарий, я действительно подумал, что у вас проблемы с вашим подходом, но он работает.Единственное, что мне нужно было сделать, чтобы запустить тест непосредственно из IDE (IntelliJ IDEA), - это фактически делегировать приложения и исполнителей тестов в Maven, поскольку в противном случае IDEA не применяет Lombok + AspectJ одновременно.

Delegate IDE build/run actions to Maven

Если ваш подход работает, используйте его.Но на самом деле AspectJ Maven предлагает другой подход : сначала компилировать с помощью компилятора Maven в другой выходной каталог, а затем использовать этот каталог как каталог переплетения для компилятора AspectJ.Образец POM там не работает на 100%, потому что при указании выходного каталога для Javac в командной строке этот каталог должен существовать, он не будет создан компилятором.Поэтому вам также понадобится какое-нибудь уродливое действие Antrun:

<plugins>

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
      <execution>
        <id>unwovenClassesFolder</id>
        <phase>generate-resources</phase>
        <configuration>
          <tasks>
            <delete dir="${project.build.directory}/unwoven-classes"/>
            <mkdir dir="${project.build.directory}/unwoven-classes"/>
          </tasks>
        </configuration>
        <goals>
          <goal>run</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <executions>
      <execution>
        <!-- Modifying output directory of default compile because non-weaved classes must be stored
             in separate folder to not confuse ajc by reweaving already woven classes (which leads to
             to ajc error message like "bad weaverState.Kind: -115") -->
        <id>default-compile</id>
        <configuration>
          <compilerArgs>
            <arg>-d</arg>
            <arg>${project.build.directory}/unwoven-classes</arg>
          </compilerArgs>
        </configuration>
      </execution>
    </executions>
  </plugin>

  <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <configuration>
      <aspectLibraries>
        <aspectLibrary>
          <groupId>me.yarosbug</groupId>
          <artifactId>aspects</artifactId>
        </aspectLibrary>
      </aspectLibraries>

      <forceAjcCompile>true</forceAjcCompile>
      <sources/>
      <weaveDirectories>
        <weaveDirectory>${project.build.directory}/unwoven-classes</weaveDirectory>
      </weaveDirectories>
    </configuration>
    <executions>
      <execution>
        <phase>process-classes</phase>
        <goals>
          <goal>compile</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

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

</plugins>

Я бы предложил другой подход в качестве альтернативы:

  1. Создайте нетканый модуль Java, выполняя там Java + Lombok.
  2. Создайте отдельный модуль для бинарного плетения AspectJ, используя модуль Java в качестве зависимости переплетения.Поскольку ваш модульный тест зависит как от Lombok, так и от AspectJ, поместите тест в этот модуль.

Преимущество заключается в том, что вам не нужно возиться с несколькими компиляторами, фазами выполнения, выходными каталогами, Antrunи т.д.


Обновление:

Я клонировал ваш GitHub MCVE и этот коммит на ветке master отражает то, что я объяснил в моем примере XML выше.

Я также создал ответвление многофазную компиляцию с другим коммитом , который эффективно реорганизует проект согласно моей альтернативной идее.Я просто цитирую сообщение коммита:

Multi-phase compilation: 1. Java + Lombok, 2. AspectJ binary weaving

There are many changes (sorry, I should have split them into multiple
commits):
  - Marker annotation renamed to @marker and moved to separate module
    because the main application should not depend on the aspect module.
    Rather both application and aspect now depend on a common module.
  - New module "main-app-aspectj" does only AspectJ binary weaving on
    the already lomboked Java application.
  - Both application modules have slightly different unit tests now: One
    checks that Lombok has been applied and AspectJ has not, the other
    checks that both have been applied.
  - Aspect pointcut limits matching to "execution(* *(..))" in order to
    avoid also matching "call()" joinpoints.

The end result is that now we have a clear separation of concerns, clear
dependencies, no more scripted Ant build components and the new option
to use the lomboked code optionally with or without aspects applied
because both types or JARs are created during the build.

Не стесняйтесь добавлять мой форк в качестве другого удаленного в ваш Git-репозиторий и извлекать мои изменения оттуда.Если вы предпочитаете, чтобы я отправлял вам запросы, чтобы вам было проще, просто дайте мне знать.

...