Sessions is temporarily moving to YouTube, check out all our new videos here.

From Java to JavaScript: the Journey of GeoGebra Graphing Calculator

Zbyněk Konečný speaking at viennaJS in September, 2017
58Views
 
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Zbyněk will share how he went from a pure Java desktop app to a cross-compiled web app.


Transcript


Hi, so I'm Zbyněk and I will talk about GeoGebra, about how we went from purely Java up into tech where we first compiled it for multiple platforms including JavaScript. So GeoGebra is dynamic mathematic software and you can freely download it from our webpage and it works pretty much everywhere including Raspberry Pi. We also have some plug-ins embedded into Office 365 and Smart Notebook. We have communities around the world who have translated it into 60 languages which are finished and some people are working on stuff like experimental translation for whatever reason. So this is how GeoGebra looks when it's embedded in html so we can create some objects and type in some equations. Stuff like that. Find the roots, and so all of this started as a master thesis by Markus Hohenwarter at the University of Salzburg. It was written in Java using some Swing interfaces. And the first version only covered the geometry so it had the equations on the left and objects on the right like you've seen but it didn't support functions. That was a couple of years later. And after that GeoGebra went open source and from one developer starts getting to the current team of 15 people. Around 2010 the major problems started where all the Java applets that you could export from GeoGebra 2 into browser they just became harder to use so there were some other libraries that were providing dynamic mathematics based on JavaScript which were just faster because you don't have to initialise the JBN to start it. And also the browsers just decided not to support Java anymore so we had to find a solution and basically Google found it for us. So what we've done in GeoGebra 4.4 is we used GWT to translate all of our codes in Javascript, that was 2014. From there there was two more milestones, it was when we did 3-D rendering in 2014. And now we've released a new version that uses JavaScript also on this scope. So instead of the old Java application we now shift the JavaScript with the electron browser so that you can also run it in the scope and it looks the same in a browser. So as I have said the technology that we are using is GWT which is really nice because it's guaranteed to give you the same results. So the pure Java code gives you the same results when you run it on JVM and when you compile it into JavaScript and GWT. But there are some limitations of course in JavaScript, you can't use Java classes for files, you can't use the Java graphics, and for some performance reasons there is no way to clone objects. So we had to really separate the code base and thread projects, one that we could use everywhere and then do projects for the two different UI's for the GWT UI and for the Swing UI. There were also some problems that we had to take care of in GWT because JavaScript really doesn't have classes. ES-6 now has some classes but before it didn't have. That means that stuff like typecasting objects doesn't throw exceptions so if the code really relies on stuff being in a specific class it will just fail in a completely different place than you would expect it to fail in Java. The methods that somehow interact with the browser are different through some Java interfaces. But what they return are really JavaScript objects so you can't fully rely on the return types of those methods. Sometimes it says that it will be an int and unsuitable. Stuff like that happens. This is about code so I've edited some samples of code, how you can split, for instance, the graphics. In JVM, the graphics have some setting that allows you to compose multiple objects in some sort of semi-transparent way. That's done using composites, something that doesn't exist in JavaScript. When we implemented the two different kinds of graphics the JVM implementation is using composites and the JavaScript implementation is using just the alpha level. Then we had to create some sort of reverse that implement the same interfaces even though they are doing some different things in the background. We were able to really isolate just a couple of the Java classes that needed to be duplicated and we were able to run most of the code the same from Java and JavaScript. Some more examples. The nice thing is that GWT really provides Java interfaces for most of the API's. If some methods like filling rectangle of campus context are already implemented in GWT the code looks really simple. If they are not, GWT allows you to use these JSNI methods. JavaScript Native Interface, which means that you add this native keyword and you can write basically pure JavaScript, you just need to sort of add these random correctors that tell eclipse and GWT that this is part of JavaScript and that it shouldn't be considered Java code. Another cool thing is that you can connect GWT to SASS. Before we were using just pure CSS but we are making cover design more similar to the material guidelines we've also wanted to use SASS The way GWT deals with styles is that it's inlining them into your bundle. You can use these declarations of resources then when GWT processes the class it uses these annotations to write the Java code for you so you don't have to inline text files into your code. That would be hard, it's probably still a bad idea but JWT does it at least in the big round. You can do this by telling JWT that for SASS files you want to use this specific generator. Then the generator looks like this. It takes the Java file, it takes the Java method and extracts the annotations that you've used before and then passes it to the SASS compiler which is also coded there, is some Java part of the SASS compiler. So you can run it and this way if your running GWT in the development mode it will always recompile all of your SASS files at the refresh. This annotation tells it that this file is somehow relevant for the resource class and whenever it changes then it should be recompiled. This is just some definition of how you go about starting a new GWT app. It's just an xml file that tells GWT what the module should be called and it allows you to use some of the already present GWT libraries like the GWT user library, that's where all the UI stuff is and it also has something for parsing and working with jsn and xml. Then you need to define which classes should be converted to JavaScript. Another cool feature of GWT is that you can use this replace, replacings where you tell GWT to override some classes with something else. This means that you can also, for different browsers, define different overrides and you can separate your code and this is some sort of dependency injection which allows you to override stuff that's deep in GWT. The UI is using widgets which are Java classes and you start by defining some root panel which corresponds to a single element on your page. Then you just connect, make all of the other widgets part of the root widget. The GWT takes care of rooting the events. In JavaScript when you remove something from the dome all the event handlers are also removed. But thanks to the specific event handling in GWT it somehow emulates the event distributions and takes care of this. But you have to connect all the widgets to the root. In the big round widgets are just one layer that's on top of the html so you can also work with Java classes that correspond directly to the html text but if you work with widgets then you don't have to really care too much about whether horizontal panel is now a diff or if it's a table because GWT will do that for you. With GWT we can also use some of the existing Java stack like gradle for running the compilation, JavaCC for creating the parsers. As you've seen you can enter functions and commands in GeoGebra and it's already a complex index so you don't want to write the parcel from scratch you just want to have a grammar and a parser compiled from that. JavaCC is doing a good job there. As I've shown it's possible to SASS with it and for static analysis pmd which is just analysing every file so it's working from the source. You can also use stuff like findbugs that compiles the stuff into byte code and finds bugs. It can really solve problems where you are referencing different, you have emitted in one class that always references it's parameter and from another class you parse now to this method and it will tell you that this will always fail. This is the powerful thing that the byte code is guaranteed to give you the same results as JavaScript. And you can also use the JSNI to interface GWT code with native libraries like the JS. When in GeoGebra you start a construction it's xml file plus some images plus some more xml for styles. All of that is zipped into an archive and we are using the JS for that. To sum it up, I think there are problems with GWT that it's emulating the Java objects which make it slower than if you would write your JavaScript application from scratch. We have a lot of code for mathematics. I think it's around one million lines of code and you don't want to rewrite it from scratch. So for us there was not too many other choices. The code splitting in GWT is a bit tricky so you can use something like GWTrunAsync and give it a code back and then GWT decides which classes are only referenced from the code back and which classes are referenced from outside. The generated JavaScript is split into two files, one for the code back and one for the outside. It's hard to track why all my stuff always in the main chunk, why is it not putting this class into the code back part. And so it's a little bit tricky if you have a lot of classes. Also there's some discussion about what will GWT 3.0 look like? So what we are using is GWT 2.8 and that's using code and widgets that I spoke about. And with GWT 3.0 Google wants to compile stuff first into JavaScript for closure. They want to get rid of some code that would not be compatible with this new way of compiling things. So JSNI will also be replaced by something called JSInterop which allows you to write all the code in Java and just use some annotations to define the relations to JavaScript. The cool stuff is that this forces us to separate the logic and the UI and that we can use some java tech like findbugs. We could also use the common part of our project to run Native on Android and only add the UI for that. Google also has this java2 objective c so we can run the common part on ios natively which is much faster than running the GWT compiled stuff in a web view. I think that's all.