maven 会出现循环依赖吗? 显然会, 比如 a 依赖b, b 依赖 c, c 依赖a, 或者简单点: a 依赖b, b 依赖 a。
当然, 这里出现多次的 maven 工程 a/b/c, 其版本应该是 一致的。 就是说 不能是 a-v1 依赖b-v1, b-v1 依赖 c-v1, c-v1 依赖a-v2, a 有v1、v2 两个版本,相互之间可能关系不大,自然不能构成 循环依赖。
我们知道,如果spring 的bean 出现了 属性的循环依赖, spring 是有办法可以自动解决的( 构造器的循环依赖, 无法解决),但是,那么, 如果 maven 循环依赖, 是否也能够 maven自动解决问题呢?
答案是 否定的。
情况1 , 比如m1 依赖m1,执行 mvn package, 出现:
[INFO] Scanning for projects... [ERROR] [ERROR] Some problems were encountered while processing the POMs: [FATAL] 'dependencies.dependency.[com.tingcream:m1:1.1]' for com.tingcream:m1:1.1 is referencing itself. @ line 19, column 21 @ [ERROR] The build could not read 1 project -> [Help 1] [ERROR] [ERROR] The project com.tingcream:m1:1.1 (D:codejavaTestm1pom.xml) has 1 error [ERROR] 'dependencies.dependency.[com.tingcream:m1:1.1]' for com.tingcream:m1:1.1 is referencing itself. @ line 19, column 21 [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
如果 m1 依赖m2,然后m2 依赖m1, 那么 对m1执行 mvn package, 出现:
[INFO] ------------------------------------------------------------------------ [INFO] Building m1 1.1 [INFO] ------------------------------------------------------------------------ [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.115 s [INFO] Finished at: 2021-09-02T19:39:36+08:00 [INFO] Final Memory: 5M/15M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal on project m1: Could not resolve dependencies for project com.tingcream:m1:jar:1.1: Failure to find com.tingcream:m2:jar:1.1 in http://maven.aliyun.com/nexus/content/repositories/central/ was cached in the local repository, resolution will not be reattempted until the update interval of alimaven has elapsed or updates are forced -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException
有时候出现:
java: Some modules with cyclic dependencies [m1,m2] have 'additional command line parameters' overridden in project settings.
These compilation options were applied to all modules in the cycle.
原因就是你不能构建一个jar ,构建一半发现依赖的 jar 还不存在, 反之亦然,
可以看到, 其实就是 找不到m2, 这个是因为m2-xx.jar 不存在于 本地仓库; 我们可以先把m2 jar install到本地仓库, 但是呢,也是遇到同样问题,就是又会发现 m1-xx.jar 不存在于 本地仓库; —— 这就是 循环依赖导致的 死锁问题。 怎么 正面解决呢, maven 是不是有办法支持 循环依赖?
考虑spring 的情况。
如果 spring 中出现了 bean 的属性的循环依赖, 那么还可以通过 先把对应的 属性引用置为null, 后面再赋值。 但是maven不行。因为构建 m1 和m2 是两个不同的、完全独立的 过程, 不是一个程序中完成的, 没办法先把其中一个 先预先缓存起来。 jar 的引用也是静态的。 我 编译之前, 就必须要把 依赖的class 放置到 classpath 之下。 maven compile 的时候, 必须先把 依赖的jar 找到, 否则就无法继续, 即使能够继续, 也可能会导致 class 文件无法编译!
整个过程, 其实呢, 还是静态的! 不同于spring 循环依赖问题 是完全动态的、 内存共享的。
所以, 我认为这个maven 循环依赖问题 是无解的 ,
当然, 也有一些 旁门左道的方法。比如, 如果 构建时,本地仓库已经存在 依赖的jar, 或者伪造一个 依赖的jar, 或者使用之前的版本,改一下名字。
但是这个时候, 还是可能就是 依赖的 class 不是最新的。仍然可能编译不通过!
另外, 还可以通过
用build-helper-maven-plugin插件来规避。比如A依赖B,B依赖C,C依赖A的情况。这个插件提供了一种规避措施,即临时地将工程A、B、C合并成一个中间工程,编译出临时的模块D。然后A、B、C再分别依赖临时模块D进行编译
这种方法可以解决无法构建的问题,但是只是一个规避措施,工程的依赖关系依然是混乱的
总而言之,
class 的编译是静态的, 从而maven的编译也是静态的, 不过 maven是稍微多做了一些工作, 把依赖的jar 管理了起来。 循环依赖是不应该的, 应该极力的避免!
参考
https://blog.csdn.net/hck341204/article/details/84357644?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.essearch_pc_relevant