让Eclipse的TomcatPlugin支持Tomcat 8.x
使用tomcat插件启动项目的优势:
1.TomcatPlugin是一个免重启的开发插件,原始的Servers方式启动tomcat项目,修改xxx.ftl 或者 xxx.jsp 文件后需要重启tomcat后内容才能得到更新,而使用TomcatPlugin可以避免这种重复重启项目操作;
2.多项目同时启动时较方便。在开发环境中,可能要同时启动多个项目,而每一个平台都有一个独立的域名,使用Servers情况下,如果只使用一个8080端口启动多个项目,会有冲突。但是使用TomcatPlugin,只需要配置一下hosts文件就可以很方便的访问各个项目。
实现步骤:
1.下载eclipse tomcat 插件(略)
2.配置tomcat
tomcat插件下载完成后 Window-->Preperences 中找到tomcat配置项
3.配置server.xml
在conf/目录下找到server.xml文件,并在 Engine 标签中添加如下内容:
<Host name="www2.domain1.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
<Context path="" reloadable="true" docBase="项目目录1\src\main\webapp" workDir="项目目录1\work" >
<Loader className="org.apache.catalina.loader.DevLoader" reloadable="true" debug="1" useSystemClassLoaderAsParent="false" />
</Context>
</Host>
<Host name="www2.domain2.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
<Context path="" reloadable="true" docBase="项目目录2\src\main\webapp" workDir="项目目录2\work" >
<Loader className="org.apache.catalina.loader.MyDevLoader" reloadable="true" debug="1" useSystemClassLoaderAsParent="false" />
</Context>
</Host>
4.配置hosts文件
在windows/system32/drivers/etc 目录下找到hosts文件,添加如下内容:
# 127.0.0.1 localhost
# ::1 localhost
127.0.0.1 www2.domain1.com www2.domain2.com www2.domain3.com
5.生成jar包
1.新建一个项目(或者使用原有的项目),创建一个包 名称为:org.apache.catalina.loader, 再创建一个类,名称为 MyDevLoader,拷贝下面java代码部分
备注:你可以随意创建一个包名和类名,但需要与 <Loader className="org.apache.catalina.loader.MyDevLoader" reloadable="true" debug="1" useSystemClassLoaderAsParent="false" /> 中的className保持一至即可。
2、消除编译报错的地方。主要是tomcat 中的lib目录下相关的jar包没有引入进来。
3、重新打成JAR包,命名DevloaderTomcat8.jar。
4、将这个jar文件放入tomcat 中的lib目录下。
package org.apache.catalina.loader; import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer; import javax.servlet.ServletContext;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.loader.DevLoader.WebClassPathEntryHandler;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; /**
* @author caoxiaobo 备注:修改DevLoader源码后的,请生成jar包,然后放置tomcat中的lib目录下;
*/
public class MyDevLoader extends WebappLoader {
private static final String info = "org.apache.catalina.loader.MyDevLoader/1.0"; private String webClassPathFile = ".#webclasspath";
private String tomcatPluginFile = ".tomcatplugin"; WebappClassLoader loader = null; /**
* @see org.apache.catalina.Lifecycle#start()
* 如果您使用的是tomcat7,此处的方法名称为start(),如果是tomcat8,此处的方法名称为startInternal()
*/
public void startInternal() throws LifecycleException {
log("Starting MyDevLoader " + info);
// setLoaderClass(DevWebappClassLoader.class.getName()); // 如果是tomcat7,此处调用 start()方法,如果是tomcat8,此处调用startInternal()方法
// super.start(); // tomcat7
super.startInternal(); // tomcat8
loader = (WebappClassLoader) super.getClassLoader();
if (loader instanceof WebappClassLoader == false) {
logError("Unable to install WebappClassLoader !");
return;
} List<String> webClassPathEntries = readWebClassPathEntries();
StringBuffer classpath = new StringBuffer();
for (Iterator<String> it = webClassPathEntries.iterator(); it.hasNext();) {
String entry = (String) it.next();
File f = new File(entry);
if (f.exists()) {
if (f.isDirectory() && entry.endsWith("/") == false)
f = new File(entry + "/");
try {
URL url = f.toURI().toURL();
loader.addURL(url); // tomcat8
// loader.addRepository(url.toString()); // tomcat7
classpath.append(f.toString() + File.pathSeparatorChar);
log("added " + url.toString());
} catch (MalformedURLException e) {
logError(entry + " invalid (MalformedURL)");
}
} else {
logError(entry + " does not exist !");
}
}
/*
* try { devCl.loadClass("at.kase.webfaces.WebApplication");
* devCl.loadClass("at.kase.taglib.BaseTag");
* devCl.loadClass("at.kase.taglib.xhtml.XHTMLTag");
* devCl.loadClass("at.kase.common.reflect.ClassHelper");
* devCl.loadClass("javax.servlet.jsp.jstl.core.Config");
* log("ALL OKAY !"); } catch(Exception e) { logError(e.toString()); }
*/
String cp = (String) getServletContext().getAttribute(Globals.CLASS_PATH_ATTR);
StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparatorChar + "");
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
// only on windows
if (token.charAt(0) == '/' && token.charAt(2) == ':')
token = token.substring(1);
classpath.append(token + File.pathSeparatorChar);
}
// cp = classpath + cp;
getServletContext().setAttribute(Globals.CLASS_PATH_ATTR, classpath.toString());
log("JSPCompiler Classpath = " + classpath);
} private void log(String msg) {
System.out.println("[MyDevLoader] " + msg);
} private void logError(String msg) {
System.err.println("[MyDevLoader] Error: " + msg);
} private List<String> readWebClassPathEntries() {
List<String> rc = null; File prjDir = getProjectRootDir();
if (prjDir == null) {
return new ArrayList<String>();
}
log("projectdir=" + prjDir.getAbsolutePath()); // try loading tomcat plugin file
// DON"T LOAD TOMCAT PLUGIN FILE (DOESN't HAVE FULL PATHS ANYMORE)
rc = loadTomcatPluginFile(prjDir); if (rc == null) {
//rc = loadWebClassPathFile(prjDir);
} if (rc == null)
rc = new ArrayList<String>(); // should not happen !
return rc;
} private File getProjectRootDir() {
File rootDir = getWebappDir();
FileFilter filter = new FileFilter() {
public boolean accept(File file) {
return (file.getName().equalsIgnoreCase(webClassPathFile)
|| file.getName().equalsIgnoreCase(tomcatPluginFile));
}
};
while (rootDir != null) {
File[] files = rootDir.listFiles(filter);
if (files != null && files.length >= 1) {
return files[0].getParentFile();
}
rootDir = rootDir.getParentFile();
}
return null;
} private List<String> loadWebClassPathFile(File prjDir) {
File cpFile = new File(prjDir, webClassPathFile);
if (cpFile.exists()) {
FileReader reader = null;
try {
List<String> rc = new ArrayList<String>();
reader = new FileReader(cpFile);
LineNumberReader lr = new LineNumberReader(reader);
String line = null;
while ((line = lr.readLine()) != null) {
// convert '\' to '/'
line = line.replace('\\', '/');
rc.add(line);
}
return rc;
} catch (IOException ioEx) {
ioEx.printStackTrace();
return null;
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception ignored) {
}
}
} else {
return null;
}
} private List<String> loadTomcatPluginFile(File prjDir) {
File cpFile = new File(prjDir, tomcatPluginFile);
if (!cpFile.exists()) {
return null;
}
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = null;
try {
saxParser = saxParserFactory.newSAXParser();
// 仿照 Digester 类来实现xml解析
WebClassPathEntryHandler dh = new WebClassPathEntryHandler();
saxParser.parse(cpFile, dh);
String[] jars = dh.getBodyText().toString().split(";");
List<String> rc = new ArrayList<String>();
for (String path : jars) {
if (isNotBlank(path)) {
// 如果是编译后../classes 文件夹路径
if (!path.endsWith(".jar")) {
if (path.endsWith("/classes")) {
path = prjDir.getParentFile() + path;
}
}
rc.add(path);
}
}
return rc;
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} private ServletContext getServletContext() {
// return ((Context) getContainer()).getServletContext(); // tomcat7
return super.getContext().getServletContext(); // tomcat8
} private File getWebappDir() {
File webAppDir = new File(getServletContext().getRealPath("/"));
return webAppDir;
} private static boolean isNotBlank(String str) {
return null != str && !"".equals(str) && !"".equals(str.trim());
} /**
* 内部类,用来解析 .tomcatplugin 文件中的jar
*
* @author Administrator
*
*/
private class WebClassPathEntryHandler extends DefaultHandler { private String localTag;
private StringBuilder bodyText = new StringBuilder(); @Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equals("webClassPathEntry")) {
localTag = "webClassPathEntry";
}
} @Override
public void characters(char[] buffer, int start, int length) throws SAXException {
if ("webClassPathEntry".equals(localTag)) {
bodyText.append(buffer, start, length);
bodyText.append(";");
} } public StringBuilder getBodyText() {
return bodyText;
} }
}
特别提醒:这个类是加载你当前项目根目录下 .#webclasspath 或.tomcatplugin 文件的内容中的jar 文件的,有些项目没有这个文件,则需要从其它项目中拷贝一份出来放入你的项目根目录下。
上面那个冗余代码比较多,下面这个示例为了更方便理解Tomcat 类的加载过程,我把它优化了一下:
package org.apache.catalina.loader; import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.net.URL;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.apache.catalina.LifecycleException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; public class DevLoader extends WebappLoader { /**
* 通过 URLClassLoader 加载类/jar 文件
*/
private static WebappClassLoader loader = null; private String webClassPathFileName = ".#webclasspath";
private String tomcatPluginFileName = ".tomcatplugin"; @Override
protected void startInternal() throws LifecycleException {
super.startInternal();
// 仿照Digester获取ClassLoader的写法(Digester是用来解析xml文件的类)
loader = (WebappClassLoader) super.getClassLoader(); // 获取conf/context.xml中Context标签配置的 docBase路径
String contextPath = this.getContext().getServletContext().getRealPath("/");
System.out.println(contextPath);
File rootDir = new File(contextPath);
// 获取项目根路径
FileFilter filter = new FileFilter() {
public boolean accept(File file) {
return (file.getName().equalsIgnoreCase(webClassPathFileName)
|| file.getName().equalsIgnoreCase(tomcatPluginFileName));
}
};
// 递归向上找父文件夹
while (rootDir != null) {
File[] files = rootDir.listFiles(filter);
if ((files != null) && (files.length >= 1)) {
rootDir = files[0].getParentFile();
break;
} else {
rootDir = rootDir.getParentFile();
}
}
File webClassPathFile = new File(rootDir, webClassPathFileName);
File tomcatPluginFile = new File(rootDir, tomcatPluginFileName);
/**
* 先加载 .#webclasspath 文件
*/
if (webClassPathFile.exists()) {
loadJars$WebClasspath(webClassPathFile);
return;
}
if (tomcatPluginFile.exists()) {
loadJars$TomcatPlugin(tomcatPluginFile, rootDir);
}
} /**
* 加载jar文件 这里是解析.#webclasspath文件并加载jar文件
*/
private void loadJars$WebClasspath(File webClassPathFile) {
FileReader reader = null;
LineNumberReader lr = null;
try {
reader = new FileReader(webClassPathFile);
lr = new LineNumberReader(reader);
String path = null;
while ((path = lr.readLine()) != null) {
if (isNotBlank(path)) {
path = path.replace('\\', '/');
File file = new File(path);
URL url = file.toURI().toURL();
loader.addURL(url);
System.out.println("[DevLoader]" + path);
}
}
} catch (IOException ioEx) {
ioEx.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} finally {
try {
if (reader != null)
reader.close();
if (lr != null)
lr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 加载jar文件 这里是解析.tomcatplugin文件并加载jar文件
*/
private void loadJars$TomcatPlugin(File tomcatPluginFile, File rootDir) { SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = null;
try {
saxParser = saxParserFactory.newSAXParser();
// 仿照 Digester 类来实现xml解析
WebClassPathEntryHandler dh = new WebClassPathEntryHandler();
saxParser.parse(tomcatPluginFile, dh);
String[] jars = dh.getBodyText().toString().split(";");
for (String path : jars) {
if (isNotBlank(path)) {
// 如果是编译后../classes 文件夹路径
if (!path.endsWith(".jar")) {
if (path.endsWith("/classes")) {
path = rootDir.getParentFile() + path;
}
}
File f = new File(path.trim());
URL url = f.toURI().toURL();
loader.addURL(url);
System.out.println("[DevLoader]" + path);
}
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private static boolean isNotBlank(String str) {
return null != str && !"".equals(str) && !"".equals(str.trim());
} /**
* 内部类,用来解析 .tomcatplugin 文件中的jar
*/
class WebClassPathEntryHandler extends DefaultHandler { private String localTag;
private StringBuilder bodyText = new StringBuilder(); @Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equals("webClassPathEntry")) {
localTag = "webClassPathEntry";
}
} @Override
public void characters(char[] buffer, int start, int length) throws SAXException {
if ("webClassPathEntry".equals(localTag)) {
bodyText.append(buffer, start, length);
bodyText.append(";");
} } public StringBuilder getBodyText() {
return bodyText;
} } }
右键项目--> Properties --> Tomcat
至此我们已经配置完结了!
点击如下图标开始启动项目
出现如下信息表示配置成功.
最新文章
- win7升win10,初体验
- CAD2008 启动慢 卡住
- linux查看一条命令的执行结果是1还是0
- C#操作内存读写方法的主要实现代码
- MVC4 导出word
- 在VC中显示和处理图片的方法
- javascript面向对象程序设计系列(一)---创建对象
- Asp.Net WebApi Action命名中已‘Get’开头问题
- 计划任务可以过UAC?直接添加到计划任务(未经测试)
- 初识Java,猜字游戏
- UML类图10分钟快速入门 - From 圣杰
- Aseprite入门教程
- 解决Navicat 出错:1130-host . is not allowed to connect to this MySql server,MySQL
- @Component注解的解析
- 1、jQuery 为什么要学习jQuery?
- VMware虚拟机中CentOS 7的硬盘空间扩容
- LINQ学习之旅(五)
- Java知多少(7)类与对象
- v-show v-if 的使用
- DOM-设置样式心得