我目前正在开发一个由另一个程序作为插件接收的程序。父程序(接收插件的程序)拥有它自己的依赖项,在我的例子中,关注的是Guava。父版本的版本为21.0,而我创建的插件具有需要版本20.0的依赖项,并且似乎不与新版本配合,并且无论版本的pom是什么版本。插件,它似乎仍然使用21的父版本。
Tl; dr:当父程序使用更高版本时,Maven是否有任何方法可以使用较低版本(在我的情况下为20.0)的依赖项? (这是否可能,因为插件很可能被反射,因此将始终使用父依赖?插件是使用依赖项构建的。)
答案 0 :(得分:1)
Maven是一个构建工具,它不会在运行时控制您的依赖项(即应用程序已在运行时)。所以这不是maven问题,因此maven不是寻找解决方案的地方。
如果您无法控制托管应用程序,只能控制您的插件,那么您别无选择,而是使用插件和应用程序共有的相同版本的依赖项。
如果你拥有(控制)托管应用程序和插件,那么你需要正确处理插件。这很容易说,但更难做到。
您应该寻找已经为您解决的现有框架
一些例子是:OSGi,JPF,PF4J,还有更多......
另外,请查看以下SOF问题:Best way to build a Plugin system with Java
简而言之 -
这是在应用程序中支持插件的经典问题 在我看来,最好的解决方案是将插件与托管应用程序隔离开来。这可以使用不同的类加载器实现 - 当然 - 反射。
您的应用程序正在运行,其类以“常规”方式加载 - 这里没什么特别的。但是,为了在运行时将插件的代码与应用程序的依赖项隔离,您需要使用不同的类加载器(例如URLClassLoader
)加载插件类和依赖项。非常重要的是,这个类加载器没有将应用程序的类加载器作为父类,否则您仍将面临冲突的版本控制问题(正如您现在所做的那样)。
修改强>
当您只能控制插件时,处理这种情况的另一种选择 -
例如,您可以编写自己的类加载器并在插件的入口点使用它(以便使用此类加载器加载除入口点之外的所有插件类)。要做到这一点,你需要编写类加载器,它首先尝试从插件jar加载一个类,然后委托给它的父加载器。这是可行的(实际上并不太难),但是违反了类加载器合同(第一个委托给父母,只有在没有找到的情况下自己加载)。
我仍然认为确保使用相同的依赖项更好更强大,特别是当应用程序有更新的版本时......