该插件在任何给定的Gradle build中为嵌入式的Tomcat Web容器提供了Web应用程序的部署功能。它扩展了战争插件。目前支持Tomcat版本6.0.x,7.0.x,8.0.x,8.5.x和9.0.x。
该插件的典型用例是在开发过程中支持部署。由于容器的快速启动时间,该插件允许快速的Web应用程序开发。 Gradle在同一JVM中启动嵌入式容器。当前,容器不能作为单独的过程分配。该插件也无法将战争文件部署到远程容器。如果您正在寻找此功能,请改用货物插件。
要使用插件的功能,您将需要将其二进制文物添加到构建脚本的classpath中并应用插件。
插件罐需要在构建脚本的类路径中定义。它直接在Gradle插件门户网站上可用。以下代码片段显示了如何检索它的示例:
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath ' com.bmuschko:gradle-tomcat-plugin:2.7.0 '
}
}JAR文件带有两个插件:
| 插件标识符 | 取决于 | 类型 | 描述 |
|---|---|---|---|
| com.bmuschko.tomcat-bas | - | tomcatbaseplugin | 提供TOMCAT自定义任务类型,预配置类Path。 |
| com.bmuschko.tomcat | com.bmuschko.tomcat-bas | tomcatplugin | 提供了启动和停止嵌入式tomcat容器的任务,并揭示名为tomcat的扩展。 |
com.bmuschko.tomcat插件可帮助您快速启动。如果您还可以,如果预先配置的任务,这是可取的选项。大多数插件用户都会使用此选项。要使用tomcat插件,请在构建脚本中包含以下代码段:
apply plugin: 'com.bmuschko.tomcat'
如果您需要对任务的完全控制或不想执行预配置的任务,则需要使用com.bmuschko.tomcat-base插件。如果您仅设置仅用于功能测试的容器,则可能是这种情况。缺点是,每个任务都必须在构建脚本中单独配置。要使用Tomcat基本插件,请在构建脚本中包含以下代码段:
apply plugin: 'com.bmuschko.tomcat-base'
此外,需要将tomcat运行时库添加到tomcat配置中。目前,该插件支持Tomcat版本6.0.x,7.0.x,8.0.x,8.5.x和9.0.x。确保您不会混合不同版本的Tomcat库。
tomcat 6.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 6.0.51 '
tomcat " org.apache.tomcat:catalina: ${ tomcatVersion } " ,
" org.apache.tomcat:coyote: ${ tomcatVersion } " ,
" org.apache.tomcat:jasper: ${ tomcatVersion } "
}tomcat 7.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 7.0.76 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}tomcat 8.0.x:
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 8.0.42 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}Tomcat 8.5.x:
请注意,仅需要通过log4j 1.x启用容器记录的依赖性tomcat-embed-logging-juli (log4j社区不再支持)。 log4j 2.x可用于容器记录,而无需声明任何额外的库。
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 8.5.16 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.2 " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}
tomcat {
httpProtocol = ' org.apache.coyote.http11.Http11Nio2Protocol '
ajpProtocol = ' org.apache.coyote.ajp.AjpNio2Protocol '
}Tomcat 9.0.x:
请注意,仅需要通过log4j 1.x启用容器记录的依赖性tomcat-embed-logging-juli (log4j社区不再支持)。 log4j 2.x可用于容器记录,而无需声明任何额外的库。
repositories {
mavenCentral()
}
dependencies {
def tomcatVersion = ' 9.0.1 '
tomcat " org.apache.tomcat.embed:tomcat-embed-core: ${ tomcatVersion } " ,
" org.apache.tomcat.embed:tomcat-embed-logging-juli:9.0.0.M6 " ,
" org.apache.tomcat.embed:tomcat-embed-jasper: ${ tomcatVersion } "
}
tomcat {
httpProtocol = ' org.apache.coyote.http11.Http11Nio2Protocol '
ajpProtocol = ' org.apache.coyote.ajp.AjpNio2Protocol '
}com.bmuschko.tomcat插件预先定义以下任务:
| 任务名称 | 取决于 | 类型 | 描述 |
|---|---|---|---|
| Tomcatrun | - | Tomcatrun | 启动一个tomcat实例,并将爆炸的Web应用程序部署到它。 |
| Tomcatrunwar | - | Tomcatrunwar | 启动一个tomcat实例并将战争部署到它。 |
| tomcatstop | - | tomcatstop | 停止tomcat实例。 |
| tomcatjasper | - | tomcatjasper | 运行JSP编译器,并使用Jasper将JSP页面变成Java源。 |
Tomcat插件使用与战争插件相同的布局。
Tomcat插件通过名为tomcat的扩展名揭示了以下属性:
httpPort :TOMCAT应该收听HTTP请求的TCP端口(默认为8080 )。httpsPort :TOMCAT应该收听HTTPS请求的TCP端口(默认为8443 )。ajpPort :TOMCAT应该在上听AJP请求的TCP端口(默认为8009 )。stopPort :TOMCAT应该在上收听管理员请求的TCP端口(默认为8081 )。stopKey :要求停止时传递给Tomcat的钥匙(默认为null )。contextPath :将注册Web应用程序的URL上下文路径(默认为WAR名称)。enableSSL :确定是否应创建HTTPS连接器(默认为false )。daemon :指定tomcat服务器是否应在后台运行。如果是THUM,则此任务在服务器启动后立即完成。当false时,此任务会阻止直到停止Tomcat服务器(默认为false )。keystoreFile :用于SSL的密钥库文件,如果启用了(默认情况下,将生成一个密钥库)。httpProtocol :要使用的HTTP协议处理程序类名称(默认为org.apache.coyote.http11.Http11Protocol )。httpsProtocol :要使用的HTTPS协议处理程序类名称(默认为org.apache.coyote.http11.Http11Protocol -protocol)。ajpProtocol :要使用的AJP协议处理程序类名称(默认为org.apache.coyote.ajp.AjpProtocol )。users :具有username , password和roles用户列表。用于与这些用户配置基本身份验证的tomcat。以下示例代码显示了如何更改默认的HTTP/HTTPS端口。为了启用SSL,我们将属性enableSSL设置为true 。 Web应用程序将在“上下文路径sample-app下访问。
tomcat {
httpPort = 8090
httpsPort = 8091
enableSSL = true
contextPath = ' sample-app '
users {
user {
username = ' user1 '
password = ' 123456 '
roles = [ ' developers ' , ' admin ' ]
}
user {
username = ' user2 '
password = ' abcdef '
roles = [ ' manager ' ]
}
}
}此外,您可以设置以下可选任务属性:
contextPath :URL上下文路径您的Web应用程序将在(默认为WAR名称)下注册。webDefaultXml :默认Web.xml。如果未定义org.apache.catalina.servlets.DefaultServlet和org.apache.jasper.servlet.JspServlet的实例。additionalRuntimeResources :定义Web应用程序未提供的其他运行时罐或目录。URIEncoding :指定用于解码HTTP连接器URI字节的字符编码(默认为UTF-8 )。daemon :指定tomcat服务器是否应在后台运行。如果是THUM,则此任务在服务器启动后立即完成。当false时,此任务会阻止直到停止Tomcat服务器(默认为false )。configFile :tomcat上下文xml文件的路径(默认为tomcatRun的src/main/webapp/META-INF/context.xml ,默认为tomcatRunWar的战争中的META-INF/context.xml )。outputFile :将tomcat日志消息写入到的文件。如果文件已经存在,则将附加新消息。reloadable :如果您不使用上下文文件(默认为true ),则强制上下文扫描。keystorePass :如果启用了SSL的密钥库密码。truststoreFile :用于SSL的TrustStore文件,如果已启用。truststorePass :用于SSL的TrustStore密码,如果已启用。clientAuth :要使用的clientauth设置,值可能是: true , false或want (默认为false )。注意: keystoreFile和truststoreFile每个都需要File对象的实例file("/path/my.file")
在以下示例代码中,我们声明了tomcatRun任务的自定义上下文文件。
tomcatRun . configFile = file( ' context.xml ' )要配置Jasper编译器任务,您可以选择在tomcat扩展程序的jasper关闭中设置以下属性:
validateXml :确定是否应验证web.xml (默认为null )。validateTld :确定是否应验证web.xml (默认为null )。uriroot :Web应用程序root Directory(默认为src/main/webapp )。webXmlFragment :生成的web.xml文件要引用的生成的Web XML片段。addWebXmlMappings :自动将生成的Web XML片段添加到web.xml文件中。注意:这将修改项目中的web.xml文件,而不是构建目录。outputDir :输出目录编译的JSP最终将输入(默认为build/jasper )。classdebuginfo :是否应使用调试信息(默认为true )来编译类文件。compiler :哪个编译器ANT应用于编译JSP页面。有关更多信息,请参见蚂蚁文档。如果未设置该值,则将使用默认的Eclipse JDT Java编译器代替使用ANT。没有默认值。compilerSourceVM :JDK版本是与源文件兼容的源文件(默认为1.6 )。compilerTargetVM :什么JDK版本是与(默认为1.6 )兼容的生成文件。poolingEnabled :确定是否启用了标签处理程序池。这是一个汇编选项。它不会改变已经编译的JSP的行为(默认为true )。errorOnUseBeanInvalidClassAttribute :当useBean操作中类属性的值不是有效的bean类(默认为true )时,贾斯珀是否会发出错误。genStringAsCharArray :是否应将文本字符串作为char阵列生成,以在某些情况下提高性能(默认为false )。ieClassId :使用<jsp:plugin> tags(默认为clsid:8AD9C840-044E-11D1-B3E9-00805F499D93 )时,将发送到Internet Explorer的类ID值。javaEncoding :用于生成Java源文件的Java文件编码(默认为UTF8 )。trimSpaces :是否应修剪动作或指令之间的模板文本中的白色空间(默认为TrimSpaces.TRUE )。xpoweredBy :确定是否通过生成的Servlet添加X-Power-By响应标头(默认为false )。tomcat {
jasper {
validateXml = true
webXmlFragment = file( " $w ebAppDir /WEB-INF/generated_web.xml " )
outputDir = file( " $w ebAppDir /WEB-INF/src " )
}
}调用JSP时,我会得到一个编译异常。我缺少什么吗?
您可能看到的例外可能与此相似: org.apache.jasper.JasperException: Unable to compile class for JSP 。 tomcat 7.x和8.x要求您在类路径中让Eclipse ECJ 3.6.x。但是,此版本的依赖关系在Maven Central中不存在。您必须下载该依赖关系,并将其放入您自己的存储库中或在本地磁盘上定义存储库,您可以将其放入。以下示例:
repositories {
flatDir name : ' localRepository ' , dirs : ' lib '
}为什么我在javax.servlet.Servlet上获得java.lang.ClassCastException ?
Tomcat对拥有javax.servlet:jsp-api版本的依赖javax.servlet:servlet-api非常敏感。默认情况下,他们已经被嵌入了嵌入式tomcat库的及依赖性。您可能看到的例外看起来与此相似:
java.lang.ClassCastException: org.springframework.web.servlet.DispatcherServlet cannot be cast to javax.servlet.Servlet
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1062)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935)
at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5262)
at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5257)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
为了解决此操作,请确保您以这样的范围提供providedCompile JSP和Servlet模块依赖项:
providedCompile ' javax.servlet:servlet-api:2.5 ' ,
' javax.servlet:jsp-api:2.0 '如何远程调试我的tomcat由插件启动?
如果您想远程调试应用程序,则必须在启动容器之前在GRADLE_OPTS环境变量中设置以下JVM选项。您选择的端口号取决于您。
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
然后,Tomcat将在指定的端口上聆听输入远程调试连接。启动容器时,您应该看到以下消息:
Listening for transport dt_socket at address: 5005
检查有关如何配置连接到远程调试端口的IDE文档。
我的Tomcat容器需要使用JNDI DataSource。我如何设置我的项目?
首先,您必须确保使用tomcat配置声明连接池依赖关系。
tomcat 6.0.x:
def tomcatVersion = ' 6.0.35 '
tomcat " org.apache.tomcat:dbcp: ${ tomcatVersion } "有关详细信息,请参见Maven Central上的坐标。
以后的版本:
def tomcatVersion = ' 9.0.8 '
tomcat " org.apache.tomcat:tomcat-dbcp: ${ tomcatVersion } "有关详细信息,请参见Maven Central上的坐标。
如果您决定使用默认设置,则将您的context.xml放在目录src/main/webapp/META-INF中。要设置自定义位置,您可以使用“惯例”属性configFile 。这是如何为tomcatRun和tomcatRunWar设置它的示例。
[tomcatRun, tomcatRunWar] * . configFile = file( ' context.xml ' )请参阅tomcat文档以获取上下文属性列表。以下示例显示了如何设置MySQL JNDI DataSource。
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< Context >
< Resource name = " jdbc/mydatabase "
auth = " Container "
type = " javax.sql.DataSource "
username = " superuser "
password = " secretpasswd "
driverClassName = " com.mysql.jdbc.Driver "
url = " jdbc:mysql://localhost:3306/mydb "
validationQuery = " select 1 "
maxActive = " 10 "
maxIdle = " 4 " />
</ Context >如何使用插件使用热代码部署?
该插件提供了开箱即用的支持,用于通过属性reloadable来交换字节代码。默认情况下,此选项已被结果,因此您不需要任何其他配置更改。您需要做的就是拥有由tomcatRun启动的容器的运行实例。启动您喜欢的编辑器,更改生产源文件,保存它并通过gradle compileJava将其重新编译到另一个终端中。几秒钟后,重新加载了上下文,您应该看到在运行容器的终端窗口中反映的行为:
Reloading Context with name [/myapp] has started
Reloading Context with name [/myapp] is completed
另外,您可以使用其他商业字节代码交换技术。该配置通常是特定于产品的。请参阅产品的文档,以了解如何为您的项目设置。下一节介绍了如何使用JREBEL设置Gradle和插件。首先,下载Jrebel,将其安装在计算机上并设置许可证。要告诉jrebel哪个目录要扫描更改字节代码,您需要创建rebel.xml文件。在您的Web模块中,将文件放在build/classes/main下方,以便可以由tomcat插件加载。为了创建文件的配置,gradle jrebel插件派上用场。不需要使用插件。您还可以决定手工创建配置。请记住, gradle clean将删除文件。要在多模型项目方案中设置JREBEL,请参阅文档。以下代码片段显示了一个示例rebel.xml文件。
<? xml version = " 1.0 " encoding = " UTF-8 " ?>
< application xmlns : xsi = " http://www.w3.org/2001/XMLSchema-instance " xmlns = " http://www.zeroturnaround.com "
xsi : schemaLocation = " http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd " >
< classpath >
< dir name = " /Users/ben/dev/projects/mywebproject/build/classes/main " >
</ dir >
</ classpath >
< web >
< link target = " / " >
< dir name = " /Users/ben/dev/projects/mywebproject/src/main/webapp " >
</ dir >
</ link >
</ web >
</ application >编辑您的Gradle启动脚本,并在其中添加以下行,以告诉Gradle使用Jrebel代理。请确保设置指向您的jrebel安装目录的环境变量REBEL_HOME 。
JAVA_OPTS="-javaagent:$REBEL_HOME/jrebel.jar $JAVA_OPTS"
在使用gradle tomcatRun的Web模块启动时,您应该看到有关正在使用的JREBEL许可证以及扫描更改目录的信息。对于我们的示例rebel.xml文件,它看起来像这样:
JRebel: Directory '/Users/ben/dev/projects/mywebproject/build/classes/main' will be monitored for changes.
JRebel: Directory '/Users/ben/dev/projects/mywebproject/src/main/webapp' will be monitored for changes.
如果已重新编译文件,则通过将其写入这样的控制台来指示这一点:
JRebel: Reloading class 'de.muschko.web.controller.TestController'.
需要作为我的构建的一部分运行企业内集成测试。需要做什么?
通常,单位和集成测试通过惯例分开保留。一个约定可能是以不同的方式命名测试源文件,例如集成测试始终以后缀IntegrationTest结束,单位测试文件以Test结束。通过这样做,您可以单独运行它们。对于运行集成测试,您将需要作为守护程序线程运行Tomcat任务,并在测试完成后将其关闭。以下示例演示了如何设置提供此功能的Gradle任务。当然,这只是这样做的一种方法。以下示例需要gradle> = 1.7:
apply plugin : ' com.bmuschko.tomcat-base '
ext {
tomcatStopPort = 8081
tomcatStopKey = ' stopKey '
}
task integrationTomcatRun( type : com.bmuschko.gradle.tomcat.tasks.TomcatRun ) {
stopPort = tomcatStopPort
stopKey = tomcatStopKey
daemon = true
}
task integrationTomcatStop( type : com.bmuschko.gradle.tomcat.tasks.TomcatStop ) {
stopPort = tomcatStopPort
stopKey = tomcatStopKey
}
task integrationTest( type : Test ) {
include ' **/*IntegrationTest.* '
dependsOn integrationTomcatRun
finalizedBy integrationTomcatStop
}
test {
exclude ' **/*IntegrationTest.* '
}如何添加不属于Web应用程序源代码一部分的JAR文件或目录?
类型AbstractTomcatRun的每个任务都揭示了一个名为additionalRuntimeResources的属性,该属性用于与Web应用程序Runtime Class Path混合。
[tomcatRun, tomcatRunWar] . each { task ->
task . additionalRuntimeResources << file( ' /Users/bmuschko/config/props ' )
task . additionalRuntimeResources << file( ' /Users/bmuschko/ext/jars/my.jar ' )
}