带有 OpenJDK 11 且没有 Spring Context 的 AspectJ 1.9.4 无法作为依赖模块工作

2023-11-30

我正在尝试使用 AspectJ 创建自定义加载时注释,在没有 Spring Context 的情况下打开 JDK11。它在模块内运行良好,注释在类加载时编织,方面在运行时执行。没问题,但是当aspectJ实现模块添加为对另一个模块的依赖时。 AspectJ 和注释不处理。我是否缺少任何配置?

module-a

@Documented
@Inherited
@Target(METHOD)
@Retention(RUNTIME)
public @interface Counter {
    String name() default "";
}
@Aspect
public class CounterAspect {
    @Around("execution(* *.*(..)) && @annotation(counter)")
    public void myBeforeLogger(ProceedingJoinPoint joinPoint, Counter counter) {

        System.out.println("Okay - we're in the before handler...");
        System.out.println("The test annotation value is: " + counter.name().toString());
}

资源/META-INF/aop.xml

<aspectj>
    <aspects>
        <aspect name="CounterAspect"/>
    </aspects>
    <weaver options="-verbose">
        <!-- weave anything -->
        <include within="*" />
    </weaver>
</aspectj>

pom.xml

<properties>
    <aspectj.version>1.9.4</aspectj.version>
</properties>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>${aspectj.version}</version>
</dependency>
<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.11</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.9</version>
            <configuration>
                <argLine>
                -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
                </argLine>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

module-b

pom.xml

<dependency>
    <groupId>org.mymodule</groupId>
    <artifactId>module-a</artifactId>
    <version>1.0.0</version>
</dependency>
public class MyCounter {
    @Counter(name="call_count")
    public void count() {}
}
public class MyCounterTest {
    @Test
    public void testCount() {
        MyCounter counter = new MyCounter();
        counter.count();
        //NOTE: I expect CounterAspect from module-a should be intercepted. It is not working!!!! There is no aspectJ class loading verbose in console.
    }
}

我建议您创建一个包含一些预定义属性、依赖版本和插件配置的父 POM。您的两个子模块(一个用于应用程序 + 测试,一个用于方面)可以使用这些定义,这会导致子模块 POM 更短:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>de.scrum-master</groupId>
  <artifactId>aspectj-ltw-test-multi-module</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.source-target.version>11</java.source-target.version>
    <aspectj.version>1.9.4</aspectj.version>
  </properties>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.3</version>
          <configuration>
            <source>${java.source-target.version}</source>
            <target>${java.source-target.version}</target>
            <!-- IMPORTANT -->
            <useIncrementalCompilation>false</useIncrementalCompilation>
          </configuration>
        </plugin>
        <plugin>
          <groupId>com.nickwongdev</groupId>
          <artifactId>aspectj-maven-plugin</artifactId>
          <version>1.12.1</version>
          <configuration>
            <!--<showWeaveInfo>true</showWeaveInfo>-->
            <source>${java.source-target.version}</source>
            <target>${java.source-target.version}</target>
            <Xlint>ignore</Xlint>
            <complianceLevel>${java.source-target.version}</complianceLevel>
            <encoding>${project.build.sourceEncoding}</encoding>
            <!--<verbose>true</verbose>-->
            <!--<warn>constructorName,packageDefaultMethod,deprecation,maskedCatchBlocks,unusedLocals,unusedArguments,unusedImport</warn>-->
          </configuration>
          <executions>
            <execution>
              <!-- IMPORTANT -->
              <phase>process-sources</phase>
              <goals>
                <goal>compile</goal>
                <goal>test-compile</goal>
              </goals>
            </execution>
          </executions>
          <dependencies>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjtools</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
            <dependency>
              <groupId>org.aspectj</groupId>
              <artifactId>aspectjweaver</artifactId>
              <version>${aspectj.version}</version>
            </dependency>
          </dependencies>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.9</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>${aspectj.version}</version>
      </dependency>
      <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
      </dependency>
      <dependency>
        <groupId>de.scrum-master</groupId>
        <artifactId>aspect</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <modules>
    <module>aspect</module>
    <module>application</module>
  </modules>

</project>

请注意,我没有使用原始的 AspectJ Maven 插件,而是使用支持 Java 11 的分支。原始版本仍然落后。正如您所说,您想使用 Java 11,您必须这样做。使用 Java 8,您可以使用原始插件。

方面模块:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>de.scrum-master</groupId>
    <artifactId>aspectj-ltw-test-multi-module</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <groupId>de.scrum-master</groupId>
  <artifactId>aspect</artifactId>
  <version>1.0-SNAPSHOT</version>

