4

I have a Groovy project (using Eclipse) which makes use of several @Grab statements. This works fine on my development machine. However I need to distribute this application including all its dependencies to other machines which don't have any internet connection, i.e. it won't be possible to download the necessary JARs from these machines.

Is there a way to somehow automatically include the dependencies into the project, e.g. a lib folder? This way I could just copy the project to another machine and use it.

M. Justin
  • 14,487
  • 7
  • 91
  • 130
Robert Strauch
  • 12,055
  • 24
  • 120
  • 192
  • 1
    Download the dependencies and put them in a lib folder maybe? Sounds like you are looking for a build tool. Have you looked at gradle? https://docs.gradle.org/current/userguide/groovy_plugin.html – tim_yates Oct 30 '15 at 08:54
  • I would explore creating an uberjar. I haven't tried it myself with Groovy. With regular java it's straightforward with Maven. – Sridhar Sarnobat Jul 27 '17 at 19:50

4 Answers4

5

So, lets say for example you have a script Script.groovy like so, that you currently run with groovy Script.groovy:

@Grab('com.github.groovy-wslite:groovy-wslite:1.1.2')
import wslite.rest.*

def client = new RESTClient("http://httpbin.org")
def response = client.get(path:'/get')

assert 200 == response.statusCode
println "Received : $response.json"

Now, we want to get this into a jar file that you can distribute, and people can just run with java -jar myApp.jar

So make the following folder structure:

myApp
 |-- src
 |    |-- main
 |         |-- groovy
 |              |-- example
 |                   |-- Script.groovy
 |-- build.gradle

Then, in Script.groovy, put your script (with a package name, and no @Grab annotation):

package example

import wslite.rest.*

def client = new RESTClient("http://httpbin.org")
def response = client.get(path:'/get')

assert 200 == response.statusCode
println "Received : $response.json"

And in build.gradle, put this script which pulls down the groovy, and groovy-wslite dependencies, and applies the shadow-jar plugin to bundle all dependencies into one single fat jar:

plugins {
  id "com.github.johnrengelman.shadow" version "1.2.2"
}

apply plugin: 'groovy'
apply plugin: 'application'

repositories {
    jcenter()
}

mainClassName = 'example.Script'

dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.4.5'
    compile 'com.github.groovy-wslite:groovy-wslite:1.1.2'
}

You can then (assuming you have installed Gradle), simply run:

gradle shadowJar

Which will compile your code, and put it and all its dependencies into build/libs/myApp-all.jar

So then, you can just run:

java -jar build/libs/myApp-all.jar

And your script should run as before...

You can then distribute this jar file, instead of just the script...

Hope this helps

tim_yates
  • 167,322
  • 27
  • 342
  • 338
1

I would suggest switching to Gradle or some other build tool that downloads the dependencies at build time. As you probably already know grape pulls down all the dependencies at runtime.

Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the grab() calls in Groovy, a set of classes leveraging Ivy to allow for a repository driven module system for Groovy. This allows a developer to write a script with an essentially arbitrary library requirement, and ship just the script. Grape will, at runtime, download as needed and link the named libraries and all dependencies forming a transitive closure when the script is run from existing repositories such as Ibiblio, Codehaus, and java.net.

This link might help you in your transition to using Gradle with your Groovy script.

Running Groovy scripts from Gradle

Community
  • 1
  • 1
Dale
  • 1,613
  • 4
  • 22
  • 42
0

You could copy your Grape repo to the target deployment servers. Should be ~/.groovy/Grape. Then you can keep your @Grabs in the scripts as is

Nicholas
  • 15,916
  • 4
  • 42
  • 66
0

Two solutions

  1. Replace the whole build progress with gradle, just like what's mentioned by @tim_yates' answer.

  2. Use grape install command to pre-install the packages into the grape local repo, whose default path is "~/.groovy/grapes".Then package the scripts and the grape dir together. You might switch the grape repo dir to somewhere you prefer. See section 3.5 of http://docs.groovy-lang.org/latest/html/documentation/grape.html

Jiankuan Xing
  • 387
  • 3
  • 9