Gradle: Run multiple webapps with Jetty

2019-06-24 06:05发布

问题:

I want to run two webapps created by the same Gradle project into a Jetty server. Let's call these two webapps "ninja" and "warrior".

Both webapps are very similar, they only differ in the application-context file (referenced in the web.xml file) and resources.

In order to deploy them, these two options are accepted:

  • Use different ports:
http://www.example.com:8080/app (ninja webapp)
http://www.example.com:8081/app (warrior webapp)
  • Use different paths:
http://www.example.com:8080/ninja_app
http://www.example.com:8080/warrior_app

Having one or two instances of Jetty should be ok for this project.

This is my project layout:

/src/main/java
/src/main/resources
/src/main/webapp (ninja webapp)
/src/main/webapp-warrior

First question: How to create two war files with Gradle?

Second question: How to deploy the two war files in the Jetty Server with Gradle?

回答1:

If you don't want to create two different projects, you may want to create two different gradle profiles, using the apply from: feature from Gradle.

For each webapp instance, ninja and warrior, you must create a script file with all the information specific for the profile.

In these new gradle build files, ninja-profile.gradle and warrior-profile.gradle, you can set the specific configurations that differ from ninja to warrior, which in this case could be:

  1. Resources folder: you can create a separated resources folder for each of the instances
  2. Jetty configuration: if you want to run two different instances of the 2 webapps, each of them in a separated jetty instance.

In your "main" build file you define everything that is common for all profile and build needs, plus you add the following line:

apply from: "${profile}-profile.gradle"

When you run Gradle you can pass the name of the profile using the -P option:

$ gradle -Pprofile=ninja tasks 

or

$ gradle -Pprofile=warrior tasks


回答2:

Please have a look at Gretty gradle plugin: https://github.com/akhikhl/gretty

It supports multiple web-apps out of the box. It helps you to:

  1. run web-app projects "inplace", i.e. from compiled classes
  2. run web-app projects as WAR files
  3. run non-project WAR-files from the file system
  4. run non-project WAR-files from maven repositories (of course, WAR is downloaded first)

Additionally you can:

  • Debug multiple web-apps on the same Jetty server under any Java IDE debugger.
  • Perform integration tests with multiple web-apps on the same Jetty server.
  • Perform code coverage with Jacoco - both client-side and server-side.

There is a lot of documentation helping with everything: http://akhikhl.github.io/gretty-doc/

Disclosure: I am author of Gretty plugin.

Happy coding :)



回答3:

We finally implemented a solution where sourceSets were created for both projects, so the directory layout is:

  • /src/main/java: Contains common classes for both projects
  • /src/main/webapp: Contains common webapp for both projects.
  • /src/ninjaMain/resources: Contains the specific resources for the ninja project
  • /src/warriorMain/resources: Contains the specific resources for the warrior project

Then, the build.gradle file was configured to create two war files. After that, both war files were deployed in the same webapp container using cargo and jetty:

apply 'java'
apply 'war'
apply 'cargo'


task createNinjaWar(type: War, dependsOn: classes) {
    baseName = 'ninja'      
    from file('src/main/webapp')
    destinationDir = file("$buildDir/dist")     
    webInf {
        from ('src/ninjaMain/resources') { into 'classes' }
    }
}

task createWarriorWar(type: War, dependsOn: classes) {  
    baseName = 'warrior'    
    from file('src/main/webapp')
    destinationDir = file("$buildDir/dist")                 
    webInf {
        from ('src/warriorMain/resources') { into 'classes' }       
    }
}    

// Deploy
cargo {
    containerId = 'jetty9x'
    port = 8080
    deployable {
        context = 'ninja'           
        file = createNinjaWar.archivePath
    }
    deployable {
        context = 'warrior'
        file = createWarriorWar.archivePath
    }
}

The access URL for the two web applications are now:

  • http://www.example.com:8080/ninja
  • http://www.example.com:8080/warrior


回答4:

For better readbility, code organisation and simpler maintenance these two projects should be separated. Then jetty plugin can be applied and configured separately for each project and all env can be start in parent build.gradle file.



标签: gradle Jetty war