4

几天前我问了这个问题,并设法使用编译时编织使其工作。

但是,当应用程序运行并调用我通过 AOP 混合到 DTO 中的 toString() 方法时,我得到以下异常。

我没想到运行时类路径中需要 AspectJ。毕竟,我使用了编译时编织,所以字节码应该已经处于最终状态,对吧?为什么预计 AspectJ 会在运行时出现?

java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:506)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)[osgi-3.6.2.R36x_v20110210.jar:]
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)[osgi-3.6.2.R36x_v20110210.jar:]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)[:1.6.0_35]
    ... 51 more

有没有办法指示 AspectJ 在生成的字节码中删除对自身的所有引用?

注意:我在 OSGi 环境中运行 - 但这绝对无关紧要。

4

2 回答 2

3

无论您使用编译时、编译后时间还是加载时编织,编织的字节码都将依赖于少数类型 - 将它们放入 jar 中被认为比将它们生成到每个已编译的应用程序中更容易。这些类型被封装在小 jar 'aspectjrt.jar' 中。您不需要类路径上的 weaver jar 或编译器 jar,只需要小的运行时 jar。它包含一些不同的东西:

  • 可能已用于编写方面的运行时可见注释的定义(@Before,@Aspect)
  • 出现问题时的异常类型 (NoAspectBoundException) 或实现语言功能 (SoftException)
  • 用于实现某些语言功能的实用程序代码,例如 cflow 线程本地堆栈管理。
  • thisJoinPoint 的所有支持类。当您在 thisJoinPoint 上访问 getSignature() 之类的内容时,您可能会得到一个 MemberSignature。

如果您不使用这些语言功能,如果可以避免很多这些,但 NoAspectBoundException 可能仍然是一个问题——即使是最简单的方面也取决于此。现在没有办法编译可以完全避免 jar 依赖。

可以修改 AspectJ生成额外的代码来完全避免依赖,但这不是一个常见的请求,因此没有对其进行任何工作。

(有些构建的 aspectjrt.jar 包含正确的 OSGi 清单信息,可在该环境中使用 - 标准发行版中包含的 jar 现在无法正确获取该清单)

于 2013-01-17T01:43:43.223 回答
0

我相信无论编织何时发生,您仍然需要 AspectJ 运行时库。

于 2013-01-14T15:09:59.453 回答