如何将 Java 源代码交叉编译为 JavaScript?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/440302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:39:02  来源:igfitidea点击:

How to Cross-Compile Java Source Code to JavaScript?

javascriptjavacode-translation

提问by Rich Apodaca

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?

给定一组 Java 源代码文件,我如何将它们编译成一个或多个可以与手工编写的 JavaScript 一起使用的 JavaScript 文件?

GWTis 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.

GWT是一种选择,但到目前为止我看到的每个示例都旨在构建精美的网站。只是将 Java 源代码转换为可以与手工编写的 JavaScript 一起使用的 Javascript 的简单用例还没有得到很好的记录

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

在 GWT 邮件列表上就这个主题开始了一个线程,但对于这是否可行,意见似乎不一。

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 thisand this.

有人给出了一个非常有用的提示,那就是查看GWT-Exporter。问题是源代码和文档都不容易获得,尽管有thisthis

edit: GWT-Exporter source code is here

编辑:GWT-Exporter 源代码在这里

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

我也看过Java2Script。但同样,我无法找到如何解决我的简单用例的示例。

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

解决这个问题的最佳方法是什么?我错过了更好的东西吗?

回答by Jacob Mattison

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).

当您使用 GWT 时,您基本上是将 UI 部分转换为 Javascript(并且假定您使用编写 Java 时提供的 UI 小部件)。在 Javascript 中只能访问一些 Java 库。通常,在 GWT 应用程序中,任何大量使用 Java 库的东西都将在服务器端运行并作为 AJAX 连接到 Javascript(GWT 为您处理)。因此,GWT 不一定会将您的完整应用程序转换为 Javascript(尽管如果您愿意限制对 Java 库和某些功能的使用,它也可以)。

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.

无论如何,如果这种方法(从 Javascript 中调用服务器上运行的 Java)对您有吸引力,一个不错的选择是DWR,它基本上允许您的 Javascript 直接调用服务器上运行的 Java 类中的方法(无需您构建 Web 服务或其他前端)。不是你问的,我知道。

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

更相关的是,看起来有一个示例应用程序的源代码,演示了 gwt-exporter 的使用

回答by Brad Peabody

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?

给定一组 Java 源代码文件,我如何将它们编译成一个或多个可以与手工编写的 JavaScript 一起使用的 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.

内置的 Java API 和 Java 语言特性与 JavaScript 的特性之间没有直接关联。因此,任何创建“转换器”的尝试都将是不完整的。作为一个基本示例,Java 类没有直接对应的 JavaScript 习语。

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.

也就是说,我对解决您的问题的建议是首先尝试使用GWT:设置一个演示项目,放入库的源代码并从 JavaScript 端调用它,然后查看 GWT 在它的 .js 文件中输出的内容。此处其他海报建议的其他一些工具也绝对值得一试。

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.

你没有说明你的项目的源代码有多大,但如果它很小(比如少于一千行代码),即使是手工完成的转换也不应该是非常困难的。如果它比那个大得多,我建议您检查一下您是否真的想要它作为 JavaScript 代码。

回答by will

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

这是另外两个选项,需要研究的内容和第三个选项不转换,只是住在一起。

  1. Java2Javascript
  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.

一个 Eclipse Java 到 JavaScript 编译器插件和一个 JavaScript 版本的 Eclipse 标准小部件工具包 (SWT) 与其他常用实用程序的实现,例如 java.lang.* 和 java.util.*。您可以通过 Java2Script Pacemaker 将基于 SWT 的富客户端平台 (RCP) 转换为富 Internet 应用程序 (RIA)。

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

Javascript 经验有限的 Java - 您需要移植必要的依赖项或通过 jQuery 等工具找到替代方案。

  1. DukeScript
  1. 杜克脚本

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.

当我查看 DukeScript 时,它会编译一些前端 Javascript 并从浏览器的 Javascript 调用后面的 Java。它似乎或多或少是一种混合方法,因此您可以使用来自 Javascript 的 Java 库。我会违反 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.

利用 Java 运行时的更完整的 Java 体验。如果我想在浏览器环境之外使用它,我会在 Java 上使用 Javascript。

  1. Nashhorn
  1. 纳什霍恩

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.

将此视为使用 Java 资源作为 Javascript 基础的示例:Nashorn 和 JavaFX,作为富 Javascript 操作客户端的示例。无论如何,使用 Java 中的 Javascript 引擎,您不需要在 Javascript-VM 到对象代码到 Java-VM 之间进行太多转换。

回答by Katona

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

虽然问题是关于将 Java 源代码编译为 JavaScript,但我认为值得一提的是,TeaVM可以将 Java 字节码编译为 JavaScript。我从未尝试过,但似乎很有希望。

回答by Renaud Pawlak

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.

我不确定它是否适合您的用例,但是如果您同意放弃 Java API 并使用 Java 中的 JavaScript API,那么您可以使用JSweet,这是一个构建在 TypeScript 之上的 Java 到 JavaScript 的转译器。它使您可以访问数百种类型良好的 JavaScript API(DOM、jQuery、下划线、angularjs 等)。它生成 JavaScript 代码,您可以将其与遗留的 JavaScript 和 TypeScript 代码混合使用。

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

注意:JSweet不适用于遗留 Java 代码和遗留 Java API,但您的用例没有提到重用遗留代码。

