标签:
在产品打包发布时一个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