該插件在任何給定的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 ' )
}