2017-10-10 94 views
0

我需要将单个应用程序连接到两个不同的应用程序。第一个应用程序在版本1中使用协议P,第二个在版本2中使用相同的协议。库不兼容,所以我必须在我的应用程序中使用这两个协议。问题是他们使用相同的软件包,例如com.company.P和体系结构(类名,包)是相同的。在一个应用程序中具有相同包名的相同库的两个版本

是否可以在同一个应用程序中使用它们?

+0

是:使用两个ClassLoaders –

+0

@MauricePerry如何?任何示例都会有用。 – Trismegistos

回答

1

这是一个很简单的例子:你需要为你的主应用程序一个罐子,在你定义一个接口服务:

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类,它必须始终通过一个接口。

+0

不幸的是我的情况是我没有接口。我在两个不同的罐子里有两个具有相同限定名称的类。 – Trismegistos

+0

@Trismegistos好的,写一个接口 –

+0

我不能因为那些库不是由我提供的。 – Trismegistos

相关问题