本文主要解析一下java9 module相关选项html
在classpath的全部jar(无论是否模块化)共同组成一个unnamed moduleunnamed modules会声明依赖全部的named module,且exports本身的全部包,可是一个named module不能声明依赖unnamed module。若是一个package在named和unnamed模块中都有定义,则使用named中的package。java
默认--illegal-access=permit,即容许unnamed modules反射(java.lang.reflect/java.lang.invoke)使用全部named modules中的类
这个选项主要是为了方便迁移到java9而设计的,不过在java10可能会移除掉sql
有module-info.java的模块,是java9正规的module
没有module-info.java的jar包,若是放在module-path下,java9模块系统自动将其变成automatic module(其中若是jar包中MANIFEST.MF文件有Automatic-Module-Name属性,取其值做为模块名,没有的话,将jar包文件名根据必定规则提取模块名,若是提取不成功则没法转变为automatic module
)
automatic modulemacos
包含main方法的module,经过--module指定
模块系统解析的根模块,从根模块解析(
在编译时期,而不是运行时
)模块依赖,能够经过--add-modules mod1,mod2来将除JDK默认root modules外的模块添加到模块依赖解析中,能够经过扫描模块描述符把相关依赖的模块也同时解析了。
JDK9默认的root module是java.se模块bootstrap
java -d java.se java.se@9 requires java.sql transitive requires java.scripting transitive requires java.logging transitive requires java.security.jgss transitive requires java.management transitive requires java.instrument transitive requires java.naming transitive requires java.xml transitive requires java.compiler transitive requires java.desktop transitive requires java.sql.rowset transitive requires java.management.rmi transitive requires java.base mandated requires java.rmi transitive requires java.xml.crypto transitive requires java.datatransfer transitive requires java.prefs transitive requires java.security.sasl transitive
因为java.se.ee不在默认的root modules中,所以--add-modules的最多见的用途是用来添加ee中的模块,好比javv.xml.bind
java -d java.se.ee java.se.ee@9 requires java.xml.bind transitive requires java.base mandated requires java.corba transitive requires java.activation transitive requires java.transaction transitive requires java.xml.ws transitive requires java.se transitive requires java.xml.ws.annotation transitive
layer之于module,就至关于classloader之于class,layer是module的一个加载和实例化的机制。一般用来在运行时动态加载modules
boot layer是java模块系统首先使用的layer。它包括了bootstrap loader,platform loader,application loader。java runtime会根据--add-modules指定的root modules来构建模块依赖图,这一层就是boot layer。api
--module指定包含main方法的module
--add-modules添加module到root set中,方便解析模块依赖
- ALL-DEFAULT,添加unnamed modules的默认root module添加到root set - ALL-SYSTEM,添加系统模块(java,jdk,javafx等开头的模块,即jdk自身带的模块)到root set - ALL-MODULE,添加module-path上全部可读的module到root set
module-path能够分为三类oracle
--module-path将没有模块声明的jar变为automatic module;module-path能够是class/jar目录,jar,jmod目录
用来在将目录或jar包中的class文件添加/覆盖到指定module,一般在测试环节使用
java --path-module targetModuleName=jarDir/replace.jar --module-path moduleDir -m com.example.module/com.example.module.Main
把replace.jar中的class添加或覆盖到targetModule中
用于缩小模块范围,好比
java --limit-modules java.se.ee --list-modules java.activation@9 java.base@9 java.compiler@9 java.corba@9 java.datatransfer@9 java.desktop@9 java.instrument@9 java.logging@9 java.management@9 java.management.rmi@9 java.naming@9 java.prefs@9 java.rmi@9 java.scripting@9 java.se@9 java.se.ee@9 java.security.jgss@9 java.security.sasl@9 java.sql@9 java.sql.rowset@9 java.transaction@9 java.xml@9 java.xml.bind@9 java.xml.crypto@9 java.xml.ws@9 java.xml.ws.annotation@9 jdk.httpserver@9 jdk.unsupported@9
用来限定编译及运行时可使用的模块,限定的范围是main module,--add-modules添加的modules,以及该参数指定的modules及其transitive依赖的modules
当包含main方法的module是unnamed modules的时候,常常用这个参数来减小须要被解析的模块数量。
编译时+运行时
)配合javac使用的时候就是容许编译时能够访问
javac -d outputDir --add-exports java.base/sun.net=com.example --module-source-path src $(find . -name "*.java")
配合java使用的时候就是容许运行时能够访问
java --module-path outputDir --add-exports java.base/sun.net=com.example -m com.example/com.example.Main
用来建立、查看jmod文件
cd $JAVA_HOME ➜ Home ./bin/jmod list ./jmods/java.logging.jmod classes/module-info.class classes/java/util/logging/ConsoleHandler.class classes/java/util/logging/ErrorManager.class classes/java/util/logging/FileHandler$1.class classes/java/util/logging/FileHandler$InitializationErrorManager.class classes/java/util/logging/FileHandler$MeteredStream.class classes/java/util/logging/FileHandler.class classes/java/util/logging/Filter.class classes/java/util/logging/Formatter.class classes/java/util/logging/Handler$1.class classes/java/util/logging/Handler.class classes/java/util/logging/Level$1.class classes/java/util/logging/Level$KnownLevel.class classes/java/util/logging/Level$RbAccess.class classes/java/util/logging/Level.class classes/java/util/logging/Logger$1.class classes/java/util/logging/Logger$ConfigurationData.class classes/java/util/logging/Logger$LoggerBundle.class classes/java/util/logging/Logger$RbAccess.class classes/java/util/logging/Logger$SystemLoggerHelper$1.class classes/java/util/logging/Logger$SystemLoggerHelper.class classes/java/util/logging/Logger.class classes/java/util/logging/Logging.class classes/java/util/logging/LoggingMXBean.class classes/java/util/logging/LoggingPermission.class classes/java/util/logging/LogManager$1.class classes/java/util/logging/LogManager$2.class classes/java/util/logging/LogManager$3.class classes/java/util/logging/LogManager$4.class classes/java/util/logging/LogManager$5.class classes/java/util/logging/LogManager$6.class classes/java/util/logging/LogManager$7.class classes/java/util/logging/LogManager$Cleaner.class classes/java/util/logging/LogManager$CloseOnReset.class classes/java/util/logging/LogManager$ConfigProperty.class classes/java/util/logging/LogManager$LoggerContext$1.class classes/java/util/logging/LogManager$LoggerContext.class classes/java/util/logging/LogManager$LoggerWeakRef.class classes/java/util/logging/LogManager$LoggingProviderAccess.class classes/java/util/logging/LogManager$LogNode.class classes/java/util/logging/LogManager$ModType.class classes/java/util/logging/LogManager$RootLogger.class classes/java/util/logging/LogManager$SystemLoggerContext.class classes/java/util/logging/LogManager$VisitedLoggers.class classes/java/util/logging/LogManager.class classes/java/util/logging/LogRecord$CallerFinder.class classes/java/util/logging/LogRecord.class classes/java/util/logging/MemoryHandler.class classes/java/util/logging/SimpleFormatter.class classes/java/util/logging/SocketHandler.class classes/java/util/logging/StreamHandler$1.class classes/java/util/logging/StreamHandler.class classes/java/util/logging/XMLFormatter.class classes/sun/net/www/protocol/http/logging/HttpLogFormatter.class classes/sun/util/logging/internal/LoggingProviderImpl$JULWrapper.class classes/sun/util/logging/internal/LoggingProviderImpl$LogManagerAccess.class classes/sun/util/logging/internal/LoggingProviderImpl.class classes/sun/util/logging/resources/logging.class classes/sun/util/logging/resources/logging_de.class classes/sun/util/logging/resources/logging_es.class classes/sun/util/logging/resources/logging_fr.class classes/sun/util/logging/resources/logging_it.class classes/sun/util/logging/resources/logging_ja.class classes/sun/util/logging/resources/logging_ko.class classes/sun/util/logging/resources/logging_pt_BR.class classes/sun/util/logging/resources/logging_sv.class classes/sun/util/logging/resources/logging_zh_CN.class classes/sun/util/logging/resources/logging_zh_HK.class classes/sun/util/logging/resources/logging_zh_TW.class conf/logging.properties legal/COPYRIGHT legal/LICENSE ➜ Home ./bin/jmod describe ./jmods/java.logging.jmod java.logging@9 exports java.util.logging requires java.base mandated provides jdk.internal.logger.DefaultLoggerFinder with sun.util.logging.internal.loggingproviderimpl contains sun.net.www.protocol.http.logging contains sun.util.logging.internal contains sun.util.logging.resources platform macos-amd64
弄清楚modules的分类及其相关选项,能够有助于咱们更好地使用java9的模块系统。app