This episode covers Groovy and Java interoperability: using Java libraries from Groovy, importing Java packages, accessing enums, and calling Java methods. You will also learn to run Groovy inside a Java application and vice versa with GroovyShell.

Groovy's strength is inseparable from the Java ecosystem. Since both live on the JVM, Groovy can use the millions of existing Java libraries — and Java applications can leverage Groovy's flexibility for scripting.
Episode 10 covers using Java libraries from Groovy, importing Java packages, accessing enums, calling Java methods, and running Groovy inside a Java application and vice versa. You'll see smooth two-way integration without adapters.
Imports in Groovy are identical to Java. The difference is that Groovy also has shorthand for static and wildcard imports:
import java.util.concurrent.TimeUnit
import static java.lang.Math.*
def lamaMenunggu = TimeUnit.SECONDS.toMillis(30)
println "30 detik = ${lamaMenunggu} ms"
println "Nilai maksimal: ${max(10, 20)}"import java.util.concurrent.TimeUnit imports an ordinary Java class, and import static java.lang.Math.* imports all static members at once. max(10, 20) can be called directly without the Math prefix.
To use external Java libraries, Groovy provides @Grab, which downloads dependencies from Maven Central when the script runs:
@Grab("com.google.code.gson:gson:2.10.1")
import com.google.gson.Gson
def gson = new Gson()
def json = gson.toJson([nama: "Arman", umur: 25])
println json@Grab("com.google.code.gson:gson:2.10.1") fetches Gson from Maven Central automatically. new Gson().toJson(...) turns a Groovy map into JSON — an example of integrating with a well-known Java library without build setup.
import java.time.DayOfWeek
def hari = DayOfWeek.SATURDAY
switch (hari) {
case DayOfWeek.SATURDAY:
case DayOfWeek.SUNDAY:
println "Akhir pekan!"
break
default:
println "Hari kerja"
}
println DayOfWeek.values().collect { it.name() }.join(", ")import java.time.DayOfWeek imports a Java enum, and case DayOfWeek.SATURDAY compares it in a switch. DayOfWeek.values().collect { it.name() } converts all enum values into a list of strings.
def text = " Groovy Dan Java "
println text.trim()
println text.toUpperCase().split(" ").toList()
def map = new java.util.HashMap()
map.put("kunci", "nilai")
println map.get("kunci")text.toUpperCase().split(" ").toList() calls the Java methods toUpperCase and split, then converts the resulting array into a Groovy list. new java.util.HashMap() creates a pure Java object, and all its methods can be called without issues.
For Java applications that want to evaluate dynamic scripts, Groovy provides GroovyShell. Add the groovy-4.0.24 dependency to the project classpath:
java -cp groovy-4.0.24.jar:. Mainimport groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class Main {
public static void main(String[] args) {
Binding binding = new Binding();
binding.setVariable("nama", "Arman");
GroovyShell shell = new GroovyShell(binding);
Object hasil = shell.evaluate("println \"Halo, ${nama}\"");
}
}java -cp groovy-4.0.24.jar:. Main puts the Groovy jar on the classpath, and new GroovyShell(binding) evaluates a script that uses variables from the binding. This pattern is often used for rule engines or plugins that can be extended without recompilation.
import groovy.lang.GroovyClassLoader;
GroovyClassLoader loader = new GroovyClassLoader(Main.class.getClassLoader());
Class<?> cls = loader.parseClass("class Halo { String sapa() { 'hi' } }");
Object obj = cls.getDeclaredConstructor().newInstance();loader.parseClass(...) compiles a string into a Groovy class, then getDeclaredConstructor().newInstance() creates an instance of it. The parsed class can be used like an ordinary Java class via reflection.
class Utils {
static String sambung(String a, String b) {
return a + b;
}
}
def hasil = Utils.sambung("Groovy", "Java")
println hasil
def u = new Utils()
println u.class.nameUtils.sambung("Groovy", "Java") calls a static method of a Groovy class, and u.class.name checks its actual class. Since all Groovy classes are GroovyObject, a Java application can use them through an agreed-upon interface.
The key to smooth interop is a shared classpath. When a Groovy script runs in a Java project, use options to leverage the project classpath:
groovy -cp "build/classes/java/main:lib/*" script.groovygroovy -cp "build/classes/java/main:lib/*" script.groovy adds the compiled Java classes and project libraries to the script classpath. With this, Groovy can use the same Java business logic classes as the main application.
Three patterns you can choose from based on your needs:
@Grab for dependencies, no project.GroovyShell for plugins, rules, or dynamic configuration.Choose the first pattern for quick tooling, the second for core applications, and the third for parts that need to be flexible.
Episode 10 showed how seamless Groovy and Java integration is: importing and calling Java libraries works directly, @Grab downloads dependencies for standalone scripts, Java enums and methods are accessed without adaptation, and GroovyShell opens up dynamic scripting from Java applications.
The key takeaways:
@Grab downloads dependencies from Maven Central at runtime.GroovyShell evaluates dynamic scripts from a Java application.GroovyClassLoader compiles Groovy classes from Java.In episode 11 next, we'll discuss testing and quality — unit testing with Spock and JUnit, mocking, data-driven tests, behavior-driven syntax, as well as static type checking and linting for Groovy code.