Tomcat打包时多项目共享jar和精确指定jar版本

it2024-12-28  16

在产品打包发布时一个tomcat中如果存在多个war,部署的一般方式是部署到%TOMCAT_HOME%/webapps目录下,目录结构遵循J2EE规范,把引用的jar放到%TOMCAT_HOME%/webapps/xxxxx.war/WEB-INF/lib下面即可。但是多个项目完全可能引用了相同的jar,如何使多项目共享这个jar呢?项目发布时经常由于jar冲突造成很多问题,如果使打出的包精确指定所需要的jar版本呢?如何不放到%TOMCAT_HOME%/webapps目录,而把war放到特定的位置如何加载呢呢?本文将解决以上几个问题。     1.下载tomcat的zip包并解压,在%TOMCAT_HOME%/conf/Catalina/localhost文件夹下创建一个lkexample.xml文件,内容如下: [html] view plaincopy <?xml version="1.0" encoding="UTF-8"?>   <Context docBase="../../apps/lk-example.war">       <Loader className="com.tgb.lk.example.dist.ManifestClasspathWebappLoader"/>   </Context>   2.将待部署的lk-example.war放到../../apps/lk-example.war下,并将lk-example.war/WEB-INF/lib下的所有jar剪接到../lib下,文件结构目录见下图 3.编写com.tgb.lk.example.dist.ManifestClasspathWebappLoader.java类并打包为jar [java] view plaincopy package com.tgb.lk.example.dist;       import org.apache.catalina.Container;   import org.apache.catalina.LifecycleException;   import org.apache.catalina.core.StandardContext;   import org.apache.catalina.loader.WebappLoader;       import java.io.*;   import java.util.jar.Attributes;   import java.util.jar.Manifest;       /**  * 从War中的MANIFEST.MF获得类路径并进行额外加载  */   public class ManifestClasspathWebappLoader extends WebappLoader {           public ManifestClasspathWebappLoader() {           super();       }               public ManifestClasspathWebappLoader(ClassLoader parent) {           super(parent);       }           @Override       protected void startInternal() throws LifecycleException {           final Container container = getContainer();           if (container instanceof StandardContext) {                   File baseFile = new File(((StandardContext) container).getRealPath(""));                   if (baseFile.exists() && baseFile.canRead()) {  //是否可读                       if (baseFile.isDirectory()) {     //目录                           final File manifestFile = new File(baseFile, "META-INF/MANIFEST.MF");                           if (manifestFile.exists() && manifestFile.canRead() && manifestFile.isFile()) {     //MANIFEST.MF文件可读                               System.out.println("[DIST] found MANIFEST.MF" + manifestFile);                               try {                               FileInputStream fileInputStream = new FileInputStream(manifestFile);                               setClasspaths(baseFile, fileInputStream);                               } catch (FileNotFoundException e) {                               e.printStackTrace();                           }                           }                       } else if (baseFile.isFile()) { //文件(war)                       }                   }           }               super.startInternal();       }           /**       * 设置MANIFEST.MF流中的类路径       *       * @param baseFile       * @param inputStream       */       private void setClasspaths(File baseFile, InputStream inputStream) {           String classpaths[] = null;           try {               final Manifest manifest = new Manifest(inputStream);               final Attributes attributes = manifest.getMainAttributes();               String classpathValue = attributes.getValue("Class-Path");               if (classpathValue != null) {          //可以不为null说明发现Class-Path                   classpathValue = classpathValue.replaceAll("[\r\n]+$", ""); //移除换行                   classpaths = classpathValue.split("\\s+");     //拆分类路径字符串               }           } catch (IOException e) {               e.printStackTrace();           }               if (classpaths != null) {   //如果发现类路径则设置类路径               for (String classpath : classpaths) {                   addRepository(new File(baseFile.getParent(), classpath).toURI().toString());    //转换相对路径为实际路径并转换为URI               }               System.out.println("[DIST] " + baseFile.getName() + " append " + classpaths.length + " classpaths.");               }           }       }   4.将打出的jar包放到%TOMCAT_HONE%\lib下。 5.修改你的war工程的pom.xml,加入如下配置并运行mvn package命令: [html] view plaincopy <build>           <plugins>               <plugin>                   <artifactId>maven-war-plugin</artifactId>                   <configuration>                       <archive>                           <manifest>                               <addClasspath>true</addClasspath>                               <classpathPrefix>../lib/</classpathPrefix>                               <useUniqueVersions>false</useUniqueVersions>                           </manifest>                       </archive>                   </configuration>               </plugin>           </plugins>       </build>   观察打出的war包lk-example.war/META-INF/MANIFEST.MF文件,这个文件中打出了war精确引用的jar版本。如下图: 6.将打出的war包解压到apps目录文件下。 7.运行tomcat即可访问http://localhost:8080/lkexample。       总结,修改%TOMCAT_HOME%/conf/Catalina/localhost/lkexample.xml指定了tomcat加载的应用以及加载应用时使用的webapp类加载器,通过自己重写的类加载器ManifestClasspathWebappLoader加载了xxxx.war/META-INF/MANIFEST.MF中精确的jar路径所引用的jar.如果发布的项目有多个war可以同时都指定引用lib下精确版本的jar文件,这样相同的jar就可以被多个项目使用。

转载于:https://www.cnblogs.com/jym-sunshine/p/4859248.html

相关资源:数据结构—成绩单生成器
最新回复(0)