0

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.

van
  • 9,159
  • 19
  • 60
  • 93
  • You mean you want to call a method in `Simple` class from your `build.gradle` file? What is the method called? – smac89 Dec 12 '19 at 17:25

2 Answers2

1

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!
injecteer
  • 20,038
  • 4
  • 45
  • 89
1

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

lance-java
  • 25,497
  • 4
  • 59
  • 101