如何用aspectj编写hibernate?

nhaq1z21  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(104)

我有一个带有方面的库,它可以扫描所有语句的执行,并使用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>

但是当我尝试以同样的方式编织hibernate核心依赖

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

我在aspectj编译任务中遇到错误。
在日志中我发现了很多这样的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插件有一个选项来跳过一些编织,如果他们导致了一个错误,或者也许我必须把一些属性来解决通用参数类型?
Full aspectj compiler log
我没有发现任何链接有相同的问题编织,但有一个最接近的例外:link

lmyy7pcs

lmyy7pcs1#

谢谢你的两个MCVE项目。他们帮助我重现了这个问题,实际上它是一个AspectJ问题。织入器中的某个方法调用缺少空值检查,这随后会导致在切入点中解析方法签名时出错,从而指向织入期间不可用的方法。假设一个call()切入点被编织到一个类中,但是一个依赖类不可用,或者存在于一个不同的版本中,使用不同的方法。这是个棘手的案子,但你碰到了.
我正在解决这个问题,请参阅AspectJ issue #243
此外,我还为您的项目发送了两个PR:

您在其中一个版本中使用Java 17,因此您应该使用AspectJ.dev版本的AspectJ Maven插件,因为Mojohaus版本仍然不支持1.14.0版本的Java 17。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>

相关问题