我还没有尝试在插件开发中使用aspectj,所以可能还有一些额外的东西。但是,为了确保目标在编译时正确编织并可以运行,您需要做一些事情。
-
-
方面需要位于类路径上的导出包中
-
目标插件需要在类路径上有aspectjrt,这样它才能处理方面
-
编译目标时,需要使用aspectj编译器来编织目标。
更新,我无法重现您的问题(即,它在我的盒子上工作正常)。为了复制这种情况,我在源目录中创建了一个带有单个Logging.aj文件的AspectJ项目。我将其作为jar文件(称为logging.jar)导出到另一个项目的根目录(另一个项目也设置为包含“Main”类的AspectJ项目)。然后,我修改了“main”项目的方面路径,以包括logging.jar和方面,并将建议编织到每个doSomethingAa()和doSomethingB()方法调用中。
我在代码中发现的唯一问题是,静态方法调用是针对“A”而不是“Main”。
以下是主项目的.classpath文件中的条目:
<classpathentry kind="lib" path="logging.jar">
<attributes>
<attribute name="org.eclipse.ajdt.aspectpath"
value="org.eclipse.ajdt.aspectpath"/>
</attributes>
</classpathentry>
我尝试过各种排列,我唯一能做到的就是
工作是通过删除AspectJ特性或从构建路径中删除jar。
您是否忽略了其他可能影响您工作空间的因素?
更新:根据您的评论,我向我的工作区添加了第三个项目(aj_client),并完成了以下步骤:
-
修改Logging.aj以执行System.out调用,排除了log4j配置问题
-
将aj_日志(包含logging.aj的AspectJ项目)导出到logging.jar
-
将logging.jar添加到aj_目标的方面路径
-
将aj_目标(包含Main.java的AspectJ项目)导出到target.jar
-
在aj_客户端项目(没有AspectJ特性)中创建了一个新类(Client.java)。
-
将target.jar、logging.jar(和log4j.jar)添加到aj_客户机的Java构建路径并运行它。
Client.java包含一个方法:
public static void main(String[] args) {
Main.main(args);
}
运行时,此操作失败,并出现NoClassDefFoundError:
Exception in thread "main" java.lang.NoClassDefFoundError: org/aspectj/lang/Signature
at Client.main(Client.java:6)
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.Signature
为了解决这个问题,我修改了aj_客户端的.classpath,使其上有aspectjrt(通过手动添加
AspectJ运行库
类路径容器)并重新运行,程序执行并输出日志记录语句:
Entering function: doSomethingAa with input parameters: [java.lang.String message] = [Tal] [java.util.Map map] = [{FirstKey=FirstValue, SecondKey=SecondValue}]
log4j:WARN No appenders could be found for logger (A.class).
log4j:WARN Please initialize the log4j system properly.
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingAa with input parameters: [java.lang.String message] = [Guy] [java.util.Map map] = [{Happy=Birthday, Tal=Guy}]
Exit function: void target.Main.doSomethingAa(int, String, Map)
Entering function: doSomethingB with input parameters: [java.lang.String name] = [TalG]
Exit function: void target.Main.doSomethingB(int, String)
Entering function: doSomethingB with input parameters: [java.lang.String name] = [GuyG]
Exit function: void target.Main.doSomethingB(int, String)
Finished running main
aj_客户端的.classpath文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
<!-- the other jars for the logging and target projects -->
<classpathentry kind="lib" path="/aj_target/target.jar"/>
<classpathentry kind="lib" path="/aj_target/log4j-1.2.14.jar"/>
<classpathentry kind="lib" path="/aj_target/logging.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
具有
<!--aspectjrt from Maven repository-->
<classpathentry kind="lib" path="C:/maven-2.2.0/repo/aspectj/aspectjrt/1.5.3/aspectjrt-1.5.3.jar"/>
<!--aspectjrt from Eclipse plugin -->
<classpathentry kind="lib" path="C:/eclipse-3.5/eclipse/plugins/org.aspectj.runtime_1.6.5.20090618034232/aspectjrt.jar"/>
在证明日志代码是编织的之后,我返回并将logging.aj更改为再次使用getLog().info()调用,发现日志语句不再输出。为了解决这个问题,我添加了一个log4j.xml配置文件(只指定根appender)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
DEBUG class - A
INFO Logging - Exit function: void target.Main.doSomethingAa(int, String, Map)
INFO Logging - Entering function: doSomethingB with input parameters: [java.lang.String name] = [TalG]
DEBUG class - B
INFO Logging - Exit function: void target.Main.doSomethingB(int, String)
INFO Logging - Entering function: doSomethingB with input parameters: [java.lang.String name] = [GuyG]
DEBUG class - B
INFO Logging - Exit function: void target.Main.doSomethingB(int, String)
Finished running main
注意:在清理、构建和导出target.jar之前,您需要小心确保已经清理、构建和导出了logging.jar,然后才清理客户机项目。如果你把订单搞砸了,你会得到不匹配的内容。
总结
和
类路径上有一个aspectjrt.jar
和
您已经正确配置了log4j,日志将被输出。
您可以通过添加类路径容器或指定兼容aspectjrt.jar的路径来指定aspectjrt依赖项