我需要将单个应用程序连接到两个不同的应用程序。第一个应用程序在版本1中使用协议P,第二个在版本2中使用相同的协议。库不兼容,所以我必须在我的应用程序中使用这两个协议。问题是他们使用相同的软件包,例如com.company.P和体系结构(类名,包)是相同的。在一个应用程序中具有相同包名的相同库的两个版本
是否可以在同一个应用程序中使用它们?
我需要将单个应用程序连接到两个不同的应用程序。第一个应用程序在版本1中使用协议P,第二个在版本2中使用相同的协议。库不兼容,所以我必须在我的应用程序中使用这两个协议。问题是他们使用相同的软件包,例如com.company.P和体系结构(类名,包)是相同的。在一个应用程序中具有相同包名的相同库的两个版本
是否可以在同一个应用程序中使用它们?
这是一个很简单的例子:你需要为你的主应用程序一个罐子,在你定义一个接口服务:
package multiverse;
public interface Service {
public String getDescription();
}
和一个主类创建在两个广口瓶服务的一个实例不同的目录:
package multiverse;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
private static final Logger LOG = Logger.getLogger(Main.class.getName());
private static final File DIR1
= new File("../multiverse-v1/dist");
private static final File DIR2
= new File("../multiverse-v2/dist");
public static void main(String[] args) {
Service service1 = loadService(DIR1);
Service service2 = loadService(DIR2);
System.out.println(service1.getDescription());
System.out.println(service2.getDescription());
}
private static Service loadService(File dir) {
try {
File[] jars = dir.listFiles((File file) -> file.isFile()
&& file.getName().toLowerCase().endsWith(".jar"));
URL[] urls = new URL[jars.length];
for (int i = 0; i < jars.length; ++i) {
urls[i] = jars[i].toURI().toURL();
}
ClassLoader cl = new URLClassLoader(urls);
Class<? extends Service> clazz
= (Class<? extends Service>) cl.loadClass(
"multiverse.ServiceImpl");
return clazz.newInstance();
} catch (MalformedURLException | ClassNotFoundException
| InstantiationException | IllegalAccessException ex) {
LOG.log(Level.SEVERE, null, ex);
throw new RuntimeException(ex.getMessage());
}
}
}
现在我有服务的两个实施方式中,在两个不同的罐,一个在每个上述程序所使用的目录:
package multiverse;
public class ServiceImpl implements Service {
@Override
public String getDescription() {
return "Service V1";
}
}
和
package multiverse;
public class ServiceImpl implements Service {
@Override
public String getDescription() {
return "Service V2";
}
}
注意,他们必须进入服务界面,当他们编译。该接口可以与主程序位于同一个罐子中,也可以在单独的罐子中。主程序不能直接访问每个实现所用的jar类,它必须始终通过一个接口。
不幸的是我的情况是我没有接口。我在两个不同的罐子里有两个具有相同限定名称的类。 – Trismegistos
@Trismegistos好的,写一个接口 –
我不能因为那些库不是由我提供的。 – Trismegistos
是:使用两个ClassLoaders –
@MauricePerry如何?任何示例都会有用。 – Trismegistos