Download presentation
Presentation is loading. Please wait.
1
Compiling Java to Javascript
How to Replace Applets Without the Plugin Davin McCall Michael Kölling King’s College, London
2
Greenfoot Challenges of teaching Java programming at school
Discuss the origin, motivation behind Greenfoot: simple API, motivational through fun games, simple to take ownership Sharing / displaying work: “stick it on the fridge” “Actors” in a “Scenario”
3
Greenfoot and applets “Stick it on the fridge” – the Greenfoot Gallery
Facilitates online discussion, collaboration and learning
4
Issues in applet deployment
Many security problems Actions taken by browser vendors and Oracle Applet signing Applets increasingly unsuitable for Greenfoot Gallery Rise of HTML 5 Warnings, then prohibitions against running unsigned applets (or in the browser) against running applets at all; against running with older plugin versions; prohibition in communicating with the origin server over the network. No longer possible to use UserInfo Less suitable for “on the fridge” type sharing of work
5
Let’s talk about: Java We all know this … but: Class-based
Several primitive types Threading, concurrency primitives Standard library; AWT/Swing/JavaFX
6
Let’s talk about: Javascript
None of the above Wat (Gary Bernhardt > Array(10).join(“wat” – 1) + “ Batman!” “NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN Batman!” No integer types\ Wat talk is a humorous expose of peculiarities in Ruby and Javascript
7
Let’s talk about: Javascript (2)
“prototype” based Primitive numeric type is equivalent to Java’s double. No multi-threading (except webworkers), very callback driven No GUI as such, but we do have DOM manipulation Slightly different exception model Translation not simple, but possible*: TeaVM! Prototype based: all objects have a prototype object which they “inherit” attributes/functions from Double has 53 bits of precision
8
TeaVM A Java-to-Javascript transpiler … So not actually a VM
- Alexey Andreev Supports multi-threading Supports all language constructs including lambdas Implements some commonly used Java API classes Actually converts Java bytecode to Javasript, can be used for Kotln, Scala etc. Open source (Apache 2). Uses javascript VM of browser, with some runtime support libraries
9
TeaVM: How does it work? In some cases can do a straight-forward translation of Java to equivalent Javascript
10
private void setLocationDrag(int x, int y) // in greenfoot
private void setLocationDrag(int x, int y) // in greenfoot.Actor { if (world != null) { int oldX = this.x; int oldY = this.y; if (world.isBounded()) { this.x = limitValue(x, world.width); this.y = limitValue(y, world.height); } else { this.x = x; this.y = y; } if (this.x != oldX || this.y != oldY) { if (boundingRect != null) { int dx = (this.x - oldX) * world.cellSize; // etc
11
$dx = ($this.$x - $oldX | 0) * $this.$world.$cellSize | 0;
function g_Actor_setLocationDrag($this, $x, $y) { var $oldX, $oldY, $dx, $dy, $i, var$8; if ($this.$world !== null) { $oldX = $this.$x; $oldY = $this.$y; if (g_World_isBounded($this.$world) == 0) { $this.$x = $x; $this.$y = $y; } else { $this.$x = g_Actor_limitValue($this, $x, $this.$world.$width); $this.$y = g_Actor_limitValue($this, $y, $this.$world.$height); } if (!($this.$x == $oldX && $this.$y == $oldY)) { if ($this.$boundingRect !== null) { $dx = ($this.$x - $oldX | 0) * $this.$world.$cellSize | 0; // etc Notice ”| 0” for coercion to integer $dx = ($this.$x - $oldX | 0) * $this.$world.$cellSize | 0;
12
int dx = (this.x - oldX) * world.cellSize;
$dx = ($this.$x - $oldX | 0) * $this.$world.$cellSize | 0; From Java: int dx = (this.x - oldX) * world.cellSize; Notice ”| 0” for coercion to integer Bitwise OR with 0 coerces value to 32-bit integer long??!!
13
TeaVM: thread support Any method that can suspend is marked asynchronous An asynchronous method is transpiled to a while loop with a switch statement in the body A variable is introduced to act like a program counter To suspend, the entire function state (variables and PC) is saved to a stack before returning to caller Check for suspend is performed after each call to an asynchronous method Check for resume at beginning of method Threads can suspend and resume Any method that calls an asynchronous method must also be marked asynchronous itself TeaVM “threads” do not actually execute in parallel
14
static void initialise() { try { greenfootImage = new GreenfootImage(GreenfootUtil.getGreenfootLogoPath()); } catch (Exception e) { e.printStackTrace(); System.err.println("Greenfoot installation is broken - reinstalling Greenfoot might help."); } }
15
static void initialise() { try { greenfootImage = new GreenfootImage(GreenfootUtil.getGreenfootLogoPath()); } catch (Exception e) { e.printStackTrace(); System.err.println("Greenfoot installation is broken - reinstalling Greenfoot might help."); } } function g_Actor_initialise() { var $e, var$2, $$je, $ptr, $tmp; $ptr = 0; if ($rt_resuming()) { var $thread = $rt_nativeThread(); $ptr = $thread.pop();var$2 = $thread.pop();$e = $thread.pop(); } main: while (true) { switch ($ptr) { case 0: try { g_Actor_$callClinit(); $e = new g_GreenfootImage; var$2 = gu_GreenfootUtil_getGreenfootLogoPath(); $ptr = 1; continue main; } catch ($$e) { $$je = $$e.$javaException; if ($$je && $$je instanceof jl_Exception) { $e = $$je; } else { throw $$e; jl_Throwable_printStackTrace($e); jl_System_$callClinit(); ji_PrintStream_println(jl_System_err, $rt_s(25)); return; case 1: a: { b: { g_GreenfootImage__init_($e, var$2); if ($rt_suspending()) { break main; g_Actor_greenfootImage = $e; break b; Java Javascript
16
while (true) { switch ($ptr) {
function g_Actor_initialise() { var $e, var$2, $$je, $ptr, $tmp; $ptr = 0; if ($rt_resuming()) { var $thread = $rt_nativeThread(); $ptr = $thread.pop();var$2 = $thread.pop();$e = $thread.pop(); } main: while (true) { switch ($ptr) { case 0: try { g_Actor_$callClinit(); $e = new g_GreenfootImage; var$2 = gu_GreenfootUtil_getGreenfootLogoPath(); $ptr = 1; continue main; } catch ($$e) { // removed for purpose of example } case 1: $ptr = 0; while (true) { switch ($ptr) { GreenfootUtil. getGreenfootLogoPath()
17
case 1: a: { b: { try { g_GreenfootImage__init_($e, var$2); if ($rt_suspending()) { break main; } // (etc) } return; default: $rt_invalidPointer(); }} $rt_nativeThread().push($e, ar$2, $ptr); } new GreenfootImage() Asynchronous methods result in complicated code, slower
18
TeaVM: interaction with Javascript
Possible to implement Java methods with Javascript Declare methods as “native” and use an annotation to specify the Javascript method body @JSBody( params = { "array", "mediaType" }, script = "var blob = new Blob([array], {type: mediaType}); return URL.createObjectURL(blob);" ) private static native String toBlobUrl(Uint8Array array,~ String mediaType);
19
Integration into Greenfoot.org site
Greenfoot.org : Ruby-on-Rails JRuby! Call directly into TeaVM to perform translation of scenarios as they are uploaded Greenfoot API re-implemented using HTML 5 APIs
20
Demonstration
21
Conclusion Have to maintain Applets in the post-plugin era?
It is possible with TeaVM! Davin McCall – Michael Kölling - Greenfoot: TeaVM:
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.