javahibernatejdbcaspectjaspectj-maven-plugin

How to weave hibernate by aspectj?


I have a library with aspect which scan all statement executions and doing some logic with sql sentence.

@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
}

When I use it for jdbc operations it works fine. I also used it with spring-jdbc like that

<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>

But when I try to weave hibernate core dependency the same way

<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>

I have an error on aspectj compile task.

In logs I found a lot of NPE's(264) like that

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

How to resolve that? Maybe aspectj plugin has an option to skip some weaves if they causes an error or maybe I have to put some properties to resolve that generic parameter types?

Full aspectj compiler log

I don't find any links with same problem in weaving, but there is one with closest exception: link


Solution

  • Thanks for the two MCVE projects. They helped me to reproduce the problem, and it is actually an AspectJ problem. There are missing null checks for a certain method call in the weaver, which subsequently leads to errors in case of parsing method signatures in pointcuts, pointing to methods unavailable during weaving. Imagine that a call() pointcut is woven into a class, but then a dependency class is unavailable or is present in a different version with different methods. It is an edge case, but you bumped into it.

    I am in the process of fixing the problem, see AspectJ issue #243.

    Furthermore, I sent you two PRs for your projects:

    You are using Java 17 in one of them, so you should use the AspectJ.dev version of AspectJ Maven Plugin, because the Mojohaus version still does not support Java 17 in version 1.14.0. The AspectJ.dev version is also the version recommended by the AspectJ project, because it is better maintained and has a few more features. In the PRs, I also updated the AspectJ version to the latest snapshot containing the fix for your problem, so you can easily retest. Not important here, but FYI, the snapshot also has Java 20 compilation support, while the latest release 1.9.19 only supports Java 19.


    Update: In order to use an AspectJ snapshot, you need this repository:

    <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>