jetty7模块依赖关系

原创文章,转载请注明出处!



 1.介绍

Jetty7与以前版本相比,包的组织结构有较大的变化——从原有的jetty.jar, jetty-util.jar到现在的十五个Jar文件。一下子多出这么多包,可能会让人手忙脚乱了,好在内容并没有增加特别多。而且,这也不完全是坏事。归功于Maven,jetty7的组织结构显得特别清楚,有利于学习过程中理解jetty的组织架构。当然,前提是你理清这些jar文件之间的依赖关系!

1.1.Maven依赖关系

上文已经提到过,etty7是采用Maven构建的,那么在我们就可以通过使用Maven的相关插件来Show出包之间的依赖关系了——maven dependency:tree或许就是个不错的工具。例如,要找出jetty-servlet模块依赖了哪些其它的模块:

# mvn -f jetty-servlet/pom.xml dependency:tree
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'dependency'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Jetty :: Servlet Handling
[INFO]    task-segment: [dependency:tree]
[INFO] ------------------------------------------------------------------------
[INFO] [dependency:tree]
[INFO] org.eclipse.jetty:jetty-servlet:jar:7.0.0.RC2-SNAPSHOT
[INFO] +- junit:junit:jar:3.8.2:test
[INFO] \- org.eclipse.jetty:jetty-security:jar:7.0.0.RC2-SNAPSHOT:compile
[INFO]    \- org.eclipse.jetty:jetty-server:jar:7.0.0.RC2-SNAPSHOT:compile
[INFO]       +- javax.servlet:servlet-api:jar:2.5:compile
[INFO]       +- org.eclipse.jetty:jetty-continuation:jar:7.0.0.RC2-SNAPSHOT:compile
[INFO]       \- org.eclipse.jetty:jetty-http:jar:7.0.0.RC2-SNAPSHOT:compile
[INFO]          \- org.eclipse.jetty:jetty-io:jar:7.0.0.RC2-SNAPSHOT:compile
[INFO]             \- org.eclipse.jetty:jetty-util:jar:7.0.0.RC2-SNAPSHOT:compile                                   
 
 

1.2依赖类型

jetty7使用了三种Maven依赖类型,如下:

compile 这是一种"硬依赖"关系!如果你想重新编译Jetty或者要运行Jetty,那么就必需满足这个依赖关系。在上例中,jetty-servlet对jetty-security有这种硬依赖关系,对于jetty-server, jetty-http, jetty-io等,则是一种"间接性硬依赖"关系。
provided 该类型的依赖又可以细分为两种情况:
1.可选依赖:要求在编译模块时,满足这种依赖依赖关系,但在运行环境(run-time)中,不强制要求满足。比如,jetty-util依赖于slf4j-api,如果要编译jetty-util,则一定要将slf4j置于classpath中。但在使用jetty-util组件时,slf4j则为可选的。
2.环境性依赖:也是一种运行时依赖关系,但比较微妙。举例说明吧:test-jetty-webapp依赖于servlet-api,只有servlet-api存在时,才能够通过编译。但是打包test-jetty-webapp时,并不需要将servlet-api.jar置于WEB-INF/lib目录中。这是因为test-jetty-webapp将被部署于servlet容器中,而servlet容器又依赖于servlet-api,也就是说,在容器成功启动后,就表示servlet-api被成功引入。那么在启动webapp应用时,依赖于servlet-api的应用也会正常启动——test-jetty-webapp在"Servlet容器环境"下运行时,就不需要提供servlet-api了。这也就是所谓的环境依赖吧!
test 单元测试时依赖的包

2.树型依赖关系

上图是Jetty7编译时依赖关系结构图,最右边的一列是外部依赖,其余的则是内部依赖关系。图中的各个模块是以jar组织的,而不同的Jar包又可以划分为逻辑组。逻辑组可以便于理解Jetty模块之间的关系,如下:

2.1HTTP

HTTP组表示了Jetty的核心模块,由jetty-util, jetty-io, jetty-http三个jar包组成,同时为jetty-client和jetty-server使用。

2.2Server

同上面的HTTP组一起,再加上jetty-server, jetty-continuation和servlet-api,就可以组成一个运行HTTP服务器所需要的最小依赖集合。在这种情况下,servlet-api所扮演的角色就与我们平常所理解的有所不同。在这里,你可以把它当成Jetty提供的,用于供开发人员扩展的处理器API。在HTTP服务器模式下运行的Jetty不提供Servlet容器功能!

2.3Servlet和WEB应用

在Servler组(见2.2)的基础上,再增加jetty-security和jetty-servlet就可以组成一个Servlet容器。这时我们能够编写Servlet、Filter等扩展功能,但这还不足以满足Servlet规范。我们不能够像一般的Java WEB应用那样,通过web.xml来配置servlet、filter等,只能使用硬编码的方式来配置。加入jetty-xml和jetty-webapp后,就形成了一个我们所熟知的Servlet容器了。如果再加上jetty-deploy,那么部署采用WAR形式打包的应用就更加方便了!

