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

54
给定一组Java源代码文件,如何将它们编译成一个或多个JavaScript文件,以便与手工制作的JavaScript一起使用? GWT是一种选择,但到目前为止,我看到的每个示例都旨在构建花哨的网站。仅将Java源代码转换为可与手工制作的JavaScript一起使用的Javascript的简单用例没有得到很好的记录
我在GWT邮件列表上开始了一个线程讨论这个问题,但意见似乎对是否可行存在分歧。
有人给出了一个非常有用的提示,那就是查看GWT-Exporter。问题是,既没有源代码,也没有文档可以轻易获得,尽管有这个这个
编辑:GWT-Exporter源代码在这里

我也看过Java2Script。但是,我没有找到解决我的简单用例的示例。

如何最好地解决这个问题?我是否错过了更好的东西?


这个问题讨论了一个非常相似的主题:使用GWT将Java库编译为JavaScript。https://dev59.com/a3A75IYBdhLWcg3wv77A - Anderson Green
2
非常详尽的问题。你做得很好,表达了你已经探索过的内容。做得好。 - Spina
你可以尝试在你的Java项目中使用Scala-js https://github.com/lampepfl/scala-js - Java/Scala互操作性 http://www.scala-lang.org/old/faq/4)。 - Ruslans Uralovs
8个回答

12
当你使用GWT时,基本上是将UI部分转换为Javascript(假设你在编写Java代码时使用提供的UI小部件)。只有一些Java库可以在Javascript中访问。通常,在GWT应用程序中,任何重度使用Java库的内容都会在服务器端运行,并作为AJAX连接到Javascript(GWT会为您处理)。因此,GWT不一定会将您的完整应用程序转换为Javascript(尽管如果您愿意限制对Java库和某些功能的使用,则可以这样做)。
无论如何,如果这种方法(从Javascript内部调用在服务器上运行的Java)吸引了您,一个不错的选择是DWR,它基本上允许您的Javascript直接调用在服务器上运行的Java类中的方法(而无需构建Web服务或其他前端)。我知道这不是你要求的。
更相关的是,看起来有一个演示使用gwt-exporter的示例应用程序的源代码

这将是一个相当小的非GUI Java库。我之前没有看到过DWR,它看起来对于大型项目非常有用。我甚至没有看到gwt-exporter项目的源目录 - 感谢您指出它。那看起来很有前途。 - Rich Apodaca
这是示例应用程序的新链接:http://code.google.com/p/gwt-exporter/source/browse/trunk/samples/src/main/java/exporterdemo/public/ExporterDemo.html - Jacob Mattison
1
新链接也失效了。 :/ - Anderson Green
这里有一个新链接:https://code.google.com/p/gwt-exporter/source/browse/samples/exporterdemo/src/main/java/exporterdemo/public/ExporterDemo.html - Jacob Mattison
此外,这是 gwt-exporter 项目主页的链接--它的变化可能性较小(示例应用程序在更改目录格式时会更改位置):https://code.google.com/p/gwt-exporter/ - Jacob Mattison

10

我不确定它是否适合您的使用情况,但如果您同意放弃Java API并使用Java中的JavaScript API,则可以使用JSweet,这是一个建立在TypeScript之上的Java到JavaScript转换器。它为您提供了许多类型良好的JavaScript API(DOM、jQuery、underscore、angularjs等),生成JavaScript代码,您可以将其与旧有的JavaScript和TypeScript代码混合使用。

注意:JSweet不适用于旧有的Java代码和Java API,但您的使用情况没有提到重用旧有代码。

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


这似乎太严格了。它说找不到类X、Y、Z。有没有办法让它变得不那么严格?我只需要一个TS的近似值,然后可以手动修复任何剩余的错误。我只想要一个可以指向包结构的东西,然后它会输出一个TS等效项。JSweet能做到这一点吗? - Oliver Watkins
我希望https://dev59.com/FJrga4cB1Zd3GeqPll12能够提供关于这个问题足够的细节。 - Renaud Pawlak

10
给定一组Java源代码文件,我如何将它们编译成一个或多个可以与手工编写的JavaScript一起使用的JavaScript文件?
尽管有很多将Java应用程序转换为JavaScript的解决方案,但您对一个解决方案感兴趣,其中新的JavaScript代码可以与生成的代码进行交互。这是对其他答案的更新(截至2018年)。
有不同类型的工具。例如,您可以找到允许您(1)将Java代码转换为JavaScript的工具;(2)将字节码转换为JavaScript、asm.js或WebAssembly的工具;(3)直接在浏览器中执行Java应用程序的工具;以及(4)创建结合Java和JavaScript的解决方案的工具。您必须根据您的要求选择要使用的解决方案。
将Java源代码转换为Javascript
一些解决方案可以将Java源代码转换为相应的Javascript版本。通常,这些解决方案会将Java转换为Javascript,但不支持Java运行时的所有行为和库。生成的代码可能不支持某些Java标准库。通常,它们用于使用Java创建HTML应用程序,而不是用于迁移代码。
优点:生成的解决方案可能包含非常小的文件。您可以使用它来重用自己的业务逻辑类,而无需考虑GUI或特定平台的库。
缺点:可能无法使用Java平台的某些功能。它需要访问源代码。
  • JSweet 将 Java 转换为 JavaScript。它包含了对1000多个 JavaScript 库的 API 绑定。您可以编写使用这些库的 Java 代码。
  • j2s 是 Eclipse RAP 平台使用的编译器,用于将 Java 代码转换为 JavaScript。它在此处用于将 SWT(GUI)小部件转换为 JavaScript 和 HTML。它不支持所有的 Java 标准库。

