Polygene™
Introduction
Tutorials
Javadoc
Samples
Core
Libraries
Extensions
Tools
Glossary 

Scripting

code

docs

tests

The Scripting Library allows Mixin methods to be implemented in any JSR-223 scripting language, loaded dynamically on first use and allowing reloading of the script in runtime.

Table 19. Artifact

Group IDArtifact IDVersion

org.apache.polygene.libraries

org.apache.polygene.library.scripting

3.0.0


The Scripting Library is a Generic mixin class that implements Composite interfaces by delegating to script functions using Java Scripting API. All Java Scripting API (JSR-223) implementations that support

    ((javax.script.Invocable) scriptEngine).invokeFunction( functionName, arguments );

should be supported. On Java.Net there is a list of Java Scripting API languages.

It is important to understand that the ScriptEngines must be present on the classpath, or they will not be available, with the exception of JavaScript which uses the built-in Nashorn engine.

We welcome additional information and samples of languages that has been tried and tested.

Table 20. Language Support

Language Supported Tested License Implementation

JavaScript

Yes

Yes

?

Nashorn, built-in Java 8 and later

Groovy

Yes

Yes

Apache

Apache Groovy

Ruby

Yes

No

(EPL|GPL|LGPL) + Ruby

JRuby

Python

Yes

No

Python

Jython, must use jython-standalone

Kotlin

Yes

No

Apache

Jetbrains

Lua

Yes

No

MIT

luaj.org,

Clojure

Yes

No

CPL

https://github.com/pmf/clojure-jsr223


The following languages may or may not be supported, and was found at Java.Net Scripting project

Table 21. Potential Languages

Language Location License

beanshell

ejs

freemarker

https://freemarker.apache.org

Apache

jacl

jaskell

https://github.com/MarchLiu/jaskell

MIT

jawk

jelly

Apache

jep

jexl

https://commons.apache.org/jexl/

Apache

jst

judo

juel

ognl

https://commons.apache.org/ognl/

Apache

pnuts

scheme

http://sisc-scheme.org/

(MPLv1.1

GPLv2)

velocity

https://velocity.apache.org

Apache

xpath

xslt


Table 22. Not Compatible Languages

Language Comment

Java

Implementation exists at https://github.com/nickman/javax-scripting/ which is forked from https://java.net/projects/scripting. It doesn’t support Invocable, and additional work on ScriptMixin is required to support this. Alternatively, fork the ScriptEngine implementation and support Invocable in it.


Javascript

In Javascript, we map directly to JS functions with the same name.

For the following Polygene composite type,

package org.apache.polygene.library.scripting;
  [...snip...]


@Mixins(ScriptMixin.class)
public interface HelloSpeaker
{
    String sayHello();
}

we need a implementation in a resource file (visible on classpath) named org/apache/polygene/library/scripting/HelloSpeaker.js that looks like this;

function sayHello() {
    return "Hello, JavaScript";
}

Groovy

The Groovy Scripting Library is a Generic mixin that implements interfaces by delegating to Groovy code from classpath resources.

But before looking at how to use the Scripting library we’ll see that you don’t need Scripting library at all if you simply need to use Groovy classes as Fragments. Groovy is a fully Java compatible language and can be used directly, similarly to Scala.

Then we’ll see how to use Groovy class scripts and method scripts.

All examples below are based on this type:

package org.apache.polygene.library.scripting;
  [...snip...]


@Mixins(ScriptMixin.class)
public interface HelloSpeaker
{
    String sayHello();
}

Using compiled Groovy classes

To directly use compiled Groovy classes as Fragments you don’t need this library at all.

Having this Groovy class compiled ;

HelloSpeakerMixin.groovy. 

class HelloSpeakerMixin
    implements HelloSpeaker
{

    String sayHello() {
        "Hello there, Groovy"
    }
}

assemble it directly:

SingletonAssembler assembler = new SingletonAssembler(
    assembly -> assembly.transients( HelloSpeaker.class )
                        .withMixins( HelloSpeakerMixin.class )
);
HelloSpeaker speaker = assembler.module().newTransient( HelloSpeaker.class );
assertThat( speaker.sayHello(), equalTo("Hello there, Groovy") );

Using Groovy function scripts

Declare a Groovy function in a resource file located in the same package as the implemented type with the name <type>.groovy:

HelloSpeaker.groovy. 

def sayHello() {
    "Hello, Groovy"
}

Then assemble it with the normal ScriptMixin:

SingletonAssembler assembler = new SingletonAssembler(
    assembly -> assembly.values( HelloSpeaker.class )
                        .setMetaInfo( Scripting.GROOVY )
                        .withMixins( ScriptMixin.class )
);
HelloSpeaker speaker = assembler.module().newValue( HelloSpeaker.class );
assertThat( speaker.sayHello(), equalTo("Hello, Groovy") );