How to Cross-Compile Java Source Code to JavaScript?
Asked Answered
A

8

54

Given a set of Java source code files, how can I compile them into one or more JavaScript files that can be used with hand-crafted JavaScript?

GWT is one option, but every example I've seen so far is aimed at building fancy websites. The simple use case of just converting Java source to Javascript that can be used together with handcrafted JavaScript hasn't been well-documented.

I started a thread on the GWT mailing list on this subject, but opinions seem to be mixed on whether this is even feasible.

One person gave a very useful tip, which was to check out GWT-Exporter. The problem is that neither source code nor documentation is readily available, although there's this and this.

edit: GWT-Exporter source code is here

I've also seen Java2Script. But again, I wasn't able to find examples of how to solve my simple use case.

What's the best approach to this problem? Is there something better I'm missing?

Aluminothermy answered 13/1, 2009 at 19:1 Comment(3)
This question discusses a very similar topic: compiling Java libraries to JavaScript using GWT. #3126056Pinnule
Very thorough question. You did a great job expressing what you'd explored already. Nicely done.Kelsi
You can try using Scala-js github.com/lampepfl/scala-js for your java project - java/scala interoperability scala-lang.org/old/faq/4)Eatables
E
12

When you use GWT, you're basically converting the UI portion into Javascript (and it assumes that you use the UI widgets provided when you write your Java). Only some of the Java libraries are accessible within Javascript. Typically in a GWT application anything that makes heavy use of Java libraries would run on the server side and connect to the Javascript as AJAX (which GWT handles for you). So GWT isn't necessarily converting your full application into Javascript (though it can if you're willing to limit your use of Java libraries and some functionality).

At any rate, if this approach (calling out to Java running on a server from within Javascript) appeals to you, one nice option is DWR, which basically allows your Javascript to directly call methods in Java classes running on the server (without you having to build a web service or other frontend). Not what you asked, I know.

More relevantly, it looks like there's source code for a sample app demonstrating the use of gwt-exporter.

Erastes answered 13/1, 2009 at 19:47 Comment(5)
This would be for a fairly small, non-gui java library. I hadn't seen DWR, which looks like it could be very useful for larger projects. I Didn't even see the source directory for the gwt-exporter project - thanks for pointing it out. That looks promising.Aluminothermy
Here's a new link to the sample app: code.google.com/p/gwt-exporter/source/browse/trunk/samples/src/…Erastes
The new link is also dead. :/Pinnule
And here's a new link: code.google.com/p/gwt-exporter/source/browse/samples/…Erastes
Also, here's a link to the project home of gwt-exporter -- that's less likely to change (the sample app changes location when they change their directory format): code.google.com/p/gwt-exporterErastes
P
10

I am not sure if it fits your use case, but if you agree to drop Java APIs and use JavaScript APIs from Java, then you can use JSweet, a Java to JavaScript transpiler built on the top of TypeScript. It gives you access to hundreds of well-typed JavaScript APIs (DOM, jQuery, underscore, angularjs, etc). It generates JavaScript code and you can mix it with legacy JavaScript and TypeScript code.

Note: JSweet will not work for legacy Java code and legacy Java APIs, but your use case did not mention reusing legacy code.

[UPDATE] Since version 1.1, JSweet now also supports some Java APIs such as Collections (java.util). So, it is possible to reuse legacy Java code to a certain extent. It is also quite straightforward to add your own support for Java APIs.

Pyxis answered 16/12, 2015 at 9:57 Comment(2)
this seems too strict. It says it can't find class X,Y,Z. Is there any way to make it less strict? I just need a TS approximation even, where i can fix whatever leftover errors there are by hand. I just want something i can point to a package structure, and then it spits out a TS equivalent. Can jsweet do this?Annabellannabella
I hope that https://mcmap.net/q/340213/-installed-jsweet-now-what will give enough details on that matter.Pyxis
G
10

Given a set of Java source code files, how can I compile them into one or more JavaScript files that can be used with hand-crafted JavaScript?

Although there are many solutions to convert Java applications to Javascript, you are interested on a solution where new javascript code may interact with the resulting code. This is an update (as 2018) of the other answers.

There are different types of tools. For instance, you may find tools that allow you (1) convert java code to javascript; (2) convert bytecode to javascript, asm.js or webassembly; (3) execute java applications directly in the browser and (4) create solutions that combine java and javascript. You must select the solution to use depending on your requirements.


Converting Java source code to Javascript

Some solutions take java source code and produce a javascript equivalent version. Usually, these solutions transforms the Java to Javascript, but do not support all the behaviours and libraries of the Java runtime. The resulting code may not support some java standard libraries. Typically, they are used to create HTML application using Java but not for migrating the code.
Pros: The resulting solution may include very small files. You can use it to reuse your own business logic classes without considering GUI or platform specific libraries.
Cons: it is possible that you cannot use some functionalities of the Java platform. It requires access to the source code.

  • JSweet converts Java to javascript. It includes API bindings for 1000+ javascript libraries. You can write java code that use these libraries.
  • j2s, is the compiler used by the Eclipse RAP platform to translate java code to javascript. It is used there to convert the SWT (GUI) widgets to javascript and HTML. It does not support all the Java standard libraries

Converting Java bytecode to Javascript

These solutions take compiled java code (.class files) and produces equivalent code in javascript, asm.js or webassembly. Considering that the java code may depend on java standard libraries (i.e., the JRE), these solutions typically includes ported and pre-compiled libraries.
Pros: you do not need to change anything in your code. You do not need the source code neither.
Cons: the resulting solution may require the load of a lot of files.

  • Bck2Brwsr, a Java VM that may compile ahead-of-time the java bytecode to javascript. It produces a javascript file for each .jar file.
    • You may use the vm javascript object to load a class into javascript and execute static methods (using vm.loadClass(.., function(class){..}}). There is an example in the documentation for the gradle plugin and the maven task.
  • TeaVM, is another Java VM that may convert ahead-of-time the code to javascript. In contrast to Bck2Brwsr, it supports threads, produces a single file for all your classes and provide better debugging support.
  • DukeScript, transpile java code and bytecode to javascript using Bck2Brwsr or TeaVM.
  • Dragome, transpile java bytecode to javascript.
  • CheerpJ (a commercial product) may run complete java applications using Swing and AWT. It provides a very complete javascript environment that support operating system, thread and network functionalities.
    • It provides a complete runtime API. You can run a main method using cheerpjRunMain( <class>, <jar> ). You can create objects using cjNew( <class>, <params>...) and invoke static methods using cjCall( <class>,<method>,<params>...). There are many other methods you may consider.

Running Java code in Javascript

DoppioJVM is a complete JVM written in Typescript.
Pros: It emulates a lot of elements of the operating system, including filesystems, TTY consoles and threads.
Cons: Considering that it is an interpeter, it may result slower than other solutions. (I have not tested it)

  • DoppioJVM is a JVM written in Typescript
    • The documentation includes snippets of code to load and run the classes. You can run a static method using jvm.runClass( <class>, [ <args>...], function(response){..}). You can run a Jar file and perform many other tasks.

Create applications combining Java and Javascript

Some other solutions provide, not only the tools for compiling the code, but also frameworks and solutions to create java and javascript solutions. For instance, CheerpJ has complete versions of the Swing and AWT libraries for graphical user interfaces, but they may result very slow. You may replace the user interface by using new HTML versions that run faster on the browser.
Pros: You can reuse existing code without changes, mainly some libraries and business logic. You may remove from your solutions libraries that run not efficiently in the browser.
Cons: If you wanna keep maintaining your java desktop version, you must deal with different code for the browser.


Recommendation

  • If you wanna reuse few classes created by your own, you may try JSweet. You may create javascript modules (libraries) that you can use easily with javascript and typescript.
  • If you wanna reuse a medium to large codebase that rely on multiple java libraries, you may try CheerpJ, Dukescript or Dragome. You may reuse large parts of your code and create (gradually) the user interface and client-to-server communications using technologies that are more browser-friendly.
  • If you wanna run complete java applications without change, you may try CheerpJ. It can run Swing and AWT user interfaces. It also provide an Applet runner.
Gariepy answered 15/7, 2018 at 15:11 Comment(0)
C
9

While the question is about compiling Java sources to JavaScript I think it's worth mentioning that there is TeaVM which compiles Java bytecode to JavaScript. I have never tried it, but it seems very promising.

Crumpled answered 17/11, 2015 at 17:14 Comment(0)
N
5

Here's two other options, things to look into and a third option not converting, just living together.

  1. Java2Javascript

I have been wanting to try this out -- Looks closer to what's been asked. Quoting the web page:

an Eclipse Java to JavaScript compiler plugin and an implementation of JavaScript version of Eclipse Standard Widget Toolkit (SWT) with other common utilities, such as java.lang.* and java.util.*. You can convert your SWT-base Rich Client Platform (RCP) into Rich Internet Application (RIA) by Java2Script Pacemaker.

A limited Java in Javascript experience - You'd need to port your necessary dependencies or find alternatives via tools like jQuery, etc.

  1. DukeScript

As I view DukeScript, it compiles some front-end Javascript and calls Java behind, from the browser's Javascript. It seems more or less a hybrid approach so you can use the Java wealth of libraries from Javascript. I will fall foul of a browser security policy for Java.

A more full-Javascript on Java experience leveraging the Java-runtime. If I wanted that outside the browser environment I'd use Javascript on Java.

  1. Nashhorn

Consider this as an example of using Java's resources as foundation for Javascript: Nashorn and JavaFX, as an example for a rich Javascript operated client. Anyway with a Javascript engine inside Java you're not needing to translate between a Javascript-VM to object-code to a Java-VM quite so much.

Northern answered 13/2, 2015 at 2:4 Comment(5)
Your view of DukeScript isn't entirely correct. You can also run DukeScript applications in a Browser by using TeaVM or bck2brwsr as VM.Roxie
That's my understanding, I need a ''V/M plugin" of some description. That option is not "doing javascript" it is calling Java from Javascript.Northern
bck2brwsr and TeaVM aren't plugins. Their main purpose is to run Java code in the browser without the need for a plugin. So it will not "fall foul of a browser security policy for Java."Roxie
Hi -- I need to review DukeScript, DukeScript used to require Java libraries on the target machine to run things. Or you needed to only use a limited set of methods. TeaVM looks like the idea. It doesn't say what version of Java and the Java API are supported. Does the references to GWT mean we are stack with the Java 1.6 profile from last century?Northern
The available Java API in the Browser is indeed limited. bck2brwsr has two profiles, compact (hudson.apidesign.org/view/bck2brwsr/job/bck2brwsr.javadoc/…) and mini. The idea is similar to GWT, only provide core APIs that really make sense in a browser based client. If you need the full profile you have to create a desktop application.Roxie
P
4

Not entirely on-topic, but Kotlin is a 100% Java-compatible language that can compile to JavaScript.

IntelliJ IDEA can automatically convert Java to Kotlin and compile it to run on Node or the browser.

Peroxide answered 3/9, 2016 at 12:31 Comment(2)
Kotlin has ~1MB runtime.Gilliette
This only works if the code is written 100% in Kotlin since Kotlin can't compile to Javascript if you are using Java libraries.Destinee
C
2

Given a set of Java source code files, how can I compile them into one or more JavaScript files that can be used with hand-crafted JavaScript?

There is no direct correlation between both the built-in Java API and Java language features, and those of JavaScript. So any attempt at creating a "converter" is going to be incomplete. As a fundamental example, Java classes don't have a direct corresponding JavaScript idiom.

Whether or not an incomplete conversion tool will work for your use case is impossible to know without the source code.


That said, my suggestion to solving your problem would be to first attempt to use GWT: set up a demo project, drop in the source of your library and call it from the JavaScript side and see what GWT outputs in it's .js file. Some of the other tools suggested by other posters here are definitely worth checking out as well.

If that is fruitful and gets you part of the way, great.

From there, you'll need/want to do the remainder of the conversion by hand. After all, assuming you want the code to actually function correctly, a manual review would definitely be in order. Some unit tests being converted along with it would be ideal as well.

You don't state how large the source of your project is, but if it's small (let's say less than a thousand lines of code), even a complete conversion by hand shouldn't be extremely difficult. If it's much larger than that, I would suggest reviewing if you actually want that as JavaScript code anyway.

Childs answered 5/10, 2013 at 21:12 Comment(0)
W
0

This question is from 13 years ago; yes, I know. But I'll put my addition here as this is an excellent repository of answers on the topic, and as it comes up first in a Google search it is likely to have the most eyeballs on it.

I'm a former GWT developer. And agree it is an excellent solution & technology. But also yes as mentioned, the cross compilation part mostly (arguably, completely) focuses on the W in its name (Google WEB Toolkit): the client-side JavaScript part of full stack SPA Web applications, its serialization & communication, it's client/server logic partitioning, et al.

I just stumbled onto something that is relatively new -- a 2014-2015 offshoot of GWT placed into the public domain in 2018 -- that I think is more generally focused and what was being requested in the original post (13 years ago, lol). I'm eager to try it.

J2CL: https://github.com/google/j2cl

I read about it here, which to me was a good & thorough intro of the technology (have a look and let me know if you agree or not):

https://www.infoq.com/news/2019/05/j2cl-java-javascript-transpiler/

Write answered 9/3, 2022 at 18:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.