Warm tip: This article is reproduced from stackoverflow.com, please click
dsl jython scripting

Delegating global functions to Java with Jython

发布于 2020-04-20 11:31:04

I would like to bind my functions implemented in Java into the global scope of a Jython interpreter instance (so I don't need to manually import them first in my scripts).

If this helps, I'm looking for a similar thing to Groovy's DelegatingScript, where you can set the delegate of the script body to a Java/Groovy object, so the objects functions are directly callable inside the DSL script.

Is there any way to achieve this?

Questioner
NagyI
Viewed
50
NagyI 2020-02-06 02:09

Turned out this is rather easy to do. You can put static functions into the Dsl class and those can be directly invoked inside the script.

Note: this is not exactly the same what Groovy does, because there you bind the local scope to an object rather than a class, but with some thinking this can be still very useful.

App.java

public final class App {
  public static void main(String[] args) throws Exception {
    try (PythonInterpreter py = new PythonInterpreter()) {
      py.exec("from hu.company.jythontest.Dsl import *");
      try (FileInputStream script = new FileInputStream("./etc/test.py")) {
        py.execfile(script);
      }
      var blocks = py.get("blocks", List.class);
      System.out.println(blocks.toString());
    }
  }
}

Dsl.java

public final class Dsl {
  public static class Block {
    private final String id;
    public Block(String id) {
      this.id = id;
    }
    public String getId() {
      return id;
    }
    @Override
    public String toString() {
      return id;
    }
  }
}

test.py

blocks = [Block('%d' % i) for i in range(10)]

Output:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]