2011-09-19 73 views
0

罐子LIB的,我有幾個將由我的web應用中使用第三方JAR文件。這些JAR文件實際上有不同的版本。加載不同的版本,從servlet的

E.g.

版本1.0的JAR

  • /opt/lib/third-party-jars/1.0/3rdparty1.jar
  • /opt/lib/third-party-jars/1.0/3rdparty2.jar

2.0版的JAR

  • /opt/lib/third-party-jars/2.0/3rdparty1.jar
  • /opt/lib/third-party-jars/2.0/3rdparty2.jar

是否有可能加載不同的版本庫的servlet得到動態加載之前?任何框架都可以在不更改現有代碼的情況下做到這一點?

public class Servlet1 extends HttpServlet { 

    protected void doPost(....) { 
     MyBusinessLogic businessLogic = new MyBusinessLogic(); 
     businessLogic.run() // My business logic spawns here which will start involving third-party classes 
    } 
} 

或者是有可能在我的業務邏輯代碼之前動態加載版本1.0或2.0庫被調用?我可以使用的一種方法是使用自定義類加載器和"setContextClassLoader",但這需要使用反射來重構我所有的業務邏輯。這將是一個巨大的努力。我試圖不改變我現有的業務邏輯代碼。

回答

0

一般來說,你想要的是不平凡困難的事:servlet容器已經包含了複雜的類加載器的層次結構,並試圖混合又一個替代通常會導致不必要的痛苦,應該避免。然而,看看JCL:它可以做你想做的。

0

據我知道你無法控制它的類加載器是用來加載在web.xml中定義的servlet。

在JavaEE的6,你也許能夠使用ServletContext.addServlet()添加一個servlet,它類,你從你自己的類加載器獲取。所以,你可以有一個虛擬的「引導」的servlet(或監聽器或過濾器 - 只要它在啓動時加載)認爲:

  • 使用JAR文件的相應版本創建您的自定義類加載器
  • 創建真正從您的自定義類加載servlet類(這個servlet類不應該在web.xml中指定)
  • 寄存器()這類使用ServletContext.addServlet

我要去純粹關閉該規範在這裏,我的天堂」噸測試它,並做不知道它是否會實際工作。

1

具有相同的罐子的多個版本是不支持Java的東西。有兩個選項:

  • 延長Tomcat的類加載器提供自定義加載邏輯
  • 使用OSGi的。Virgo是一個基於OSGi的servlet容器

但是,這些都會使事情不必要地複雜化。我建議介紹一些由多個提供商實施的SPI。所以:

public interface BusinessLogic { .. } 

然後兩瓶,有兩種實現方式 - com.foo.FooBLcom.bar.BarBL。然後你配置你需要哪一個,並用Class.forName(..).newInstance(..)

0

實例化如同其他幾個人已經提到的那樣,做你所提出的並不是微不足道的。這可能有助於您進一步解釋爲什麼需要加載不同版本的JAR,以及觸發此決定的條件是什麼。瞭解這可能會幫助其他人針對您的問題提出不同的解決方案。

例如,是否可以爲在WAR/EAR中捆綁相應的第三方JAR的每個版本創建多個WAR或EAR程序集?將第三方JAR捆綁在獨立的WAR/EAR中可確保您正在查找的類加載器可見性。這不應該需要太多/任何新的編碼,只需要重新組裝。或者,如果捆綁第三方JAR不是一種選擇,並且您正在使用諸如WAS之類的應用服務器,則可以利用共享庫,以便其中一個WAR引用1.0版本的JAR,另一個引用2.0版本。

相關問題