2011-09-19 88 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版本。

相关问题