[英]Integrating a third-party API into a Java application with clashing dependencies
我正在开发一个现有的应用程序,它具有相当多的外部JAR依赖项。 我需要增强它以与具有API的第三方应用程序集成。 可悲的是,API并没有得到很好的控制,并且还附带了大量自己的依赖项,其中一些依赖于我的。
我相信我应该使用类加载器解决这个问题,但我很难看到如何正确地构造它们。
为了简单起见,假设我们的myapp.jar具有hibernate3.jar依赖性,而vendor-api.jar具有hibernate2.jar依赖性(并假设它们不兼容)。
我的新代码将驻留在myapp.jar库中(尽管如果这会有帮助,它可能在一个单独的jar中)。 由于供应商API的工作方式,我的新代码需要从vendor-api.jar库扩展一个类。
如何以这样的方式构造类加载器:vendor-api.jar中的任何东西只访问它自己的依赖项,而我这边的任何东西只访问myapp.jar和依赖项?
谢谢,乔恩
我自己没有尝试过这个,但是从内存中来看,每个冲突类都需要在一个兄弟级的类加载器中,并且两者之间的任何通信都需要经历一个共同的祖先。 但是,祖先不能(AFAIK)“直接”引用其子类中的类,并且必须通过反射API访问它们。
沿着这些方向的东西应该起作用(干编码)YMMV。 评论和错误发现欢迎。
class Orchestrator {
URL[] otherAppClasspath = new URL[] { new URL("file:///vendor-api.jar"),
new URL("file:///hibernate2.jar"),
new URL("file:///code-extending-vendor-api.jar" };
URLClassLoader otherAppLoader = new URLClassLoader(otherAppClasspath);
URL[] yourAppClasspath = new URL[] { new URL("file:///myapp.jar"),
new URL("file:///hibernate3.jar") };
URLClassLoader yourAppLoader = new URLClassLoader(yourAppClasspath);
public void start() {
Method yourAppEntryPoint = yourAppLoader.findClass("com/company/Main").getMethod("start", new Class[] { Orchestrator.class } );
yourAppEntryPoint.invoke(null, new Object[] { this });
}
public static void main(String[] args) {
new Orchestrator().start();
}
// define some abstracted API here that can be called from your app
// and calls down into classes in the other app
public String getSomeResultFromOtherApp(int someArgument) {
Method otherAppAPI = otherAppLoader.findClass("com/company/ExtendingAPIClass").getMethod("getSomeResult", new Class[] { Integer.class });
return (String)otherAppAPI.invoke(null, new Object[] { someArgument });
}
}
@ fd的答案提供了一个应该工作的技术机制 - 给予或采取一些拼写错误,异常处理等。
但是,我认为最好不要尝试这样做...除非你对第三方API的依赖仅限于极少数类的极少数方法。 您依赖的每个类都必须动态加载,并且必须以反射方式查找和调用每个方法。 太多,你的代码库将受到影响。
如果我是你,我会尝试以其他方式解决依赖问题:
从你说的话来看,这可能很难。
使用OSGi可以长期帮助您。 这是我正在尝试的实现 - http://felix.apache.org
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.