写点什么

在 Fedora Core 上交付 Java 应用

  • 2007-12-17
  • 本文字数:2508 字

    阅读完需:约 8 分钟

编者注:本文介绍的内容主要是基于 Fedora4 版本,尽管现在 Fedora 已经发布了 8 版本,但经过内部讨论我们还是决定发布这篇文章,原因在于本文提供了一个很好的开发思路,相信对读者会有帮助!

在 Fedora 的发布版中,Fedora4 是首个包含了大量用 Java 编程语言编写的代码的版本。正是由于 GNU 类路径(Classpath)和 GNU gcj(GNU Compiler for Java)的改进才促成了这些附加部分。

GCJ 基础

首先,GNU gcj 不是 Java。

然而,gcj 的目标是实现一个完整的系统,该系统兼容于 Java 并且将预编译器(ahead-of-time compiler)置于中心。它拥有一个基于 GNU 类路径的净化类库和一个内置的解释器。其编译器可以将 Java 源文件、类文件、甚至是整个 jar 文件编译成目标码。

以前 gcj 对待 Java 采取的是一种“激进且传统”的方式,它认为 Java 好像是 C++ 的某个不常用的方言似的。这么做有好的一面,然而不幸的是两者的运行时链接模型差异太大——因此当遇到一些规模比较大、复杂度比较高的 Java 应用时,这种方法就无能为力了,特别是面对那些有着复杂的类加载机制的 Java 应用时,显得尤为突出。

在 GCC4.0 的发布版中,我们对 gcj 实现了一种新的编译方式,称之为二进制兼容性 ABI(Binary Compatibility Application Binary Interface)。这种编译方式将所有的链接推迟到运行时刻进行并且完全实现了 Java 的二进制兼容规范——正好是让预编译的代码与类装载结合所需要的。

我们还增加了一个类映射数据库。在运行时,只要我们定义好一个类,gcj 运行时(叫做“libgcj”)就会在数据库中寻找这个类。如果找到该类(注意我们这里使用的是类的“内容”,而不仅仅是类名),那么 libgcj 就会映射到该共享库中,该库包含了编译后的类。

这两个改变使得我们可以做一些更强大的事情:我们可以预编译 Java 程序而不必要求任何应用级的改变。此外,由于采用了新的方式对字节码进行校验,我们还能确保编译的代码在运行时的类型安全。

构建 RPM

在 Fedora Core 上构建 Java 应用是很简单的——现存的构建方式不会发生变化。Fedora Core 舶来了“Ant“并且使用来自 Eclipse 的 Java 编译器将 Java 代码编译成字节码。

描述如何编写 RPM 已经超出了本文讨论的范围,但是 Fedora RPM 指南上有一些有用的信息,JPackage 上也有一些 Java 特定的指南。

一旦你的程序被编译成字节码,你就可以将他们编译为本地代码。因为 gcj 尚不包含一个即时编译器(JIT),这就是其获得合理性能的方法。在某些情况下,其性能可能会超过已有即时编译器,因为 gcj 使用了共享库……当你同时运行应用程序的多个实例时,你就会看到这种巨大的差异。

Fedora 提供了两个程序,使得本地编译包的工作变得更简单。我们在构建 RPM 时会使用到他们。

第一个程序是“aot-compile-rpm”。它会搜索 jar 文件并且使用 gcj 将他们编译到共享库中。aot-compile-rpm 知道一些 gcj 特定的技巧,例如在编译前将比较大的 jar 文件分割为若干个小的文件(在运行时编译一个大的 jar 文件将耗费大量内存资源),在链接结果共享库时使用–Bsymbolic(这会导致运行时性能改善)。

假如你没有在构建 RPM,那么一个替代方案就是直接将程序中的 jar 文件编译到共享库中。这里我展示一个最简单的方法(我之前提到过,对于一个大的 jar 文件,这样做会非常慢):

gcj -fjni -findirect-dispatch -fPIC -shared \
-Wl,-Bsymbolic -o foo.jar.so
foo.jar

分解一下:

  • -fjni 告诉 gcj 在 Java 代码中的本地方法(native methods)是用 JNI 实现的。
  • -findirect-dispatch 告诉 gcj 使用二进制兼容性 ABI(Application Binary Interface)。
  • 当构建一个共享库时我们需要使用 -fPIC 和 -shared
  • -WI 和 -Bsymbolic 告诉链接器在可能的情况下绑定共享库中的引用。

Fedora Core 提供的第二个有用的程序是 rebuild-gcj-db。当安装或者卸载一个 RPM 改变了全局类映射数据库时,我们将使用该程序,并且该程序应该运行在 RPM 的 %post 和 %postun 部分。

rebuild-gcj-db 根据约定来运转——它假设每个包在目录 /usr/lib/gcj(对于多架构操作系统中 64 位的包,目录为 /usr/lib64/gcj,有相应的 RPM 宏去解决这个问题)下的某个地方安装自己的类映射数据库。然后它循环遍历所有的这些个体数据库并且把他们整合到运行时使用的全局数据库中。

