简体   繁体   中英

Gradle: Call a Groovy static method from a task

I have a Gradle project that used the Groovy plugin.

The folder structure of the gradle project is:

src
 main
  groovy
    com
      acme
       runner
  resources
build.gradle

I have a task that uses JavaExec that calls the main method for the Simple Class defined in Simple.groovy as below:

task runScript(type: JavaExec) {
    description 'Run Groovy script'     
    // Set main property to name of Groovy script class.
    main = 'com.acme.runner.Simple'
    // Set classpath for running the Groovy script.
    classpath = sourceSets.main.runtimeClasspath
}

I would like to define a task calls another method in the Simple class is this possible and does it have the be a static method? Thanks.

A slightly not-straight-forward solution would be to control the method invocation from the main method or script's body based on task's args value:

Simple.groovy

package com.playground

switch( args ? args[ 0 ] : null ) {
    case 'a':
        hello()
        break
    case 'b':
        bye()
        break
    default:
        println 'Don\'t know what you mean'
}

void hello() {
    println 'Hello a!'
}

void bye() {
    println 'Goodbye a!'
}

gradle task:

task runScript(type: JavaExec) {
    description 'Run Groovy script'
    main = 'com.playground.Simple'
    classpath = sourceSets.main.runtimeClasspath
    args 'a' // 'b'
}

Produces

> Task :compileJava NO-SOURCE
> Task :compileGroovy UP-TO-DATE
> Task :processResources NO-SOURCE
> Task :classes

> Task :runScript
Hello a!

You could use a Classloader and reflection to run the class in the Gradle jvm.

task invokeCompiledClass {
   dependsOn compileGroovy
   doLast {
      // invoke new Simple().foo("bar") 
      def urls = sourceSets.main.runtimeClasspath.collect { it.toURI().toURL() } 
      ClassLoader cl = new URLClassLoader(urls as URL[]) 
      Class type = cl.loadClass('com.playground.Simple') 
      def instance = type.newInstance()
      Method method = type.getMethod("foo", String.class)
      Object result = method.invoke(instance, "bar") 
   } 
} 

Related answer here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM