在运行时之前,编译器将Java字节码翻译成平台无关的C代码吗?

6
我正在寻找一个编译器,在运行之前将Java字节码翻译成平台无关的C代码(Ahead-of-Time编译)。
然后,我应该能够使用标准的C编译器将C代码编译成目标平台的可执行文件。我理解这种方法只适用于某些不经常修改的Java应用程序。
那么有哪些Java到C的编译器可用?

找到了针对Oracle数据库的特定情况的链接:http://download.oracle.com/docs/cd/B28359_01/java.111/b31225/chone.htm#BABCIHGA - Rudiger
你想要实现的确切目标是什么?一个EXE文件? - Thorbjørn Ravn Andersen
好的,不是可执行文件,而是可移植的C语言源代码。 - Rudiger
Java的大部分复杂性和功能都在其库中。如果没有这些库,还有什么意义呢? - Peter Lawrey
最困难的部分不是将字节码转换为C语言(即使C语言可能很难读懂),而是要从中制作出一些东西,可以使用适用于C语言的GC或不使用GC,并且将其中每个字节码片段都翻译成集合、异常处理等内容。我真的看不出考虑它的意义所在。 - Fredrik
对于Lawrey先生的观点,我也有同样的问题。似乎可以使用Ahead-of-Time编译来以本地编译形式交付核心Java类库。 - Rudiger
7个回答

8
我可以建议一个名为JCGO的工具,它是一个Java源代码到C语言翻译器。如果你需要转换字节码,则可以使用一些工具(例如JadRetro+Jad)反编译类文件并将源文件传递给JCGO。该工具一次性翻译您的Java程序中的所有类,并生成C文件(每个类一个.c和.h文件),进而可以通过第三方工具编译成针对目标平台高度优化的本机代码。目前不支持Java泛型。支持AWT/Swing和SWT。

我会看一下;很高兴看到最近有这样的产品。 - Rudiger

3

为什么这样做?Java虚拟机包含一个运行时的Java-to-assembly编译器。

在运行时进行编译可以获得更好的性能,因为所有关于运行时值的信息都是可用的。而预先编译必须对运行时值进行假设,因此可能会产生不太快的代码。有关详细信息,请参阅Cliff Click的Java vs C performance


运行时编译可能会获得更好的性能。这取决于您的用例,就像链接中所说的那样。但这并不是将Java编译为C的原因。 - dmckee --- ex-moderator kitten
@dmckee 确实如此,加入了一些“鼬鼠词” :) - akuhn
为什么这样做?一个可能的原因是,GCC和其他C编译器针对的平台和架构比任何JIT更多,可能比所有现有JIT的联合还要多。话虽如此,如果您的目标没有适合的JIT增强JVM,那可能是因为它对于任何实际的Java代码来说都太弱了,而Java-> C->本地路线也不会起作用。 - Steve Jessop
如果你的平台不支持Java,那么用C或C++编写代码比依赖Java到本地编译器更好。它会运行得更快,更易于使用。此外,我从未听说过任何情况下Java到本地编译器能够超越Hotspot,除了启动时间。我认为你不需要使用含糊其辞的措辞。 - BobMcGee
除了本地编译的Java比较,而不是相等的... :P - BobMcGee
显示剩余3条评论

3

GCJ具备这种能力,但它对Java 1.4之后的特性支持不够完善,而且Swing支持可能会有问题。但实际上,HotSpot JIT编译器击败了所有预先编译的Java编译器。请参见Excelsior JET的基准测试

Toba将转换(旧)Java字节码为C源代码。然而,它自Java 1.1以来就没有更新过。它可能有助于部分便于移植,但它无法处理Java拥有的所有复杂库。


请问您能否提供GCC/GCJ编译成C的文档链接?谢谢。 - imz -- Ivan Zakharyaschev
GCJ编译器已不再提供。作为替代方案,可以使用TeaVMJWebAssembly将Java字节码编译为WebAssembly,然后使用wasm2c将其反编译为C。 - Anderson Green

2

1

据我所知,目前没有这样的产品,但您有两个选择:

  • 实现自己的字节码到C语言的转换器。Byte-code非常简单,这并不太难。

  • 如果您只需要本地二进制文件(即不需要C源代码),那么可以尝试使用GCJ

注意:如果您出于性能原因而这样做,那么您将会失望。Java通常与C/C++一样快。此外,VM的改进将使所有Java代码更快,但不会影响您的本地二进制文件。编译代码只会让启动时间稍微好一点。


我相信这是GCJ的一种模式,尽管它通常是从源代码编译成字节码或本地代码。不过,我同意性能较差的观点。 - BobMcGee
@BobMcGee请给我一个链接,该链接能够详细说明GCC/GCJ的将代码编译为C的功能。 - imz -- Ivan Zakharyaschev

1

0

曾经有一个名为TowerJ的产品,它本质上是Java的“通过C”静态编译器,但现在已经不存在了。

我听说Sun Labs在Sun SPOT项目中创建了类似的东西,但我不确定它是否公开。

@BobMcGee:在你提到的基准测试中,GCJ确实输了,但Excelsior JET(这是一个32位AOT编译器)在所有三个测试系统上都击败了32位HotSpot,所以我不确定你的观点是什么。

但毕竟,谎言、可恶的谎言和基准测试


哦,该死。我本以为Excelsior JET只是在进行字节码优化和专有JIT VM的测试。这就是你没有仔细阅读的后果。 - BobMcGee
1
@BobMcGee:没问题。:) 顺便说一下,许多客户购买Excelsior JET来保护他们的应用程序免受Java反编译器的攻击;只要性能与HotSpot相当,他们就不在意性能。 - Dmitry Leskov

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