Skip to content
AgileLogics
6 min read

Using Java Libraries

Prerequisites: Classes and objects

Every Java library works in Groovy — the standard library, anything on Maven Central, and your own team's code.

Default imports

Groovy imports these packages automatically: java.lang, java.util, java.io, java.net, groovy.lang, groovy.util, and the classes java.math.BigDecimal and java.math.BigInteger. Everything else needs an import:

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import static java.lang.Math.PI
import java.util.concurrent.ConcurrentHashMap as CMap   // import alias

def launch = LocalDate.of(2026, 3, 15)
def review = launch.plusWeeks(6)
println review
println review.format(DateTimeFormatter.ofPattern('dd MMM yyyy', Locale.UK))
println ChronoUnit.DAYS.between(launch, review)
println review.dayOfWeek
println PI.round(4)

def cache = new CMap<String, Integer>()
cache.put('hits', 1)
cache.merge('hits', 1, Integer::sum)
println cache
2026-04-26
26 Apr 2026
42
SUNDAY
3.1416
[hits:2]
  • import ... as Name gives a class a shorter or clearer name.
  • import static brings in static members like PI.
  • Java getters become properties: review.dayOfWeek calls getDayOfWeek().

Dates with Groovy extras

import java.time.*

def start = LocalDate.of(2026, 12, 29)
def end = start + 5                  // plus days
(start..end).each { print "${it.dayOfMonth} " }
println()
println end - start
println Duration.ofMinutes(135).toString()
29 30 31 1 2 3
5
PT2H15M

Groovy adds operators and ranges to java.time types: date + 5 adds days, and date ranges iterate day by day.

Java streams and functional interfaces

import java.util.stream.Collectors

def words = ['delta', 'alpha', 'charlie', 'bravo', 'alpha']
def result = words.stream()
    .distinct()
    .sorted()
    .map(String::toUpperCase)
    .collect(Collectors.joining(', '))
println result

Runnable task = { println 'running as a Runnable' }
task.run()
java.util.function.Function<Integer, Integer> twice = { it * 2 }
println twice.apply(21)
ALPHA, BRAVO, CHARLIE, DELTA
running as a Runnable
42

Closures convert automatically to Java functional interfaces, so APIs written for Java lambdas accept them.

Grabbing libraries from Maven Central

Scripts can declare dependencies with Grape's @Grab annotation — no build file needed:

// illustrative — downloads a library on first run
@Grab('org.apache.commons:commons-lang3:3.18.0')
import org.apache.commons.lang3.StringUtils

println StringUtils.abbreviate('Groovy scripts can use any Java library', 25)
Groovy scripts can use...

The first run downloads the jar (and its dependencies) into a local cache in ~/.groovy/grapes, so later runs are fast. For applications, declare dependencies in Gradle instead (Level 3).

What's next

Try the Intermediate Projects, then continue to Level 3 — Advanced: metaprogramming, DSLs, Gradle, Jenkins pipelines, Spock, and Groovy in production.