У меня есть библиотека с аспектом, которая сканирует все выполнения операторов и выполняет некоторую логику с предложением 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
Я не нашел ссылок с такой же проблемой в плетении, но есть одна с ближайшим исключением: ссылка
Вы также, кажется, используете Lombok, что может привести к проблемам во время компиляции в связи с AspectJ. Но я не хочу спекулировать. Мне нужно увидеть минимальную версию вашего проекта, настолько маленькую, насколько это возможно, достаточно большую, чтобы воспроизвести проблемы компиляции. Тогда я могу проанализировать это и предложить решение.
Библиотека с аспектом github.com/niallrox/db-analyzer Приложение с зависимостью аспекта github.com/niallrox/djidjya-java-kubernetes-template
«Отсутствует POM для com.djidjya.team:djidjya-boot-starter:jar:2.10, информация о зависимостях отсутствует». Кроме того, ваш проект имеет зависимость не от Hibernate, а от Spring JDBC. Ваш вопрос описывает это по-другому.
djidjya-boot-starter является частной библиотекой и не имеет внутри никаких баз данных. Я написал о spring jdbc в начале вопроса. Для возникновения ошибки вы должны переключить зависимость стартера jdbc на стартер jpa и сплести другую библиотеку, как я написал в описании. Я удалю свой стартер из зависимостей, чтобы легко воспроизвести
@kriegaex Я обновляю приложение (удаляю стартер и включаю библиотеку гибернации, чтобы сплести конфиг в pom) github.com/niallrox/djidjya-java-kubernetes-template




Спасибо за два проекта 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
Я нашел репозиторий. Спасибо, это решение помогло мне с компиляцией, но мой вызов репозитория spring jpa (PersonRepository.findAll) не запускает аспект. Вы знаете, почему эта проблема? Может я не вплел важные зависимости?
Извините, я забыл добавить репо в PR, но только что обновил свой ответ выше. Я собирал AspectJ локально, поэтому я не заметил, что вы не сможете найти снимки без дополнительного репо. Что касается вашего другого вопроса, я слишком занят в данный момент, чтобы разобраться с ним. Я должен был бы проанализировать ваши аспекты и то, как они сотканы. Это отдельный вопрос, не связанный с этим.
Я согласен с вами, я создам еще один
Сплетение должно работать, но сплетенные классы Hibernate будут частью вашего JAR-файла приложения. Если у вас все еще есть исходная библиотека Hibernate в пути к классам, вы можете столкнуться с конфликтами с повторяющимися классами. Это можно решить, но это сильно зависит от вашего фактического POM или набора POM. Я не могу ответить на это одним предложением. Может быть, вместо посткомпилирования плетение во время загрузки облегчило бы вам жизнь. Я могу вам помочь, но мне нужно больше, чем фрагмент POM. Пожалуйста, опубликуйте MCVE воспроизводящую проблему на GitHub