官术网_书友最值得收藏!

Revisiting the classpath problems

In Chapter 1, Introducing Java 9 Modularity, we looked at two problems faced by our friends Jack and Amit:

  • Jack couldn't easily encapsulate internal library types and prevent use of that type outside the library, while retaining the ability to freely use them inside his own library
  • Amit couldn't reliably assemble a set of compiled Java code and guarantee that all the dependencies and imports of those types are sufficiently met before the program actually hits the dependency at runtime

Have we solved these problems with the module system? Thankfully, yes!

We've already seen how the Java module's encapsulation prevents certain types from being accessed outside the module, even if the type is public, unless the package they belong to is explicitly exported. Indeed, we applied the same concept to hide the BubbleSortUtilImpl class from external use. When it comes time to upgrade our library, should we feel the need to modify (or even remove) that class, we can rest assured that the only consumer of that code is in the library itself.

How about the second problem--runtime verification? It turns out, the Java runtime refers to the same module-info module descriptor (this time in .class format) to figure this out. You ran the Main class in the packt.addressbook module and it worked fine because the runtime found the dependent module packt.sortutil in the module path. Let's see what happens if it doesn't find it. If I were to delete the compiled sortutil directory in the out directory, and run packt.addressbook/packt.addressbook.Main again, notice the error you get:

$ java --module-path out --module packt.addressbook/packt.addressbook.Main
  
Error occurred during initialization of VM
java.lang.module.ResolutionException: Module sortutil not found,
required by addressbook
at java.lang.module.Resolver.fail(java.base@9/Resolver.java:841) at java.lang.module.Resolver.resolve(
java.base@9/Resolver.java:154)
...

The error message points out that the packt.sortutil module is not found, but the important thing to notice here is when the error is thrown. It's not when the class is loaded and the runtime tries to find the dependent types that it encounters this error. The error occurs right at the VM initialization time as the message clearly mentions. This is a huge advantage when it comes to reliability of your Java code. If there are potential errors, the runtime catches that right at initialization and not at some arbitrary point in time during execution.

One of the requirements that the module system was designed to meet is to achieve fidelity across phases. What does this mean? You've seen how the module descriptor enabled you to build modules, encapsulate types, and verify availability of the necessary dependencies by allowing you to specify the contract about each module. These benefits affect not only the compilation process of your code, but also the runtime process. The same module definition that lets the compiler know something is wrong when a required module is missing can also provide the runtime with the same information! Thanks to the module descriptor being compiled into the code as a class file, the Java runtime can also read the same descriptor and know well in advance if every module that is depended upon by the code that needs to be run is available. You get the same behavior and error checking across the compilation and execution phases.

主站蜘蛛池模板: 新和县| 安徽省| 饶河县| 新蔡县| 白河县| 仙桃市| 南康市| 禹州市| 灵宝市| 菏泽市| 兰考县| 桐庐县| 扎兰屯市| 邮箱| 双柏县| 达孜县| 井冈山市| 辽源市| 武威市| 神农架林区| 正蓝旗| 周至县| 郯城县| 叶城县| 长泰县| 大厂| 延安市| 胶州市| 神木县| 宁化县| 曲阳县| 利津县| 遵义市| 吴江市| 平武县| 蒙山县| 伊宁市| 德庆县| 台湾省| 西丰县| 于都县|