在产品打包发布时一个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就可以被多个项目使用。
- tomcat中设置多项目共享jar;类包
随着服务器上的tomcat部署的项目越来越多,最近在部署一个新的项目的时候出现内存溢出的错误 Exception in thread "main" java.lang.OutOfM ...
- Maven打包时去掉项目版本号
Maven打包后,jar或war文件名里带有版本号信息,如projectname0.0.1-SNAPSHOT.jar等,怎么去掉呢? 解决办法: 打开项目pom.xml文件,在<build> ...
- eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错? java.lang.ClassNotFoundException: com.branchitech.app.startup.AppStartupContextListener java.lang.ClassN
eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错?java. ...
- Eclipse项目中引用第三方jar包时将项目打包成jar文件的两种方式
转载自:http://www.cnblogs.com/lanxuezaipiao/p/3291641.html 方案一:用Eclipse自带的Export功能 步骤1:准备主清单文件 “MANIFES ...
- [JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
(1)项目导入JAR包:1.在项目目录里建立一个libs目录,将外部jar包拷贝在里面.2.右键点击项目,Bulid Path->Configure Build Path3.在设置Libraie ...
- spring boot (2):spring boot 打包tomcat、tomcat 部署多个项目、服务器部署项目SSL 设置(阿里云)
一.spring boot 内置tomcat配置https: 关于自签名证书可以看下上一篇 spring boot1 更详细的可以看转载 https://www.jianshu.com/p/8d4ab ...
- maven打包时包含本地jar
项目中需要使用maven的打包工具,生成zip压缩包,使用的插件是assembly-plugin.因为一些特殊的原因,需要使用一些本地的jar进行依赖,加载外部jar后编码过程中没有任何问题,但是打包 ...
- 通过idea 打包 spring maven项目打包为可执行jar包
用assembly打包一直报错: shangyanshuodeMacBook-Pro:target shangyanshuo$ java -jar jobscrawler-1.0-SNAPSHOT-j ...
- maven打包时无法加载lib下的jar
© 版权声明:本文为博主原创文章,转载请注明出处 问题描述: 项目在本地部署没有问题,但是使用maven打包时报错: ***(引用jar中某个类的的路径) 不存在 ***(某个java类中的某行某列) ...
随机推荐
- DOM(七)使用DOM控制表格
表格的css控制就先不说了,首先分享下表格常用的DOM 表格添加操作的方法常用的为insertRow()和insertCell()方法. row是从零开始计算起的,例如: var oTr = docu ...
- Grunt-cli的执行过程以及Grunt加载原理
通过本篇你可以了解到: 1 grunt-cli的执行原理 2 nodeJS中模块的加载过程 Grunt-cli原理 grunt-cli其实也是Node模块,它可以帮助我们在控制台中直接运行grunt命 ...
- Andriod开发环境的发展演变
安卓早先只能使用JAVA开发应用程序,现在支持多种编程语言,方便了许多程序员,但主流的应该还是JAVA语言.早先安卓开发经常用到eclipse,但自从google 发布了Android studio后 ...
- usefull-url
http://www.johnlewis.com/ http://codepen.io/francoislesenne/pen/aIuko http://www.rand.org/site_info/ ...
- simple-LDAP-auth / ldap_auth.php
<?php /** * simple class for LDAP authentification * Copyright (C) 2013 Petr Palas This program i ...
- 曲线行驶s弯道技巧图解【转】
s弯道怎么走?在走S弯的时候,最主要的就是控制车的速度,在做每个动作的时候要保持一样的速度,不要一会快一会慢的,在开的时候,因为每个人的身高,体型不一样,每个人看的点位都是不一样的,每次在开的时候要找 ...
- 【UVA 1451】Average
题 题意 求长度为n的01串中1占总长(大于L)的比例最大的一个子串起点和终点. 分析 前缀和s[i]保存前i个数有几个1,[j+1,i] 这段区间1的比例就是(s[i]-s[j])/(i-j),于是 ...
- HYSBZ - 2152 聪聪和可可
Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...
- 数组实现栈的结构(java)
自定义数组实现栈的结构. package test; public class MyArrayStackClient { public static void main(String[] args) ...
- JAVA敏捷开发环境搭建
前面介绍了创业型软件公司的工作模式,这里详细介绍下如何实施,第一步是先要搭建环境,有了环境才能开展工作. 整个软件项目分为四个环境 开发本地环境.开发环境.测试环境.IDC环境.和传统C++开发不一样 ...