写点什么

在 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:30782
用户头像

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

关注

评论

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

Logii 指纹浏览器中如何设置代理

Geek_bf375d

爬虫 https IP 代理IP 代理IP设置

一种LED驱动专用控制电路方案

芯动大师

springboot是如何解决这些问题的?

想要飞的猪

当我遇见腾讯混元大模型|社区征文

法医

大模型

彻底搞懂Redis事务机制

程序员花卷

缓存 分布式数据库 后端 事务 redis 精讲

如何为 Windows 8.1 设置代理

Geek_bf375d

爬虫 代理IP 代理IP设置 免费代理ip 跨境电商

AI大模型驶向产业之海,需要高质数据“河道”引航

脑极体

存储

如何设置和使用 Proxifier教程

Geek_bf375d

爬虫 https IP 代理IP 代理IP设置

INFINI Labs 产品更新 | 修复 Easysearch 跨集群复制索引同步问题,Gateway 内存异常增长等问题

极限实验室

Gateway 产品更新 easysearch 极限科技

spring中的设计模式

想要飞的猪

iOS 的IP代理设置

Geek_bf375d

爬虫 https IP 代理IP 代理IP设置

文心一言 VS 讯飞星火 VS chatgpt (147)-- 算法导论12.2 2题

福大大架构师每日一题

福大大架构师每日一题

为什么美国程序员工作比中国程序员工作轻松、加班少?

代码生成器研究

《三国杀》完成鸿蒙原生应用开发,更多游戏品类加入鸿蒙生态

最新动态

SQL 算术运算符:加法、减法、乘法、除法和取模的用法

小万哥

MySQL 数据库 程序员 sql 后端开发

Spring Boot 外部化配置的应用

玄兴梦影

ZK的数据结构以及协议

想要飞的猪

企业数字化转型,如何战略性的使用数据和 IT ?

飞算JavaAI开发助手

如何在VMMask指纹浏览器中设置代理

Geek_bf375d

爬虫 https IP 跨境电商 TikTok

2023年度盘点:10款好用的AI图片生成工具推荐!总有一款是你的菜。

彭宏豪95

人工智能 设计 在线白板 AIGC AI绘画

Windows 10 上的代理设置

Geek_bf375d

爬虫 https IP 代理IP 代理IP设置

如何在 PS4 中添加IP代理

Geek_bf375d

爬虫 https 代理IP 代理IP设置 跨境电商

Windows 11 的代理设置:启用和禁用

Geek_bf375d

爬虫 IP 代理IP 代理IP设置 HTTPS协议

Linux的代理设置

Geek_bf375d

爬虫 代理IP 代理IP设置 跨境电商 HTTPS协议

关于VO/DTO/DO/PO价值的思考

姚秋实(Nacol)

Java 设计模式 架构设计 架构师

低代码开发平台真的靠谱吗?

代码生成器研究

Android 上的代理设置

Geek_bf375d

爬虫 代理IP 代理IP设置 跨境支付 HTTPS协议

springMVC是如何处理请求的与Spring容器有何关系?

想要飞的猪

微服务常用的组件与相关问题

想要飞的猪

如何在没有 Root 权限的 Android 上设置IP代理

Geek_bf375d

爬虫 https 代理IP 代理IP设置 跨境电商

Windows 7 上配置代理服务器

Geek_bf375d

爬虫 https IP 代理IP 代理IP设置

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