使用 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+Jetty JSP 编译器问题的解决方法? (Java 1.5 源代码级别无法识别)