Skip to content

Commit

Permalink
Replace Nashorn with GraalVM (#1857)
Browse files Browse the repository at this point in the history
  • Loading branch information
plata authored Jun 10, 2019
1 parent 4659606 commit 240e682
Show file tree
Hide file tree
Showing 42 changed files with 569 additions and 182 deletions.
6 changes: 1 addition & 5 deletions docs/_docs/Developers/intellij-idea.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ add: JavaFXApplication with:
* Main class: `org.phoenicis.javafx.JavaFXApplication`
* VM options:
```
--add-modules=ALL-MODULE-PATH --module-path=phoenicis-dist/target/lib
```
* **With Java 11**, you may need to remove the = in --module-path
```
--add-modules=ALL-MODULE-PATH --module-path phoenicis-dist/target/lib
--add-modules=jdk.crypto.ec,java.base,javafx.base,javafx.web,javafx.media,javafx.graphics,javafx.controls,java.naming,java.sql,java.scripting,jdk.scripting.nashorn,jdk.internal.vm.ci,jdk.internal.vm.compiler,org.graalvm.truffle,jdk.jsobject,jdk.xml.dom --module-path phoenicis-dist/target/lib -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=phoenicis-dist/target/lib/compiler.jar
```
* Program arguments: empty
* Working directory: `/path/to/phoenicis`
Expand Down
36 changes: 36 additions & 0 deletions docs/_docs/Developers/script-interaction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: "Interaction between Phoenicis and its Scripts"
category: Developers
order: 10
toc: true
---

The interaction between Phoenicis and its scripts occurs through interfaces.

### Accessing a JavaScript Script from Java
Every script type that Phoenicis uses has its own Java interface.
To access a JavaScript script, Phoenicis proceeds like followed:

1) Execute the script using a `PhoenicisScriptEngine`
2) Cast the result object of the executed script into the desired interface type
3) Interact with the interface object

