Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specify multiple main classes using gradle 'application' plugin

Tags:

java

gradle

I would like to use the Gradle "application" plugin to create startScripts for a second mainClass. Is this possible? Even if the application plugin doesn't have this functionality built in, is it possible to leverage the startScripts task to create a second pair of scripts for a different mainClass?

like image 986
Jeff Nelson Avatar asked Aug 24 '13 18:08

Jeff Nelson


People also ask

What does Gradle application plugin do?

The Application plugin facilitates creating an executable JVM application. It makes it easy to start the application locally during development, and to package the application as a TAR and/or ZIP including operating system specific start scripts.

Can I have multiple build Gradle?

Java Prime Pack Small projects have a single build file and a source tree. It is very easy to digest and understand a project that has been split into smaller, inter-dependent modules. Gradle perfectly supports this scenario that is multi-project build.

Which are the two types of plugins in Gradle?

There are two general types of plugins in Gradle, binary plugins and script plugins.


2 Answers

Add something like this to your root build.gradle:

// Creates scripts for entry points
// Subproject must apply application plugin to be able to call this method.
def createScript(project, mainClass, name) {
  project.tasks.create(name: name, type: CreateStartScripts) {
    outputDir       = new File(project.buildDir, 'scripts')
    mainClassName   = mainClass
    applicationName = name
    classpath       = project.tasks[JavaPlugin.JAR_TASK_NAME].outputs.files + project.configurations.runtimeClasspath
  }
  project.tasks[name].dependsOn(project.jar)

  project.applicationDistribution.with {
    into("bin") {
      from(project.tasks[name])
      fileMode = 0755
    }
  }
}

Then call it as follows either from the root or from subprojects:

// The next two lines disable the tasks for the primary main which by default
// generates a script with a name matching the project name. 
// You can leave them enabled but if so you'll need to define mainClassName
// And you'll be creating your application scripts two different ways which 
// could lead to confusion
startScripts.enabled = false
run.enabled = false

// Call this for each Main class you want to expose with an app script
createScript(project, 'com.foo.MyDriver', 'driver')
like image 53
kylejmcintyre Avatar answered Nov 06 '22 04:11

kylejmcintyre


I combined parts of both of these answers to arrive at the relatively simple solution:

task otherStartScripts(type: CreateStartScripts) {
    description "Creates OS specific scripts to call the 'other' entry point"
    classpath = startScripts.classpath
    outputDir = startScripts.outputDir
    mainClassName = 'some.package.app.Other'
    applicationName = 'other'
}

distZip {
    baseName = archivesBaseName
    classifier = 'app'
    //include our extra start script 
    //this is a bit weird, I'm open to suggestions on how to do this better
    into("${baseName}-${version}-${classifier}/bin") {
        from otherStartScripts
        fileMode = 0755
    }
}

startScripts is created when the application plugin is applied.

like image 4
w25r Avatar answered Nov 06 '22 04:11

w25r