gradle中使用嵌入式(embedded) tomcat, debug 启动

在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 to 8080).
  • httpsPort: The TCP port which Tomcat should listen for HTTPS requests on (defaults to 8443).
  • ajpPort: The TCP port which Tomcat should listen for AJP requests on (defaults to 8009).
  • stopPort: The TCP port which Tomcat should listen for admin requests on (defaults to 8081).
  • stopKey: The key to pass to Tomcat when requesting it to stop (defaults to null).
  • 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 to false).
  • 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 to false).
  • 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 to org.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 to org.apache.coyote.ajp.AjpProtocol).
  • users: List of users with usernamepassword and roles. 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 and org.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 to UTF-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 to false).
  • configFile: The path to the Tomcat context XML file (defaults to src/main/webapp/META-INF/context.xml for tomcatRun, defaults to META-INF/context.xml within the WAR for tomcatRunWar).
  • 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 to true).
  • 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: truefalse or want (defaults to false).

Note: keystoreFile and truststoreFile each require an instance of a File 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 whether web.xml should be validated (defaults to null).
  • validateTld: Determines whether web.xml should be validated (defaults to null).
  • uriroot: The web application root directory (defaults to src/main/webapp).
  • webXmlFragment: The generated web XML fragment file to be referenced by your web.xml file.
  • addWebXmlMappings: Automatically add the generated web XML fragment to the web.xml file. Caution: this will modify the web.xml file in the project, not the build directory.
  • outputDir: The output directory the compiled JSPs will end up in (defaults to build/jasper).
  • classdebuginfo: Should the class file be compiled with debugging information (defaults to true).
  • 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 to 1.6).
  • compilerTargetVM: What JDK version are the generated files compatible with (defaults to 1.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 to true).
  • errorOnUseBeanInvalidClassAttribute: Should Jasper issue an error when the value of the class attribute in an useBean action is not a valid bean class (defaults to true).
  • genStringAsCharArray: Should text strings be generated as char arrays, to improve performance in some cases (defaults to false).
  • ieClassId: The class-id value to be sent to Internet Explorer when using <jsp:plugin> tags (defaults to clsid:8AD9C840-044E-11D1-B3E9-00805F499D93).
  • javaEncoding: Java file encoding to use for generating java source files (defaults to UTF8).
  • trimSpaces: Should white spaces in template text between actions or directives be trimmed (defaults to false).
  • xpoweredBy: Determines whether X-Powered-By response header is added by generated servlet (defaults to false).

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员与猫

ASP.NET Core WebListener 服务器

原文地址:WebListener server for ASP.NET Core By Tom Dykstra, Chris Ross WebListener是...

1787
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (5)

之前的配置都是在内存中, 下面将如何把这些数据存储到Sql Server数据库, 这样更适合生产环境. 这部分基本完全参考官方文档: https://ident...

3185
来自专栏ppjun专栏

【详细】Android热更新Bugly集成配置

上一篇文章说道tinker的热更新,可是少了点补丁包的管理,这一篇文章介绍的bugly就是增强版的,更加方便你集成tinker和包括了补丁包的后台管理。 为什...

742
来自专栏Java后端技术

spring-boot-starter大力出奇迹

​  上篇文章我们已经聊了SpringBoot的启动过程中的各类扩展点,那么从http://start.spring.io上我们生成的demo项目中,到目前就剩...

902
来自专栏晓晨的专栏

Entity Framework Core 2.0 使用入门

1443
来自专栏烙馅饼喽的技术分享

本人有生以来的第一篇博客,嘿嘿,就发这个吧, 怎样在虚拟主机上使用Castle框架的ActiveRecord

        我在某个私人项目中使用了Castle 的 ActiveRecord.用起来那是真叫个爽,整个项目里楞是一句SQL语句都没有,嘿嘿。超级喜欢上了这...

2545
来自专栏张善友的专栏

Code-First Migrations随Entity Framework 4.3一同发布

Entity Framework 4.3 版本终于为开发者带来了迁移(Migrations)功能,从此以后使用EF不必依赖于单独预发布的迁移库了。 什么是EF迁...

1749
来自专栏向治洪

gradle构建android项目详解

1、用Gradle构建 1.1 工程结构 ? 如图所示,这是一个不能更普通的Android的Gradle工程了。 根目录下面的settings.gradl...

2815
来自专栏NetCore

Fluent Nhibernate之旅(五)--利用AutoMapping进行简单开发

Fluent Nhibernate(以下简称FN)发展到如今,已经相当成熟了,在Nhibernate的书中也相应的推荐了使用FN来进行映射配置,之前写的FN之旅...

2276
来自专栏cmazxiaoma的架构师之路

IDEA入门(1)--lombok和Junit generator2插件的运用

1413

扫码关注云+社区