Gradle Application Plugin - Building multiple start scripts / dists for the same project with different mainClassName

Viewed 4902

We have a Gradle project using the java plugin that has a couple of command line tools it needs to build. The project is just packaged up into a jar with its dependencies. We'd then like a couple of start scripts to kick off the various entry points in that project for each of these tools.

Naturally the application plugin is a good choice. And so we changed java to application and provided a mainClassName to create start scripts and tar distributable's. This worked to create a single application jar, but only one set of start scripts that used the mainClassName specified.

How can we create multiple start scripts for different entry points? (different mainClassName's?)

One approach I tried was creating some subprojects that had the application plugin applied and specified the individual mainClassNames seperatately

allprojects {
    apply plugin: 'java'
        
    repositories { 
        // maven repos           
    }

    dependencies {
        compile 'com.thirdparty:somejar:1.0'
    }

    sourceCompatibility = 1.7
}


subprojects {
    apply plugin: 'application'
}
    
project(':tools:csvLoader') {
    mainClassName = 'com.demo.tools.csvLoader.Loader'
}

project(':tools:summariser') {
    mainClassName = 'com.demo.tools.summary.Summarise'
}

And referenced in the root projects settings.gradle

include "tools","tools:csvLoader","tools:summariser"

This worked - but each subproject creates an identical jar (just named with the name of the subproject) and each subdir build folder holds a copy of that jar plus another copy of all the dependencies. Thats feels a little wasteful. It could also be confusing to a new developer seeing the subprojects there with all these tasks and no code whatsoever.

Is there a better way go about telling gradle to make multiple application related tasks but changing the mainClassName for each without having to resort to creating empty subprojects?

Thanks!

2 Answers

Here's one way to generate multiple start scripts with Gradle's application plugin:

mainClassName = "com.example.PrimaryEntryPoint"

startScripts {
  applicationName = 'primary'
}

// For convenience, define a map of additional start scripts.
// Key is script name and value is Java class.
def extraStartScripts = [
    'secondary' : 'com.example.SecondaryEntryPoint',
    'tertiary'  : 'com.example.TertiaryEntryPoint'
]

// Create a task for each additional entry point script.
extraStartScripts.each { scriptName, driverClass ->
  Task t = task(scriptName + "-script",
       group: 'CLI Script Generation',
       type: CreateStartScripts) {
    mainClassName = driverClass
    applicationName = scriptName
    outputDir = startScripts.outputDir
    classpath = startScripts.classpath
  }
  startScripts.dependsOn(t)
}
Related