戴镣铐的自由 - Java 陷阱
理查德·斯托曼 著前言
自这篇文章首次发布以来,Sun(现在是 Oracle 的一部分)已经根据 GNU 通用公共许可证重新授权了其大部分 Java 平台参考实现,且现在有一个自由的 Java 开发环境。因此,Java 语言本身不再是陷阱。
但是,您必须小心,因为并非每个 Java 平台都是自由的。Sun 继续分发非自由的可执行 Java 平台,其他公司也这样做。
Java 的自由环境称为IcedTea。Sun 释放的源代码被包含在其中。因此,它是您应该使用的。许多 GNU/Linux 发行版包含了 IceTea,但其中一些发行版包括非自由的 Java 平台。(请注意,于 2015 年 10 月添加:Java 的自由实现在许多 GNU/Linux 发行版中被称为 OpenJDK。)
为了可靠地确保 Java 程序在自由的环境中正常运行,您需要使用 IcedTea 开发它们。理论上,Java 平台应该兼容,但它们并不是 100% 兼容。
此外,还有一些名称上带有 “Java” 的非自由程序,例如 JavaFX,并且还有一些非自由 Java 程序包,您可能会很感兴趣,但是需要拒绝它们。所以,请检查您想使用的任何软件包的许可证。 如果使用 Swing,请确保使用和 IcedTea 一起发布的自由版本。(注意,在 2015 年 10 月添加:JavaFX 的自由替代叫做 OpenJFX,已经发布。)
除了这些 Java 规范外,此处描述的一般问题仍然很重要,因为任何非自由库或编程平台都可能导致类似问题。我们必须从 Java 的历史中吸取教训,以便将来避免其他陷阱。
另请参见: JavaScript 陷阱。
2004 年 4 月 12 日
如果你的程序是自由软件,这基本上是道德的——但有一个陷阱,您必须警惕。您的程序虽然本身是自由的,但可能受其依赖的非自由软件的限制。由于问题对于 Java 程序而言今天最为突出,因此我们将其称为 Java 陷阱。
如果程序的用户拥有一些关键的自由,则该程序为自由软件。粗略地说,它们是:运行程序的自由,学习和更改源代码的自由,重新分发源代码和二进制文件的自由以及发布改进版本的自由。(请参阅 自由软件定义。)一个有源代码的程序是不是自由软件,只依赖于其许可证的含义。
程序是否可以在自由世界中使用,供那些想生活在自由中的人们使用,这是一个更复杂的问题。这不是仅由程序本身的许可证确定的,因为没有程序可以独立运行。每个程序都依赖于其他程序。例如,程序需要编译或解释,因此它取决于编译器或解释器。如果编译为字节码,则取决于字节码解释器。而且,它需要库才能运行,并且它还可以调用在其他进程中运行的其他单独程序。所有这些程序都是依赖项。依赖关系可能是程序运行必需的,或者可能仅对于某些功能是必需的。无论哪种方式,如果没有依赖,程序或其部分功能将无法实现。
如果某个程序的某些依赖项是非自由的,则意味着该程序的全部或部分无法在完全自由的系统中运行——在自由世界中无法使用。当然,我们可以重新分发该程序,并在我们的计算机上保留副本,但是如果它无法运行,那就不好了。程序是自由软件,但是由于其非自由依赖关系而受到束缚。
在任何类型的软件,任何语言中都可能出现这种问题。例如,仅在 Microsoft Windows 上运行的自由程序在自由世界中显然毫无用处。但是,如果它依赖于其他非自由软件,则在 GNU/Linux 上运行的软件也可能无用。过去,Motif(在我们拥有 LessTif 之前)和 Qt(在其开发人员使它成为自由软件之前)是造成此问题的主要原因。 大多数3D视频卡只能与非自由驱动程序一起完整使用,这也会导致此问题。但是今天这个问题的主要根源是 Java,因为编写自由软件的人经常会觉得 Java 很性感。由于对语言的吸引力而被蒙蔽,他们忽略了依赖的问题,落入了 Java 陷阱。
Sun 的 Java 实现不是自由的。标准 Java 库也是非自由的。我们确实有 Java 的自由实现,例如 GNU Java编译器(GCJ)和 GNU Classpath,但它们尚不支持所有功能。我们仍在追赶。
如果您在 Sun 的 Java 平台上开发 Java 程序,则有可能在不注意的情况下使用仅限 Sun 的功能。到您发现此问题时,您可能已经使用了几个月,并且重做工作可能需要花费几个月的时间。“您可能会说,从头开始要做太多的工作了。”然后,您的程序将落入 Java 陷阱中。它在自由世界中将无法使用。
避免 Java 陷阱的可靠方法是在系统上只有 Java 的自由实现。然后,如果您使用的是自由软件尚不支持的 Java 功能或库,那么您将立即发现并可以立即重写该代码。
Sun 继续开发其他标准 Java 库,并且几乎所有的库都是非自由的。在许多情况下,即使是库的“规范”也是商业秘密,并且 Sun 针对这些规范的最新许可证禁止发布除规范的完整实现之外的任何内容。(请参看 https://jcp.org/aboutJava/communityprocess/JSPA2.pdf 和 https://jcp.org/aboutJava/communityprocess/final/jsr129/j2me_pb-1_0-fr-spec-license.html 等示例。)
幸运的是,该规范许可证确实允许以自由软件的形式发布实现;可以允许其他接收该库的人进行更改,而无需遵守该规范。但是该要求具有禁止使用协作开发模型来产生自由实现的效果。使用该模型将需要发布不完整的版本,而那些已经阅读过该规范的人将被禁止这样做。
在自由软件运动的早期,不可避免地要依赖非自由程序。在拥有GNU C编译器之前,每个C程序(无论是否自由)都依赖于非自由的C编译器。在拥有GNU C库之前,每个程序都依赖于一个非自由的C库。在我们拥有第一个自由内核 Linux 之前,每个程序都依赖于非自由内核。在有 BASH 之前,每个 shell 脚本都必须由非自由 shell 解释。不可避免的是,最初的程序一开始会受到这些依赖的阻碍,但是我们接受了这一点,因为我们的计划包括随后的救援。我们的总体目标是建立一个自洽的 GNU 操作系统,其中包括所有这些依赖项的自由替代。如果我们达到了目标,我们的所有程序都会被拯救。事情就这样发生了:有了 GNU/Linux 系统,我们现在可以在自由平台上运行这些程序了。
今天的情况有所不同。我们现在拥有功能强大的自由操作系统和许多自由的编程工具。无论您想做什么工作,都可以在自由的平台上完成;甚至不需要暂时接受非自由依赖。人们今天落入陷阱的主要原因是因为他们没有对此进行考虑。解决该问题的最简单方法是教会人们认识它并且不陷入它。
为了使 Java 代码免受 Java 陷阱的影响,请安装自由的 Java 开发环境并使用它。一般来说,无论使用哪种语言,请睁大眼睛,检查代码所依赖的程序的自由状态。验证程序是否自由的最简单方法是在“自由软件目录”(自由软件目录)查找。如果程序不在目录中,则可以对照 自由软件许可证列表 审查其许可证。
我们正试图挽救被困的 Java 程序,因此,如果您喜欢 Java 语言,我们邀请您一起帮助开发 GNU Classpath。使用GCJ编译器和 GNU Classpath 验证你的程序,并报告在已实现的类中遇到的任何问题也很有用。然而,完成 GNU Classpath 需要花费时间;如果非自由库的还在持续增加,我们可能永远不会有所有最新的库。因此,请不要给您的自由软件套上枷锁。今天,当您编写应用程序时,请一开始就按照在自由工具上运行的目标来编写。