注意到使用 gcj 去编译一个 Java 程序并不总是能成功的。Gcj 的类库尚不完整,有时程序会使用到某些尚未实现的 API。例如,Swing 目前仍在积极开发中。同样,尽管 Sun 公司已经发布了警告,一些包使用了私有的com.sun.* 或者sun.* 下的APIs,——然而一般来说,gcj 并没有实现他们。

谁在使用?

Fedora Core 4 使用了 gcj 来为很多应用程序进行编译。

  • 首先,Fedora 包含了 ant 以及 ant 的很多依赖,以此来编译和运行其他 Java 程序。它也包含了 Eclipse 的 Java 编译器。
  • Tomcat 及其依赖。
  • OpenOffice 中的 Java 代码。
  • Eclipse IDE 和一些插件,比如 CDT。

Fedora5 中的新面孔:

  • RSSOwl ,一个 RSS 阅读器。
  • Azureus ,一个强大的 BitTorrent 客户端。
  • Frysk ,一个用来监控运行的进程或线程的执行分析技术。

JOnAS 应用服务器,一个 J2EE 实现,也在进行中但是它还尚未通过 Fedora Extras 的审查。

接下来的工作

在过去的一年中,GNU Classpath 社区向着目标大踏步地前进,我们期望在 2006 年能继续保持这个势头。我们有一个经常更新的 API 比较页面;你可以在这里追踪我们API 的状态。

我们也在为gcj 的核心改进而努力工作着:将编译器,运行时和类库更新到Java5。

最后,我们正在libgcj 里实现Java 的安全架构。这会实现一个 Mozilla 的插件 netx (Java Web Start 的一个实现)。

个人简介

Tom Tromey 于 1990 年毕业于加利福尼亚理工学院。现主要从事 Red Hat 下的 GNU Java 编译器和运行时开发工作。他编写了 GNU Automake。

查看英文原文: Delivering Java Apps on Fedora Core - - - - - -

译者简介:张龙,同济大学软件工程硕士,现就职于理光软件研究所。主要从事文档工作流和办公自动化解决方案的研发工作。热衷于 Java 轻量级框架的研究,对敏捷方法很感兴趣。曾有若干年的 J2EE 培训讲师经历。参与 InfoQ 中文站内容建设,请邮件至 china-editorial[at]infoq.com

2007-12-17 00:30792
用户头像

发布了 88 篇内容, 共 265.1 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

架构师训练营第十三周课程笔记及心得

Airs

IoT数据模型设计

soolaugust

物联网 IoT 数据模型 工业物联网 七日更

第九周总结

小兵

测开之函数进阶· 第1篇《递归函数》

清菡软件测试

测试开发

架构一期第十三周作业

Airs

训练营第十三周作业 1

仲夏

极客大学架构师训练营

LeetCode题解:92. 反转链表 II,递归,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

蚂蚁集团下架互联网存款产品:互联网金融是天使还是魔鬼

石头IT视角

与前端训练营的日子 --Week08

SamGo

学习

点个外卖,我把「软中断」搞懂了

小林coding

Linux 操作系统

工作3年,看啥资料能月薪30K?

小傅哥

Java 面试 小傅哥 七日更 技术成长

第九周-作业一

ray-arch

盘点2020 | 21 张图总结我的 2020 年

Geek_z9ygea

盘点2020

DeFi平台DAPP软件系统开发

系统开发

JVM 垃圾回收原理

梧桐

MySQL修改账号密码方法大全

Simon

MySQL 七日更

Synchronized用法原理和锁优化升级过程(面试)

叫练

synchronized 轻量级锁 偏向锁 多线程与高并发 同步

盘点2020 | 干饭人 cxuan 活下来了

苹果看辽宁体育

学习 总结 盘点2020

阿里 10 年:一个普通技术人的成长之路

阿里巴巴云原生

阿里云 云原生 技术人 自我思考 职场成长

4. 上新了Spring,全新一代类型转换机制

YourBatman

Spring Framework 类型转换 Converter

盘点2020|从写程序到写文章,一个宅男程序猿到平台写手的心路历程

罗小龙

程序猿 盘点2020 心路历程 宅男 平台写手

围观|第一代云原生企业米哈游如何让想象发生?

阿里巴巴云原生

阿里云 最佳实践 运维 云原生 游戏开发

快手基于 Apache Flink 的优化实践

Apache Flink

flink

Java并发编程:AQS的原子性如何保证

李尚智

Java java 并发

Linux 如何实现定时调度任务

Near

Linux Timer 定时调度

生产环境全链路压测建设历程 15:达成了99.99%,建设了哪些稳定性产品、工具?

数列科技杨德华

全链路压测 七日更

一文搞懂 CountDownLatch 用法和源码!

苹果看辽宁体育

Java 源码 并发

ETHERZ流动性挖矿系统软件APP开发

系统开发

训练营第十三周作业 2

仲夏

Cache Design Patterns

邵俊达

《面试官不讲武德》对Java初级程序猿死命摩擦Http协议

Silently9527

面试 https HTTP 图解https

在Fedora Core上交付Java应用_Java_Tom Tromey_InfoQ精选文章