Java模块化系统初探

发表于:2015-9-29 11:18

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:闵大为    来源:51Testing软件测试网采编

  Java 模块化系统自提出以来经历了很长的时间,直到 2014 年晚些时候才最终以 JSR(JSR-376) 定稿,而且这个部分有可能在 Java 9 中出现。但是一直以来都没有可以使用的原型。9 月 11 日,OpenJDK 发布的早期构建版本终于包含了 Jigsaw 项目。
  昨天,我和同事 Paul Bakker 在 JavaZone 上对于 Java 模块化系统进行了讨论。整个讨论都建立在JSR-376 需求文档以及身边一些珍贵的信息上。在年初提出举行这个报告的时候,我们曾深信不疑地认为在这个会上我们能够展示一个原型,但是事情却没有按预想的那样发展。现在的情况是,这个原型将在我们的报告结束之后发布。这也意味着,报告中的一些内容已经有点过时了,但是主要的思想还是很有新意的。如果你对 Java 模块化系统方案一无所知的话,建议你在阅读这篇文章之前先去看一下我们的报告。我们的报告介绍了现在的方案,并进一步与 OSGi 进行了比较。
  为什么要使用模块?
  什么是模块?我们为什又需要它们?如果希望有一个深入的讨论,请阅读“State of the module system”或者看一下我们的报告。对这块还不是很了解的人来说,这里有Cliff 的注释版本。
  我们都知道 Java 有 jar 文件。但是,事实上这些都只是包含一些class(类)的压缩文件,这些 jar 包内部都是一些 package (包)。当你利用一些不同的 jar 包来运行应用程序的时候(复杂一点的程序也适用),你需要把它们放到指定的类路径中。然后默默祈祷。因为没有有效的工具来帮助你知道,你是否已经把应用所需要的 jar 包都放入类路径中了。或者有可能你在不经意间将同样的类文件(在不同的 jar 包中)都放入了类路径中。类路径灾难(类似于 DLL 灾难)是真实存在的。这会导致运行时出现糟糕的状况。同时,在运行时我们也无法得知 jar 中包含哪些类。从 JRE 角度来说只知道有一堆类文件。事实上 jar 包之间是相互依赖的,但目前还不能把这种依赖关系记录到数据文件中去。理想的情况是,你可以隐藏 jar 包中类文件具体的实现,只是提供一些公共的 API 。在 Java 中提出模块化系统就是为了解决这些问题的:
  模块成为首先要考虑的部分,它能够分装实现细节并且只暴露需要的接口。
  模块准确地描述了他们能够提供的接口,以及他们的需要部分(依赖)。由此,我们可以在开发的过程中弄清和处理依赖关系。
  模块系统极大地提升了大型系统的可维护性、可靠性、安全性。至少 JDK 本身还缺少这样的系统。通过这样的模块系统,模块图能够自动地构建。这个图只包括了你的应用程序运行时所须要的模块。
  安装 JDK9 预览版
  如果你想亲自尝试编写示例代码,你需要安装包含 Jigsaw 原型的 JDK9 早期构建版本。在 OSX 上,你需要解压文档,然后把解压出来的目录移动到 Library/Java/JavaVirtualMachines/ 下。然后你需要设置环境变量,将 JAVA_HOME 环境变量指向 JDK9 的目录。我使用了非常好用的setjdk 脚本,通过它可以在命令窗口中实现 Java 安装的命令切换。你很有可能不愿意使用这个早期构建版本作为你的 Java 安装版本。你可以通过 java -version 来确认安装完成。输出如下面所示:
  java version "1.9.0-ea"
  Java(TM) SE Runtime Environment (build 1.9.0-ea-jigsaw-nightly-h3337-20150908-b80)
  Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-jigsaw-nightly-h3337-20150908-b80, mixed mode)
  只要输出中包含 Jigsaw ,你就可以继续了。文章后面的示例代码可以去 https://github.com/sandermak/jigsaw-firstlook 下载。
  一个简单的例子
  你仍旧可以通过类、jar包以及类路径这样“传统方式”的方式来使用 JDK9 。但是明显地我们想要采用模块的方式。所以我们将创建一个包含两个模块的工程:模块一使用了模块二中的代码。
  首先要做的就是,构建我们的工程并把两个模块很好地区分开来。然后,模块中需要以 module-info.java 文件的形式添加元数据。我们的示例构建如下:
  src
  module1
  module-info.java
  comtestTestClassModule1.java
  module2
  module-info.java
  commoretestTestClassModule2.java
  接着,我们将介绍 package (包)层最顶上的一层(module1、 module2),这部分你在之前已经构建好了。在这些“模块目录”中,可以看到 module-info.java 文件在根目录下。此外请注意,这两个类都是在显示命名的包中的。
  请看 TestClassModule1 的代码:
  package com.test;
  import com.moretest.TestClassModule2;
  public class TestClassModule1 {
  public static void main(String[] args) {
  System.out.println("Hi from " + TestClassModule2.msg());
  }
  }
  看起来很普通对吧?这里并没有涉及模块,而是导入了 TestClassModule2 ,主函数之后会去调用其中的 msg() 方法。
  package com.moretest;
  public class TestClassModule2 {
  public static String msg() {
  return "from module 2!";
  }
  }
  到目前为止,module-info.java 还是空的。
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号