简体   繁体   English

第三方库在Tomcat中的最佳实践

[英]Third party libraries best practice in Tomcat

I am using Tomcat for hosting my Java Web and Web Service applications for a long time now. 我正在使用Tomcat来托管我的Java Web和Web服务应用程序很长一段时间。 Mostly for Spring and Grails applications at the moment. 主要用于SpringGrails应用程序。

Lately in one project a discussion came up, about how deal with dependencies/libraries in Tomcat production environments: 最近,在一个项目中,讨论了如何处理Tomcat生产环境中的依赖项/库:

In my projects I am deploying big WAR files holding all the required dependencies for the application in WEB-INF/lib folder. 在我的项目中,我正在部署大型WAR文件 ,其中包含WEB-INF / lib文件夹中应用程序的所有必需依赖项。 The only things I put in the tomcat/lib folder are the JAR files for JDBC connections managed by tomcat. 我在tomcat / lib文件夹中放置的唯一内容是由tomcat管理的JDBC连接的JAR文件。

The customer has a long history with WebSphere and thinks the container should hold most of the the required dependencies. 客户与WebSphere有着悠久的历史,并认为容器应该包含大部分所需的依赖项。 So they want to put JAR files for used frameworks or WebService API's (like Metro) in the tomcat/lib folder and have skinny WAR files . 因此,他们希望将已使用的框架或WebService API(如Metro)的JAR文件放在tomcat / lib文件夹中,并具有瘦的WAR文件

The problem with that solution in my opinion is that if you have an application that requires another version of a dependency that is already included in the tomcat/lib folder you can get errors and strange behavior. 在我看来,该解决方案的问题在于,如果您的应用程序需要已包含在tomcat / lib文件夹中的其他版本的依赖项,则可能会出现错误和奇怪的行为。

Is there some best practice or official document that talks about this issue? 是否有一些最佳实践或官方文件谈论这个问题? What is your opinion about this? 你对此有何看法?

Packaging dependent jars into the war file may yield a bigger war file, but it provides a lot of benefits. 将依赖包装的jar包装到war文件中可能会产生更大的war文件,但它提供了很多好处。 The big war file becomes a single, self-contained, complete unit of deployment. 大战争文件成为一个单独的,独立的,完整的部署单元。 You can take that war file and deploy it to a developer desktop, a customer acceptance environment, and a production environment, and have confidence that your own code in the war file is referencing the expected versions of all dependencies. 您可以获取该war文件并将其部署到开发人员桌面,客户接受环境和生产环境,并确信war文件中您自己的代码引用了所有依赖项的预期版本。

In my experience, the only time to place a jar into Tomcat's lib folder instead of the war file is when your code references some library by interface, and you won't know the underlying implementation until deployment time. 根据我的经验,将jar放入Tomcat的lib文件夹而不是war文件的唯一时间是当您的代码通过接口引用某个库时,在部署时间之前您将不知道底层实现。 For example, I had a project integrating with JMS, and I knew that I had to support multiple deployments of the messaging infrastructure. 例如,我有一个与JMS集成的项目,我知道我必须支持消息传递基础架构的多个部署。 Some environments needed to use ActiveMQ. 某些环境需要使用ActiveMQ。 Other environments needed to use Websphere MQ. 使用Websphere MQ所需的其他环境。 In that case, I packaged the JMS interface jar into the war file, and then at deployment time, I placed either the ActiveMQ or the Websphere MQ implementation jar into tomcat/lib. 在这种情况下,我将JMS接口jar打包到war文件中,然后在部署时,我将ActiveMQ或Websphere MQ实现jar放入tomcat / lib。

Of course, that meant that the war file was no longer really a complete unit of deployment. 当然,这意味着war文件不再是一个完整的部署单元。 Instead, deployment was a two-step process. 相反,部署过程分为两步。 It's a trade-off. 这是一种权衡。 I thought this was easier than managing multiple war file build variants, each bundling a different JMS provider jar. 我认为这比管理多个war文件构建变体更容易,每个变量捆绑一个不同的JMS提供者jar。

Is there some best practice or official document that talks about this issue? 是否有一些最佳实践或官方文件谈论这个问题?

I doubt you will find official documents (from the Tomcat developers/community) to support this theory, although it is very valid. 我怀疑你会发现官方文件(来自Tomcat开发者/社区)来支持这个理论,尽管它非常有效。 I had to prepare one in my previous job, so that the EAR file of the application could be deployed across multiple J2EE containers. 我必须在之前的工作中准备一个,以便可以跨多个J2EE容器部署应用程序的EAR文件。

There is one thing in favour though. 但有一点是有利的。 You can bring up the IBM Redbook titled "WebSphere Application Server V6.1: Classloader Problem Determination" (quite dated, given that WAS 7 is available) which demonstrates how to created shared libraries in WebSphere. 您可以打开标题为“WebSphere Application Server V6.1:类加载器问题确定”的IBM红皮书(鉴于WAS 7可用,已经过时了),它演示了如何在WebSphere中创建共享库。 On WebSphere, one can create multiple such libraries for applications that require differing versions. 在WebSphere上,可以为需要不同版本的应用程序创建多个此类库。 On Tomcat, you are the mercy of an administrator who may not know what a class loader is, given that all shared libraries is dumped into $CATALINA_HOME\\lib . 在Tomcat上,由于所有共享库都被转储到$ CATALINA_HOME \\ lib中 ,因此您可能不知道类加载器是什么的管理员的怜悯。

The Redbook also has this bit of advice (replace utility file with utility JAR and you have your answer): 红皮书也有这方面的建议(用实用程序JAR替换实用程序文件,你有答案):

Where you should not place utility files 你不应该放置实用程序文件的地方

In deciding where best to place your utility files, it is important to recognize that these files should not be included in the WebSphere Application Server's environment. 在决定放置实用程序文件的最佳位置时,必须认识到这些文件不应包含在WebSphere Application Server的环境中。

For example: app_server_root/lib, app_server_root/lib,/ext* , app_server_root/java (including any subdirectories), or the JVM classpath. 例如:app_server_root / lib,app_server_root / lib,/ ext *,app_server_root / java(包括所有子目录)或JVM类路径。

Adding utility files to those directories can cause problems with the WebSphere runtime environment and can cause unexpected results, including the overwriting of WebSphere classes that can be detrimental to the overall functionality of the server. 将实用程序文件添加到这些目录可能会导致WebSphere运行时环境出现问题,并可能导致意外结果,包括覆盖可能对服务器的整体功能有害的WebSphere类。

I would go for Optional Packages: http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/index.html 我会选择可选包: http//docs.oracle.com/javase/6/docs/technotes/guides/extensions/index.html

Steps: 脚步:

  1. Package your code, libraries in a jar/war. 将你的代码,库打包在jar / war中。

  2. In the MANIFEST.MF of the above declare the extension list jars 在上面的MANIFEST.MF中声明了扩展名列表jar

  3. Referred them in the target applications 在目标应用程序中引用它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM