我在Linux机器上使用jlink创建了运行时映像.我linux在include文件夹下看到了文件夹.这是否意味着我只能将此运行时映像用于Linux平台?如果是,有没有办法在一个平台上为另一个平台创建运行时映像(例如在Linux for Windows上,反之亦然)
在Java 9中,是否允许使用循环模块?如果不是,原因是什么?
module com.foo.bar {
requires com.foo.baz;
exports com.foo.bar.fizz;
}
module com.foo.baz {
requires com.foo.bar;
exports com.foo.baz.buzz;
}
Run Code Online (Sandbox Code Playgroud) java java-platform-module-system java-9 java-module module-info
我似乎无法找到关于是否仍然可以在运行时扫描所有可用类(用于接口,注释等)的任何信息,就像Spring,Reflections和许多其他框架和库当前所做的那样,面对Jigsaw相关的更改类的加载方式.
编辑:这个问题是关于扫描寻找类的真实物理文件路径.另一个问题是关于动态加载类和资源.这是相关的,但非常重复.
更新:Jetty项目为此制定了标准化API的 JEP建议.如果你有办法帮助实现这个目标,请做.否则,等待和希望.
更新2:找到这个相关的发声帖子.引用后代的代码片段:
如果您真的只是想了解启动层中的模块内容(启动时解析的模块),那么您将执行以下操作:
ModuleLayer.boot().configuration().modules().stream()
.map(ResolvedModule::reference)
.forEach(mref -> {
System.out.println(mref.descriptor().name());
try (ModuleReader reader = mref.open()) {
reader.list().forEach(System.out::println);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
});
Run Code Online (Sandbox Code Playgroud) java classpath java-platform-module-system java-9 java-module
我使用java 9模块设置了一个小测试项目.结构如下所示:
.
??? build.gradle
??? src
??? main
? ??? java
? ??? module-info.java
? ??? slfTest
? ??? Main.java
??? test
??? java
??? slfTest
??? MainTest.java
Run Code Online (Sandbox Code Playgroud)
(随意克隆,看一看自己:git clone https://github.com/michas2/slfTest.git)
Main和Main Test类只记录一些简单的输出:
Logger logger = LoggerFactory.getLogger(Main.class);
logger.info("Hello World");
Run Code Online (Sandbox Code Playgroud)
现在gradle run按预期工作,但gradle test给出了ClassCastException.
$ gradle run -q
[main] INFO slfTest.Main - Hello World
$ gradle test -q
java.lang.ClassCastException: org.slf4j.simple/org.slf4j.simple.SimpleLoggerFactory cannot be cast to org.gradle.internal.logging.slf4j.OutputEventListenerBackedLoggerContext
at org.gradle.internal.logging.slf4j.Slf4jLoggingConfigurer.configure(Slf4jLoggingConfigurer.java:42)
at org.gradle.internal.logging.config.LoggingSystemAdapter.startCapture(LoggingSystemAdapter.java:54)
at org.gradle.internal.logging.services.DefaultLoggingManager$StartableLoggingSystem.start(DefaultLoggingManager.java:297)
at org.gradle.internal.logging.services.DefaultLoggingManager.start(DefaultLoggingManager.java:73) …Run Code Online (Sandbox Code Playgroud) 在Java 9的模块声明中有2个结构:
exports com.foo;
Run Code Online (Sandbox Code Playgroud)
和
opens com.foo;
Run Code Online (Sandbox Code Playgroud)
凡exports赠款编译时访问,同时opens允许运行时访问,如反射和资源.
opens有一个宽容exports,你可以将整个模块定义为open,结果与显式打开每个包相同:
open module com.mod {
Run Code Online (Sandbox Code Playgroud)
但是没有相似的结构
exported module com.mod {
Run Code Online (Sandbox Code Playgroud)
我的问题:为什么会这样; 有什么决定允许一次打开整个模块而不是出口?
java java-platform-module-system java-9 java-module module-info
java doc中的ModifierforExports表明了这一点
MANDATED导出在模块声明的源中隐式声明.
SYNTHETIC未在模块声明的源中显式或隐式声明导出.
看几个module-info.classes,我可以看到通常有两种类型的用法:
module java.base {
...
exports java.util; // type 1
exports java.util.concurrent;
exports java.util.concurrent.atomic;
exports jdk.internal to jdk.jfr; // type 2
exports jdk.internal.jmod to
jdk.compiler,
jdk.jlink;
...
}
Run Code Online (Sandbox Code Playgroud)
在合格的出口做介绍这两种,但没有对枚举类型没有提及.这些是文档中提到的不同类型吗?
Q1.一般来说SYNTHETIC和MANDATED作为在使用调节剂Exports,ModuleDescriptor,Opens和Requires.这两者之间的区别是什么,在实践中优于另一个?
Q2.Synthetic Modifier如果没有在模块的源代码中声明,那么无论如何都是一个例子?
在JRE-9/lib目录中(至少在Windows上),有一个新文件,modules其大小约为107 MB.是否可以提取该文件或列出其中的Java模块?
我可以看到一个名为的新工具jmod可用jdk-9/bin/jmod.exe,但是用于读取.jmod位于的文件,jdk-9/jmods它无法读取文件modules.
我将Java 8中的maven项目迁移到Java 9项目而没有任何构建工具Eclipse OxyGen 1a.
所以我的module-info.java看起来像这样:
但java.xml.bind不可访问,虽然它在我的模块路径中:
那么这里有什么问题?
Java9引入了Multi-Release JAR.
假设我使用java8有多模块Gradle项目:
project-root
settings.gradle
build.gradle
/module1
/src
... (common maven structure)
/module2
/module3
Run Code Online (Sandbox Code Playgroud)
这是Gradle中常见的多模块项目.假设我需要MR-Jar module1.
我无法添加module1-java9定位Java9,因为基础是8 - 到目前为止,我的Gradle和IntelliJ IDEA都抱怨.Gradle是用java8编译的,但是我需要为模块启用java9运行时(不知道怎么做); 在IntelliJ IDEA中我可以为模块设置java9运行时,但每次重新加载gradle配置时它都会被覆盖.
而且,即使我以某种方式添加它,我需要指示module11)构建第二个和2)包括module1-java9.以下是这种情况的图纸:
project-root
settings.gradle
build.gradle
/module1
/module1-java9 (added java9 module)
/module2
...
Run Code Online (Sandbox Code Playgroud)
或者,这可以在module1具有不同来源的情况下完成:src和src-java9.但我怀疑这会被接受.这是一张图:
project-root
settings.gradle
build.gradle
/module1
/src
/src-java9 (added java9 source folder)
/module2
/module3
Run Code Online (Sandbox Code Playgroud)
到目前为止,我只看到它module1-java9是一个单独的项目(不是模块),module1只是在那里调用gradle并获取输出.是的,这是gradle调用gradle :)))
有没有开发人员友好的方式来做到这一点?
从IDEA 2018.2.1开始,IDE从模块化的依赖项开始错误突出显示"不在模块图"中的包.我module-info.java在项目中添加了一个文件并添加了必需的requires语句,但我现在无法访问src/main/resources目录中的资源文件.
(有关完整示例,请参阅此GitHub项目.)
当我使用./gradlew run或./gradlew installDist+生成的包装器脚本时,我能够读取资源文件,但是当我从IDE运行我的应用程序时,我不是.
我向
JetBrains 提出了一个问题,我学到的是IDEA正在使用模块路径,而Gradle默认使用类路径.通过向我添加以下块build.gradle,我能够让Gradle 也 ...无法读取任何资源文件.
run {
inputs.property("moduleName", moduleName)
doFirst {
jvmArgs = [
'--module-path', classpath.asPath,
'--module', "$moduleName/$mainClassName"
]
classpath = files()
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试export将我感兴趣的资源目录作为"包",并在编译时遇到构建失败:
错误:包是空的或不存在:mydir
使用opens而不是exports获得相同的错误,但降级为警告.
我甚至尝试移动mydir资源目录src/main/java,但是这产生了相同的错误/警告,并且还导致资源没有被复制到build目录中.
应该在Java 9中使用哪些资源,以及如何访问它们?
注意:在继续研究问题之后,我已经相当大地编辑了这个问题.在最初的问题中,我还试图弄清楚如何在资源目录中列出文件,但在调查过程中我确定这是一个红色的鲱鱼 - 首先,因为阅读资源目录只有在资源是从file:///URL 读取(也许甚至不是),第二,因为普通文件也没有工作,所以很明显问题是资源文件一般而不是专门用于目录.
解:
按照Slaw的回答,我将以下内容添加到build.gradle:
// at compile …Run Code Online (Sandbox Code Playgroud) java ×10
java-9 ×10
java-module ×10
java-platform-module-system ×4
gradle ×3
module-info ×3
classpath ×1
eclipse ×1
jdk-tools ×1
jlink ×1
jmod ×1
slf4j ×1