use JavaFX from Jython on top of Java 8

Java 8 GA has released!

On March 18, 2014, Java 8 became GA. Simultaneously, the version number of JavaFX was raised upto 8 – JavaFX 8.

Preview

I wrote a blog post containing Jython scripts using JavaFX API. http://blog.elliptium.net/2012/12/use-JavaFX-from-Jython

Let’s retry these scripts with Java 8.

Retry

In order to re-compile Jython with Java 8, run folloing commands:

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home

$ java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

$ brew uninstall jython
Uninstalling /usr/local/Cellar/jython/2.5.3...

$ brew install jython
$ jython
*sys-package-mgr*: processing new jar, '/usr/local/Cellar/jython/2.5.3/libexec/jython.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/resources.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/rt.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jsse.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jce.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/charsets.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/jfr.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/cldrdata.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/dnsns.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/jfxrt.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/localedata.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/nashorn.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/sunec.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar'
*sys-package-mgr*: processing new jar, '/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext/zipfs.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Java/Extensions/MRJToolkit.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Java/Extensions/QTJava.zip'
Jython 2.5.3 (2.5:c56500f08d34+, Aug 13 2012, 14:48:36)
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0
Type "help", "copyright", "credits" or "license" for more information.
>>>

## OK

Create a jython script hello.py, then run with jython command.

# hello.py
from javafx.application import Application
from javafx.scene import Scene
from javafx.scene.control import Label
from javafx.scene.layout import AnchorPane


class Hello(Application):
    def start(self, stage):
        stage.setTitle("Hello, World!")

        root = AnchorPane()
        label = Label("Hello, World!")
        root.getChildren().add(label)

        scene = Scene(root, 100, 40)
        stage.setScene(scene)

        stage.show()


if __name__ == '__main__':
    Application.launch(Hello().class, [])
$ jython hello.py
Traceback (most recent call last):
  File "hello.py", line 4, in <module>
    from javafx.scene.control import Label
java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:340)
    at org.python.core.Py.loadAndInitClass(Py.java:909)
    at org.python.core.Py.findClassInternal(Py.java:844)
    at org.python.core.Py.findClassEx(Py.java:895)
    at org.python.core.packagecache.SysPackageManager.findClass(SysPackageManager.java:133)
    at org.python.core.packagecache.PackageManager.findClass(PackageManager.java:28)
    at org.python.core.packagecache.SysPackageManager.findClass(SysPackageManager.java:122)
    at org.python.core.PyJavaPackage.__findattr_ex__(PyJavaPackage.java:137)
    at org.python.core.PyObject.__findattr__(PyObject.java:863)
    at org.python.core.imp.importFromAs(imp.java:1015)
    at org.python.core.imp.importFrom(imp.java:987)
    at org.python.pycode._pyx0.f$0(hello.py:23)
    at org.python.pycode._pyx0.call_function(hello.py)
    at org.python.core.PyTableCode.call(PyTableCode.java:165)
    at org.python.core.PyCode.call(PyCode.java:18)
    at org.python.core.Py.runCode(Py.java:1275)
    at org.python.util.PythonInterpreter.execfile(PythonInterpreter.java:235)
    at org.python.util.jython.run(jython.java:247)
    at org.python.util.jython.main(jython.java:129)
Caused by: java.lang.IllegalStateException: Toolkit not initialized
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:276)
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:271)
    at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:562)
    at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:524)
    at javafx.scene.control.Control.<clinit>(Control.java:81)
    ... 20 more

java.lang.ExceptionInInitializerError: java.lang.ExceptionInInitializerError

Hmm…, Label class, somehow, could not be imported.

to be continued…

I will be back, in order to run JavaFX with Jython.