在gradle項目中使用embedded tomcat。
最開始部署項目需要手動將web項目打成war包,然后手動上傳到tomcat的webapp下,然后啟動tomcat來部署項目。這種手動工作通常還要指定端口,指定項目位置等,這些操作是重復的操作。
開發的時候,ide自然想到集成這些功能,於是都是server模塊,設置好參數就可以run server,測試了。個人操作的時候確實挺方便的,然而當團隊協作的時候,每個人都要手動去設置這些參數,而且大家或許還在使用着各種各樣的idea。eclipse和idea的配置方式截然不同。這好在都是java程序員,但還有前端呢,前端的同事一起開發的時候,他們會感覺這些配置繁瑣。
后來發現,框架發展到現在反而更傾向於命令行的方式了。embedded 就是一種流行的方式。
當項目集成了embedded tomcat之后,只要type gradlew tomcatRun就可以運行項目。這樣即使是前端程序員也可以本地調試項目了。
1.創建一個gradle web項目
在idea中,new -> project -> gradle -> web 就可以創建一個空的gradle web項目。
在build.gradle 中添加tomcat的依賴:
buildscript { repositories { jcenter() } dependencies { classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.5' } } dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' def tomcatVersion = '7.0.59' 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 插件:
apply plugin: 'com.bmuschko.tomcat'
2. 運行
這時候就可以運行了。在命令行中輸入:
gradlew tomcatRun
第一次運行會下載對應的jar包,然后顯示:
Started Tomcat Server The Server is running at http://localhost:8080/embTomcat
端口默認8080,contextPath默認為項目名。
2.1 Task
tomcatRun 為 運行 exploded web application;
tomcatRunWar 則是運行war包。
Task Name | Depends On | Type | Description |
---|---|---|---|
tomcatRun | - | TomcatRun | Starts a Tomcat instance and deploys the exploded web application to it. |
tomcatRunWar | - | TomcatRunWar | Starts a Tomcat instance and deploys the WAR to it. |
tomcatStop | - | TomcatStop | Stops the Tomcat instance. |
tomcatJasper | - | TomcatJasper | Runs the JSP compiler and turns JSP pages into Java source usingJasper. |
2.2修改默認配置
習慣了'/'作為contextPath:
tomcatRun.contextPath = '/'
tomcatRunWar.contextPath = '/'
這時候運行結果:
:tomcatRunWar Started Tomcat Server The Server is running at http://localhost:8080
8080端口就挺好的,當然,如果想要自定義也是可以的:
tomcatRun.httpPort=8089
事實上,也提供可更加細膩的自定設置。這時候需要再添加一個依賴:
apply plugin: 'com.bmuschko.tomcat-base'
然后一個自定配置實例:
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'] } } }
啟動運行:
D:\workspace\springboot\embTomcat>gradlew tomcatRun --stacktrace :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :tomcatRun Started Tomcat Server The Server is running at http://localhost:8090/sample-app
可以看到,這個開啟了https,頁面可以直接訪問https的地址了。端口設置為8091. 通過都設置為8443.
2.3 Extension properties
The Tomcat plugin exposes the following properties through the extension named tomcat
:
httpPort
: The TCP port which Tomcat should listen for HTTP requests on (defaults to8080
).httpsPort
: The TCP port which Tomcat should listen for HTTPS requests on (defaults to8443
).ajpPort
: The TCP port which Tomcat should listen for AJP requests on (defaults to8009
).stopPort
: The TCP port which Tomcat should listen for admin requests on (defaults to8081
).stopKey
: The key to pass to Tomcat when requesting it to stop (defaults tonull
).contextPath
: The URL context path under which the web application will be registered (defaults to WAR name).enableSSL
: Determines whether the HTTPS connector should be created (defaults tofalse
).daemon
: Specifies whether the Tomcat server should run in the background. When true, this task completes as soon as the server has started. When false, this task blocks until the Tomcat server is stopped (defaults tofalse
).keystoreFile
: The keystore file to use for SSL, if enabled (by default, a keystore will be generated).httpProtocol
: The HTTP protocol handler class name to be used (defaults toorg.apache.coyote.http11.Http11Protocol
).httpsProtocol
: The HTTPS protocol handler class name to be used (defaults toorg.apache.coyote.http11.Http11Protocol
).ajpProtocol
: The AJP protocol handler class name to be used (defaults toorg.apache.coyote.ajp.AjpProtocol
).users
: List of users withusername
,password
androles
. Used to configure tomcat with basic authentication with these users.
到這里基本已經可以使用了。當然,如果想要更多的了解深入的配置:https://github.com/bmuschko/gradle-tomcat-plugin
Task properties
Furthermore, you can set the following optional task properties:
contextPath
: The URL context path your web application will be registered under (defaults to WAR name).webDefaultXml
: The default web.xml. If it doesn't get defined an instance oforg.apache.catalina.servlets.DefaultServlet
andorg.apache.jasper.servlet.JspServlet
will be set up.additionalRuntimeResources
: Defines additional runtime JARs or directories that are not provided by the web application.URIEncoding
: Specifies the character encoding used to decode the URI bytes by the HTTP Connector (defaults toUTF-8
).daemon
: Specifies whether the Tomcat server should run in the background. When true, this task completes as soon as the server has started. When false, this task blocks until the Tomcat server is stopped (defaults tofalse
).configFile
: The path to the Tomcat context XML file (defaults tosrc/main/webapp/META-INF/context.xml
fortomcatRun
, defaults toMETA-INF/context.xml
within the WAR fortomcatRunWar
).outputFile
: The file to write Tomcat log messages to. If the file already exists new messages will be appended.reloadable
: Forces context scanning if you don't use a context file (defaults totrue
).keystorePass
: The keystore password to use for SSL, if enabled.truststoreFile
: The truststore file to use for SSL, if enabled.truststorePass
: The truststore password to use for SSL, if enabled.clientAuth
: The clientAuth setting to use, values may be:true
,false
orwant
(defaults tofalse
).Note:
keystoreFile
andtruststoreFile
each require an instance of aFile
object e.g.file("/path/my.file")
Example
In the following example code, wes declare a custom context file for the task
tomcatRun
.tomcatRun.configFile = file('context.xml')
To configure the Jasper compiler task you can choose to set the following properties within the
jasper
closure of thetomcat
extension:
validateXml
: Determines whetherweb.xml
should be validated (defaults tonull
).validateTld
: Determines whetherweb.xml
should be validated (defaults tonull
).uriroot
: The web application root directory (defaults tosrc/main/webapp
).webXmlFragment
: The generated web XML fragment file to be referenced by yourweb.xml
file.addWebXmlMappings
: Automatically add the generated web XML fragment to theweb.xml
file. Caution: this will modify theweb.xml
file in the project, not the build directory.outputDir
: The output directory the compiled JSPs will end up in (defaults tobuild/jasper
).classdebuginfo
: Should the class file be compiled with debugging information (defaults totrue
).compiler
: Which compiler Ant should use to compile JSP pages. See the Ant documentation for more information. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value.compilerSourceVM
: What JDK version are the source files compatible with (defaults to1.6
).compilerTargetVM
: What JDK version are the generated files compatible with (defaults to1.6
).poolingEnabled
: Determines whether tag handler pooling is enabled. This is a compilation option. It will not alter the behaviour of JSPs that have already been compiled (defaults totrue
).errorOnUseBeanInvalidClassAttribute
: Should Jasper issue an error when the value of the class attribute in an useBean action is not a valid bean class (defaults totrue
).genStringAsCharArray
: Should text strings be generated as char arrays, to improve performance in some cases (defaults tofalse
).ieClassId
: The class-id value to be sent to Internet Explorer when using<jsp:plugin>
tags (defaults toclsid:8AD9C840-044E-11D1-B3E9-00805F499D93
).javaEncoding
: Java file encoding to use for generating java source files (defaults toUTF8
).trimSpaces
: Should white spaces in template text between actions or directives be trimmed (defaults tofalse
).xpoweredBy
: Determines whether X-Powered-By response header is added by generated servlet (defaults tofalse
).Example
tomcat { jasper { validateXml = true webXmlFragment = file("$webAppDir/WEB-INF/generated_web.xml") outputDir = file("$webAppDir/WEB-INF/src") } }
2.4FAQ
編譯錯誤!
org.apache.jasper.JasperException: Unable to compile class for JSP
tomcat7+需要一個jar包來編譯,如果沒有則添加:
repositories { flatDir name: 'localRepository', dirs: 'lib' }
反正我是沒遇到。
Why do I get a java.lang.ClassCastException
on javax.servlet.Servlet
?
依賴多個版本servlet-api導致了錯誤:
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 'javax.servlet:servlet-api:2.5',
'javax.servlet:jsp-api:2.0'
2.4 Debug
debug啟動需要設置gradle的環境變量,即運行gradle命令的時候插入(fork)一些參數命令。
可以設置環境變量GRADLE_OPTS為:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
即監聽5005端口。這時候運行則會顯示:
Listening for transport dt_socket at address: 5005
在idea中監聽端口:Run->edit configurations ->+ -> remote, 默認配置就可以了。
什么?不知道怎么設置環境變量?
作為一個java程序員的第一件事就是設置環境變量。當然,我們可以在程序運行的時候添加環境變量,比如在idea中使用自帶的gradle插件的時候指定參數,我感覺相當繁瑣,不過還是記錄下來。
首先,edit configurations -> + -> gradle ->
然后,點擊運行:
這時候就已經在監聽5005端口了,只需要添加remote debug就可以了:
edit configurations -> + -> remote:
debug:
2.5 gradle提供debug:
這種方式還是相當繁瑣的。不就是設置環境變量嗎,好吧,我確實沒去研究怎么設置了,應該是在腳本中添加的,以后再研究吧。下面介紹一個簡單的方式:
gradlew tomcatRun -Dorg.gradle.debug=true
沒錯,這樣就可以了。剩下的監聽remote同上。命令行結束會等待監聽,debug remote就可以了。
github: https://github.com/winsnow/jsp-tag
reference:
https://github.com/bmuschko/gradle-tomcat-plugin/blob/master/README.md
https://docs.gradle.org/current/userguide/gradle_command_line.html
https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties