使用 GWT 编译器的 Java 到 JavaScript

Posted

技术标签:

【中文标题】使用 GWT 编译器的 Java 到 JavaScript【英文标题】:Java to JavaScript using GWT compiler 【发布时间】:2012-01-15 02:40:34 【问题描述】:

我编写了一些想要转换为 javascript 的 Java 代码。 我想知道是否可以使用 GWT 编译器将提到的 Java 代码编译成 JavaScript 代码保留所有方法、变量和参数的名称。 我尝试使用 -draftCompile 关闭代码优化来编译它,但方法名称被破坏了。 如果 GWT 编译器不能做到这一点,可以使用其他工具吗?

更新

Java 代码只依赖于 GWT 模拟类,因此 GWT 编译器肯定能够处理它。

更新 2

这个Java方法:

public String method()

被翻译成这个 JavaScript 函数:

function com_client_T_$method__Lcom_client_T_2Ljava_lang_String_2()

使用编译器选项:

-style DETAILED
-optimize 0
-draftCompile

因此无法保留名称。但是有没有办法控制它们的变化方式?

澄清

例如,假设您有一个用 Java(或其他一些简单的数学实用程序)编写的排序算法。 sort() 方法接受一个整数数组。并在排序后的数组中返回这些整数。现在说,我同时拥有 Java 和 JavaScript 应用程序。我想用 Java 编写一次这个方法,通过 GWT 编译器运行它,或者保持方法名称相同,或者让它以可预测的方式更改,这样我就可以检测到它并知道如何将它改回 sort( )。然后我可以将该代码放入我的 JavaScript 应用程序并使用它。如果 Java 版本发生变化,我也可以自动重新生成它。从技术上讲,我有一个很好的理由,我对 GWT 的概念有很高的理解,我只是在寻找这个问题的答案。

结论

主要问题的答案是。 虽然可以保留方法名称,但它的主体是不可用的。其中的方法调用分散在生成的文件中,因此,它们不能用于 JavaScript 库,而这正是本主题的重点。

【问题讨论】:

否 - 您可以自己查看编译器标志:code.google.com/intl/de-DE/webtoolkit/doc/latest/… 没有以所需方式更改编译器行为的选项。 使用 -style PRETTY 而不是 DETAILED 进行测试 - 也许这样就可以了。 从“$”开始的部分是否是一些可预测的字符串,直到下一个下划线? PRETTY 对方法名称的破坏要少得多。对于method(),我现在得到$method()。我们正在取得进展:)。 我知道这是旧的,但如果其他人偶然发现它,这看起来很有希望:code.google.com/p/gwt-exporter 【参考方案1】:

不 - 这在 GWT 编译器中是不可能的,因为 GWT 编译器的构建是为了从 Java 中生成优化且性能非常好的 JavaScript。

最大的优势是,您可以在 Java 中维护您的项目并使用 GWT 将其编译为 JavaScript。因此没有必要阻止 JavaScript 结果中的变量名和方法名,因为所有更改和工作都在 JAVA 源中完成。

在 GWT 的 JavaScript 输出中工作并不是那么容易,而且确实需要大量工作!

更新

通过 David 的提示,我找到了 Compiler-Option "-style"。您可以尝试以下选项:

-style=PRETTY -optimize=0

我不知道这是否真的会生成“人类可读”的代码。我认为不会,因为 GWT 框架仍将是生成的 JavaScript 的一部分,因此很难对 JavaScript 结果进行更改。试试看,让我们知道...

【讨论】:

为什么这个答案会被否决?这对我来说很有意义。将 Java 语义映射到 JavaScript 通常是一个非常困难的问题,GWT 通过针对 Web 客户端行为等进行简化。 不正确。 GWT 编译器可以选择优化code.google.com/webtoolkit/doc/latest/…,它还可以选择根本不压缩输出(PRETTY 或 DETAILED)。提问者说他​​想知道这是否可能,而不是使用 GWT 有什么优势。 @David 最初的问题没有提供任何关于 Java 源代码性质的描述。例如,GWT 仅支持一小部分标准 JDK 库。在“只是一些 Java 代码”的一般情况下,不一定首先针对 GWT 编写,很可能 GWT 完全没用。 生成的编译器输出将在 GWT 项目之外使用,因此它必须是可读的。 @Pointy 我假设发布者理解这一点,也许他可以澄清一下。我假设问题是,假设他有数学、集合和其他基本操作(即没有小部件、输入操作等),他能否将他用 Java 编写的代码翻译成 JavaScript 并针对这些方法执行调用(并希望函数名称是可预测的)。我的反对意见是说必须优化 GWT 输出,现在已经澄清并因此删除。【参考方案2】:

虽然您可以将编译器设置为输出“漂亮”代码,但我建议您为要从 GWT 项目外部调用的类编写导出函数。我相信 GWT 文档中的某处详细说明了如何执行此操作,但我找不到它,所以这里是我刚刚创建的示例。

class YourClass 
    public YourClass() 
        ...
    

    public void yourMethod() 
        ...
    

    public static YourClass create() 
        return new YourClass();
    

    public final static native void export() /*-
          $wnd.YourClass = function() 
              this.instance = new @your.package.name.YourClass::create()()
          

          var _ = $wnd.YourClass.prototype;
          _.yourMethod = function() this.instance.@your.package.name.YourClass::yourMethod()()
    -*/;

编辑

详细地说,您的代码会像平常一样被混淆,但是由于导出功能,您可以轻松地在外部引用这些函数。您不必在 JavaScript 中重写 Java 类中的任何内容。你只用 JavaScript 编写引用,所以你可以这样做:

var myInstance = new YourClass();
myInstance.yourMethod();

当然,您必须从 GWT 应用程序中的某个位置(很可能在您的 EntryPoint 中)调用静态导出方法才能完成这项工作。

有关从 JavaScript 引用 Java 方法的更多信息: http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html#methods-fields

【讨论】:

假设我要保留 Java 代码,这种方法会起作用。我只需要一个工具来将 Java 方法转换为 JavaScript 函数。为了省去在 JavaScript 中重新实现相同算法的麻烦。 但是您可以使用此方法来识别编译器创建的相关 JavaScript 函数。您要求一个可预测的命名方案,就是这样! window.YourClass.yourMethod 将指向 JavaScript 中的新混淆名称。【参考方案3】:

也许我可以回答您的第二个问题:“如果 GWT 编译器不能做到这一点,其他工具可以吗?”

我使用Java2Script 已经有一段时间了,也用于相当大的项目。与本机 JavaScript 集成很好,名称得以保留,一段时间后,甚至可以轻松地将生成的 JavaScript(在浏览器调试器中)与原始 Java 代码匹配。

乌多

【讨论】:

【参考方案4】:

您可以通过编写调用它的内联 JavaScript 来“导出”您的函数,当您使用 @Export 和类似方法注释类和方法时,有一个工具 gwt-exporter 会自动执行此操作。更多信息:https://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLibrariesToJavascript_en

【讨论】:

以上是关于使用 GWT 编译器的 Java 到 JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

GWT 2.5.1编译始终抛出Java堆空间错误

GWT:从服务器中分离 js + css + 图像

GWT+Jetty JSP 编译器问题的解决方法? (Java 1.5 源代码级别无法识别)

Maven - 添加源依赖;但 Eclipse 中没有可用于 GWT 编译的 Java 源文件

如何将类型添加到 GWT 的序列化策略白名单?

GWT 中的 PropertyChangeSupport