Как сплести спящий режим по аспектам?

У меня есть библиотека с аспектом, которая сканирует все выполнения операторов и выполняет некоторую логику с предложением sql.

@Pointcut("target(java.sql.Statement)")
public void statement() {}

@AfterReturning("!within(AnalyzerAspect) && statement() && args(sql)")
public void after(JoinPoint jp, String sql) throws Throwable {
  // some logic
}

Когда я использую его для операций jdbc, он отлично работает. Я также использовал его с spring-jdbc, как это

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>${aspect.compiler.plugin.version}</version>
  <configuration>
    <weaveDependencies>
      <weaveDependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
      </weaveDependency>
    </weaveDependencies>
    <aspectLibraries>
      <aspectLibrary>
        <groupId>edu.ifmo.diploma</groupId> <!-- My library -->
        <artifactId>db-analyzer</artifactId>
      </aspectLibrary>
    </aspectLibraries>
    <complianceLevel>11</complianceLevel>
    <showWeaveInfo>true</showWeaveInfo>
    <Xlint>ignore</Xlint>
    <encoding>UTF-8</encoding>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
        <goal>test-compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Но когда я пытаюсь сплести зависимость ядра гибернации таким же образом

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>${aspect.compiler.plugin.version}</version>
  <configuration>
    <weaveDependencies>
      <weaveDependency>
        <groupId>org.hibernate.orm</groupId>
        <artifactId>hibernate-core</artifactId>
      </weaveDependency>
    </weaveDependencies>
    <aspectLibraries>
      <aspectLibrary>
        <groupId>edu.ifmo.diploma</groupId> <!-- My library -->
        <artifactId>db-analyzer</artifactId>
      </aspectLibrary>
    </aspectLibraries>
    <complianceLevel>11</complianceLevel>
    <showWeaveInfo>true</showWeaveInfo>
    <Xlint>ignore</Xlint>
    <encoding>UTF-8</encoding>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>
        <goal>test-compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

У меня ошибка в задаче компиляции аспекта.

В журналах я нашел много таких NPE (264)

end public class org.hibernate.metamodel.mapping.ordering.ast.ParseTreeVisitor
 -- (NullPointerException) Cannot invoke "org.aspectj.weaver.ResolvedMember.getGenericParameterTypes()" because the return value of "org.aspectj.weaver.Shadow.getResolvedSignature()" is null
Cannot invoke "org.aspectj.weaver.ResolvedMember.getGenericParameterTypes()" because the return value of "org.aspectj.weaver.Shadow.getResolvedSignature()" is null
java.lang.NullPointerException: Cannot invoke "org.aspectj.weaver.ResolvedMember.getGenericParameterTypes()" because the return value of "org.aspectj.weaver.Shadow.getResolvedSignature()" is null

Как это решить? Может быть, у плагина аспекта есть возможность пропустить некоторые переплетения, если они вызывают ошибку, или, может быть, мне нужно добавить некоторые свойства для разрешения этих общих типов параметров?

Полный лог компилятора aspectj

Я не нашел ссылок с такой же проблемой в плетении, но есть одна с ближайшим исключением: ссылка

Сплетение должно работать, но сплетенные классы Hibernate будут частью вашего JAR-файла приложения. Если у вас все еще есть исходная библиотека Hibernate в пути к классам, вы можете столкнуться с конфликтами с повторяющимися классами. Это можно решить, но это сильно зависит от вашего фактического POM или набора POM. Я не могу ответить на это одним предложением. Может быть, вместо посткомпилирования плетение во время загрузки облегчило бы вам жизнь. Я могу вам помочь, но мне нужно больше, чем фрагмент POM. Пожалуйста, опубликуйте MCVE воспроизводящую проблему на GitHub

kriegaex 11.06.2023 20:02