[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.

[更新] 从 1.1 版开始,JSweet 现在还支持一些 Java API,例如 Collections (java.util)。因此,可以在一定程度上重用遗留 Java 代码。添加您自己的 Java API 支持也非常简单。

回答by Fabian Zeindl

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

不完全是主题,但Kotlin是一种 100% 兼容 Java 的语言,可以编译为 JavaScript。

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

IntelliJ IDEA 可以自动将 Java 转换为 Kotlin 并编译运行在 Node 或浏览器上。

回答by Jaime

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?

给定一组 Java 源代码文件,我如何将它们编译成一个或多个可以与手工编写的 JavaScript 一起使用的 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.

尽管有许多将 Java 应用程序转换为 Javascript的解决方案,但您对新的 javascript 代码可能与生成的代码进行交互的解决方案感兴趣。这是其他答案的更新(如 2018 年)。

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.

有不同类型的工具。例如,您可能会找到允许您 (1) 将 java 代码转换为 javascript 的工具;(2) 将字节码转换为 javascript、asm.js 或 webassembly;(3) 直接在浏览器中执行 java 应用程序和 (4) 创建结合 java 和 javascript 的解决方案。您必须根据您的要求选择要使用的解决方案。



Converting Java source code to Javascript

将 Java 源代码转换为 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.

一些解决方案采用 java 源代码并生成 javascript 等效版本。通常,这些解决方案将 Java 转换为 Javascript,但并不支持 Java 运行时的所有行为和库。生成的代码可能不支持某些 Java 标准库。通常,它们用于使用 Java 创建 HTML 应用程序,但不用于迁移代码。优点:最终的解决方案可能包含非常小的文件。您可以使用它来重用您自己的业务逻辑类,而无需考虑 GUI 或特定于平台的库。缺点:您可能无法使用 Java 平台的某些功能。它需要访问源代码。

  • JSweetconverts 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
  • JSweet将 Java 转换为 javascript。它包括 1000 多个 javascript 库的 API 绑定。您可以编写使用这些库的 Java 代码。
  • j2s是 Eclipse RAP 平台用于将 java 代码转换为 javascript 的编译器。它用于将 SWT (GUI) 小部件转换为 javascript 和 HTML。它不支持所有的 Java 标准库


Converting Javascript bytecode to javascript

将 Javascript 字节码转换为 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.

这些解决方案采用已编译的 java 代码(.class 文件)并在 javascript、asm.js 或 webassembly 中生成等效代码。考虑到 java 代码可能依赖于 java 标准库(即 JRE),这些解决方案通常包括移植和预编译库。优点:您不需要更改代码中的任何内容。您也不需要源代码。缺点:最终的解决方案可能需要加载大量文件。

  • 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 vmjavascript 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 pluginand 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 mainmethod 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.
  • Bck2Brwsr,一个 Java VM,可以将 Java 字节码提前编译为 javascript。它为每个 .jar 文件生成一个 javascript 文件。
    • 您可以使用vmjavascript 对象将类加载到 javascript 中并执行静态方法(使用vm.loadClass(.., function(class){..}})。gradle 插件maven 任务的文档中有一个示例。
  • TeaVM是另一个 Java VM,可以提前将代码转换为 javascript。与 Bck2Brwsr 相比,它支持线程,为所有类生成单个文件并提供更好的调试支持。
  • DukeScript,使用 Bck2Brwsr 或 TeaVM 将 java 代码和字节码转换为 javascript。
  • Dragome,将 java 字节码转换为 javascript。
  • CheerpJ (一种商业产品)可以使用 Swing 和 AWT 运行完整的 Java 应用程序。它提供了一个非常完整的javascript环境,支持操作系统、线程和网络功能。
    • 它提供了完整的运行时 API。您可以main使用cheerpjRunMain( <class>, <jar> ). 您可以使用创建对象cjNew( <class>, <params>...)并使用调用静态方法cjCall( <class>,<method>,<params>...)。您可以考虑许多其他方法。


Running Java code in Javascript

在 Javascript 中运行 Java 代码

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 是一个用 Typescript 编写的完整 JVM。优点:它模拟了操作系统的许多元素,包括文件系统、TTY 控制台和线程。缺点:考虑到它是一个interpeter,它可能会比其他解决方案慢。(我没有测试过)

  • DoppioJVMis a JVM written in Typescript
    • The documentationincludes 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.
  • DoppioJVM是一个用 Typescript 编写的 JVM
    • 文档包括用于加载和运行类的代码片段。您可以使用jvm.runClass( <class>, [ <args>...], function(response){..}). 您可以运行 Jar 文件并执行许多其他任务。


Create applications combining Java and Javascript

创建结合 Java 和 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.

其他一些解决方案不仅提供用于编译代码的工具,还提供用于创建 java 和 javascript 解决方案的框架和解决方案。例如,CheerpJ 具有用于图形用户界面的完整版本的 Swing 和 AWT 库,但它们可能会导致速度非常慢。您可以使用在浏览器上运行速度更快的新 HTML 版本来替换用户界面。优点:您可以不加更改地重用现有代码,主要是一些库和业务逻辑。您可以从您的解决方案库中删除在浏览器中运行不高效的解决方案库。缺点:如果你想保持你的 Java 桌面版本,你必须为浏览器处理不同的代码。



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, Dukescriptor 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.
  • 如果你想重用你自己创建的几个类,你可以试试JSweet。您可以创建 javascript 模块(库),您可以轻松使用 javascript 和 typescript。
  • 如果您想重用依赖多个 Java 库的大中型代码库,您可以尝试CheerpJDukescriptDragome。您可以重用大部分代码,并使用对浏览器更友好的技术(逐渐)创建用户界面和客户端到服务器的通信。
  • 如果你想不加改变地运行完整的java应用程序,你可以试试CheerpJ。它可以运行 Swing 和 AWT 用户界面。它还提供了一个Applet 运行程序