  <build>
    <plugins>
      <plugin>
        <groupId>com.nickwongdev</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
    </dependency>
  </dependencies>
</project>
<aspectj>
  <aspects>
    <aspect name="de.scrum_master.aspect.CounterAspect"/>
  </aspects>
  <weaver options="-verbose">
    <!-- weave anything -->
    <include within="*"/>
  </weaver>
</aspectj>
package de.scrum_master.aspect;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Inherited
@Target(METHOD)
@Retention(RUNTIME)
public @interface Counter {
  String name() default "";
}
package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class CounterAspect {
  @Around("execution(* *.*(..)) && @annotation(counter)")
  public void myBeforeLogger(ProceedingJoinPoint joinPoint, Counter counter) {
    System.out.println(joinPoint + " -> " + counter.name());
  }
}

应用模块:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>de.scrum-master</groupId>
    <artifactId>aspectj-ltw-test-multi-module</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <groupId>de.scrum-master</groupId>
  <artifactId>application</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>de.scrum-master</groupId>
      <artifactId>aspect</artifactId>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <argLine>
            -javaagent:${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar
          </argLine>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
package de.scrum_master.app;

import de.scrum_master.aspect.Counter;

public class MyCounter {
  @Counter(name = "call_count")
  public void count() {}
}
package de.scrum_master.app;

import org.junit.Test;

public class MyCounterTest {
  @Test
  public void testCount() {
    new MyCounter().count();
  }
}

现在如果你跑mvn clean verify要不就mvn clean test您将获得应用程序模块测试的以下控制台日志:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
[AppClassLoader@2aae9190] info AspectJ Weaver Version 1.9.4 built on Friday May 10, 2019 at 08:43:10 PDT
[AppClassLoader@2aae9190] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@2aae9190
[AppClassLoader@2aae9190] info using configuration (...)/SO_AJ_LTWTestMultiModule_56397605/aspect/target/classes/META-INF/aop.xml
[AppClassLoader@2aae9190] info register aspect de.scrum_master.aspect.CounterAspect
[IsolatedClassLoader@74e52ef6] info AspectJ Weaver Version 1.9.4 built on Friday May 10, 2019 at 08:43:10 PDT
[IsolatedClassLoader@74e52ef6] info register classloader org.apache.maven.surefire.booter.IsolatedClassLoader@74e52ef6
[IsolatedClassLoader@74e52ef6] info using configuration (...)/SO_AJ_LTWTestMultiModule_56397605/aspect/target/classes/META-INF/aop.xml
[IsolatedClassLoader@74e52ef6] info register aspect de.scrum_master.aspect.CounterAspect
Running de.scrum_master.app.MyCounterTest
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access using Lookup on org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor (file:/(...)/.m2/repository/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar) to class java.lang.ClassLoader
WARNING: Please consider reporting this to the maintainers of org.aspectj.weaver.loadtime.ClassLoaderWeavingAdaptor
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[AppClassLoader@2aae9190] info processing reweavable type de.scrum_master.aspect.CounterAspect: de\scrum_master\aspect\CounterAspect.aj
[AppClassLoader@2aae9190] info successfully verified type de.scrum_master.aspect.CounterAspect exists.  Originates from de\scrum_master\aspect\CounterAspect.aj
execution(void de.scrum_master.app.MyCounter.count()) -> call_count
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.885 sec

请特别注意

execution(void de.scrum_master.app.MyCounter.count()) -> call_count

这就是您想要的,加载时间编织方面将开始进行您的测试。


Update:我创建了一个GitHub 存储库为你。您可以克隆它,而不是从这个答案复制我的所有代码片段。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有 OpenJDK 11 且没有 Spring Context 的 AspectJ 1.9.4 无法作为依赖模块工作 的相关文章

  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 如何让 BlazeDS 忽略属性?

    我有一个 java 类 它有一个带有 getter 和 setter 的字段 以及第二对 getter 和 setter 它们以另一种方式访问 该字段 public class NullAbleId private static final
  • 日期语句之间的 JPQL SELECT [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我想将此 SQL 语句转换为等效的 JPQL SELECT FROM events WHERE events date BETWE
  • 不同帐户上的 Spring Boot、JmsListener 和 SQS 队列

    我正在尝试开发一个 Spring Boot 1 5 应用程序 该应用程序需要侦听来自两个不同 AWS 帐户的 SQS 队列 是否可以使用 JmsListener 注解创建监听器 我已检查权限是否正确 我可以使用 getQueueUrl 获取
  • .properties 中的通配符

    是否存在任何方法 我可以将通配符添加到属性文件中 并且具有所有含义 例如a b c d lalalala 或为所有以结尾的内容设置一个正则表达式a b c anything 普通的 Java 属性文件无法处理这个问题 不 请记住 它实际上是
  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类

随机推荐