1 背景知识
1.1 Jar&war包
Jar/war/ear都是打包方式,其打包方式基本都差不多,都是用jdk中的jar命令打包的(jar命令是基于unix的tar命令实现的),只不过内部包含的文件和目录格式有所不同,目标文件的扩展名也不一样。
war包是一个web应用(web模块),打成包后可以部署到web容器中。对Tomcat来说,将war文件包放置它的\webapps\目录下,启动Tomcat,这个包可以自动进行解压,形成web app的目录,相当于发布了。
jar包:通常是开发时要引用通用类(库),打成包便于存放管理。jar一般只是包括一些class文件,如果jar包在声明了Main_class之后是可以用java命令运行的
ear包:企业级应用,通常是EJB打成ear包。
WAR是Sun提出的一种Web应用程序格式,与JAR类似,也是许多文件的一个压缩包。这个包中的文件按一定目录结构来组织:通常其根目录下包含有Html和Jsp文件或者包含这两种文件的目录,另外还会有一个WEB-INF目录,这个目录很重要。通常在WEB-INF目录下有一个web.xml文件和一个classes目录,web.xml是这个应用的配置文件,而classes目录下则包含编译好的Servlet类和Jsp或Servlet所依赖的其它类(如JavaBean)。通常这些所依赖的类也可以打包成JAR放到WEB-INF下的lib目录下,当然也可以放到系统的CLASSPATH中,但那样移植和管理起来不方便.
$ jar cvf jar-file.jar dir […] 将一个或多个目录打包成一个jar包
2 JDK&JRE
2.1 JDK的安装
虽然可以通过apt-get或者二进制文件的形式进行安装,但是建议采用压缩包解压后设置环境变量的形式进行安装,因为这样更便于管理和升级。
2.1.1 Linux系统的安装
- 下载jdk软件包并 (官方JDK下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html ),ubuntu 64位系统建议安装jdk-7u25-linux-x64.tar.gz
- 将安装包解压缩到想要安装的目录 tar zxf jdk-7u25-linux-x64.tar.gz
- 在~/.bashrc 或~/.bash_profile文件中设置JAVA_HOME, CLASSPATH, PATH等环境变量:
|
export JAVA_HOME="/home/zxin10/jdk6_x64/jdk1.6.0_38" export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=".:${JAVA_HOME}/lib/jre/lib/rt.jar:${JAVA_HOME}/lib/tools.jar" export PATH=${JAVA_HOME}/bin:$PATH |
- 查看变量:
echo $VAENAME
2.1.2 Winows系统配置环境变量
- 添加JAVA_HOME环境变量,变量值: C:\Program Files\Java\jdk1.7.0_03
- 添加CLASSPATH环境变量,变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
- 在PATH环境变量中追加: ;%JAVA_HOME%\bin;
2.2 JVM启动参数
2.2.1 运行jar包中的主类
如果jar中的MANIFEST.MF文件里面添加了 Main-Class: test.someClassName, 可以在控制台里输入java -jar jarName.jar即可以运行这个jar中的main类。
如果MANIFEST文件中没有指定Main-Class类,则还需要添加主类的全称路径: java -jar jarName.jar package.MainClass
jar包它提供了一个Manifest.mf文件,用来描述这个jar包的属性等信息。比如Main-class,比如Class-Path,对!就是这个Class-Path能够解决以上所有问题,让你不再烦恼jar包的classpath。你只要在Manifest.mf中指定你所依赖的jar包名称,然后将这些jar包置于应用程序jar包的同一层目录或者子目录,然后就轻轻松松的可以运行程序啦。
一个可执行的 JAR 必须通过 menifest 文件的头引用它所需要的所有其他从属 JAR。如果使用了 -jar 选项,那么环境变量 CLASSPATH 和在命令行中指定的所有类路径都被 JVM 所忽略。
2.2.2 参考文档
JVM启动参数大全(主要转载了http://blog.csdn.net/sfdev/article/details/2062042 )
http://www.blogjava.net/midstr/archive/2008/09/21/230265.html
JVM系列三:JVM参数设置、分析
http://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html
Java命令行运行参数说明大全(偷来的)
http://xinklabi.iteye.com/blog/837435
JVM6.0 扩展启动参数选项大全
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html (官方版)
http://kenwublog.com/docs/java6-jvm-options-chinese-edition.htm (中文版)
2.3 JVM的远程调试
Sun Microsystem 的 Java Platform Debugger Architecture (JPDA) 技术是一个多层架构,能够在各种环境中轻松调试 Java 应用程序。JPDA 由两个接口(分别是 JVM Tool Interface 和 JDI)、一个协议(Java Debug Wire Protocol)和两个用于合并它们的软件组件(后端和前端)组成。JPDA 不仅能够用于桌面系统,而且能够在嵌入式系统上很好地工作。

图 41 Java 平台调试器架构(URL: http://www.ibm.com/developerworks/cn/opensource/os-eclipse-javadebug/)
2.3.1 常用缩写
常用的缩写:
- VM — 虚拟机(Virtual Machine)
- JDI — Java 调试接口(Java Debug Interface)
- JDT — Java 开发工具(Java Development Tools)
- JDWP — Java 调试网络协议(Java Debug Wire Protocol)
- JPDA — Java 平台调试器架构(Java Platform Debugger Architecture)
- JVM — Java 虚拟机(Java Virtual Machine)
- JVMDI — JVM 调试接口(JVM Debug Interface)
- JVMTI — JVM 工具接口(JVM Tool Interface)
2.3.2 虚拟机与调试相关的启动参数
而JVM本身就支持远程调试,只需要在各模块的JVM启动时加载以下参数:
- -Xdebug, 启用调试特性
- -Xrunjdwp, 启用JDWP实现,包含若干子选项:
² transport=dt_socket, JPDA front-end和back-end之间的传输方法。dt_socket表示使用套接字传输。
² address=8000, JVM在8000端口上监听请求,这个设定为一个不冲突的端口即可。
² server=y, y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是调试器。
² suspend=y, y表示启动的JVM会暂停等待,直到调试器连接上才继续执行。suspend=n,则JVM不会暂停等待。
被调试服务器的Java App启动范例: java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="8000" -jar test.jar
调试客户机的启动: java -Xdebug -Xrunjdwp:transport=dt_socket,address=127.0.0.1:8000,通常这个是在SDK中自动启动,无需手动输入。
3 Tomcat & Apache httpd的区别
- Tomcat是一个完全采用Java实现的web容器,提供Servlet和JSP API和运行环境,主要提供动态web内容,但它内置了一个与httpd功能类似的web服务器;Httpd是一个采用C语言实现的静态web服务器,如果要支持动态web需要与其他CGI程序结合。
- Tomcat默认端口是8080,httpd默认端口是80。
4 Tomcat的安装与部署
How to Install Apache Tomcat 7(on Windows, Macs, Ubuntu) and Get Start with Java Servlet Programming
http://www.ntu.edu.sg/home/ehchua/programming/howto/Tomcat_HowTo.html
从Tomcat 7.0.27 版本开始, 支持WebSocket协议(RFC6455)。
4.1 源码编译
更多信息请参考源码目录中的BUILDING.txt文件。
http://tomcat.apache.org/tomcat-7.0-doc/setup.html
4.2 Apt-get安装Tomcat7
tomcat运行时将以tomcat7组中的tomcat7用户运行。
4.2.1 安装命令
Sudo apt-get install tomcat7
4.2.2 目录结构
- /usr/share/tomcat7: 二进制文件安装目录,即CATALINA_HOME。
|
/ $ ls -l /usr/share/tomcat7 drwxr-xr-x 2 root root 4096 Aug 27 17:16 bin -rw-r--r-- 1 root root 39 Jul 13 2012 defaults.md5sum -rw-r--r-- 1 root root 1960 Jul 13 2012 defaults.template |
- /etc/init.d/tomcat7: 启动脚本, 里面设置了JAVA_HOME以及java虚拟机的启动参数等信息, 该脚本最终调用了 /usr/share/tomcat7/bin/catalina.sh脚本。
² catalina.sh脚本用于启动和关闭tomcat服务器,是最关键的脚本。另外的脚本startup.sh和shutdown.sh都是使用不同的参数调用了该脚本。
² Tomcat的入口位于org.apache.catalina.startup.Bootstrap类中的main方法,并且传过来的最后一个命令行参数是start,该类位于/usr/share/tomcat7/bootstrap.jar当中。
- /etc/default/tomcat7: 默认属性设置文件,通常为空目录。
- /var/lib/tomcat7: 配置文件 & web app 部署目录,即CATALINA_BASE。
|
/var/lib/tomcat7$ ls -l drwxr-xr-x 3 tomcat7 tomcat7 4096 Aug 27 17:16 common lrwxrwxrwx 1 root root 12 Apr 2 04:32 conf -> /etc/tomcat7 # 实际目录为/var/log/tomcat7/, 保存了tomcat的日记 lrwxrwxrwx 1 root root 17 Apr 2 04:32 logs -> ../../log/tomcat7, drwxr-xr-x 3 tomcat7 tomcat7 4096 Aug 27 17:16 server drwxr-xr-x 3 tomcat7 tomcat7 4096 Aug 27 17:16 shared drwxrwxr-x 3 tomcat7 tomcat7 4096 Aug 27 17:16 webapps # 实际目录为 /var/cache/tomcat7/ lrwxrwxrwx 1 root root 19 Apr 2 04:32 work -> ../../cache/tomcat7 |
- /etc/tomcat7$: 配置文件的真实目录
|
/etc/tomcat7$ ls -l drwxrwxr-x 3 root tomcat7 4096 Aug 27 17:16 Catalina -rw-r--r-- 1 root tomcat7 5586 Apr 2 04:32 catalina.properties -rw-r--r-- 1 root tomcat7 1394 Feb 26 2012 context.xml -rw-r--r-- 1 root tomcat7 2370 Jul 13 2012 logging.properties drwxr-xr-x 2 root tomcat7 4096 Aug 27 17:16 policy.d -rw-r--r-- 1 root tomcat7 6500 Apr 2 04:32 server.xml -rw-r----- 1 root tomcat7 1530 Feb 26 2012 tomcat-users.xml -rw-r--r-- 1 root tomcat7 152716 Feb 26 2012 web.xml |
- /var/cache/tomcat7/目录,
|
/var/cache/tomcat7/ $ ls -l -a /var/cache/tomcat7/ drwxr-xr-x 3 tomcat7 tomcat7 4096 Aug 27 17:16 Catalina -rw-r--r-- 1 root root 9281 Aug 27 17:16 catalina.policy |
- JVM_TMP, CATALINA_TMPDIR临时目录: /tmp/tomcat7-tomcat7-tmp/
4.3 解压缩安装
通过解压缩方式运行的tomcat将不会为tomcat新建一个用户和群组,而是会将以当前用户运行。
4.3.1 具体步骤
- 安装JDK或者JRE并设置相关环境变量。
- 下载tomcat安装文件并解压到欲安装的目录,注意: 请保持解压缩后得到的"apache-tomcat-[version]"格式的目录名。
- 设置tomcat的环境变量:新建一个环境变量CATALINA_HOME,并将它的值赋值为安装文件解压缩后的目录,如: C:\apache-tomcat-7.0.42。
- [可选] 新建CATALINA_BASE环境变量,将其值赋值为the root directory of the "active configuration" of Tomcat,该值默认与CATALINA_HOME相同。
- 直接运行tomcat\bin\startup.bat文件,即可启动tomcat。
更多信息请参考解压缩后得到的RUNNING.txt文件和http://tomcat.apache.org/tomcat-7.0-doc/windows-service-howto.html。
4.3.2 目录结构
主要的目录结构:
- bin: contains the binaries; and startup, shutdown and other scripts.
- conf: contains the system-wide configuration files, such as server.xml, web.xml, context.xml, and tomcat-users.xml.
- lib: contains the Tomcat's system-wide JAR files, accessible by all webapps. You could also place external JAR file (such as MySQL JDBC Driver) here.
- logs: contains Tomcat's log files. You may need to check for error messages here.
- webapps: contains the webapps to be deployed. You can also place the WAR file for deployment here.
- work: Tomcat's working directory used by JSP, for JSP-to-Servlet conversion.
- temp: Temporary files.
4.4 属性&配置文件
启动脚本中包含的主要属性有:
- CATALINA_HOME: 表示Tomcat静态部分的目录(目录)
- CATALINA_BASE: 表示当前Tomcat实例的工作目录。Tomcat可以通过为每个实例定义一个CATALINA_BASE目录来实现多实例。如果没有配置多实例,则$CATALINA_BASE与$CATALINA_HOME的值是相同的。该目录中包含conf/webapps/logs等子目录
- JAVA_HOME: 表示Java运行环境或JDK环境的位置
- JAVA_OPTS: 设置Java命令行选项(启动参数)
- JPDA_TRANSPORT: 设置JPDA调试器使用的透明传输协议,默认值为dt_socket
- JPDA_ADDRESS: 设定与catalina jpda start命令一起使用的JPDA地址,默认值为8000
- CATALINA_PID: 可以存储在Tomcat启动和停止时要使用的进程ID对应的路径。
配置文件位于: {CATALINA_BASE}/conf/目录,主要的配置文件有:
- server.xml,是tomcat的主配置文件,配置了tomcat的侦听端口,Engine name="Catalina" defaultHost="localhost"以及是否自动解压和部署war包等属性,以及服务器的根URI、webapp在{CATALINA_BASE}中的目录名(默认为webapps)等。
- web.xml,适用于整个web应用程序的配置文件,主要定义了mine映射、Default Welcome File List(用户直接访问某个目录时返回的文件)等。
- tomcat-users.xml用于认证的默认角色、用户以及密码清单等。
- context.xml,默认的context设置,应用于tomcat中的每个web app。目前主要定义了默认需要监控的资源文件WEB-INF/web.xml。
4.5 Tomcat的启动与停止
4.5.1 启动脚本分析
CATALINA_HOME表示Tomcat静态部分的目录(目录),CATALINA_BASE表示当前Tomcat实例的工作目录。Tomcat可以通过为每个实例定义一个CATALINA_BASE目录来实现多实例。如果没有配置多实例,则$CATALINA_BASE与$CATALINA_HOME的值是相同的。
4.5.2 环境变量的设置
除CATALINA_HOME和CATALINA_BASE之外,可以在"setenv"脚本中设置所有的环境变量。这个脚本可以位于CATALINA_BASE/bin 或 CATALINA_HOME/bin目录,并且被命名为setenv.bat (on Windows) 或 setenv.sh (on *nix),这个文件必须可读。
默认情况下是没有"setenv"脚本的。如果"setenv"脚本同时出现在CATALINA_BASE/bin 和 CATALINA_HOME/bin目录,则优先使用CATALINA_BASE/bin目录中的脚本。
4.5.3 apt-get的Tomcat的启动与停止
常见的启动方法:
- Redhat: $ /etc/rc.d/init.d/tomcatX start|stop|restart
- Ubuntu: $ /etc/init.d/tomcatX/ start|stop|restart
- 通用方式: $ service tomcatX start|stop|restart
4.5.4 参考信息
更多信息请参考解压缩后得到的RUNNING.txt文件
4.6 多tomcat实例
CATALINA_HOME表示Tomcat的安装目录,CATALINA_BASE表示当前Tomcat实例的工作目录。Tomcat可以通过为每个实例定义一个CATALINA_BASE目录来实现多实例。如果没有配置多实例,则$CATALINA_BASE与$CATALINA_HOME的值是相同的。
- 安装目录下最重要的子目录有: bin、lib、conf等
- 工作目录下重要子目录有: conf、temp、work、logs和webapps等。
4.6.1 Windows部署多实例
http://www.cnblogs.com/erik/archive/2012/06/19/2554715.html
以在instance对应的目录下写一个startup.bat来完成该instance的启动工作,该脚本使用脚本所在的目录作为CATALINA_BASE,可以在从任何目录下运行,并且保留了tomcat启动脚本的参数:
@echo off
set CMD_LINE_ARGS=
:setArgs
if ""%1""=="""" goto doneSetArgs
set CMD_LINE_ARGS=%CMD_LINE_ARGS% %1
shift
goto setArgs
:doneSetArgs
set EXECUTABLE=%CATALINA_HOME%/bin/startup.bat
set CATALINA_BASE=%~dp0
call "EXECUTABLE" %CMD_LINE_ARGS%
4.6.2 Linux部署多实例
具体步骤:
- 将tomcat安装目录中的conf复制到当前tomcat实例的工作目录$CATALINA_BASE。运行启动将本时,会自动将当前脚本所在的目录设置成CATALINA_BASE。
- 新建bin work temp logs webapps等子目录,将要部署的web应用放到webapps里面。
- 修改$CATALINA_BASE/conf下的server.xml,修改其中的一个Server和2个连接的端口号。shutdown常用的端口有: 8005, 8006, 8007;HTTP connector 常用的端口有: 8080, 8081, 8082。
|
<Server port="8005" shutdown="SHUTDOWN"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> |
- $CATALINA_BASE/bin目录在新建启动脚本,本使用脚本来启动Tomcat(假设tomcat程序位于/usr/share/tomcat)。启动脚本的内容如下:
|
#!/bin/bash CATALINA_HOME=/usr/share/tomcat CATALINA_BASE=/home/xxx/tomcat CATALINA_PID=/home/xxx/tomcat/pid export CATALINA_HOME CATALINA_BASE CATALINA_PID /usr/share/tomcat/bin/catalina.sh start |
除了CATALINA_HOME等变量,还可以指定其他的参数,比如: JAVA_OPTS="-Xms800m -Xmx1500m "
- $CATALINA_BASE/bin目录在新建tomcat停止脚本,如果想要停止tomcat,则使用该脚本来停止Tomcat。具体内容如下:
|
#!/bin/bash CATALINA_HOME=/usr/share/tomcat CATALINA_BASE=/home/xxx/tomcat CATALINA_PID=/home/xxx/tomcat/pid export CATALINA_HOME CATALINA_BASE CATALINA_PID /usr/share/tomcat/bin/catalina.sh stop -force |
4.6.3 配置tomcat集群
从零认识tomcat,构建一机多实例tomcat集群(主要介绍了server.xml配置文件)
http://grass51.blog.51cto.com/4356355/1123400
4.7 tomcat的日志
4.7.1 支持的日志框架
运行在tomcat之上的web app可以采用以下日志接口:
- Use system logging API, java.util.logging.
- Use the logging API provided by the Java Servlets specification, javax.servlet.ServletContext.log(...)
- Use any logging framework of its choice.
The logging frameworks used by different web applications run independently of each other.
日志的区别:
- java.util.logging。它的开启是启动Java虚拟机时通过一些系统属性来设置的。Tomcat启动脚本已经做了这些设置,但是如果使用其他工具来运行tomcat,例如通过jsvc或者在IDE中启动tomcat,则需要特别留意,有可能日志功能并没有开启。
- javax.servlet.ServletContext.log(...)。它是根据tomcat的日志配置来执行的,Web app中不能对其进行取代。它是比java.util.logging更早的API,它几乎没有提供什么选择。例如,比如控制日志的级别。
- Console。当tomcat在linux系统上运行时,控制台输出被重定向到catalina.out.文件。可以在通过环境变量对输出的文件名进行配置(见启动脚本)。任何写向System.err/out中的内容将被保存到该文件。主要包括:
² 被java.lang.ThreadGroup.uncaughtException(..)打印的未捕获的一场。
² The default logging configuration in Apache Tomcat writes the same messages to the console and to a log file.
² Thread dumps, if you requested them via a system signal
- Access logging。A related, but different feature is access logging.
4.7.2 日志的级别
4.7.3 JULI
JDK 提供的java.util.logging日志接只能配置整个Java虚拟机的日志而无法对每个web app的日志进行配置,因此,在默认情况下,tomcat使用一个JULI容器替代原有的 LogManager实现。在默认情况下,JULI是开启的。
JULI支持标准的JDK java.util.logging的、使用编程或属性文件的方式的配置机制。主要的不同是:可以针对每个classloader设置属性文件并且对属性文件的语法进行了扩展以允许更自由的定义handlers并将它们赋给loggers。因此,可以在以下层面对日志进行设定:
- 在${catalina.base}/conf/logging.properties文件中进行全局配置。这个文件被java.util.logging.config.file系统属性所指定,在启动脚本中可以对这个属性进行设置。如果没有设置或者这个文件不可读,则默认使用JRE中的${java.home}/lib/logging.properties文件。
- 在WEB-INF/classes/logging.properties 中对当前web app的日志进行设置。In the web application. The file will be WEB-INF/classes/logging.properties
JRE中默认的logging.properties指定了ConsoleHandler,它将logging路由到System.err.。Apache tomcat的默认conf/logging.properties也增加几个FileHandlers。
handler's的日志级别默认是INFO,并且能够设置成SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST 或 ALL。也可以指定特定的packages的日志级别。
必须确保ConsoleHandler's (or FileHandler's')的日志级别高于想要收集日志的门槛,因此,最好设置成FINEST 或 ALL。
4.7.4 采用log4j输出tomcat内部之日志
可以采用log4j来取代所有Tomcat内部的java.util.logging日志。如果仅仅只是替代web app中的日志,则只需要将log4j.jar(或log4jx.y.z.jar)和log4j.properties文件分别拷贝到web app的WEB-INF/lib和WEB-INF/classes当中。
4.7.4.1 Log4j的属性文件
Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。
log4j.properties配置详解
http://www.cnblogs.com/ITEagle/archive/2010/04/23/1718365.html
http://blog.sina.com.cn/s/blog_56fd58ab0100tcna.html
http://summerbell.iteye.com/blog/487736
http://issaxl.blog.51cto.com/3593612/1030705
http://blog.csdn.net/chinarenzhou/article/details/4350746
http://my.oschina.net/sfilyh/blog/51922
4.7.4.2 Log4j的日志级别
日志记录的优先级,分为ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF或者自定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。
如果将日志的级别设置成DEBUG,将会产生大量的日志并影响到tomcat 的速度。
4.7.4.3 系统结构

图 6-1 log4j系统结构(URL: http://logging.apache.org/log4j/2.x/manual/architecture.html)
4.7.4.4 Tomcat7的配置
具体步骤:
- 新建log4j.properties文件,并将其保存到$CATALINA_BASE/lib目录。log4j.properties文件文件的内容如下,其中可以根据需要在log4j.rootLogger=INFO log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=ALL等处对输出的日志级别进行设置,在log4j.appender.CATALINA.File=${catalina.base}/logs/log4j.log处等输出的日志的文件名进行设置。
|
log4j.rootLogger=INFO, CATALINA
# Define all the appenders log4j.appender.CATALINA=org.apache.log4j.DailyRollingFileAppender log4j.appender.CATALINA.File=${catalina.base}/logs/log4j.log log4j.appender.CATALINA.Append=true log4j.appender.CATALINA.Encoding=UTF-8 # Roll-over the log once per day log4j.appender.CATALINA.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.LOCALHOST=org.apache.log4j.DailyRollingFileAppender log4j.appender.LOCALHOST.File=${catalina.base}/logs/localhost. log4j.appender.LOCALHOST.Append=true log4j.appender.LOCALHOST.Encoding=UTF-8 log4j.appender.LOCALHOST.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.LOCALHOST.layout = org.apache.log4j.PatternLayout log4j.appender.LOCALHOST.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.MANAGER=org.apache.log4j.DailyRollingFileAppender log4j.appender.MANAGER.File=${catalina.base}/logs/manager. log4j.appender.MANAGER.Append=true log4j.appender.MANAGER.Encoding=UTF-8 log4j.appender.MANAGER.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.MANAGER.layout = org.apache.log4j.PatternLayout log4j.appender.MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.HOST-MANAGER=org.apache.log4j.DailyRollingFileAppender log4j.appender.HOST-MANAGER.File=${catalina.base}/logs/host-manager. log4j.appender.HOST-MANAGER.Append=true log4j.appender.HOST-MANAGER.Encoding=UTF-8 log4j.appender.HOST-MANAGER.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.HOST-MANAGER.layout = org.apache.log4j.PatternLayout log4j.appender.HOST-MANAGER.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Encoding=UTF-8 log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
# Configure which loggers log to which appenders log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=ALL, LOCALHOST log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager]=\ ALL, MANAGER log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager]=\ ALL, HOST-MANAGER |
注意: 在该配置中manager 和 host-manager有独立的日志文件,其它日志文件都输出到log4j.log当中。如果想要输出更详细的日志,可以在属性文件中增加一下配置:
|
log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG log4j.logger.org.apache.catalina.core=DEBUG log4j.logger.org.apache.catalina.session=DEBUG |
- 从http://logging.apache.org/log4j/处下载log4j的jar包,并从下载的压缩包中取出最新版本的log4j的jar包,如: log4j-1.2.17.jar,然后将该jar重命名为log4j.jar。
- 从http://tomcat.apache.org/download-70.cgi 的Extras的Extras处下载tomcat-juli.jar and tomcat-juli-adapters.jar两个jar包,分别对应的连接是JULI log4j jar 和 JULI adapters jar。下载的tomcat-juli.jar与默认的tomcat-juli.jar不同,它包含了完整的Apache Commons Logging。
- 如果想要配置tomcat全局采用log4j,则执行下面操作:
a) 将log4j.jar 和tomcat-juli-adapters.jar 放到$CATALINA_HOME/lib目录。
b) 将下载的tomcat-juli.jar替代掉原有的$CATALINA_HOME/bin/tomcat-juli.jar
- 如果$CATALINA_HOME 和 $CATALINA_BASE指向不同的目录,并且只想$CATALINA_BASE中的tomcat实例采用log4j,则执行以下操作:
a) 如果不存在$CATALINA_BASE/bin 和$CATALINA_BASE/lib目录,则先创建这些目录。
b) 将log4j.jar 和tomcat-juli-adapters.jar 放到$CATALINA_BASE/lib目录。
c) 将tomcat-juli.jar 放到$CATALINA_BASE/bin/目录
d) 如果以security manager运行,则需要对$CATALINA_BASE/conf/catalina.policy 文件进行调整(using a different copy of tomcat-juli.jar)。
- 删除$CATALINA_BASE/conf/logging.properties 文件以防止java.util.logging 产生0长度的日志文件。
- 启动tomcat
更详细步骤请参考: http://tomcat.apache.org/tomcat-7.0-doc/logging.html
4.7.4.5 Tomcat6之前版本的配置
http://hanxin0311.iteye.com/blog/368614
http://blog.csdn.net/terryzero/article/details/4034796
http://commons.apache.org/proper/commons-logging/download_logging.cgi
http://www.apache.org/dist/commons/logging/binaries/
4.8 部署war包web程序
常见几种比较简单的war包部署方式:
- 将war包放置到tomcat的${ CATALINA_BASE}/webapps目录下,重启Tomcat,这个war包将自动解压并形成web app目录,相当于发布了。如果将${ CATALINA_BASE}/conf/server.xml文件中Host元素上设置autoDeploy="true",则有可能不需要重新启动tomcat。
注意: 还可以在${CATALINA_BASE}/conf/server.xml文件中的Host容器元素中为web应用程序增加了Context元素。如果增加了Context元素的话,则将以将autoDeploy设置成false,否则有可能导致server.xml中增加的Context对应的web app被部署两次。如果将path设置成空(""),则将可以将这个web app映射成服务器的根URI("/")。
|
<?xml version='1.0' encoding='utf-8'?> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="my-webapp.war" path="/my-webapp"/> </Host> </Engine> </Service> </Server>
|
- 通过manager web应用程序进行部署,通过manager web应用程序可以通过web界面来管理自己的web应用程序。但tomcat需要进行一些特殊的配置。
4.8.1 Manager web设置
可以通过manager web对web应用程序进行管理。Tomcat中默认自动启动了Manager Web,但访问/manager/html需要manager-gui角色,默认情况下,没有用户拥有该角色。
可以配置{CATALINA_BASE}/conf/tomcat-user.xml文件,在tomcat-users容器元素中增加角色和用户的配置信息,具体配置信息如下:
|
<tomcat-users> <role rolename="manager-gui"/> <role rolename="manager"/> <user username="jya" password="windy" roles="manager, manager-gui"/> </tomcat-users> |
然后登录http://10.46.169.15:8080/manager/html ,即可对web app进行配置。
通常管理用户只需要"manager-gui" manager-script"两个角色的权限,但如果出现401 403错误时,可以同时授予其它几个角色的权限。
|
<tomcat-users> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager"/> <role rolename="admin-gui"/> <user username="jya" password="windy" roles="manager-gui,manager-script,manager,admin-gui"/> </tomcat-users> |
其中manager-gui和admin-gui是Tomcat的管理界面,manager-script指的就是manager/text这个命令行接口了
4.8.2 主要URI和静态网页
- http://10.46.169.15:8080/ 主界面,可以通过页面上的Server Status链接查询服务器状态信息,Manager app等进入Manager web界面
- http://10.46.169.15:8080/manager/html,http://10.46.169.15:8080/manager/html/list Manager web界面,可以管理web app,可以查看到所以安装的web app已经映射路径
- http://10.46.169.15:8080/manager/status,可以查看tomcat服务器以及jvm等状态信息。
- 此外,还可以访问webapps目录下的docs和examples目录,这都是一些静态网页。http://10.46.169.15:8080/docs/ ,http://10.46.169.15:8080/examples/ 。用户开可以在在webapps目录下创建新的子目录和静态网页并通过浏览器访问它,如: http://10.46.169.15:8080/test/hello.html,但直接将静态网页放置在根目录下的话,通常访问不了。
4.8.3 配置https访问
对服务器单向认证的具体步骤:
- 利用jdk自带的keytool工具在密钥仓库文件中创建一个密钥对或使用openssl将由证书机构(CA)颁发的证书导入到一个PKCS12 keystore当中。
- keytool创建密钥对: $ keytool -genkey -alias tomcat -keyalg RSA。需注意alias和keypass对应的口令。
- 导入原有证书: $ openssl pkcs12 -export -in mycert.crt -inkey mykey.key -out mycert.p12 -name tomcat -CAfile myCA.crt -caname root -chain
- 配置 $CATALINA_BASE/conf/server.xml以使用密钥仓库中的密钥对,比如使用tomcat对应的密钥。删除掉原来的注释符号,然后添加最后一行即可。
|
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" keystoreFile="/home/jya/.keystore" keystorePass="cloudy98"/> |
注意: tomcat可以通过 <Connector protocol>字段来配置所使用的ssl。通常有两种类型: JRE自带的JSSE或Openssl的APR,默认为JSSE。更详细的配置请参: http://tomcat.apache.org/tomcat-8.0-doc/ssl-howto.html。
- 测试tomcat配置是否成功。启动 Tomcat 并访问 https://localhost:8443. 将看到 Tomcat 默认的首页。
- 配置当前应用使用 SSL。打开应用的WEB-INF/web.xm文件,增加如下配置项:
|
<security-constraint> <web-resource-collection> <web-resource-name>securedapp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> |
将 URL 映射设为 /* ,整个应用都要求是 HTTPS 访问,而 transport-guarantee 标签设置为 CONFIDENTIAL 以便使应用支持 SSL。如果希望关闭 SSL ,只需要将 CONFIDENTIAL 改为 NONE 即可。
- [可选步骤]根据处服务器的密钥对导出证书并添加到客户端浏览器的“受信任的根证书颁发机构”当中。
a) 导出服务器的证书: $ keytool -keystore /home/jya/.keystore -export -alias tomcat -file tomcat.cer
b) 双击tomcat.cer文件,然后将其导入到“受信任的根证书颁发机构”当中。
这样当浏览器浏览网页时将不会弹出告警信息。
对服务器和客户端双向认证的具体步骤:
http://jingyan.baidu.com/article/a948d6515d3e850a2dcd2ee6.html
更多详细参考: http://tomcat.apache.org/tomcat-8.0-doc/ssl-howto.html。
4.9 Tomcat的部署
http://tomcat.apache.org/tomcat-7.0-doc/deployer-howto.html
Apache2.2+Tomcat7.0整合配置详解
http://www.cnblogs.com/leslies2/archive/2012/07/23/2603617.html
4.10 其它小技巧
4.10.1 查看tomcat版本信息
Linux 下进入tomcat安装文件夹的bin目录下 执行./version.sh: /usr/share/tomcat7/bin/version.sh
4.10.2 Class Loader HOW-TO
如(图 41)所示,tomcat主要包含4中类型的classloader
- Bootstrap — This class loader contains the basic runtime classes provided by the Java Virtual Machine, plus any classes from JAR files present in the System Extensions directory ($JAVA_HOME/jre/lib/ext).
- System — This class loader is normally initialized from the contents of the CLASSPATH environment variable. All such classes are visible to both Tomcat internal classes, and to web applications. However, the standard Tomcat startup scripts ($CATALINA_HOME/bin/catalina.sh or %CATALINA_HOME%\bin\catalina.bat) totally ignore the contents of the CLASSPATH environment variable itself, and instead build the System class loader from the following repositories:
² $CATALINA_HOME/bin/bootstrap.jar — Contains the main() method that is used to initialize the Tomcat server, and the class loader implementation classes it depends on.
² $CATALINA_BASE/bin/tomcat-juli.jar or $CATALINA_HOME/bin/tomcat-juli.jar — Logging implementation classes. These include enhancement classes to java.util.logging API, known as Tomcat JULI, and a package-renamed copy of Apache Commons Logging library used internally by Tomcat. See logging documentation for more details. If tomcat-juli.jar is present in $CATALINA_BASE/bin, it is used instead of the one in $CATALINA_HOME/bin. It is useful in certain logging configurations
² $CATALINA_HOME/bin/commons-daemon.jar — The classes from Apache Commons Daemon project. This JAR file is not present in the CLASSPATH built by catalina.bat|.sh scripts, but is referenced from the manifest file of bootstrap.jar.
- Common — This class loader contains additional classes that are made visible to both Tomcat internal classes and to all web applications.The locations searched by this class loader are defined by the common.loader property in $CATALINA_BASE/conf/catalina.properties. Normally, application classes should NOT be placed here.
- WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

图 6-2 tomcat的classloader(URL: http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html)
4.11 经典书籍
深入剖析Tomcat [平装], 定价: ¥ 43.70, 主要介绍了基于tomcat编程, 非amazon直营
http://www.amazon.cn/%E6%B7%B1%E5%85%A5%E5%89%96%E6%9E%90Tomcat-%E5%85%8B%E5%B0%BC%E4%BA%9A%E4%B8%87/dp/product-description/B006R3TUIC/ref=dp_proddesc_0?ie=UTF8&s=books
Tomcat权威指南(第2版) [平装] 价格: ¥ 43.50 , 主要介绍了tomcat的部署与配置
http://www.amazon.cn/Tomcat%E6%9D%83%E5%A8%81%E6%8C%87%E5%8D%97-%E5%B8%83%E9%87%8C%E6%B3%B0%E6%81%A9/dp/product-description/B002T1FTHW/ref=dp_proddesc_0?ie=UTF8&s=books
4.12 错误以及解决方案
4.12.1 Error listenerStart
现象: 启动web app时提示Error listenerStart
可能的原因:
- webapps要用到的classe文件根本没有复制到WEB-INF/classes目录下面(java.lang.NoClassDefFoundError,而这个信息可能默认没输出到控制台,尤其是用了spring的,这是个粗心的低级错误)
- 缺少jar包
- lib下的同一个库的jar文件存在多个不同版本,引起版本冲突.
- lib下的jar与tomcat版本不相对应
4.13 参考资料
JDK和Tomcat的简单整合
http://supportopensource.iteye.com/blog/1884939
4.13.1 启动脚本分析
Tomcat启动脚本catalina.sh
http://oss.org.cn/ossdocs/apache/tomcat/heavyz/02-catalina.sh.html
tomcat启动过程分析 (主要介绍了xml配置文件)
http://blog.chinaunix.net/uid-24723303-id-3154876.html
Tomcat7启动分析(一)启动脚本(bat脚本)
http://tyrion.iteye.com/blog/1908330
Tomcat7启动分析(二)Bootstrap类中的main方法
http://tyrion.iteye.com/blog/1912107
5 Apache httpd
5.1 Linux系统管理httpd
5.1.1 编译Apahce源码
详细参考: http://httpd.apache.org/docs/2.4/install.html
- 从http://www.apache.org/dist/httpd/ 出下载源码
- 新建apche安装目录: $ mkdir -p /usr/local/apache2
- 根据配置文件生成makefile文件。常见的配置选项有:
- ./configure --prefix=/usr/local/apache2 --enable-module=so [--enable-rewrite]
- ./configure --prefix=/usr/local/apache2 --enable-module=so --enable-module=alias --enable-module=all --enable-shared=max --enable-module=vhost_alias --enable-shared=vhost_alias --enable-deflate --enable-cache --enable-disk-cache --enable-mem-cache --enable-file-cache --enable-rewrite --enable-static-support
- 编译并安装: $ make && make install
- 启动apache。
5.1.2 完全删除apache2
- 删除apache二进制文件以及相关库
|
$ sudo apt-get --purge remove apache2 $ sudo apt-get --purge remove apache2.2-common $ sudo apt-get autoremove [apache2] |
- 找到没有删除掉的配置文件并删除
|
$ sudo find /etc -name "*apache*" -exec rm -rf {} \; $ sudo rm -rf /var/www |
5.1.3 Apache的目录结构
在ubuntu环境下apache默认路径如下:
- 安装路径: /etc/httpd
- 配置文件: /etc/httpd/conf/httpd.conf
- 启动脚本: /usr/sbin/apachectl
- web目录: /var/www/html
- 日志目录: /usr/local/apache2/logs/, 其中/usr/local/apache2/logs/httpd.pid包含有当前httpd进程的进程号。如果是老版本的apache,日志目录有可能是/usr/local/apache/logs/。
- web app 目录(即war包的安装目录): /var/lib/tomcat6/webapps/, 如果采用源代码安装,一般默认安装在/usr/local/apache2目录下。修改web目录: 编辑/etc/apache2/sites-enabled/000-default文件,将“DocumentRoot /var/www”中的“/var/www”修改成想要设定的目录,然后重启Apache2服务即可。
5.1.4 Apache2的目录结构
Apache2相关目录:
- 日志位于/var/log/apache2
- 默认ServerRoot目录: /etc/apache2,配置文件也位于其中
5.1.5 Apache的启动&关闭
详细参考: http://httpd.apache.org/docs/2.4/invoking.html
http://httpd.apache.org/docs/2.4/stopping.html
启动httpd执行文件的推荐方法是使用apachectl控制脚本。 此脚本设置了在某些操作系统中正常运行httpd所必需的环境变量。在 CentOS 系统中执行如下命令:sudo service httpd restart;在 Ubuntu 系统中执行:sudo service apache2 restart。
apachectl会传递命令行的所有参数, 因此所有httpd的选项多半也可以用于apachectl。 可以直接修改apachectl脚本, 改变头部的HTTPD变量使之指向httpd文件的正确位置, 也可以设置任意命令行参数使之总是有效。
apachectl脚本 /usr/local/apache2/bin/apachectl start|stop|restart,
直接使用httpd可以执行文件: /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -D /usr/local/apache2/htdocs/
-f 指定配置文件
-D 指定网页文件所在的目录
当apache没有找到默认的启动页面时,使用/etc/httpd/conf.d/welcome.conf中指定的默认页面,有时是/var/www/error/noindex.html
5.2 Windows平台的使用
Apache httpd也提供了windows版本
http://httpd.apache.org/docs/2.4/platform/windows.html
官网没有提供直接压缩的版本,可以下载httpd-2.2.25-win32-x86-openssl-0.9.8y.msi格式的安装文件,安装到指定的目录。
Windows版本的Apache是多线程的,与Unix版本不同,在Unix系统上,每个请求都是由单独的进程来处理。在windows系统上,apache只运行两个进程,由子进程负责处理请求,在子进程内,每个请求被一个单独的线程处理。
5.2.1 重要的目录结构
<DIR> bin
<DIR> cgi-bin
<DIR> conf
<DIR> error
<DIR> htdocs
<DIR> icons
<DIR> logs
<DIR> manual
<DIR> modules
5.3 Apache的配置
httpd被调用后第一件事情是找到并读取配置文件httpd.conf。
5.3.1 配置文件的位置
httpd.conf配置文件的位置是在编译时设定的:
- Linux平台的配置脚本默认位置: /usr/local/apache2/conf/httpd.conf
- windows平台的配置脚本默认位置: /path/to/install/conf/httpd.conf
但也可以象下面这样在运行时用 -f 可选参数来指定:
/usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf
5.3.2 配置php
配置apache, 让其支持php:
# vi /usr/local/apache2/conf/httpd.conf
找到AddType application/x-gzip .gz .tgz, 添加
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
找到DirectoryIndex index.html, 修改成
DirectoryIndex index.html index.php index.html.var
5.4 Apache2的配置
Apache2配置信息与之前的版本做了重大的调整,相关的配置信息不再集中字啊httpd.conf文件当中,相关的指令而是分散到各个文件和目录当中。配置文件主要位于/etc/apache2目录中,其中apache2.conf文件是关键配置文件,是主入口,由它来负责通过Include质量载入其它目录和文件中的配置信息,
主要的文件和目录有:
- apache2.conf,主配置文件,负责载入其它配置信息
- mods-available,apache自带的可允许加载模块的加载指令(.load)和对应模块的配置信息(.conf)。需要载入的模块的指令位于mods-enabled子目录中,并且以".load"结尾。需要载入的模块的配置文件位于mods-enabled子目录中,并且以" .conf"结尾。
- mods-enabled,当前加载的模块,该目录中保存的都是一些符号链接。如果要加载mods-available子目录中的某个模块,只需要在mods-enabled中建立到mods-available子目录相关模块和配置文件的符号链接即可。
- sites-available,该子目录中保存着允许加载的virtual host的配置信息
- sites-enabled,该子目录中保存着已经加载的virtual host,该目录中保存的基本都是到sites-available子目录中的配置文件的符号链接。该目录中通常有一个名为000-default的符号链接,该符号链接通常指向../sites-available/default,000-default通常是默认virtual host。
- httpd.conf,该配置文件通常为空,应该用来保存一个httpd的通用配置信息。
- ports.conf,该配置文件中通常保存在httpd的侦听端口号
- conf.d子目录,一些通用声明
apache2.conf加载配置文件,依次为:
- Include mods-enabled/*.load
- Include mods-enabled/*.conf
- Include httpd.conf
- Include ports.conf
- Include conf.d/
- Include sites-enabled/
5.4.1 正反向代理配置
可以通过配置/etc/apache2/sites-available目录中virtual host的配置信息增加如下配置:
|
# 所有配置都位于<VirtualHost></VirtualHost>字段内 # 配置正向代理 ProxyRequests On ProxyVia On <Proxy *> Order deny,allow Deny from all Allow from internal.example.com </Proxy>
# 配置反向代理 ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass /foo http://foo.example.com/bar ProxyPassReverse /foo http://foo.example.com/bar
# 还可以通过之前的<Proxy>的阻止功能来控制谁能访问代理。示例如下: <Proxy *> Order Deny,Allow Deny from all Allow from 192.168.0 </Proxy>
# 通过反向代理对用户的身份做认证, <Location /login/> AuthType Basic AuthName "Gerrit Code Review" AuthBasicProvider file AuthUserFile $gerrit.home/etc/passwords Require valid-user </Location> |
需要注意的是: 当配置反向代理时,ProxyPass和ProxyPassReverse都需要配置,如果配置的某个路径包含了另一个路径,则另一个路径在必须位于该配置路径的前面。例如: /file/dir目录必须位于 /file目录前面,否则/file/dir对应的URL是访问不到的。
反向代理还可以用来对登录的用户做身份认证,最简单的身份认证是通过htpasswd创建的口令文件来保存用户认证信息。
5.4.2 参考文档
http://httpd.apache.org/docs/2.4/
http://httpd.apache.org/docs/2.4/vhosts/name-based.html
Virtual Host 配置: http://httpd.apache.org/docs/2.4/vhosts/name-based.html
apache做反向代理服务器: http://yahoon.blog.51cto.com/13184/162922
Apache模块 mod_proxy : http://apache.jz123.cn/mod/mod_proxy.html
apache代理&反向代理的配置: http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
5.5 其它工具
5.5.1 htpasswd
htpasswd -bc /path/to/passwdFile scm scm
- -c是创建passwdFile, 如果该文件已经存在,并且只是想增加用户,则不需要-c参数,否则将会覆盖原来已经存在的文件,
- -b参数将直接在命令行中输入密码,而不需要交互模式输入。
问题: 当httpd在执行身份认证时,有可能遇到由于权限不够,无法访问口令文件的问题,,即使将该口令文件的权限设置成777,也无法访问。
原因: 可能是因为httpd所在的用户和组对该文件所在的目录没有执行权,所以无法检索到该目录下的文件。运行ls -al命令将会看到相关权限。
解决拌饭: 将口令文件所在的路径中所有的目录的执行权限都赋予httpd进程所在用户,或者将口令文件保存到该用户具有执行权限的路径当中。
6 Maven入门
Maven是一个软件项目管理综合工具,能够管理构建、报告、文档,以及根据中心化的信息来管理依赖。Ant和Ivy 2.0集成在一起,与Maven 2进行比较才比较合适。
6.1 基本概念

图 6-1 maven交互操作模型(URL: http://www.ibm.com/developerworks/cn/education/java/j-mavenv2/j-mavenv2.html )
6.1.1 目录结构
Maven安装文件目录结构:
- bin-----Maven的运行脚本
- boot-----Maven自己的类装载器
- conf-----该目录下包含了全局行为定制文件setting.xml
- lib-----Maven运行时所需的类库
一个 maven 项目在编译后 的 classes 会放在 ${basedir}/target/classes 下面, JAR 文件会放在 ${basedir}/target 下面。
初次运行mvn命令会自动将依赖的官方包下载jar到本地repository,如果不做配置,默认路径如下:
- Linux系统的为${user.home}/.m2/
- windows xp来说一般在C:/Documents and Settings/%username%/.m2下,其中%username%为操作系统登录用户名
- win7系统位于C:\Users\Administrator\.m2\ (注意: 在中文系统中,Users目录显示的是“用户”)
这时可以看到.m2/下多了个repository目录,里面有很多的项目相关jar,目录按groupId/artifactId/version排好。如果需要官方缺少的jar或公司内部jar,可以仿照这个目录结构,将做好jar放到该目录下。
6.1.2 Pom(Project Object Model)文件
一个项目所有的配置都放置在 POM 文件中:定义项目的类型、名字,管理依赖关系,定制插件的行为等等。大项目一般会分成几个子项目。在这种情况下,每个子项目就会有自己的 POM 文件,然后它们会有一个共同的父项目。这样只要构建父项目就能够构建所有的子项目了。子项目的 POM 会继承父项目的 POM。另外,所有的 POM都继承了一个 Super-POM。Super-POM 设置了一些默认值,比如在第一篇文章中提到的默认的目录结构,默认的插件等等,它遵循了惯例优于配置的原则。
运行时候的POM 要复杂的多。如果想看到运行时候的 POM 的全部内容的话,可以运行下面的命令: $mvn help:effective-pom
Pom.xml文件中的modelVersion字段表明POM文件所采用的对象模型版本。
pom.xml和 assembly.xml文件的说明
http://barty.ws/maven%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/
超级Pom的位置为%MAVEN_HOME%/lib/maven-model-builder-3.2.x.jar,打开 org/apache/maven/model/pom-4.0.0.xml 超级POM,这里面定义了中央仓库的地址。
6.1.3 坐标
在POM中,groupId, artifactId, packaging, version 叫作maven坐标,它能唯一的确定一个项目。有了maven坐标,就可以用它来指定项目所依赖的其他项目,插件,或者父项目。一般maven坐标写成如下的格式: groupId:artifactId:packaging:version。范例: com.mycompany.helloworld: helloworld: jar: 1.0-SNAPSHOT
Maven 坐标是一组可以惟一标识工件的三元组值。坐标包含了下列三条信息:
- 组 ID:代表制造该工件的实体或组织。例如,com.ibm.devworks 就是一个组 ID。
- 工件 ID:实际的工件的名称。例如,主体类名为 OpsImp 的项目也许会用 OpsImp 作为其工件 ID。
- 版本:该工件的版本号。支持的格式为 mmm.nnn.bbb-qqqqqqq-dd,其中, mmm 是主版本号,nnn 是次版本号,bbb 代表其 bug 修复水平。qqqqq(限定词)或 dd(构建号)也能添加到版本号中,这两项是可选项。
6.1.4 插件&goal
mvn 本身不会做太多的事情,它不知道怎么样编译或者怎么样打包。它把构建的任务交给插件去做。插件定义了常用的构建逻辑,能够被重复利用。这样做的好处是,一旦插件有了更新,那么所有的 maven 用户都能得到更新。
一个目标是一个工作单元,而插件则是一个或者多个目标的集合。比如说Jar插件,Compiler插件,Surefire插件等。从看名字就能知道,Jar 插件包含建立Jar文件的目标, Compiler 插件包含编译源代码和单元测试代码的目标。Surefire 插件的话,则是运行单元测试。
执行插件中的目标的命令: $ mvn pluginId:goalId。
例如,创建一个项目: $ mvn archetype:generate。archetype 是一个插件的名字,generate是目标(goal)的名字,这个命令的意思是告诉 maven 执行 archetype 插件的 generate 目标。
插件的使用:
Pom.xml文件中的<build> <plugins> <plugin> <configuration>字段可以对插件的参数进行设置,比如设置编译插件的jdk版本哈等信息。
更多的插件: http://maven.apache.org/plugins/。
插件的配置: http://maven.apache.org/guides/mini/guide-configuring-plugins.html。
6.1.5 Maven 生命周期(lifecycle phase )
生命周期指项目的构建过程,它包含了一系列的有序的阶段 (phase),而一个阶段就是构建过程中的一个步骤。
那么生命周期阶段和上面说的插件目标之间是什么关系呢?插件目标可以绑定到生命周期阶段上。一个生命周期阶段可以绑定多个插件目标。当 maven 在构建过程中逐步的通过每个阶段时,会执行该阶段所有的插件目标。不同于goal, 一个phase是指构建生命周期的一个阶段,构建生命周期是指有序的一系列phase。当给出一个phase,Maven将执行所有的在此阶段前的phase及其自身。
maven 能支持不同的生命周期,但是最常用的是默认的Maven生命周期 (default Maven lifecycle )。如果没有对它进行任何的插件配置或者定制的话,那么 mvn package命令 会依次执行默认生命周期中直到包括 package 阶段前的所有阶段的插件目标:
- process-resources 阶段:resources:resources
- compile 阶段:compiler:compile
- process-classes 阶段:(默认无目标)
- process-test-resources 阶段:resources:testResources
- test-compile 阶段:compiler:testCompile
- test 阶段:surefire:test
- prepare-package 阶段:(默认无目标)
- package 阶段:jar:jar
- deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。
- clean:清除先前构建的artifacts(在maven中,把由项目生成的包都叫作artifact)。
- site:为项目生成文档站点。
注意:可以同时指定多个生命周期,如: mvn clean compile。Clean 告诉maven清理输入出目录target/;compile告诉maven编译项目主代码。
生命周期详细参考: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html。
1.1.1.1 使Maven 2在package、install等阶段跳过运行Test的配置
方法1:
To skip running the tests for a particular project, set the skipTests property to true.
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
方法2:
You can also skip the tests via command line by executing the following command:
mvn install -DskipTests
方法3:
If you absolutely must, you can also use the maven.test.skip property to skip compiling the tests. maven.test.skip is honored by Surefire and the Compiler Plugin.
mvn install -Dmaven.test.skip=true
6.1.6 Maven 依赖管理
在POM 中,依赖关系是在pom.xml文件中<dependencies>字段中定义的。例如: 定义对于 junit 的依赖:
|
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> |
在POM 的 dependencies 部分中,scope 决定了依赖关系的适用范围。例子中 junit 的 scope 是 test,那么它只会在执行 compiler:testCompile and surefire:test 目标的时候才会被加到 classpath 中,在执行 compiler:compile 目标时是拿不到 junit 的。
scope 的默认值是 compile,即任何时候都会被包含在 classpath 中,即使在打包的时候的依赖包也会被包括进去。
还可以指定 scope 为 provided,意思是 JDK 或者容器会提供所需的jar文件。比如说在做web应用开发的时候,在编译的时候需要 servlet API jar文件,但是在打包的时候不需要把这个 jar 文件打在 WAR 中,因为servlet容器或者应用服务器会提供的。
这个例子很简单,但是实际开发中会有复杂得多的依赖关系,因为被依赖的 jar 文件会有自己的依赖关系,因为 maven 提供了传递依赖的特性,因此并不需要把那些间接依赖的 jar 文件也都定义在POM中。所谓传递依赖是指 maven 会检查被依赖的 jar 文件,把它的依赖关系纳入最终解决的依赖关系链中。
针对上面的 junit 依赖关系,如果查看看一下 maven 的本地库: ~/.m2/repository/junit/junit/3.8.1/,就会发现 maven 不但下载了 junit-3.8.1.jar,还下载了它的 POM 文件。这样 maven 就能检查 junit 的依赖关系,把它所需要的依赖也包括进来。
查看依赖常用的命令:
- mvn dependency:list 查看当前项目的已解析依赖
- mvn dependency:tree 查看当前项目的依赖树
- mvn dependency:analyze 分析当前项目的依赖状况,可以找到一些warning:
² 使用了未声明的依赖
² 没有使用已声明的依赖(这些或许可以删掉,但是要仔细分析,像spring-core,spring-beans看起来是没有用到,但是他们是spring运行必须的)
[WARNING] Used undeclared dependencies found:
[WARNING] org.slf4j:log4j-over-slf4j:jar:1.6.6:provided //未声明的依赖,建议声明
[WARNING] storm:storm-core:jar:0.9.0:provided //未声明的依赖
[WARNING] Unused declared dependencies found: //未使用
[WARNING] storm:storm:jar:0.9.0:provided
解决依赖不同版本冲突:
首先在 自己的 pom 中,人为不可能引入两个版本不同的依赖。冲突最可能的就是你依赖的依赖可能产生了冲突。比如 A 依赖 版本为2.0 的 C ,B 依赖 版本为3.0的 C。在你的pom中,你同时依赖了 A 和 B ,这时就会产生冲突。这时候你就要判断,哪个版本能同时让A和B工作(如果可以的话),然后排除掉另一个就行了。我通常都是排除掉较低的版本。
Xml代码
- <dependencies>
- <dependency>
- <groupId>A</groupId>
- <artifactId>A</artifactId>
- <version>xxx</version>
- <exclusions>
- <exclusion>
- <groupId>C</groupId>
- <artifactId>C</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>B</groupId>
- <artifactId>B</artifactId>
- </dependency>
- </dependencies>
6.1.7 Maven 库
当第一次运行 maven 命令的时候,需要连接Internet,因为它需要从默认的远程库(http://repo1.maven.org/maven2 )下载一些核心插件和jar文件。
但是不是所有的 jar 文件都是可以从默认的远程库下载的,比如说自己开发的项目。这个时候,有两个选择:要么在公司内部设置定制库,要么手动下载所需的jar文件并安装到本地库。
本地库是指 maven 下载了插件或者 jar 文件后存放在本地机器上的拷贝:
- 在 Linux 上,它的位置在 ~/.m2/repository,
- 在 Windows XP 上,在 C:\Documents and Settings\username\.m2\repository ,
- 在 Windows 7 上,在 C:\Users\username\.m2\repository。
当 maven 查找需要的 jar 文件时,它会先在本地库中寻找,只有在找不到的情况下,才会去远程库中找。
运行 $ mvn install 命令能把当前项目安装到本地库。一旦一个项目被安装到了本地库后,别的项目就可以通过 maven 坐标和这个项目建立依赖关系。
6.1.8 常用参数&命令
常用参数:
-Dxxx=yyy, 指定系统属性
-e,--errors, 输出执行时的错误信息
-f,--file <arg>, 采用指定的POM文件,而不是默认的pom.xml文件来
-o 运行offline模式,不联网更新依赖
-X, --debug, 输出执行时的debug信息
常用命令
|
命令 |
用途 |
|
mvn -P goal |
列出goal下所有的子命令 |
|
mvn archetype:generate |
创建一个符合Maven约定的空工程 |
|
mvn clean |
清除上一次构建所生成的文件 |
|
mvn compile |
编译源码 |
|
mvn test |
测试(包括编译源码、执行测试用例) |
|
mvn test-compile |
simply compile your sources (but not execute the tests), |
|
mvn install |
将当前项目编译好的jar包安装到本地仓库,以便其它项目可以使用 |
|
mvn idea:idea |
generate an IntelliJ IDEA descriptor for the project |
|
mvn deploy |
将包安装到远端仓库,以便其他开发人员可以使用 |
|
mvn help:system |
显示系统属性和环境变量 |
|
mvn javadoc:jar |
创建工程对应的Java Doc包, *-javadoc.jar |
|
mvn jar:jar |
will not recompile sources - it will simply just create a JAR from the target/classes directory, |
|
mvn source:jar |
创建源码包, *-sources.jar |
|
mvn jetty:run |
调用Jetty插件的Run目标,即在Jetty Servlet容器中启动web应用 |
|
mvn -Dwtpversion=1.0 eclipse:eclipse |
生成Wtp(Web Tools Platform)插件的Web项目 |
|
mvn -Dwtpversion=1.0 eclipse:clean |
清除Eclipse项目的配置信息(Web项目) |
|
mvn eclipse:eclipse |
将项目转化为Eclipse项目 |
|
|
|
|
mvn validate |
验证工程是否正确,所有需要的资源是否可用。 |
|
mvn verify |
运行任何检查,验证包是否有效且达到质量标准。 |
|
mvn generate-sources |
产生应用需要的任何额外的源代码,如xdoclet。 |
|
mvn dependency:sources |
下载依赖包的源码, 或者加上参数: -DdownloadSources=true |
|
mvn console |
进入maven的console,可以运行多个命令,节约时间 |
|
mvn build:start |
分析项目依赖关系并下载插件 |
6.1.9 相关工具

图 9-2 maven相关工具(URL: http://maven.apache.org/ref/3.2.3/ )
6.2 Pom.xml文件的说明
几个重要字段的说明:
- project:pom.xml文件中的顶层元素。
- modelVersion:指明POM使用的对象模型的版本。这个值很少改动。
- groupId:指明创建项目的组织或者小组的唯一标识。GroupId是项目的关键标识,通常,此标识以组织的完全限定名来定义。比如,org.apache.maven.plugins是所有Maven插件项目指定的groupId。
- artifactId: 指明此项目产生的主要产品的基本名称。项目的主要产品通常为一个JAR文件。源代码包通常使用artifactId作为最后名称的一部分。典型的产品名称使用这个格式: <artifactId>- <version>. <extension>(比 如:myapp-1.0.jar)。
- version:项目产品的版本号。Maven帮助你管理版本,可以经常看到SNAPSHOT这个版本,表明项目处于开发阶段。
- name:项目的显示名称,通常用于maven产生的文档中。
- url:指定项目站点,通常用于maven产生的文档中。
- description:描述此项目,通常用于maven产生的文档中。
6.3 环境搭建
Maven是一个Java工具,因此在安装 maven 前,必须安装JDK。JDK下载URL:http://www.oracle.com/technetwork/cn/java/javase/downloads/index.html。
Maven下载URL是: http://maven.apache.org/download.html,该页末尾处还包含了安装和设置指导。
6.3.1 Windows系统环境的搭建
- 解压安装包,如: apache-maven-3.1.0-bin.tar.gz
- 新建环境变量“M2_HOME”并赋值为maven压缩包的解压后所在的目录,例如赋值为:“C:\apache-maven-3.1.0”,注意变量的末尾不需要“\”符号。
- 新建环境“M2”,并赋值为“%M2_HOME%\bin”,然后将“%M2%”追加到Path环境变量当中。或者直接将“%M2_HOME%\bin”的值追加到Path环境变量即可。
- [可选步骤],新建并设置环境变量“MAVEN_OPTS”,该属性值可以传递给Java虚拟机,例如,可以将该值设置成“-Xms256m -Xmx512m”。
- 在命令行下输入mvn –version命令检测是否成功安装。
6.3.2 Linux系统环境的搭建
基本步骤与windows环境相同,将安装包解药后可以通过在~/.bash_profile中增加以下变量:
|
export M2_HOME=~/bin/apache-maven-3.1.0 export M2=${M2_HOME}/bin export PATH=${PATH}:${M2} |
6.3.3 配置(settings.xml)
配置文件主要包含了用户相关的认证、仓库和其他信息的配置,用来自定义Maven的行为。配置文件主要有两个:
- $M2_HOME/conf/settings.xml,对所有用户都有效的设置
- ~/.m2/settings.xml,只对当前登录用户有效的设置。缺省情况下该文件不存在,如果需要配置,可以从 $M2_HOME/conf 目录下拷贝一个过来,然后进行修改
6.3.3.1 设置代理服务器
当在公司内网使用maven时,有可能需要设置代理。设置代理服务器的配置文件位于: ${M2_HOME}/conf/settings.xml。可以在<proxies>和</proxies>字段之间添加一个或多个代理服务器的配置信息,如果是通过首次访问页面时弹出对话框的方式鉴权,则其中<username>和<password>字段是可以不配置的。
|
<proxy> <id>my-proxy</id> <active>true</active> <protocol>http</protocol> <!-- <username>userName</username> <password>password</password> --> <host>10.41.70.8</host> <port>80</port> <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts> </proxy> |
proxies下可以有多个proxy元素,如果声明了多个proxy元素,则默认情况下第一个被激活的proxy会生效。
nonProxyHost元素用来指定哪些主机不需要代理,可以使用"|"符号来分隔多个主机名。此外,该配置也支持通配符,如:*.google.com表示所有以google.com结尾的域名访问都不要通过代理。
6.3.3.2 修改本地仓库位置
仓库用于存放项目所依赖的所有jar包。
打开conf\setting.xml文件,将<localRepository>字段设置成期望的仓库路径,如: <localRepository>/path/to/local/repo</localRepository>
6.3.4 配置编译时的jdk版本
maven 2.1默认用jdk 1.3来编译,maven 3是jdk 1.5。
解决方案1:修改maven的默认jdk配置,编辑maven的conf\setting.xml文件中找到jdk配置的地方,增加以下内容:
|
<profile> <id>jdk1.6</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.6</jdk> </activation> <properties> <maven.compiler.source>1.6</maven.compiler.source> <maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.compilerVersion>1.6</maven.compiler.compilerVersion> </properties> </profile> |
解决方案2:修改项目中pom.xml文件,指定编译当前项目的jdk
|
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> |
6.4 常用插件
官方提供的插件: http://maven.apache.org/plugins/index.html
核心插件:
- clean, 清除所有构建生成的文件
- compiler, 编译Java代码
- deploy, 将构建的artifact部署到远程repository
- install, 将构建的artifact安装到local repository
其它插件:
- archetype, Generate a skeleton project structure from an archetype.
- assembly, Build an assembly (distribution) of sources and/or binaries. SVN JIRA
- dependency, Dependency manipulation (copy, unpack) and analysis.
- eclipse, Generate an Eclipse project file for the current project.
- help, Get information about the working environment for the project.
- war、jar、ejb、rar等。
6.4.1 maven-assembly-plugin
assembly用来对整个工程(代码+资源)进行打包以方便部署。步骤如下:
1. 添加此PLUGIN到项目的POM.XML中
Xml代码 收藏代码
<buizld>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.allen.capturewebdata.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
注意修改主类为你自己的主类,如果出现CLASS重名的情况,这时候就要把最新的版本号添加进去即可,
2, 在当前项目下执行mvn assembly:assembly, 执行成功后会在target文件夹下多出一个以-jar-with-dependencies结尾的JAR包. 这个JAR包就包含了项目所依赖的所有JAR的CLASS.
3.如果不希望依赖的JAR包变成CLASS的话,可以修改ASSEMBLY插件.
3.1 找到assembly在本地的地址,一般是c:/users/${your_login_name}/.m2/\org\apache\maven\plugins\maven-assembly-plugin\2.4
3.2 用WINZIP或解压工具打开此目录下的maven-assembly-plugin-2.4.jar, 找到assemblies\jar-with-dependencies.xml
3.3 把里面的UNPACK改成FALSE即可
6.4.2 jetty-maven-plugin
这个插件可以启动一个jetty web服务器,启动速度快,一旦启动,修改了jsp,页面上可以直接反应出来,修改了servlet代码,运行一下mvn compile也可以立马反应出来,方便开发。
具体步骤:
- 在pom.xml文件中的<build>/<plugins>字段内添加对jetty插件的依赖,具体内容如下:
|
<plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>7.1.6.v20100715</version> <configuration> <scanIntervalSeconds>3</scanIntervalSeconds> <webAppConfig> <contextPath>/test</contextPath> </webAppConfig> </configuration> </plugin> </plugins> |
- 运行 mvn jetty:run 命令
- 在浏览器中访问修改后的内容:http://host:8080/test/ 就可以看到修改后的index.jsp了
6.4.3 onejar-maven-plugin
用Maven生成一个包孕所有依赖jar包的可执行的jar包
create an executable jar with dependencies using Maven:
using plugin - onejar-maven-plugin. Example below (mvn package build jar):
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<configuration>
<mainClass>com.company.MainClass</mainClass>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
You need to add repository for that plugin:
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
其他参考:http://www.infoq.com/cn/news/2011/04/xxb-maven-7-plugin
http://www.infoq.com/cn/news/2011/05/xxb-maven-8-plugin/
6.5 项目管理
6.5.1 源码目录结构
Maven 使用惯例优于配置的原则 。它要求在没有定制之前,所有的项目都有如下的结构:
|
目录 |
存放的文件&子目录 |
|
${basedir} |
存放pom.xml和所有的子目录 |
|
${basedir}/src/main/java |
项目的java源代码 |
|
${basedir}/src/main/resources |
项目的资源,比如说property文件 |
|
${basedir}src/main/webapp |
jsp文件和WEB-INF子目录,maven中约定是把该文件夹当成是普通web项目中的WebRoot目录,在其内尚没有WEB-INF/classes,WEB-INF/lib文件夹,需要手工建立。 |
|
${basedir}/src/test/java |
项目的测试类,比如说JUnit代码 |
|
${basedir}/src/test/resources |
测试使用的资源 |
6.5.2 新建项目
常见新建项目的方法:
- $ mvn archetype:generate,然后根据提示做出一些选择,即可在当前目录新建一个子目录并创建项目。archetype:generate 目标会列出1000多种 archetype 让选择。Archetype 可以理解成项目的模型。Maven提供了很多种的项目模型,包括从简单的 Swing 到复杂的 Web 应用。更详细的archetype可以参考: http://repo1.maven.org/maven2/archetype-catalog.xml。
令执行完后将看到maven生成了一个名为helloworld的目录,这个名字就是在命令中指定的artifactId。
- archetype:create,被标志过时了,已经被archetype:generate所取代。
- $ mvn genapp.在创建类型提示中输入回车或者web,分别创建Java项目和Web项目,其它的步骤按照提示输入即可。
注意: 新建项目时,当前目录应该为空,否则有可能导致失败。
新建项目后,可以通过运行mvn compiler:compile/mvn compile命令或 mvn package对项目进行编译和打包。当第一次运行时,将需要下载所有的插件和依赖包,编译完的类默认将会放到${basedir}/target/classes目录。
6.5.2.1 archetype
Archetype就是一堆预先设定好的项目结构文档, 有了这个东西,在新建同一类型的项目的时候,就不用又从头捣鼓一遍。常见的archetypeArtifactId有:
- maven-archetype-archetype, An archetype which contains a sample archetype.
- maven-archetype-simple, An archetype which contains a simple Maven project.
- maven-archetype-quickstart, 比较适合创建简单的Java项目
- maven-archetype-webapp,创建web项目
- maven-archetype-j2ee-simple, An archetype which contains a simplifed sample J2EE application.
- create-from-project, 需要自己先组织目录结构和pom文件,然后在运行创建命令
archetype:help,打印帮组信息。
更多archetype: http://maven.apache.org/guides/introduction/introduction-to-archetypes.html。
6.5.2.2 新建简单web项目
具体步骤:
- 新建一个web项目。只是比普通项目多加一个参数DarchetypeArtifactId ,命令如下:mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mygroup.test -DartifactId=mywebapps -Dversion=1.0。如果不指定后面的参数,则需要根据提示行进行输入。
- 运行mvn eclipse:eclipse命令构建eclipse所需要的项目文件。在构建的项目个中没有java目录,通过手动在src/main目录下创建一个名为java的子目录即可。
6.5.2.3 新建Android项目
https://github.com/destinyd/android-archetypes
6.5.3 编译项目
默认打包是生成jar的,如果我的项目还有main方法的,我想打包成可执行的jar包,为了生成可执行的jar文件,需要借助maven-shade-plugin,配置该插件如下:
Xml代码
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>1.2.1</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>shade</goal>
- </goals>
- <configuration>
- <transformers>
- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
- <mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>
- </transformer>
- </transformers>
- </configuration>
- </execution>
- </executions>
- </plugin>
默认打包生成jar是不能够直接运行的,因为带有main方法的类信息不会添加到manifest中(打开jar文件中的META-INF/MANIFEST.MF文件,将无法看到Main-Class一行)。
plugin元素在POM中的相对位置应该在<project><build><plugins>下面。我们配置了mainClass为com.juvenxu.mvnbook.helloworld.HelloWorld,项目在打包时会将该信息放到MANIFEST中。现在执行mvn clean install,待构建完成之后打开target/目录,可以看到hello-world-1.0-SNAPSHOT.jar和original-hello-world-1.0-SNAPSHOT.jar,前者是带有Main-Class信息的可执行jar,后者是原始的jar,打开hello-world-1.0-SNAPSHOT.jar的META-INF/MANIFEST.MF,可以看到它包含这样一行信息:
Main-Class:com.juvenxu.mvnbook.helloworld.HelloWorld
现在,在项目根目录中执行该jar文件:
D:\code\hello-world > java-jar target\hello-world-1.0-SNAPSHOT.jar,可以得到正确的输出了。
1:创建名为:helloword的maven项目
2:/helloword/src/main/java下建立package包hello,在包下建类SayHello
package hello;
public class SayHello {
public String sayhello() {
System.out.println("hello............is anybody here...");
return "dddddddddddddddddddddddddd";
}
public static void main(String[] arg) {
System.out.println(new SayHello().sayhello());
}
}
3:/helloword/src/test/java下建立test包,在test包下建HelloWordTest类
package test;
import hello.SayHello;
import junit.framework.Assert;
import junit.framework.TestCase;
public class HelloWordTest extends TestCase {
public HelloWordTest(String name) {
super(name);
}
protected void setUp() { //进行初始化的任务
}
/**
* @param args
*/
public void testSayHello()
{
SayHello s = new SayHello();
String r = s.sayhello();
Assert.assertEquals("dddddddddddddddddddddddddd", r);
}
}
4:pom.xml配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.houwen.test</groupId>
<artifactId>helloword</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Helloword</name>
<!--junit依赖是为tset准备,配置后,记得install,把依赖包嵌入resourse内,-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!--maven-shade-plugin
而要得到一个可以直接在命令行通过java命令运行的JAR文件,还要满足两个条件:
JAR包中的/META-INF/MANIFEST.MF元数据文件必须包含Main-Class信息。
Maven有好几个插件能帮助用户完成上述任务,不过用起来最方便的还是maven-shade-plugin,它可以让用户配置Main-Class的值,然后在打包的时候将值填入/META-INF/MANIFEST.MF文件。关于项目的依赖,它很聪明地将依赖JAR文件全部解压后,再将得到的.class文件连同当前项目的.class文件一起合并到最终的CLI包中,这样,在执行CLI JAR文件的时候,所有需要的类就都在Classpath中了。下面是一个配置样例:
-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>hello.SayHello</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
4.1上述例子中的,运行maven package后
我的Main-Class是hello.SayHello,构建完成后,对应于一个常规的helloword-0.0.1-SNAPSHOT.jar文件,我还得到了一个original-helloword-0.0.1-SNAPSHOT.jar文件。最后,我可以通过helloword-0.0.1-SNAPSHOT.jar命令运行程序。
4.2之后再运行maven install,把生成的jar打入到本地的maven仓库,可以在C:\Documents and Settings\hcen\.m2\repository\com\houwen\test\helloword\0.0.1-SNAPSHOT
找到helloword-0.0.1-SNAPSHOT.jar
5.最后,我可以通过java -jar (jar包路径)/helloword-0.0.1-SNAPSHOT.jar命令运行程序。
6.5.4 依赖包的管理
可以通过修改当前项目的pom.xml文件来实现所依赖的包的管理与下载。
6.5.4.1 配置项目的依赖包
如想将项目依赖的junit 从3.8.1换成4.7的,具体步骤如下:
- 打开当前项目的pom.xml文件,变更<dependency>字段中junit的版本号
|
…… <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> …… |
- 重新执行相应的maven命令
6.5.4.2 检索依赖包
可以Maven 中央仓库地址:http://search.maven.org查找更多包的版本信息。
假如想下载一个struts 的jar包。在搜索框内搜索struts ,会要列出中央仓库中的所有struts版本。列表的格式与pom.xml配置文件的格式是对应的。

另一个常用的仓库: http://mvnrepository.com/,该仓库不经可以检索,还给出了依赖该框架所需要增加的配置脚本,比如检索javax.websocket。

参考http://blog.csdn.net/shanling2004/article/details/6130904
6.5.4.2 提取依赖库
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>
maven-project-info-reports-plugin
</artifactId>
</plugin>
</plugins>
</reporting>
运行命令:
mvn project-info-reports:dependencies
依赖文件在目录:E:\work\preresearch\storm\me\storm-searchpicbypicsys\target\site 目录下
mvn dependency:tree
查找依赖数,可以找重复或冲突依赖的jar包在谁的pom里包含的。这个不需要包含上面的report插件。
6.5.5 多项目管理
Maven自动支持多项目管理,只要在项目文件夹下增加子栏目,子栏目下的工程自动会成为子项目.需要在子项目中指明项目的类型。在project.properties文件中:
- 分别创建相关子项目
- 创建父项目,然后再将相关的子项目拷贝到父项目目录下。
- 修改父项目的pom.xml文件,在<modules>模块中增加相关子模块。
|
<modules> <!-- Guacamole web application --> <module>guacamole</module> <!-- Guacamole Java API --> <module>guacamole-common</module> </modules> |
6.6 问题&解决办法
6.6.1 不可识别utf-8编码
Maven编译时出现不可识别的不可识别utf-8编码。
错误原因: 不同系统采用了不同的编码格式
解决办法: 使用notepad++打开报错的文件,然后 格式 -> 以ANSI格式编码
6.7 Maven和Eclipse的结合
1.1.1 Eclipse基本
1.1.1.1 配置jre和jdk的版本一致
其中jre是运行是java的执行环境,而jdk是编译时java的执行环境。两者的版本需要一致,用命令行形式执行,不会有问题,但如果用eclipse就要保证这两者版本号的一致。
保障方法如下:
- 保障JDK的版本正确。Eclipse可以每个工程使用不同的jre和jdk(有些jdk是eclipse自身就带的,比如考虑兼容,需要老版本的jdk).这时可以走工程的buildpath路径进入,来设置每个工程的编译环境。
第一步:myproject->buildpath->Configure BuildPath

第二步: Librarier->Add Library

第三步:JRE System Library (配置JAVA的系统库)

第四步:Workspace default JRE,看默认的是否我们安装的JRE版本,如果不是的话,可以选择Installed JRES,进行安装需要版本的JRE到eclipse里来。如第五步所示:

第五步:安装JRE到eclipse,一般各版本的jre会安装在C:\Program Files\Java\ 目录下。选择该目录,然后就有备选的几个jre版本可供选择。


1.1.2 Eclipse里maven的配置
Eclipse->windows->Preferences->Maven->User Setings

1) 选择MAVEN的配置文件全路径; xxx\\apache-maven-3.2.5-bin\apache-maven-3.2.5\conf\settings.xml
2) 选择MAVEN的local repository路径,该路径在上面的配置配置文件里有配置.
1.1.3 mvn编译出eclipse的工程文件
mvn eclipse:clean
mvn eclipse:eclipse
1.1.4 导入mvn工程


6.8 参考文献
6.8.1 入门
官方资料:
http://maven.apache.org/guides/getting-started/index.html
http://maven.apache.org/guides/index.html
http://maven.apache.org/guides/mini/guide-creating-archetypes.html
Apache Maven 入门篇 ( 上 下)
http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-1-406235-zhs.html
http://www.oracle.com/technetwork/cn/community/java/apache-maven-getting-started-2-405568-zhs.html
Apache Maven 2 简介
http://www.ibm.com/developerworks/cn/education/java/j-mavenv2/j-mavenv2.html
Maven入门--概念与实例
http://www.blogjava.net/jiangshachina/archive/2006/09/01/67080.html
6.8.2 环境搭建
maven中设置代理服务器
http://blog.csdn.net/ivanmarkliu/article/details/4585336
settings.xml中重要字段的说明
http://www.360doc.com/content/07/0302/14/7147_381623.shtml
7 参考文献
[1] HTML5 differences from HTML4,
URL: http://www.w3.org/TR/html5-diff/
附录
1 附录第一章
7.1 二级标题Asd a
7.1.1 三级标题Asd asd
7.1.1.1 四级标题Asdf as
2 JNI篇
- 设置eclipse的JNI环境
![]()
- Location: C:\Program Files\Java\jdk1.6.0_25\bin\javah.exe
- Working Directory: ${project_loc}
- Arguments: -v -classpath "${project_loc}/bin/classes" -d "${project_loc}/jni" -jni ${java_type_name}
上述黄色部分是默认的待导出h文件的类文件所在的目录,${java_type_name}
在实际项目中要修改为合适的目录,运行该工具时,请确保光标在需要生成头文件的java源文件中


浙公网安备 33010602011771号