2011-08-20 64 views
0

有没有一种方法可以在运行时决定从哪个jar(部署在jboss上)中使用哪个类?决定运行时哪个库需要在JBoss上使用

下面是一个例子:

VERSION1.JAR

package com.something; 

public class MyObject { 

    public void saySomething() { 
     System.out.println("Output from version 1"); 
    } 
} 

VERSION2.JAR

package com.something; 

public class MyObject { 

    public void saySomething() { 
     System.out.println("Output from version 2"); 
    } 
} 

所以在这两个罐子都是同一个包内的同一类,但他们做不同的事情。现在我想加载MyObject,但告诉他我想用哪个jar:

package com.main 

public class Main{ 

    public static void main(String[] args) { 

     MyObject v1 = new MyObject(); 
     v1.saySomething(); 

     MyObject v2 = new MyObject(); 
     v2.saySomething(); 

    } 
} 

这可能吗?我正在使用Jboss作为应用程序服务器,并且正在做一个ejb项目。所以这个例子只是为了解释我的意思。我想也许在上下文的帮助下?

+0

您是否需要区分共享公共契约(接口)的两个不同实现(类)?或者,您是否确实有两个不同的JAR(可能是外部库),它们在同一个包中定义了同一个类的两个不同版本,并且需要根据不同的情况调用一个或另一个类? –

回答

2

不,你不能控制这个。哪一个被加载是由JBoss classloader的内部决定的,它并没有暴露给你的程序。

你应该避免这样的情况。如果你需要控制哪个类被加载,你需要把它们放在不同的包中。

+0

这并不完全正确 - 您可以通过在耳朵中打包并通过jboss-classloading.xml使用类加载参数来避开它。然而,作为一个经验法则,你是绝对正确的,这是一个糟糕的设计。 –

0

在Java中,你可以动态从jar文件加载类,但部署意味着抛弃所有决定你的应用服务器。在jboss的情况下,您可以定义一个策略,指出哪些类加载器将具有优先级。

如果您试图实施某种插件系统 - 那么不要部署罐子。这并不意味着您无法将您的罐子与您的应用程序打包在一起。对于WAR,不要将它们放在/ WEB-INF/lib中。你可以把它们放在例如。/WEB-INF/plugins并使用类似这样的方式加载它们:

ClassLoader parent = Thread.currentThread().getContextClassLoader(); 
URL url = parent.getResource("/WEB-INF/plugins/plugin-x.jar"); 
ClassLoader loader = URLClassLoader.newInstance(
    new URL[] { url }, 
    parent 
); 
Class<?> clazz = Class.forName("com.something.MyObject", true, loader); 
Object myObject = clazz.getConstructor().newInstance(); 
Method saySomething = class.getMethod("saySomething"); 
saySomething.invoke(myObject); 
相关问题