Skip to content

Instantly share code, notes, and snippets.

@matthauck
Created August 26, 2013 06:40
Show Gist options
  • Save matthauck/6338633 to your computer and use it in GitHub Desktop.
Save matthauck/6338633 to your computer and use it in GitHub Desktop.

Revisions

  1. matthauck created this gist Aug 26, 2013.
    130 changes: 130 additions & 0 deletions TomcatPlugin.groovy
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    package com.foo

    import org.gradle.api.DefaultTask
    import org.gradle.api.Plugin
    import org.gradle.api.Project
    import org.gradle.api.GradleException
    import org.gradle.api.file.FileCollection
    import org.gradle.api.tasks.TaskAction
    import org.gradle.api.plugins.WarPlugin

    class TomcatExtension {
    Map systemProperties = [:]
    String contextPath = null
    int port = 8080
    }

    class TomcatPlugin implements Plugin<Project> {

    private static final TOMCAT_VERSION = '7.0.41'

    void apply(Project project) {
    project.extensions.create('tomcat', TomcatExtension)
    project.plugins.apply(WarPlugin)

    project.configurations.create('tomcat').setVisible(false).setTransitive(true)
    project.dependencies {
    tomcat(
    "org.apache.tomcat.embed:tomcat-embed-core:${TOMCAT_VERSION}",
    "org.apache.tomcat.embed:tomcat-embed-logging-juli:${TOMCAT_VERSION}",
    "org.apache.tomcat.embed:tomcat-embed-jasper:${TOMCAT_VERSION}"
    )
    }

    project.task('tomcat',
    type: TomcatRunTask,
    dependsOn: project.war,
    group: 'Tomcat',
    description: "Launch embedded tomcat on project's war file"
    )
    }
    }

    class TomcatRunTask extends DefaultTask {

    def contextPath() {
    def contextPath = project.tomcat.contextPath ?: project.war.baseName
    if (contextPath.charAt(0) != '/') {
    contextPath = '/' + contextPath
    }

    contextPath
    }

    def makeClasspath() {
    def buildSrcJar = project.files( new File(project.rootProject.projectDir, 'buildSrc/build/libs/buildSrc.jar') )

    buildSrcJar +
    project.buildscript.configurations.classpath +
    project.files(project.buildscript.dependencies.localGroovy().resolve()) +
    project.configurations.getByName('tomcat')
    }

    @TaskAction
    def run() {

    def work = new File(project.buildDir, 'tomcat')
    work.mkdirs()

    project.javaexec {
    main = 'com.foo.TomcatMain'
    classpath = makeClasspath()

    args = [ project.war.archivePath, contextPath(), project.tomcat.port ]

    systemProperties = project.tomcat.systemProperties
    workingDir = work

    maxHeapSize = '1024m'
    minHeapSize = '512m'
    jvmArgs '-XX:MaxPermSize=256m'

    }
    }
    }

    class TomcatMain {

    private File war
    private String contextPath
    private int port

    private static String HTTP_PROTOCOL = 'org.apache.coyote.http11.Http11NioProtocol'

    TomcatMain(war, contextPath, port) {
    this.war = new File(war)
    this.contextPath = contextPath
    this.port = port.toInteger()
    }

    void run() {
    def tomcat = new org.apache.catalina.startup.Tomcat()

    // add webapp
    def ctx = tomcat.addWebapp(null, contextPath, war.getCanonicalPath())
    ctx.unpackWAR = false
    // add connector
    tomcat.service.removeConnector(tomcat.getConnector())
    tomcat.service.addConnector(makeConnector())
    // base dir (cwd of forked process)
    tomcat.setBaseDir(".")

    // start!
    tomcat.start()
    println("\nServer is started: http://localhost:${port}${contextPath}\n")
    tomcat.server.await()
    }

    def makeConnector() {
    def conn = new org.apache.catalina.connector.Connector(HTTP_PROTOCOL)
    conn.setPort(port)
    conn.setURIEncoding('UTF-8')

    conn
    }

    static void main(String[] args) {
    new TomcatMain(args[0], args[1], args[2]).run();
    }

    }