我需要将单个应用程序连接到两个不同的应用程序。第一个应用程序在版本1中使用协议P第二个在版本2中使用相同的协议。库是不兼容的,所以我必须在我的应用程序中使用这两个。问题是他们使用相同的包装,例如com.company.P和架构(类名,包)是相同的。
是否可以在同一个应用中同时使用它们?
答案 0 :(得分:1)
这是一个非常简单的示例:您的主应用程序需要一个jar,您可以在其中定义一个接口Service:
package multiverse;
public interface Service {
public String getDescription();
}
Main类从两个不同目录中的jar创建服务实例:
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());
}
}
}
现在我在两个不同的jar中有两个服务实现,在上面程序使用的每个目录中都有一个:
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";
}
}
请注意,在编译时,它们必须能够访问Service接口。此接口可以与主程序位于同一个jar中,也可以位于单独的jar中。主程序无法直接访问用于每个实现的jar类:它必须始终通过接口。