标签:
在产品打包发布时一个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文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <Context docBase="../../apps/lk-example.war"> <Loader className="com.tgb.lk.example.dist.ManifestClasspathWebappLoader"/> </Context>
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."); } } }
<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>
标签:
原文地址:http://blog.csdn.net/lk_blog/article/details/43970679