2011-08-20 30 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); 
相關問題