将Java字节码转换为Javascript
这些解决方案将编译后的Java代码(.class文件)转换为等效的Javascript、asm.js或WebAssembly代码。考虑到Java代码可能依赖于Java标准库(即JRE),这些解决方案通常包括移植和预编译的库。
优点:您不需要更改代码。您也不需要源代码。
缺点:生成的解决方案可能需要加载大量文件。
  • Bck2Brwsr是一个Java虚拟机,可以将Java字节码编译成JavaScript。它为每个.jar文件生成一个JavaScript文件。
    • 您可以使用vm JavaScript对象将类加载到JavaScript中并执行静态方法(使用vm.loadClass(.., function(class){..}})。文档中有一个示例,可以参考gradle插件maven任务
  • TeaVM是另一个可以将代码提前转换为JavaScript的Java虚拟机。与Bck2Brwsr不同的是,它支持线程,为所有类生成一个单独的文件,并提供更好的调试支持。
    • 您可以使用javaMethods.get(..).invoke(...)方法从JavaScript中调用Java。有关详细信息,请参考从JavaScript调用Java
  • DukeScript可以使用Bck2Brwsr或TeaVM将Java代码和字节码转换为JavaScript。
  • Dragome可以将Java字节码转换为JavaScript。
    • 您可以在Java中使用注解来标记静态方法,并在JavaScript中使用它:例如,您可以使用@MethodAlias(alias="windows.method1")来注解一个方法,并使用window.method1()从JavaScript中调用它。
  • CheerpJ (商业产品)可以使用Swing和AWT运行完整的Java应用程序。它提供了一个非常完整的JavaScript环境,支持操作系统、线程和网络功能。
    • 它提供了一个完整的运行时API。您可以使用cheerpjRunMain( <class>, <jar> )运行main方法。您可以使用cjNew( <class>, <params>...)创建对象,并使用cjCall( <class>,<method>,<params>...)调用静态方法。还有许多其他方法可供您参考。

在Javascript中运行Java代码

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

  • DoppioJVM是用Typescript编写的JVM
    • 文档中包含了加载和运行类的代码片段。您可以使用jvm.runClass( <class>, [ <args>...], function(response){..})来运行静态方法。您还可以运行Jar文件和执行许多其他任务。

创建结合Java和Javascript的应用程序

一些其他解决方案不仅提供编译代码的工具,还提供创建Java和Javascript解决方案的框架和解决方案。例如,CheerpJ具有完整的Swing和AWT库版本,用于图形用户界面,但可能会导致速度很慢。您可以通过使用在浏览器上运行更快的新HTML版本来替换用户界面。
优点:您可以在不更改现有代码的情况下重用现有代码,主要是一些库和业务逻辑。您可以从解决方案中删除在浏览器中运行效率低下的库。
缺点:如果您想继续维护您的Java桌面版本,您必须处理与浏览器不同的代码。

  • GWT将Java代码转换为JavaScript,但使用了一组不同的库来处理用户界面和客户端与服务器之间的通信。
  • Dukescript使用了之前提到的转换工具。
    • 它提供了一个Knockout4j库,可以轻松与HTML、DOM和其他JavaScript代码进行交互。
  • Dragome不仅可以转换Java代码,还可以与HTML/DOM进行交互
  • HTML/Java API是一个Apache项目,用于标准化从转换后的代码访问HTML/DOM/JavaScript
    • 它是由Dukescript和其他工具提供商捐赠的。

推荐

  • 如果你想重用自己创建的几个类,可以尝试使用JSweet。你可以创建可以轻松在JavaScript和TypeScript中使用的JavaScript模块(库)。
  • 如果你想重用依赖于多个Java库的中大型代码库,可以尝试使用CheerpJDukescriptDragome。你可以重用代码的大部分,并使用更适合浏览器的技术逐步创建用户界面和客户端到服务器的通信。
  • 如果你想运行完整的Java应用程序而不进行任何更改,可以尝试使用CheerpJ。它可以运行Swing和AWT用户界面。它还提供一个Applet运行器

9

虽然问题是关于将Java源代码编译为JavaScript,但值得一提的是,有一个名为TeaVM的工具可以将Java字节码编译为JavaScript。我从未尝试过它,但它看起来非常有前途。