2.4扩展(Plus)

在以上功能特性的基础上,添加jetty-jndi, jetty-plus, jetty-annotation模块,可以使Jetty具有更多"类J2EE"的功能。这些模块就统称为扩展模块(jetty Plus)了。

3.外部依赖

按上图所示依赖关系来看,如果不需要提供jsp, annotations, plus, jndi这些功能的话,那么编译jetty时,唯一需要的外部依赖包就是servlet-api——也就是说,运行一个没有jsp的标准WEB应用时,jetty唯一需要的外部包就是servlet-api.jar。

当然,Jetty还有一些可选运行时依赖包,如jetty-util包中提供的日志记录服务会在类路径中搜索slf4j,如果找到了,就会使用slf4j来记录日志,否则就使用stderr来记录日志。

4.start.jar

start.jar是一个通用的启动程序(我会在其它的文章中详细解说start.jar的应用),它并不仅限于jetty的使用,它也不是jetty组成部分。start.jar中包含jetty启动时的配置文件start.config,这个文件是不能够被修改的,但是在运行start.jar时,可以在命令行指定自己的config配置文件。

start.jar通过使用start.config中的配置选项来定义一些需要启动jar,jetty运行时使用的默认配置能够支持WEB应用,但不支持jsp特性。以下命令可以让Jetty在默认配置情况下运行:

java –jar start.jar etc/myjetty.xml

如果要在默认配置的基础上增加jsp,jmx等特性,则需要在命令行指定:

java –jar start.jar OPTIONS=Server,jsp,jmx

通常,在命令行的OPTIONS参数值中,以大写开头的值表示一组jetty模块,以小写开头的值则表示对特写模块的引用。如上文中的jsp就表示对jetty-jsp及其依赖模块的引用,jmx则表示对jetty-jmx的引用。

以下命令能够显示可用的启动参数选项:

java –jar start.jar –help

如果要查看OPTIONS参数中的可选值,则用:

java –jar start.jar –list-options

作为OPTIONS参数的扩展,还可以通过使用"lib"(指向一个包含jar文件目录),"path"来指定其它的类路径,如:

java –jar start.jar lib=/usr/share/java path=$HOME/src/myproject/classes

5.类路径执行环境

在使用start.jar启动jetty时,start.jar并不依赖于其它的jar文件去运行。用户可以通过编写一个简单的shell脚本或bat脚本即可。start.jar会根据用户提供的配置文件(在jetty7中,有两个配置文件start.ini,start.config.其中,start.ini是比较常用的,start.config比较复杂,而且被封装在start.jar包中)来组织jetty启动时所需要的类路径,解决Jetty模块之间的依赖等。通过使用–exec-print 选项,可以打印出启动jetty时具体执行的命令。如,执行以下命令:

cd /usr/local/jetty-7
java -jar start.jar OPTIONS=server path=/usr/share/java/junit4.jar --dry-run

会在命令行产生以下内容:

/usr/lib/jvm/java-1.5.0-sun-1.5.0.19/jre/bin/java \
-cp /usr/share/java/junit4-4.3.1.jar:\
/usr/local/jetty-7/lib/servlet-api-2.5.jar:\
/usr/local/jetty-7/lib/jetty-http-7.0.0.RC2-SNAPSHOT.jar:\
/usr/local/jetty-7/lib/jetty-continuation-7.0.0.RC2-SNAPSHOT.jar:\
/usr/local/jetty-7/lib/jetty-server-7.0.0.RC2-SNAPSHOT.jar:\
/usr/local/jetty-7/lib/jetty-util-7.0.0.RC2-SNAPSHOT.jar:\
/usr/local/jetty-7/lib/jetty-io-7.0.0.RC2-SNAPSHOT.jar \
-Djetty.home=/usr/local/jetty-7 \
org.eclipse.jetty.xml.XmlConfiguration \
/usr/local/jetty-7/etc/jetty.xml
 
 

大家可以仔细看一下产生的结果,其实就是我们运行一般jar应用时的命令行参数,但是start.jar通过配置文件,将这些都处理好了。

6.聚合jar包

当把jetty作为工具包来开发应用时,太多的依赖包可能会让你觉得头痛,特别是当依赖包不全的时候,也是比较烦人的事儿。好在jetty的外部依赖非常少!更好的是,jetty的编译文件还提供了些可以的编译配置,允许用户根据自己的需求,将Jetty模块编译的一个jar文件中去。可用的编译选项有:

  • jetty-all
  • jetty-all-server
  • jetty-client
  • jetty-plus
  • jetty-server
  • jetty-servlet
  • jetty-webapp

参考文章: http://wiki.eclipse.org/Jetty/Reference/Dependencies