Вы также, кажется, используете Lombok, что может привести к проблемам во время компиляции в связи с AspectJ. Но я не хочу спекулировать. Мне нужно увидеть минимальную версию вашего проекта, настолько маленькую, насколько это возможно, достаточно большую, чтобы воспроизвести проблемы компиляции. Тогда я могу проанализировать это и предложить решение.

kriegaex 11.06.2023 20:13

«Отсутствует POM для com.djidjya.team:djidjya-boot-starter:jar:2.10, информация о зависимостях отсутствует». Кроме того, ваш проект имеет зависимость не от Hibernate, а от Spring JDBC. Ваш вопрос описывает это по-другому.

kriegaex 12.06.2023 16:27

djidjya-boot-starter является частной библиотекой и не имеет внутри никаких баз данных. Я написал о spring jdbc в начале вопроса. Для возникновения ошибки вы должны переключить зависимость стартера jdbc на стартер jpa и сплести другую библиотеку, как я написал в описании. Я удалю свой стартер из зависимостей, чтобы легко воспроизвести

Maxim Rybalchenko 12.06.2023 20:23

@kriegaex Я обновляю приложение (удаляю стартер и включаю библиотеку гибернации, чтобы сплести конфиг в pom) github.com/niallrox/djidjya-java-kubernetes-template

Maxim Rybalchenko 12.06.2023 21:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
6
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Спасибо за два проекта MCVE. Они помогли мне воспроизвести проблему, и на самом деле это проблема AspectJ. Отсутствуют нулевые проверки для вызова определенного метода в вивере, что в последствии приводит к ошибкам в случае разбора сигнатур методов в pointcuts, указывающих на методы, недоступные при вивере. Представьте, что в класс вплетен call() pointcut, но тогда класс-зависимость недоступен или присутствует в другой версии с другими методами. Это крайний случай, но вы столкнулись с ним.

Я занимаюсь решением проблемы, см. AspectJ issue #243.

Кроме того, я отправил вам два PR для ваших проектов:

Вы используете Java 17 в одном из них, поэтому вам следует использовать версию AspectJ.dev плагина AspectJ Maven, поскольку версия Mojohaus по-прежнему не поддерживает Java 17 в версии 1.14.0. Версия AspectJ.dev также является версией, рекомендованной проектом AspectJ, поскольку она лучше поддерживается и имеет несколько дополнительных функций. В PR я также обновил версию AspectJ до последнего моментального снимка, содержащего исправление вашей проблемы, чтобы вы могли легко повторить тестирование. Здесь не важно, но, к вашему сведению, снимок также поддерживает компиляцию Java 20, в то время как последний выпуск 1.9.19 поддерживает только Java 19.


Обновление: чтобы использовать моментальный снимок AspectJ, вам нужен этот репозиторий:

<repositories>
    <repository>
        <id>ossrh-snapshots</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
        <releases>
            <enabled>false</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
        </snapshots>
    </repository>
</repositories>

Спасибо! В каком репо есть эти снимки? Теперь у меня есть The POM for org.aspectj:aspectjweaver:jar:1.9.20-SNAPSHOT is missing, no dependency information available

Maxim Rybalchenko 13.06.2023 10:34

Я нашел репозиторий. Спасибо, это решение помогло мне с компиляцией, но мой вызов репозитория spring jpa (PersonRepository.findAll) не запускает аспект. Вы знаете, почему эта проблема? Может я не вплел важные зависимости?

Maxim Rybalchenko 13.06.2023 11:09

Извините, я забыл добавить репо в PR, но только что обновил свой ответ выше. Я собирал AspectJ локально, поэтому я не заметил, что вы не сможете найти снимки без дополнительного репо. Что касается вашего другого вопроса, я слишком занят в данный момент, чтобы разобраться с ним. Я должен был бы проанализировать ваши аспекты и то, как они сотканы. Это отдельный вопрос, не связанный с этим.

kriegaex 13.06.2023 12:01

Я согласен с вами, я создам еще один

Maxim Rybalchenko 13.06.2023 12:11

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