aspecj-maven-plugin,编织依赖功能,随机加载java类

问题描述 投票:0回答:1

我在使用 maven 作为依赖工具的多模块项目中使用 maven-aspectj-plugin。一个简单的演示项目,您可以在这里找到demo-project

在我的实际项目中,为了与 lombok 兼容,我使用了异常的模块依赖图;

starter ---> ajc ----> 我的业务模块。

starter是程序的入口。方面位于 ajc 模块中,该模块只有方面。所有将被编织到的java类都在业务模块中。利用这个依赖,我可以在我的业务模块中使用 lombok,并且编织过程出现在 ajc 模块的编译中。此时业务模块已经用lombok编译为字节码了。当然,我需要使用 weaveDependency 样式。

长期以来一直运行良好。但今天我开始了我的另一个项目。未进入该程序。最有趣的部分是当我使用 idea 运行应用程序时,方面工作得很好。但我用罐子部署它。程序不进入aspect。我尝试使用一个简单的项目demo重现该错误。但这个方面出乎意料地效果很好。

所以我深入研究了 ajc 模块的目标目录。我在我的业务模块中找到了与编织目标java类相同的类文件。有趣的是,它回答了我的另一个问题。编织依赖项功能不会编辑目标 jar。怎么运行的?现在,我知道,它在方面目录中添加了一个带有方面的新类。 Jvm 可以选择 Java 类之一。

我认为我的问题应该来自这个随机程序。

最后的问题:我的猜测是否正确。 weave依赖的特点是复制原始java类并编辑它,然后将其放在另一个目录或另一个jar中,但与原始java类共享相同的包名和类名。但这又会带来另一个问题,有两个java类文件具有相同的包名和类名。由于文件 inode 的原因,类加载在不同的操作系统中会执行不同的操作,并且它取决于操作系统的文件系统。

是否有任何机制可以防止类加载器随机加载这两个java类文件中的一个。

我已经在细节上给出了我的猜测。想听听插件作者对这个问题的解释

java classpath classloader aspectj aspectj-maven-plugin
1个回答
0
投票

不要考虑类路径顺序,您应该使用干净且明显的选择,根本不将方面编织的原始 JAR 包含在类路径(或胖 JAR)中,因为编译期间 AspectJ 的 inpath 上的所有内容(

weaveDependencies
在AspectJ Maven中)将出现在相应模块的编译结果中,而不考虑特定类是否受到方面的影响。您的其他模块应该依赖于编织模块,但不依赖于它们的传递性非编织依赖项。

如何实现这一目标,很大程度上取决于您的情况。一些选项包括

  • 使用依赖排除,
  • 使用 Flatten Maven Plugin 为每个编织模块创建一个减少依赖的 POM,
  • 使用 Maven Assembly、Maven Shade 或 Spring Boot 应用程序打包器插件时,从打包中排除 weave 依赖项。

以上所有内容都可以在 Maven 中提供帮助,具体取决于您的情况,这就是为什么我问了您不愿意更清楚地回答的详细问题。不是我的问题,你这是搬起石头砸自己的脚。

如果你让它在 Maven 中工作,但不知何故不在你的 IDE 中工作,因为 IDE 可能不理解 Flatten Maven 的作用,并且仍然在单个多模块项目中的类路径上添加编织依赖项,你可能必须使用单独的项目用于 Aspect 编织并创建一个 uber JAR 或一个具有减少依赖的 POM 的模块,

mvn install
,然后在项目 B 中使用它。但通常有一些方法可以避免这种情况,即使它是一种干净而简单的方法,也是。

这是您项目的PR,展示了如何调整 Maven 依赖项插件以将正确的依赖项复制到 lib 目录。如果您使用类路径上的

lib
目录运行 starter 或将两者一起放入一个 fat JAR 中,它应该可以工作。类路径上不再有重复的类。

© www.soinside.com 2019 - 2024. All rights reserved.