DEV Community

Cover image for Combining Groovy and Java
Tomer Figenblat
Tomer Figenblat

Posted on • Edited on

Combining Groovy and Java

Combining Groovy scripts in our Java-based code, is easy with Maven.

You can check out the code for this tutorial in Github.

Scenario: we're asked to produce a text message to send to customers registering to some call queue to inform them that we got their registration request.
The message should include the customer name, queue number, and an informational greeting of some sort.

We have a couple of ways to accomplish that in Java.

First, we can use a basic method that takes the name and queue number as arguments:

private static String createMessage(final String name, final int queueNum) {
  return String.format(
      "Hello %s, you're number %d, please wait patiently, here is some info:\n" +
      "Anim incididunt deserunt ex ad do aliquip.\n" +
      "Ipsum voluptate laboris eiusmod sint ea do.", name, queueNum);
}

public String getMessage(final String name, final int queueNum) {
  return createMessage(name, queueNum);
}
Enter fullscreen mode Exit fullscreen mode

Let's try this as a BiFunction:

private static final BiFunction<String, Integer, String> createMessage =
    (name, queueNum) -> String.format(
      "Hello %s, you're number %d, please wait patiently, here is some info:\n" +
      "Anim incididunt deserunt ex ad do aliquip.\n" +
      "Ipsum voluptate laboris eiusmod sint ea do.", name, queueNum);

public String getMessage(final String name, final int queueNum) {
  return createMessage.apply(name, queueNum);
}
Enter fullscreen mode Exit fullscreen mode

As we add parameters to the message, i.e. eta, while using any of the above approaches, our code will get less readable and more error-prone.

So let's do function currying; it will make it easier to add parameters later on.
And it's fun invoking currying functions.

😁

private static final Function<String, Function<Integer, String>> createMessage =
    name -> queueNum -> String.format(
      "Hello %s, you're number %d, please wait patiently, here is some info:\n" +
      "Anim incididunt deserunt ex ad do aliquip.\n" +
      "Ipsum voluptate laboris eiusmod sint ea do.", name, queueNum);

public String getMessage(final String name, final int queueNum) {
  return createMessage.apply(name).apply(queueNum);
}
Enter fullscreen mode Exit fullscreen mode

Now, Let's give Groovy a try.
We'll create Groovy Script called create_message.groovy:

def name = bindName
def queueNum = bindQueueNum

"""Hello ${name}, you're number ${queueNum}, please wait patiently, here is some info:
Anim incididunt deserunt ex ad do aliquip.
Ipsum voluptate laboris eiusmod sint ea do."""
Enter fullscreen mode Exit fullscreen mode
  • The def statements allow us to bind arguments from the shell.
  • The """ marks the text as a GString, which allows us to leverage string interpolation and implied line breaks.
  • In Groovy last statement is the return statement.

Now let's invoke the script from our Java code:

public String getMessage(final String name, final int queueNum) {
  try {
    var shell = new GroovyShell();
    var scriptFile = new File(shell.getClassLoader().getResource("scripts/create_message.groovy").getFile());

    var script = shell.parse(scriptFile);

    var binding = new Binding();
    binding.setProperty("bindName", name);
    binding.setProperty("bindQueueNum", queueNum);

    script.setBinding(binding);

    return script.run().toString();
  } catch (IOException exc) {
    return exc.getMessage();
  }
}
Enter fullscreen mode Exit fullscreen mode

Adding an eta to the above approach is as simple as editing the text and binding another property. 😌

To get our script into our classpath with Maven, let's say this is our project layout:

- project
  - src
    - main
      - *.java
    - scripts
      - create_message.groovy
    - test
      - *Test.java
Enter fullscreen mode Exit fullscreen mode

First, we need to include the groovy dependency.
This will give access to Groovy's API, i.e. the GroovyShell and Binding classes.

<dependencies>
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy</artifactId>
        <version>3.0.5</version>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

We'll add the following to our build section in our pom.xml,
This will add everything from our src/scripts to our project.

<build>
    <resources>
      <resource>
        <directory>src/scripts</directory>
        <targetPath>scripts</targetPath>
      </resource>
    </resources>
</build>
Enter fullscreen mode Exit fullscreen mode

That's it, have fun and stay groovy!

Top comments (0)