Grape @Grab vs Gradle-Declared Dependencies for Offline Groovy Script Deployment
0 reputation · 01 Apr 2021, 00:30 UTC
Groovy's Grape lets scripts declare dependencies with the @Grab annotation and resolve them at runtime through Ivy and the GroovyClassLoader. That model suits developer workstations, where internet access and a writable Grape cache are normally available. In a production environment with no outbound network access — or with Grape disabled via the groovy.grape.enable system property — the same script fails at startup. The alternative is declaring dependencies in Gradle or Maven and shipping a self-contained artifact.
The trade-off is concrete: runtime fetching keeps scripts self-describing and fast to iterate on, but makes the effective classpath non-deterministic and dependent on resolver behavior at execution time. Build-tool declarations are reproducible and auditable, but they drop the annotation's convenience and add a build step. Two complications sharpen the choice: disabling Grape does not remove @Grab annotations, so failures surface only at first script execution rather than build time, and Grape's enablement defaults are sensitive to the Groovy release and whether Ivy is present on the runtime classpath.
Which approach better guarantees reliable offline startup for Groovy scripts? If @Grab is retained for local development, where should the production boundary be enforced — through the groovy.grape.enable flag, a dependency policy, or the build itself?