【问题标题】:Aspectj, how to use ajc in a modular wayAspectj,如何以模块化方式使用ajc
【发布时间】:2021-05-28 16:15:54
【问题描述】:

我正在尝试在模块化(OSGi 设置)中使用 Aspectj 编译器 ajc。似乎使用 ajc 的标准方式是获取方面和 java 代码,并将其变成一个 JAR,其中包含 -inpath-aspectpath-sourceroots 中的 all 类和资源。

我正在尝试编织来自 bnd 的 OSGi 可执行 JAR。这个可执行 jar 包含一组需要编织的包。然而,在模块化系统中,边界非常重要。一方面,清单通常包含与该捆绑包或众多扩展器之一高度相关的信息。将所有类扁平化成一个大博客是行不通的。

因此,我将每个捆绑包分开编织。但是,输出会因方面而杂乱无章。我想导入这些以保持方面模块正确的模块。但是,使用注解编程模型,我注意到 ajc 正在修改方面模块,因此我也需要重写这些模块。这很好,但由于我单独编织每个包,我有一个问题,如果 aspect 的编织可能取决于其他模块的编织?那是, 带注释的 aspect 的修改是否依赖于它所在的类?

另一个问题是同名资源会发生什么?由于我的-inpath 只是一个 JAR(捆绑包),我注意到我最终在输出中得到了正确的清单 (META-INF/MANIFEST.MF)。但是,如果-inpath 包含许多捆绑包,那么清单会是什么?或者任何其他具有相同路径并因此重叠的资源?

最后一个问题是外部依赖。我了解 acj 想要看到整个世界并将整个世界包含到输出 JAR 中。但是,我必须排除捆绑包的外部依赖项。有没有办法将 JAR 标记为:使用,但不包含。有点像 maven 的“提供”范围?

总结:

  • @Aspect 注释类的修改是否取决于应用到的目标?
  • 我可以将带有 @Aspect 注释的类编译成单独的 JAR 吗?
  • 如何处理将在运行时提供并因此必须从输出 JAR 中排除的外部依赖项。
  • 关于-inpath-sourceroots 中重叠资源路径的规则是什么?

更新与此同时,我创建了一个implementation in Bndtools

【问题讨论】:

  • 彼得,这是一个非常有趣的话题,但是它同时包含几个问题,而不是一个明确的问题和一个明确的答案,这使得回答变得困难。恐怕这种格式比 SO 更适合讨论论坛或邮件列表,例如 aspectj-users。我不是 OSGi 用户,但我基本上了解您的一些问题。我认为 GitHub 上的 MCVE 示例项目说明了您的所有问题,对于重现您的痛点将非常有帮助。那我也许可以试着在这里回答。
  • 我不确定如何制作一个可行的项目。我已经在 [bndtools][1] 中实现了这一点。但是,我不确定我是否可以依靠观察到的行为。据我所知,Aspectj 的处理模型非常扁平化的类路径,并且文档没有讨论这导致的所有潜在问题。就像在 Java 中一样,它通常可以工作 :-) 但是,在 OSGi 世界中,我们需要更正式的规范,因为我们会尝试预先检测问题。

标签: osgi aspectj modularity bnd


【解决方案1】:

@Aspect 注释类的修改是否依赖于应用到的目标?

如果你想 100% 确定你必须阅读 AspectJ 源代码,但我会假设一个方面的字节码独立于它的目标类,因为否则你不能单独编译方面,也不能构建方面库.

我可以将带有 @Aspect 注释的类编译成单独的 JAR 吗?

当然,见上文。

如何处理将在运行时提供并因此必须从输出 JAR 中排除的外部依赖项。

如果我正确理解了这个问题,您可能希望在编译期间将它们放在类路径上,而不是放在 inpath 上。

-inpath-sourceroots 中的重叠资源路径有哪些规则?

同样,您可能必须查看源代码。如果我是你,我会简单地假设选择顺序是未定义的,并确保首先没有重复。应该有 Maven 插件来帮助您过滤想要的结果。


bndtools 似乎与 Eclipse 有着密切的联系。 AspectJ 作为 Eclipse 项目也是如此。也许您可以与 AspectJ 维护者 Andy Clement 联系。不过,他忙于白天的工作,几乎没有任何空闲周期。我正在尽我所能减轻他的负担,但 OSGi 是我的盲点之一,我几乎不知道 AspectJ 源代码。我是一个比较高级的用户。

【讨论】:

  • 谢谢!关于提供的范围,您是说 -classpath JAR 对 aspectpath 和 inpath 代码可见吗?顺便说一句,这是一个 OSGi 问题,但您会在 JPMS 世界中遇到同样的问题。这是一个模块化问题。
  • 如果我们在谈论编译,是的。编译类路径上的内容对所有 sourceroot、inpath 和 aspectpath 代码也是可见的。 sourceroots 和 inpath 中的所有内容都将被切面编织并写入输出目录。 Aspectpath 和 classpath 类不会被编织也不会被写入,这就解释了为什么后两者需要再次出现在运行时类路径上。
猜你喜欢
  • 1970-01-01
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多