java - 如何让 child 在 Maven 中拥有与 parent 不同的依赖关系?

标签 java maven

我目前正在开发一个程序,该程序被另一个程序作为插件吸收。父程序(接受插件的程序)有它自己的依赖项,在我的例子中,关注的是 Guava。父版本是21.0,而我创建的插件有一个需要20.0版本的依赖,并且似乎不与较新的版本配合,并且无论插件的pom中放入什么版本,它仍然似乎使用的是 21 的父版本。

Tl;dr:当父程序使用较高版本时,Maven 有没有办法使用较低版本(在我的例子中为 20.0)的依赖项? (这是否可能,因为插件可能是通过反射接收的,因此将始终使用父依赖项?该插件是在包含依赖项的情况下构建的。)

最佳答案

Maven 是一个构建工具,它不会在运行时(即应用程序已经运行时)控制您的依赖项。所以这不是 Maven 问题,因此 Maven 不是寻找解决方案的地方。

如果您无法控制托管应用程序,而只能控制您的插件,那么您别无选择,只能使用插件和应用程序共有的相同版本的依赖项。

如果您同时拥有(控制)托管应用程序和插件,那么您需要正确处理插件。说起来容易,做起来难……
您应该寻找已经为您解决问题的现有框架。
一些例子是:OSGi , JPF , PF4J ,还有更多...
另外,请查看以下 SOF 问题:Best way to build a Plugin system with Java

简而言之-

这是应用程序中支持插件的一个经典问题。
在我看来,最好的解决方案是将插件与托管应用程序隔离。这可以通过使用不同的类加载器以及反射来实现。

您的应用程序正在运行,并且其类以“常规”方式加载 - 这里没什么特别的。但是,为了在运行时将插件的代码与应用程序的依赖项隔离,您需要使用不同的类加载器(例如 URLClassLoader)加载插件类和依赖项。非常重要的是,该类加载器不能将您的应用程序的类加载器作为父级,否则您仍然会面临版本控制冲突问题(就像现在一样)。

编辑:
当您只能控制插件时处理这种情况的另一种选择 -
例如,您可以编写自己的类加载器并在插件的入口点中使用它(以便使用此类加载器加载除入口点之外的所有插件类)。为此,您需要以首先尝试从插件 jar 加载类然后委托(delegate)给其父加载器的方式编写类加载器。这是可行的(实际上并不太难),但违反了类加载器契约(首先委托(delegate)给父级,只有在找不到时才自己加载)。
我仍然认为确保使用相同的依赖项会更好、更健壮,特别是当应用程序有较新版本时......

关于java - 如何让 child 在 Maven 中拥有与 parent 不同的依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44768246/

相关文章:

java - 在 finally block 中抛出异常

java - 每次击键 JTextField 时调用数据库中的搜索

java - 有没有办法以编程方式检索已部署 Artifact 的名称?

java - 如何覆盖 Eclipse 中的默认 JVM 参数?

java - 使 JFormattedTextField 的行为类似于 ATM 输入

java - 我可以用基本 GSON 代替基本对象输入/输出流吗?

java - Android:第一个 ListView 元素位于标题栏下方

Linux:maven 资源:复制资源插件。带空格字符的参数

java - 如何在maven spring boot应用程序中查看lombok生成的类

java - 传输 dt_socket 8787 已经在使用中