### Existing interfaces
* [`Engine`](https://github.com/PhoenicisOrg/phoenicis/blob/master/phoenicis-engines/src/main/java/org/phoenicis/engines/Engine.java)
* [`Verb`](https://github.com/PhoenicisOrg/phoenicis/blob/master/phoenicis-engines/src/main/java/org/phoenicis/engines/Verb.java)
* [`Installer`](https://github.com/PhoenicisOrg/phoenicis/blob/master/phoenicis-scripts/src/main/java/org/phoenicis/scripts/Installer.java)
* [`EngineTool`](https://github.com/PhoenicisOrg/phoenicis/blob/master/phoenicis-engines/src/main/java/org/phoenicis/engines/EngineTool.java)

### Easy casting via `PhoenicisScriptEngine`
To provide an easy method to perform all three previously mentioned step in a generic way, they could be implemented inside the `PhoenicisScriptEngine` implementations
Example method signatures:

```java
public interface PhoenicisScriptEngine {
<E> E evalAndReturn(String script, Class<E> type);

<E> void eval(String script, Class<E> type, Consumer<E> onSuccess, Consumer<Exception> onError);
}
```

Alternatively to the `String` script representation it could be a useful idea to pass `ScriptDTO` objects to the `PhoenicisScriptEngine`s.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import org.phoenicis.configuration.security.Safe;
import org.phoenicis.containers.dto.ContainerCategoryDTO;
import org.phoenicis.containers.dto.ContainerDTO;
Expand All @@ -29,7 +28,7 @@
import org.phoenicis.library.ShortcutManager;
import org.phoenicis.library.dto.ShortcutCategoryDTO;
import org.phoenicis.library.dto.ShortcutDTO;
import org.phoenicis.scripts.interpreter.InteractiveScriptSession;
import org.phoenicis.scripts.session.InteractiveScriptSession;
import org.phoenicis.scripts.interpreter.ScriptInterpreter;
import org.phoenicis.tools.config.CompatibleConfigFileFormatFactory;
import org.phoenicis.tools.config.ConfigFile;
Expand Down Expand Up @@ -142,11 +141,9 @@ public void deleteContainer(ContainerDTO container, Consumer<ContainerDTO> onSuc

interactiveScriptSession.eval("include(\"engines." + engineId + ".shortcuts.reader\");",
ignored -> interactiveScriptSession.eval("new ShortcutReader()", output -> {
final ScriptObjectMirror shortcutReader = (ScriptObjectMirror) output;

shortcutReader.callMember("of", shortcut);

final String containerName = (String) shortcutReader.callMember("container");
final org.graalvm.polyglot.Value shortcutReader = (org.graalvm.polyglot.Value) output;
shortcutReader.invokeMember("of", shortcut);
final String containerName = shortcutReader.invokeMember("container").as(String.class);
if (containerName.equals(container.getName())) {
this.shortcutManager.deleteShortcut(shortcut);
}
Expand Down
46 changes: 45 additions & 1 deletion phoenicis-dist/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,51 @@
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<excludeArtifactIds>bcprov-jdk16, bcmail-jdk16, bcpg-jdk16, commons-logging, xml-apis, xmlParserAPIs, xercesImpl</excludeArtifactIds>
<excludeArtifactIds>bcprov-jdk16, bcmail-jdk16, bcpg-jdk16, commons-logging, xml-apis, xmlParserAPIs, xercesImpl, truffle-api, graal-sdk</excludeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-graal-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.graalvm.compiler</groupId>
<artifactId>compiler</artifactId>
<version>${graalvm.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<destFileName>compiler.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-api</artifactId>
<version>${graalvm.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<destFileName>truffle-api.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
<version>${graalvm.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<destFileName>graal-sdk.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
Expand Down
2 changes: 1 addition & 1 deletion phoenicis-dist/src/flatpak/org.phoenicis.playonlinux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ modules:
- type: script
dest-filename: phoenicis-playonlinux
commands:
- /app/jre/bin/java --module-path /app/phoenicis/lib/ --add-modules=ALL-MODULE-PATH org.phoenicis.javafx.JavaFXApplication "$@"
- /app/jre/bin/java --module-path /app/phoenicis/lib/ --add-modules=jdk.crypto.ec,java.base,javafx.base,javafx.web,javafx.media,javafx.graphics,javafx.controls,java.naming,java.sql,java.scripting,jdk.scripting.nashorn,jdk.internal.vm.ci,jdk.internal.vm.compiler,org.graalvm.truffle,jdk.jsobject,jdk.xml.dom -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -classpath /app/phoenicis/lib --upgrade-module-path=/app/phoenicis/lib/compiler.jar org.phoenicis.javafx.JavaFXApplication "$@"
110 changes: 110 additions & 0 deletions phoenicis-dist/src/scripts/phoenicis-create-package-java12.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash

## TODO: This script has not been adapted for Linux

## Dependencies
# Linux:
# - fakeroot
#

VERSION="$1"

if [ "$VERSION" = "" ]; then
echo "Warning: Version not specified. Reading from pom.xml"
VERSION="$(cat ../../pom.xml|grep -4 '<parent>'|grep '<version>'|awk -F'[<>]' '/<version>/{print $3}')"
echo "Using $VERSION"
fi

SCRIPT_PATH="$(dirname "$0")"
cd "$SCRIPT_PATH"
SCRIPT_PATH="$PWD"

[ "$JAVA_HOME" = "" ] && echo "Please set JAVA_HOME" && exit 0

PHOENICIS_OPERATING_SYSTEM="$(uname)"

if [ "$PHOENICIS_OPERATING_SYSTEM" == "Darwin" ]; then
PHOENICIS_APPTITLE="Phoenicis PlayOnMac"
JPACKAGER_OS="osx"
JAR_RELATIVE_PATH="../Java"
fi

if [ "$PHOENICIS_OPERATING_SYSTEM" == "Linux" ]; then
PHOENICIS_APPTITLE="Phoenicis PlayOnLinux"
JPACKAGER_OS="linux"
JAR_RELATIVE_PATH="/usr/share/phoenicis/app"
fi

PHOENICIS_TARGET="$SCRIPT_PATH/../../target"
PHOENICIS_JPACKAGER="$SCRIPT_PATH/../../target/jpackager"
PHOENICIS_RESOURCES="$SCRIPT_PATH/../resources"
PHOENICIS_MODULES="jdk.crypto.ec,java.base,javafx.base,javafx.web,javafx.media,javafx.graphics,javafx.controls,java.naming,java.sql,java.scripting,jdk.scripting.nashorn,jdk.internal.vm.ci,jdk.internal.vm.compiler,org.graalvm.truffle,jdk.jsobject,jdk.xml.dom"
PHOENICIS_RUNTIME_OPTIONS="-XX:G1PeriodicGCInterval=5000 -XX:G1PeriodicGCSystemLoadThreshold=0 -XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5 -XX:-ShrinkHeapInSteps -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=$JAR_RELATIVE_PATH/compiler.jar --module-path=../Java --add-modules=$PHOENICIS_MODULES"
PHOENICIS_JPACKAGER_ARGUMENTS=("-i" "$PHOENICIS_TARGET/lib" "--main-jar" "phoenicis-javafx-$VERSION.jar" "-n" "$PHOENICIS_APPTITLE" "--output" "$PHOENICIS_TARGET/packages/" "--add-modules" "$PHOENICIS_MODULES" "-p" "$PHOENICIS_TARGET/lib/" "--app-version" "$VERSION" "--java-options" "$PHOENICIS_RUNTIME_OPTIONS")


_download_jpackager() {
mkdir -p "$PHOENICIS_JPACKAGER"
cd "$PHOENICIS_JPACKAGER"
wget https://download.java.net/java/early_access/jpackage/49/openjdk-13-jpackage+49_osx-x64_bin.tar.gz
tar -xvf openjdk-13-jpackage+49_osx-x64_bin.tar.gz
}


jpackager() {
if [ ! -e "$PHOENICIS_JPACKAGER/jdk-13.jdk/Contents/Home/bin" ]; then
_download_jpackager
fi

"$PHOENICIS_JPACKAGER/jdk-13.jdk/Contents/Home/bin/jpackage" "$@"
}

cd "$PHOENICIS_TARGET"

if [ "$PHOENICIS_OPERATING_SYSTEM" == "Darwin" ]; then
rm -rf "$PHOENICIS_TARGET/packages/Phoenicis PlayOnMac.app"
jpackager create-app-image --icon "$PHOENICIS_RESOURCES/Phoenicis PlayOnMac.icns" "${PHOENICIS_JPACKAGER_ARGUMENTS[@]}"
fi

if [ "$PHOENICIS_OPERATING_SYSTEM" == "Linux" ]; then
jpackager create-image "${PHOENICIS_JPACKAGER_ARGUMENTS[@]}" --linux-bundle-name "phoenicis-playonlinux"

packageName="Phoenicis_$VERSION"
cd "$PHOENICIS_TARGET"
rmdir packages/PhoenicisPlayOnLinux/
rm -rf "packages/phoenicis" 2> /dev/null
mv packages/Phoenicis\ PlayOnLinux/ packages/phoenicis
rm -rf "$packageName" 2> /dev/null
mkdir -p "$packageName/DEBIAN/"

cat << EOF > "$packageName/DEBIAN/control"
Package: phoenicis-playonlinux
Version: $VERSION
Section: misc
Priority: optional
Architecture: all
Depends: unzip, wget, xterm | x-terminal-emulator, python, imagemagick, cabextract, icoutils, p7zip-full, curl
Maintainer: PlayOnLinux Packaging <[email protected]>
Description: This program is a front-end for wine.
It permits you to install Windows Games and softwares
on Linux. It allows you to manage differents virtual hard drive,
and several wine versions.
Copyright 2011-2019 PlayOnLinux team <[email protected]>
EOF

mkdir -p $packageName/usr/share/applications
mkdir -p $packageName/usr/share/pixmaps
mkdir -p $packageName/usr/bin

cp -a packages/phoenicis $packageName/usr/share/
cp -a "$SCRIPT_PATH/../launchers/phoenicis" $packageName/usr/bin/phoenicis
chmod +x $packageName/usr/bin/phoenicis

cp "$SCRIPT_PATH/../resources/Phoenicis.desktop" "$packageName/usr/share/applications"
cp "$SCRIPT_PATH/../resources/phoenicis.png" "$packageName/usr/share/pixmaps"
cp "$SCRIPT_PATH/../resources/phoenicis-16.png" "$packageName/usr/share/pixmaps"
cp "$SCRIPT_PATH/../resources/phoenicis-32.png" "$packageName/usr/share/pixmaps"

fakeroot dpkg-deb --build "$packageName"
rm -rf deb
fi
8 changes: 5 additions & 3 deletions phoenicis-dist/src/scripts/phoenicis-create-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ PHOENICIS_OPERATING_SYSTEM="$(uname)"
if [ "$PHOENICIS_OPERATING_SYSTEM" == "Darwin" ]; then
PHOENICIS_APPTITLE="Phoenicis PlayOnMac"
JPACKAGER_OS="osx"
JAR_RELATIVE_PATH="../Java"
fi

if [ "$PHOENICIS_OPERATING_SYSTEM" == "Linux" ]; then
PHOENICIS_APPTITLE="Phoenicis PlayOnLinux"
JPACKAGER_OS="linux"
JAR_RELATIVE_PATH="/usr/share/phoenicis/app"
fi

PHOENICIS_TARGET="$SCRIPT_PATH/../../target"
PHOENICIS_JPACKAGER="$SCRIPT_PATH/../../target/jpackager"
PHOENICIS_RESOURCES="$SCRIPT_PATH/../resources"
PHOENICIS_MODULES="jdk.crypto.ec,java.base,javafx.base,javafx.web,javafx.media,javafx.graphics,javafx.controls,java.naming,java.sql,java.scripting,jdk.scripting.nashorn"
PHOENICIS_JPACKAGER_ARGUMENTS=("-i" "$PHOENICIS_TARGET/lib" "--main-jar" "phoenicis-javafx-$VERSION.jar" "-n" "$PHOENICIS_APPTITLE" "--output" "$PHOENICIS_TARGET/packages/" "--add-modules" "$PHOENICIS_MODULES" "-p" "$PHOENICIS_TARGET/lib/" "--version" "$VERSION")

PHOENICIS_MODULES="jdk.crypto.ec,java.base,javafx.base,javafx.web,javafx.media,javafx.graphics,javafx.controls,java.naming,java.sql,java.scripting,jdk.scripting.nashorn,jdk.internal.vm.ci,org.graalvm.truffle"
PHOENICIS_RUNTIME_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI --upgrade-module-path=$JAR_RELATIVE_PATH/compiler.jar"
PHOENICIS_JPACKAGER_ARGUMENTS=("-i" "$PHOENICIS_TARGET/lib" "--main-jar" "phoenicis-javafx-$VERSION.jar" "-n" "$PHOENICIS_APPTITLE" "--output" "$PHOENICIS_TARGET/packages/" "--add-modules" "$PHOENICIS_MODULES" "-p" "$PHOENICIS_TARGET/lib/" "--version" "$VERSION" "--jvm-args" "$PHOENICIS_RUNTIME_OPTIONS")

_download_jpackager() {
mkdir -p "$PHOENICIS_JPACKAGER"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

package org.phoenicis.engines;

import org.graalvm.polyglot.Value;
import org.phoenicis.repository.dto.*;
import org.phoenicis.scripts.interpreter.InteractiveScriptSession;
import org.phoenicis.scripts.session.InteractiveScriptSession;
import org.phoenicis.scripts.interpreter.ScriptInterpreter;

import java.util.ArrayList;
Expand Down Expand Up @@ -55,7 +56,7 @@ public void getSetting(String engineId, String settingId, Consumer<EngineSetting
interactiveScriptSession.eval(
"include(\"engines." + engineId + ".settings." + settingId + "\"); new Setting();",
output -> {
final EngineSetting setting = (EngineSetting) output;
final EngineSetting setting = ((Value) output).as(EngineSetting.class);
doneCallback.accept(setting);
}, errorCallback);
}
Expand All @@ -71,7 +72,8 @@ public void fetchAvailableEngineSettings(RepositoryDTO repositoryDTO,
final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession();

interactiveScriptSession.eval(this.createFetchScript(repositoryDTO),
output -> callback.accept((Map<String, List<EngineSetting>>) output), errorCallback);
output -> callback.accept(((Value) output).as(Map.class)),
errorCallback);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

package org.phoenicis.engines;

import org.graalvm.polyglot.Value;
import org.phoenicis.repository.dto.ApplicationDTO;
import org.phoenicis.repository.dto.CategoryDTO;
import org.phoenicis.repository.dto.RepositoryDTO;
import org.phoenicis.repository.dto.TypeDTO;
import org.phoenicis.scripts.interpreter.InteractiveScriptSession;
import org.phoenicis.scripts.session.InteractiveScriptSession;
import org.phoenicis.scripts.interpreter.ScriptInterpreter;

import java.util.ArrayList;
Expand Down Expand Up @@ -60,7 +61,7 @@ public void runTool(String engineId, String container, String toolId, Runnable d
interactiveScriptSession.eval(
"include(\"engines." + engineId + ".tools." + toolId + "\");",
ignored -> interactiveScriptSession.eval("new Tool()", output -> {
final EngineTool toolObject = (EngineTool) output;
final EngineTool toolObject = ((Value) output).as(EngineTool.class);
toolObject.run(container);
doneCallback.run();
}, errorCallback), errorCallback);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.graalvm.polyglot.Value;
import org.phoenicis.configuration.security.Safe;
import org.phoenicis.engines.dto.EngineCategoryDTO;
import org.phoenicis.engines.dto.EngineSubCategoryDTO;
import org.phoenicis.repository.dto.*;
import org.phoenicis.scripts.interpreter.InteractiveScriptSession;
import org.phoenicis.scripts.session.InteractiveScriptSession;
import org.phoenicis.scripts.interpreter.ScriptInterpreter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -67,7 +68,7 @@ public void getEngine(String engineId, Consumer<Engine> doneCallback, Consumer<E
interactiveScriptSession.eval(
"include(\"engines." + engineId + ".engine.implementation\"); new Engine();",
output -> {
final Engine engine = (Engine) output;
final Engine engine = ((Value) output).as(Engine.class);
doneCallback.accept(engine);
}, errorCallback);
}
Expand Down Expand Up @@ -129,7 +130,7 @@ public void fetchAvailableEngines(RepositoryDTO repositoryDTO,
final InteractiveScriptSession interactiveScriptSession = scriptInterpreter.createInteractiveSession();

interactiveScriptSession.eval(this.createFetchScript(repositoryDTO),
output -> callback.accept((Map<String, Engine>) output), errorCallback);
output -> callback.accept(((Value) output).as(Map.class)), errorCallback);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

package org.phoenicis.engines;

import org.graalvm.polyglot.Value;
import org.phoenicis.repository.dto.ApplicationDTO;
import org.phoenicis.repository.dto.CategoryDTO;
import org.phoenicis.repository.dto.RepositoryDTO;
import org.phoenicis.repository.dto.TypeDTO;
import org.phoenicis.scripts.interpreter.InteractiveScriptSession;
import org.phoenicis.scripts.session.InteractiveScriptSession;
import org.phoenicis.scripts.interpreter.ScriptInterpreter;

import java.util.ArrayList;
Expand Down Expand Up @@ -62,7 +63,7 @@ public void installVerb(String engineId, String container, String verbId, Runnab
interactiveScriptSession.eval(
"include(\"" + verbId + "\");",
ignored -> interactiveScriptSession.eval("new Verb()", output -> {
final Verb verbObject = (Verb) output;
final Verb verbObject = ((Value) output).as(Verb.class);
verbObject.install(container);
doneCallback.run();
}, errorCallback), errorCallback);
Expand Down
2 changes: 1 addition & 1 deletion phoenicis-javafx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
<dependency>
<groupId>com.github.PhoenicisOrg</groupId>
<artifactId>javafx-collections</artifactId>
<version>1.2.0</version>
<version>1.2.1</version>
</dependency>
</dependencies>
<build>
Expand Down
Loading

0 comments on commit 240e682

Please sign in to comment.