Jetty Maven plugin(插件)对于快速开发和测试是很有用的。你可以把它加到任何的通过常规的
Maven默认来构建的
webapp项目中。这个插件可以定周期地扫描你的项目为了检测变化,然后自动重新部署任何被找到的
webapp项目。
通过消除建立和部署步骤使得开发周期更加富有成效的:通过使用IDE来使你的项目改变,然后正在运行的
web container(容器)能自动地检测到它们的变化,并允许你马上测试它们。
提示1:这里的所提到内容涉及到的插件版本是
Jetty 7
及其以上。如果您使用的是
Jetty 6
版本,请在
codehaus
查考
Jetty 6 Maven Plugin guide 。
以前的版本叫做maven-jetty-plugin,现在插件名叫做jetty-maven-plugin。
提示2:jetty-7.5.3以后的版本,需要配套使用maven 3版本。
特征
快速启动:配置和运行
首先,将jetty-maven-plugin加到你(项目)的pom.xml文件定义中:
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId></plugin>
提示:设置groupId:
Maven 默认查找插件根据
org.apache.maven.plugins的groupId,即使groupId声明跟以上的都不一样。为了指出Maven所要查找在groupId定义的插件,可以通过在
settings.xml
设置插件的group,如下所示:
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <pluginGroups> <pluginGroup>org.eclipse.jetty</pluginGroup> </pluginGroups> </settings>
然后,在与pom.xml同一个根目录下,简单地输入
(如在终端中)
:
mvn jetty:run
启动Jetty并发布项目服务在http://localhost:8080。
Jetty 将持续运行直到你去停止它。在运行的时候,它会定周期的去扫描你的项目文件的变化,所以如果你保存了修改并重新编译的类文件,Jetty 会重新部署你的webapp项目,然后你就可以立即测试你刚才所做的修改了。
停止运行插件
你可以
在终端窗口中用<ctrl - c>命令来
终止(正在运行的)插件。
运行和部署
jetty-maven-plugin 有若干不同的Maven goals。每一个goal就是一个可以可以运行来完成特定任务的动作,或者是伴随着一个特别安装好web应用程序一起工作。你可能需要插入特定的goal配置来有目的的去运行它。
为了用一个特定的goal来运行jetty-maven-plugin,使用如下命令:
mvn jetty:goalname
这里的
配置元素
对于所有的
goals都
是通用的。
配置Jetty容器
这些配置元素安装你的webapp项目执行所在的Jetty环境
。
- <connectors>(可选的)一系列的org.eclipse.jetty.server.Connector对象,它是Jetty的端口监听器。如果你没有明确指出任何一个端口监听器,一个NIO(无阻塞)org.eclipse.jetty.server.nio.SelectChannelConnector将配置在8080端口中。你可以在命令行中用系统属性jetty.port改变默认端口值,比如,mvn -Djetty.port=9999 jetty:run。另一种选择是,你可以详细指定你所想要的和连接器(jetty connector)一样多的端口。你能够在一个标准的 [jetty xml config] 文件来替换配置连接器(connectors),并且把它的位置放到<jettyXml>的参数中。
- <jettyXml>(可选的)一个被应用到除了任意插件配置参数外的jetty.xml文件的位置。如果你有别的webapp,handler等需要部署,或者别的不能从插件中配置的Jetty对象,你可能会用到它。
- <scanIntervalSeconds>(可选的)如果检测到任何活动在扫描webapp项目来检测变化和如任何变化被检测到自动热部署之间的暂停时间(秒为单位)。默认的值是0,它代表的意思是不启用热部署扫描。大于0的值才是有效的。
- <systemProperties>(可选的)允许你配置为插件执行的系统属性。更多信息,查看Setting System Properties.
- <systemPropertiesFile>(可选的)一个包含系统属性的文件。设置系统属性的目的是为设置插件的执行。此处你要确保不让覆盖任何的已经在命令行中,通过JVM(java 虚拟机),或者通过POM文件中的系统属性(systemProperities)设置的系统属性。自Jetty6.1.15rc4以后版本可用。
- <loginServices>(可选的)一系列的org.eclipse.jetty.security.LoginService的实现。注意这是没有默认的实现。如果你想在你的web.xml中使用一个实现,你可以明确指定一个匹配的实现。你能够代替在jettry.xml文件中的登录服务(login services)的配置,并且添加到它在<jettyXml>参数的位置中。
- <requestLog>(可选的)一个org.eclipse.jetty.server.RequestLog的实现,它要求实现log接口。一个遵照NCSA 格式的实现是可行的,如org.eclipse.jetty.server.NCSARequestLog。这里有三种其它方式来配置RequestLog:
-
- 在一个jetty xml配置文件(在 <jettyXml> 参数中明确指定)。
- 在 context xml config file ( 在<contextXml> 参数中明确指定)。
- 在 <webApp> 元素中 Configuring Request Logs tutorial 。
配置你的WebApp项目
以下这些配置参数都可以应用到你的webapp项目中。除了run-forked和stop指令外,它们应该可以应用到所有的goals当中:
- <webApp>代表一个 org.eclipse.jetty.webapp.WebAppContext类的扩展。在这个对象中,任何的setter方法都可以用于配置你的webapp项目。以下是一小部分最有用的:
-
- <contextPath> 作为你的webapp项目的上下文相关路径。默认被设置在项目的pom.xml文件的/${project.artifactId}中。
- <descriptor> 作为你的webapp项目的web.xml文件的路径。
- <defaultsDescriptor> webdefault.xml文件的路径。这个webdefault.xml文件在web.xml文件之前被应用到你的webapp项目中的。如果没有提供,Jetty 默认使用一个已经拷贝在jetty-webapp.jar内部的文件。
- <overrideDescriptor> web.xml文件的路径。这个web.xml在你的web.xml被读取后才被应用的。你可以用这个来替换或者添加配置。
- <tempDirectory> 一个临时目录路径。当你的webapp项目正在运行时候,Jetty可以在这个目录中扩展或者拷贝jars和编译jsp。默认是值${project.build.outputDirectory}/tmp。
- <baseResource> 来自Jetty为静态资源服务的路径。默认是src/main/webapp。
- <resourceBases> 如果你有多个你想为静态内容服务的目录,用<baseResource>来代替 。这是一个批目录名。
- <baseAppFirst>(可选的)默认是true。它控制是否任何被覆盖wars文件添加在webapp项目的原始的基本资源之前或者之后。
- <jettyEnvXml>(可选的)一个jetty-env.xml文件的位置。它允许你使得JDNI绑定能满足<env-entry>,<resource-env-ref>和<resource-ref>在web.xml中的链接。注意如果你想让它们应用到多于一个webapp中,这些也可以在<jettyXml>文件中产生。
- <containerIncludeJarPattern> (jetty-8.1.6以后版本,可选的) 一个与在容器路径jars的url竞争的模式,为了选择这些应该被测试的,如像META-INF片段,资源,tid和类的继承层次的东西 (以 servlet container initializers 方式)。
- <webInfIncludeJarPattern>(jetty-8.1.6以后版本,可选的)一个与被当做在webapp的WEB-INF类路径的jar包的路径竞争的模式,一个与在容器路径jars的url竞争的模式,为了选择这些应该被测试的,如像META-INF片段,资源,tid和类的继承层次的东西 (以 servlet container initializers 方式)。默认是为了可能测试它们所有的资源,服从于任何在web.xml文件中已配置的命令排除。
- <contextXml>(可选的)一个上下文相关的xml文件路径,它处在<webApp>元素后的,被应用到你的webapp项目的中。
jetty:run 运行一个未装配的webapp项目
run goal运行在一个没有构建到WAR包的webapp项目中。相反地,Jetty 部署这个webapp项目从它组成的源码。
尽管你可以覆盖在插件中的这些配置,
它还是在maven默认项目位置中去查找webapp的
组成
部分。例如,默认查找如下:
- resources in ${basedir}/src/main/webapp
- classes in ${project.build.outputDirectory}
- web.xml in ${basedir}/src/main/webapp/WEB-INF/
这个插件在部署之前自动地确认这些被重新构建和更新类。如果你改变一个类的源码,并且你的IDE自动地在后台编译它,(jetty-maven)插件就能检测到被改变的类。
webapp项目不需要装配到一个WAR包中,为的是在开发周期中节省时间。一旦它被调用,你可以配置插件不间断的运行,一直扫描项目中的变化,然后在必要的时候自动地执行一个热重新部署。任何通过你来产生的变化将立即被反射在Jetty运行的实例中,让你快速的从编码阶段跳转到测试阶段,而不是按照编码,编译,装配,重新部署,测试这样的周期进行。
以下是一个开启每10秒钟扫描变化和设置webapp上下文相关的/test路径的小例子:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/test</contextPath>
</webApp>
</configuration></plugin>
配置附加参数
除了
<webapp>
元素
对
大多数goals是共同的
外,jetty:run目标还支持:
- <classesDirectory> 为webapp项目已经编译的类的位置。你应该很少需要去设置这个参数。相反,你应该去设置在你的项目的pom.xml文件中的<build><outputDirectory>参数。
- <testClassesDirectory> 为你的webapp项目已经编译好的测试类的位置。默认的值是${project.build.testOutputDirectory}。
- <useTestScope> 默认值为false。如果为true,则这些来自<testClassesDirectory>目录中的类和test作用域的依赖关系将被首先放在类路径中。
- <userProvidedScope>如果为true,这些provided作用域的依赖关系被放到容器的类路径中。注意:不是webapp项目类路径,因为provided指明这些依赖关系可能正常地被认为是通过容器来提供的。而且你应该非常少的需要使用它,相反你应该拷贝provided依赖关系作为<plugin>的明确的依赖关系来替代。
- <webAppSourceDirectory> 默认的被设置成${basedir}/src/main/webapp。如果你的静态源码在不同的位置,可根据需要来设置这个参数。
- <scanTargets>(可选的)一系列除了那些自动被插件地扫描外,周期性地扫描的文件和目录。
- <scanTargePatternts>(可选的)如果你有一长列的额外想要扫描的文件,可以很便利的通过使用模式匹配表达式(pattern matching expressions)来明确指出它们,而不是通过<scanTargets>枚举。一系列的<scanTargetPattern>,每一个组成一个<directory>(目录),<including>或者<excluding>参数来明确指出文件的匹配模式。
- <skip>(可选的)默认值是false。如果为true,插件的执行将退出。等同于在命令行中通过系统属性(SystemProperty)-Djetty.skip来设置。
以下是一个例子:
<project> ... <plugins> ... <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${basedir}/src/staticfiles</webAppSourceDirectory> <webAppConfig> <contextPath>/</contextPath> <descriptor>${basedir}/src/over/here/web.xml</descriptor> <jettyEnvXml>${basedir}/src/over/here/jetty-env.xml</jettyEnvXml> </webAppConfig> <classesDirectory>${basedir}/somewhere/else</classesDirectory> <scanTargets> <scanTarget>src/mydir</scanTarget> <scanTarget>src/myfile.txt</scanTarget> </scanTargets> <scanTargetPatterns> <scanTargetPattern> <directory>src/other-resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <excludes> <exclude>**/myspecial.xml</exclude> <exclude>**/myspecial.properties</exclude> </excludes> </scanTargetPattern> </scanTargetPatterns> </configuration> </plugin> </plugins></project>
无论什么原因,如果你不能运行一个没有装配的webapp项目,通过run-war和run-exploded goal都是可以运行未装配的webapp项目。
jetty:run-war 把一个装配好的webapp看做一个war包来运行
这个goal(
jetty:run-war
)首先把你的webapp项目成一个WAR文件,然后把它部署到Jetty中。如果你在scanInterval参数中设置了一个非0的值,Jetty就能监视项目的pom.xml文件和WAR文件;如果其中任意一个有变化,它都会重新部署
war包。
配置war参数
<war> 构建WAR文件的位置。默认值设为
${project.build.directory}/${project.build.finalName}.war
。如果没有满足要求,你可以设置成你的自己定制的位置。
下面是一个如何设置的例子:
<project> ... <plugins> ... <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <war>${basedir}/target/mycustom.war</war> </configuration> </plugin> </plugins></project>
jetty:run-exploded 把一个装配好的webapp项目当做一个扩展的WAR包来运行
run-exploded goal 首先装配你的webapp项目到一个被分解的WAR文件中,然后部署到Jetty。如果你给scanInterval
设置一个
非0的值,Jetty监视你的pom.xml,WEB-INF/lib,WEB-IN/classes 和WEB-INF/web.xml文件的变化并且在必要的时候重新部署它。
配置被分解的war参数
<war> 被分解的WAR包位置。这个默认值是
${project.build.directory}/${project.build.finalName},但是你可以通过设置这个参数来覆盖这个默认值。
下面是如何设置的一个例子:
<project> ... <plugins> ... <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <war>${basedir}/target/myfunkywebapp</war> </configuration> </plugin> </plugins></project>
jetty:deploy-war 运行一个预装备的war
除了没有装配当前的模块的war外,这个跟jetty:run-war基本是相同的。不同于run-war,处在插件执行阶段是不被绑定到“package”(包装)阶段。
例如,你可能想在测试编译(test-compile)阶段
启动Jetty
,然后在测试(
test
)阶段
停止Jetty
。以下的配置就是来说明这个的:
<project> ... <plugins> ... <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <war>${basedir}/target/mycustom.war</war> </configuration> <executions> <execution> <id>start-jetty</id> <phase>test-compile</phase> <goals> <goal>deploy-war</goal> </goals> <configuration> <daemon>true</daemon> <reload>manual</reload> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> </plugins></project>
jetty:run-forked 在一个独立的jvm(java虚拟机)中运行一个未装配的webapp项目
这是一个新的goal,它出现在
jetty-7.5.2
以后的版本中
。你可以强迫Jetty在一个新的jvm中启动webapp项目,任意地传递参数到jvm中。和其它的goals不一样的是,这个没有共享所有的相同的配置参数(虽然很多是相同的,也是为了你能够基于相同的配置使用大量的goals)。这些配置选项是:
- <jettyXml> 用于在一个新的jvm中配置容器的jettyxml配置文件的位置。
- <contextXml>(可选的)在一个新的jvm中配置webapp项目的上下文相关的xml文件的位置。
- <contextPath> (可选的)在一个新的jvm中的webapp项目的上下文路径。默认是/${project.artifactId}。这个属性将覆盖一个设置在<contextXml>文件中的值 。
- <webAppSourceDirectory> (可选的)你webapp项目中的静态资源的位置。默认值是src/main/webapp。这个属性将覆盖一个设置<contextXml> 文件中的值(<Set name="baseResource">)。
- <resourceDirs> (可选的,在 jetty-7.6.5以后新增的)。 一个文件夹数组,它包含构成你的webapp项目基本资源的静态内容,用<webAppSourceDirectory>来联结。 参见 <baseAppFirst>。
- <baseAppFirst>(可选的,在 jetty-7.6.5以后新增的)。默认值是true。控制着是否 <webAppSourceDirectory> 或者 <resourceDirs> 是在一列构成webapp项目的基本资源中的第一个。
- <webXml>(可选的)web.xml文件的位置。默认位置是src/main/webapp/WEB-INF/web.xml。这个属性将覆盖在<contextXml>文件中的值(<Set name="descriptor">)。
- <tmpDirectory>(可选的)临时工作目录的位置。 默认位置是target/tmp。 这个属性将覆盖在<contextXml>文件中的值(<Set name="tempDirectory"> )。
- <classesDirectory>(可选的)webapp项目编译好的类文件位置。默认位置是${project.build.outputDirectory}。
- <testClassesDirectory>(可选的)webapp项目编译好的测试类文件位置。默认位置是 ${project.build.testOutputDirectory}。
- <useTestScope>(可选的) 默认值是false。如果是true,测试类和test范围的依赖关系将放到webapp项目的类路径上。
- <useProvidedScope>(可选的)默认值是 false。如果是true,provided范围的依赖关系将被放到在Jetty容器的类路径中。
- <stopPort> (强制的) 一个端口值,它是为Jetty用来监听接收停止命令来引起它关闭。如果配置后,stopKey被用于来鉴定一个引入的停止命令。
- <stopKey> (强制的)一个字符串值,它必须发送到stopPort为了鉴定停止命令是否合法。
- <skip> (可选的) 默认值是 false。如果是true 就跳过这个(Jetty)插件的执行命令。
- <jvmArgs> (可选的)一个字符,它代表着任意的参数来传递给被分叉的jvm。
- <waitForChild> (可选的,在 jetty-7.6.5版本中新增的)默认值是true。如果为true, 父节点等待Jetty完成正在执行的命令。如果为false,父节点独自完成操作后,让Jetty执行命令的进程运行,在这种情况需要用mvn jetty:stop命令去杀死进程。
为部署您的未装配的webapp到正在一个新的jvm运行的Jetty中:
mvn jetty:run-forked
用<waitForChild>true</waitForChild>:
这个Jetty插件一直保持运行直到:你在终端中输入<ctrl-c>来停止插件,这样也会停止了分叉的jvm,抑或你使用mvn jetty:stop来停止被分叉jvm,这样也会停止了插件。
用<waitForChild>false</waitForChild>:
这个插件将分叉子节点的进程,然后退出。
注意:如果你想要设置一个自定义端口,你需要在jetty.xml中明确指出它,而非去设置
<connector><port></port></connector>
标签。这个jetty.xml文件的位置可以用jettyXml参数明确指定。
jetty:start 启动jetty不用首先执行构建到“test-compile”阶段:
这个指令是在jetty-7.6.0后新增的。它是设计用于一个指令绑定在你的pom.xml文件中。这个类似于jetty:run goal,不过不同的是,它不是首先执行构建到一
直等到test-compile阶段后,目的是为了确保所有的webapp项目中必要的类和文件已经生成
。
这是非常
有用的当你想通过在pom.xml中指令绑定控制Jetty的启停。
比如,
可以配置这个插件来
在你的单元测试开始时候
启动你的webapp项目,然后结束的时候停止。为了做这个,你需要按照一对<execution>脚本配置为这个Jetty插件,然后当Maven运行的时候,用
<daemon>true</daemon>
配置选项来迫使Jetty执行,代替不确定性地运行。你用
pre-integration-test
和
post-integration-test
指令,Maven构建阶段来触发指令和
Jetty的
终端:
<plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <scanIntervalSeconds>10</scanIntervalSeconds> <stopKey>foo</stopKey> <stopPort>9999</stopPort> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> <configuration> <scanIntervalSeconds>0</scanIntervalSeconds> <daemon>true</daemon> </configuration> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions></plugin>
当然,你可以用这个goal从命令行(mvn jetty:start),尽管如此,你首先需要确定所有的你webapp项目的生成类和文件已经存在。
更多...