例如,我遇到了对 Rails 应用程序感到害怕的开发人员和架构师,但他们喜欢编写新的 Grails 应用程序的想法。
据我所见,使用 JVM 来支持 Groovy、JRuby 和 Jython 等语言而不是直接使用 Ruby 或 Python 会产生大量资源开销。
Ruby 和 Python 几乎都可以在任何操作系统上进行解释,所以我看不到任何“一次编写,随处运行”的优势……为什么要带上笨重的 JVM?
Java 是一个成熟得多的平台,与 Ruby 或 Python(甚至 Perl,就此而言)相比,可以“插入”并使用许多现有的类库。因此,对于喜欢使用现有代码而不是自己编写所有代码的人来说,Java 是一个巨大的胜利。
例如,最近我一直在寻找类似 JAXB for Python 或 Ruby 的东西。最后,我最终还是使用了 JRuby,因为我还没有找到任何成熟的、广泛使用的 XML 绑定库。
为 JVM 编写代码(用任何语言)的巨大优势在于,如果有必要,通常很容易利用那里大量成熟的 Java 库。
而且我不知道你从哪里得到这个“笨重”的 JVM 的想法,它具有巨大的资源开销。JIT 倾向于生成非常快的代码,而按照今天的标准,核心 JVM 绝不是巨大的。它在运行时确实会占用大量内存,但这是因为现代机器具有大量 RAM,而 GC 在有大量 RAM 可供使用时效果最佳。如果需要,可以将 GC微调到地狱并返回到更保守的状态。
正如其他人所说:“Groovy 最好的一点是我不必使用Java。Groovy 的第二个优点是我可以使用 Java”。
一个似乎包含在问题中的假设是新项目是新建项目。在过去的十多年里,许多组织对 Java 进行了巨额投资,并且要求任何新项目都可以在现有(内部)代码生态系统中工作。正如所指出的,所有公开可用的 Java 库(无论是免费的/OSS 还是商业的)都有巨大的好处,但是使用现有代码甚至作为现有系统中的组件的需求至少同样重要(如果不是更多的话)所以)到大型组织。
很多还归结为平台的成熟度和功能,也就是说 JVM 和它附带的一切(整个 Java 生态系统)。我脑海中的几个例子:
您可以将远程调试器插入正在运行的 JVM 并获取有关正在运行的应用程序的各种信息,这对于 Python、Ruby 等来说是不可能的。更进一步,有JMX,这是一种编写代码的标准方法,以便对象可以被监控甚至在实时应用程序中进行调整。看看JConsole,看看你是不是有点流口水(尽管界面很丑)。
在这个方向上更进一步,还有OSGi,这是一种编写高度模块化代码的标准,可以在实时应用程序中部署、启动、停止甚至升级。使用 OSGi,您可以将大型应用程序分解为许多较小的“捆绑包”,然后可以单独维护(部署、启动/停止、升级)。这对于大型应用程序或任何需要始终保持运行的应用程序来说非常重要。
该平台对异步、可靠的消息传递有很好的支持。您将JMS作为基线,并在其上构建了许多出色且强大的库,用于用很少的代码完成复杂的事情(参见Apache Camel、ServiceMix、Mule等)。这是另一个在大型应用程序或必须在更大的代码世界中运行的应用程序中非常有价值的功能。
JVM 具有真正的(操作系统级)线程,而 Python 等。在这方面非常有限(众所周知)。(话虽这么说,共享状态并发——线程——是错误的方法;参见Erlang、Alice、Mozart/Oz等)
除了标准的 Sun 实现之外,还有许多 JVM 选择,如JRockit、IBM 的 JVM 等。这是一个与其他语言一起发展的领域——Python 有 Jython、Iron Python,甚至 PyPy 和 Stackless;Ruby 有 JRuby、Rubinius 和其他—— 但尽管这些都很好,但它们无法与各种 JVM 产品中的成熟度相提并论。
话虽如此,我真的不喜欢 Java这种语言并尽可能避免使用它。这些天来,我不必为 JVM 提供所有优秀的替代语言。Groovy 因其可访问性和与平台(甚至语言)的紧密集成而获得了我的投票,并且因为 Grails,我有时喜欢将其称为“成人的 Rails”。我更喜欢其他 JVM 语言,尤其是Clojure和Scala,但这些对于普通程序员来说并不容易。不过,Scala 最近出现了很多,特别是由于它在 Twitter 上的高调使用,因此希望在更大的环境中使用有趣且真正优秀的语言。但这是另一个话题。
为什么要和你一起使用笨重的 JVM?
JVM 不臃肿,也不慢。相反,它是一个精简、快速、深度优化的虚拟机。不幸的是,它针对静态 OOP 语言进行了优化。
尽管如此,针对 JVM 的优秀编译器确实可以创建性能良好的程序。我不知道 JRuby;但是 Jython 的目标是比普通的 C Python 更快,并且它们正在接近(在几个重要的用例中已经更快了)。
请记住,一个好的 JIT(比如那些用于 JVM 的 JIT)可以应用一些静态 C 编译器上不可用的优化,从它们那里获得更快的代码并不是白日梦。当然,为您的语言优化的 VM应该比 JVM 之类的“非通用”VM 更快;但存在成熟度问题:JVM 在那里完成了很多工作,而用于 Ruby 和 Python 的 JIT 还远远没有。
不幸的是,似乎没有更好的通用字节码虚拟机。Microsoft 的 CLI 与 JVM 存在类似的限制(ironPython 比 JPython 慢得多且重得多)。最好的候选人似乎是 LLVM。有人知道为什么 LLVM 上没有更多的动态语言吗?我见过几个 Scheme 编译器,但似乎有几个问题。
Groovy 不是解释型语言,它是一种动态语言。groovy 编译器生成在 JVM 内部运行的 JVM 字节码,就像任何其他 java 类一样。从这个意义上说,groovy 就像 java 一样,只是在 java 语言中添加了只对开发人员有意义而不对 JVM 有意义的语法。
开发人员的生产力、语法的易用性和灵活性使 groovy 对 java 生态系统具有吸引力——如果 ruby 或 python 生成 java 字节码(参见 jython),它们将同样具有吸引力。
Java 开发人员并不是真的害怕 ruby。事实上,许多人很快就接受了 groovy 或 jython 两者都接近 ruby 和 python。他们不关心的是离开这样一个令人惊叹的平台(java)来使用性能较差、可扩展性较差甚至使用较少的语言,例如 ruby(尽管有它的优点)。
RoR 最大的问题是它不可扩展且难以部署。通过使用 Java 平台,您可以利用现有的基础架构。
grails war
生成一个易于部署在 Glassfish、Jboss 等上的 war 文件。
Ruby 和 Python 几乎都可以在任何操作系统上进行解释,所以我看不到任何“一次编写,随处运行”的优势……为什么要带上笨重的 JVM?
主要是因为您想利用庞大的现有 Java 库、API 和产品生态系统,这使 Ruby 或 Python 的任何可用产品相形见绌,尤其是在企业领域。
另外,请记住,JRuby 和 Jython在许多基准测试中都比语言的常规(C 实现)更快,尤其是 Ruby(甚至 Ruby 1.9)。
针对同一虚拟机使用多种语言有很多好处,例如利用通用基础架构、代码重用、共享 API、使用概念上最适合您或特定问题域的任何语言的能力等。
同样的事情发生在 .NET 领域,有多种语言针对 CLR。Parrot (vaporware) VM 项目的目标也是相同的,这也是LLVM项目的既定目标。
原因是热点。
这是一场工程之旅。
没有多少人提到的另一个原因是与 jvm 相关的现有基础架构 - 如果您已经有一个运行 java 的服务器,为什么不使用它而不是引入另一个平台(如 rails)?
我遇到过这种情况,也对此感到困惑,这是我的理论。
企业软件充满了 Java 程序员。与各行各业的程序员一样,许多 Java 程序员都相信他们的语言是最快、最灵活和最容易使用的——他们对其他语言不太熟悉,但相信那些实践它们的人一定是野蛮人和野蛮人,因为任何开明的人当然都会使用 Java。
这些人构建了庞大而复杂的 Java 基础设施:框架的 rube-goldberg 机器和充满拜占庭继承结构的自动生成代码和非常非常大的 XML 文件。
所以,当有人走过来说“嘿!让我们使用 C 解释语言!它速度快,有整洁的库,并且脚本和原型设计要快得多!” Java 的家伙首先就像“我必须运行一个 make 文件来配置它?QUEL HORREUR!” 然后,必须在运行过时的操作系统和过时版本的 Tomcat 的服务器上部署和托管它的现实开始出现。
“嘿,我知道!这种解释语言有一个 java 版本!它可能会在高峰时段在桥上的快车道上抛锚,有时它会着火,但我可以让 Tomcat 运行它。我不’不必为了学习非 Java 的东西而弄脏我的双手,我可以将它硬塞到现有的基础设施中!赢了!”
那么,这是选择脚本语言的 java 实现的“正确”原因吗?可能不是。取决于你对“正确”的定义。但是,我怀疑这就是他们比我这样的势利小人更愿意相信的原因。