5
这里有另外两个选项,需要了解的事情和第三个选项不进行转换,只是共同生活。
  1. Java2Javascript
我一直想尝试这个 - 看起来更接近所要求的内容。引用网页上的话:

一个Eclipse Java到JavaScript编译器插件和Eclipse Standard Widget Toolkit(SWT)的JavaScript版本实现,以及其他常见的实用程序,如java.lang.*和java.util.*。您可以通过Java2Script Pacemaker将基于SWT的Rich Client Platform(RCP)转换为Rich Internet Application(RIA)。

有限的Java在Javascript体验 - 您需要通过像jQuery等工具移植必要的依赖项或找到替代品。
  1. DukeScript
就我看来,DukeScript会编译一些前端Javascript并从浏览器的Javascript调用Java。它似乎是一种混合方法,因此您可以从Javascript中使用Java丰富的库。我会遇到Java的浏览器安全策略问题。

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

  1. Nashhorn

考虑将Java资源作为Javascript的基础的示例:Nashorn和JavaFX,作为一个丰富的Javascript操作客户端的示例。无论如何,有了Java内部的Javascript引擎,你就不需要在Javascript-VM到对象代码到Java-VM之间进行太多的转换了。


你对DukeScript的看法并不完全正确。你也可以通过使用TeaVM或bck2brwsr作为虚拟机在浏览器中运行DukeScript应用程序。 - monacotoni
这是我的理解,我需要一个某种描述的“V/M插件”。该选项不是“执行JavaScript”,而是从JavaScript调用Java。 - will
1
bck2brwsr和TeaVM不是插件。它们的主要目的是在浏览器中运行Java代码,而无需插件。因此,它不会“违反Java浏览器安全策略”。 - monacotoni
嗨 - 我需要审查DukeScript,DukeScript以前需要在目标机器上安装Java库才能运行。或者你只能使用有限的方法。TeaVM看起来像是个好主意。它没有说明支持哪个版本的Java和Java API。GWT的引用是否意味着我们被困在上个世纪的Java 1.6配置文件中? - will
浏览器中可用的Java API确实有限。bck2brwsr有两个配置文件,紧凑版(http://hudson.apidesign.org/view/bck2brwsr/job/bck2brwsr.javadoc/lastSuccessfulBuild/artifact/rt/emul/compact/target/site/apidocs/index.html)和迷你版。这个想法类似于GWT,只提供在基于浏览器的客户端中真正有意义的核心API。如果您需要完整的配置文件,则必须创建桌面应用程序。 - monacotoni

4

虽然不完全相关,但Kotlin是一种100%兼容Java的语言,可以编译成JavaScript。

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


2
Kotlin 运行时大小约为1MB。 - garkin
7
只有当代码完全使用Kotlin编写时,它才能正常工作,因为如果使用Java库,Kotlin无法编译成JavaScript。 - Bitcoin Cash - ADA enthusiast

2
给定一组Java源代码文件,如何将它们编译成一个或多个JavaScript文件,以便与手工制作的JavaScript一起使用?
Java API和Java语言特性与JavaScript之间没有直接的对应关系。因此,任何创建“转换器”的尝试都将是不完整的。作为基本示例,Java类没有直接对应的JavaScript习惯用法。
无法知道不完整的转换工具是否适用于您的用例,这取决于源代码。
话虽如此,我建议您解决问题的方法是首先尝试使用 GWT:设置一个演示项目,将库源代码放入其中,并从JavaScript端调用它,看看GWT在其.js文件中输出了什么。其他一些在此帖子中由其他帖子提供的工具也绝对值得一试。
如果这很有成果并让您走了一部分路,那就太好了。
从那里开始,您需要/想要手动完成剩余的转换。毕竟,假设您希望代码实际上能正确运行,手动审核肯定是必要的。最好还要转换一些单元测试。
您没有说明项目源代码有多大,但如果它很小(比如少于一千行代码),即使完全手动转换也不应该非常困难。如果它比这大得多,我建议您审查一下自己是否真的想将其作为JavaScript代码。

0

这个问题来自13年前,是的,我知道。但是我会把我的补充放在这里,因为这是一个关于这个话题答案的优秀的仓库,而且因为它在谷歌搜索中排名第一,所以很可能会有最多的人看到。

我曾经是一个GWT开发者。我同意它是一个非常好的解决方案和技术。但是也如上所述,其交叉编译部分主要(可以说完全)集中在其名称中的W(Google WEB Toolkit)上:全栈SPA Web应用程序的客户端JavaScript部分,其序列化和通信,其客户端/服务器逻辑分区等。

我刚刚偶然发现了一些相对较新的东西——GWT的一个分支,2014-2015年发布,2018年放置于公共领域——我认为它更加普遍地聚焦于原始帖子(13年前)中所请求的内容。我渴望尝试它。

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

我在这里阅读了关于它的介绍,对我来说它是一个很好的、详尽的技术介绍(看看并告诉我你是否同意):

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接