我听说过
为了加速Maven构建,我已下载jdk9-ea并发现它需要更长的时间.而且,感觉Maven开始之前有更长的延迟.
我试图使用以下代码粗略测量JVM启动时间
public class Sampler {
public static void main(String[] args) throws IOException, InterruptedException {
long t = System.currentTimeMillis();
if (args.length == 0 || args[0].startsWith("-")) {
sample(30, args);
} else {
long t0 = Long.parseLong(args[0]);
System.out.println(t - t0);
}
}
static void sample(int n, String[] options) throws IOException, InterruptedException {
File samples = new File("samples.txt");
for (int i = 0; i < n; i++) {
String javaPath = String.join(
System.getProperty("file.separator"),
System.getProperty("java.home"),
"bin",
"java");
List<String> command …Run Code Online (Sandbox Code Playgroud) 我有一个使用这种技术的项目在JDK 8及更早版本中运行良好.但是,在JDK 9中,这个jar被删除了,它不再起作用:
com.sun的"dependencies.dependency.systemPath":tools:jar指的是一个不存在的文件/usr/lib/jvm/java-9-jdk/../lib/tools.jar.请验证您使用JDK而不仅仅是JRE运行Maven.
(虽然JDK 9中没有 tools.jar ,但这条路看起来很奇怪)
什么是可以在JDK版本甚至JDK供应商中工作的最佳实践?我甚至没有在OpenJDK上找到JDK 9的任何解决方法(同时保持项目可在JDK 8上构建).
由于Jigsaw项目的核心是Java模块系统,因此能够仅限制对特定模块内特定程序元素(类,方法和字段)的访问是很好的.
当模块中的某些元素对于此模块基本上是公共的时,它可能会有所帮助,但不应在此模块外部访问.
所以我说的是"package-local"之后的下一级访问,可以命名为"module-local".
然而,简要介绍Jigsaw规则和早期规范并没有帮助我弄清楚这种功能.更具体地说,该Modifier规范不包含任何新元素.
那么在未来的Java 9中还有其他任何可能吗?
我有以下Java 9模块:
module com.example.a {
exports com.example.a;
}
Run Code Online (Sandbox Code Playgroud)
使用导出类型:
public class Api {
public static void foo(ImplDetail args) {}
}
Run Code Online (Sandbox Code Playgroud)
和非导出类型:
package com.example.b.internal;
public class ImplDetail {}
Run Code Online (Sandbox Code Playgroud)
导出的类型使用非导出类型作为公共方法中的方法参数类型.我假设编译器会拒绝这种不一致的类配置,因为其他模块中的客户端无法真正调用该foo()方法,因为它们无法实例化参数类型.
令我惊讶的是,这个模块是由javac成功编译的.我可以看到传递的特殊情况null,但我仍然认为这样的API定义格式错误,并且认为它不应该被支持,理想情况下由编译器强制执行.
不解除这种情况的原因是什么?
安装JDK9后,我在运行Scala项目时遇到此异常.将Scala升级到2.12.2也无法解决我的问题.
我试图将我的基于Scala/sbt的项目切换到Java 9.如果我使用sbt编译项目,它可以工作.
如果我尝试使用IntelliJ的Build选项构建项目,我会立即得到错误
Error:Module 'xyz' production: java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter
Run Code Online (Sandbox Code Playgroud)
我试图将模块添加为依赖项
libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.0"
Run Code Online (Sandbox Code Playgroud)
并添加到IntelliJ的编译器设置中(javac以及scala编译器)
<option name="ADDITIONAL_OPTIONS_STRING" value="--add-modules java.xml.bind" />
Run Code Online (Sandbox Code Playgroud)
但不幸的是,没有帮助.
我在这里关注Jigsaw 快速入门.我成功运行了jlink给出的命令:
jlink --module-path $JAVA_HOME/jmods:mlib --add-modules com.greetings --output greetingsapp
Run Code Online (Sandbox Code Playgroud)
这会生成一个"运行时映像",它是一个展开的目录结构,如下所示:
~ tree -d greetingsapp
greetingsapp
??? bin
??? conf
? ??? security
? ??? policy
? ??? limited
? ??? unlimited
??? include
? ??? darwin
??? legal
? ??? java.base
??? lib
??? jli
??? security
??? server
Run Code Online (Sandbox Code Playgroud)
我该怎么办?我期待一个二进制可执行文件,而不是一个展开的目录树.
该bin目录有一个java和一个keytool.我没有看到任何.jar文件或.class文件通过捆绑的java可执行文件运行.
从Java-8开始,我知道类加载器的层次结构如下: -
Bootstrap类加载器 - >扩展类加载器 - >应用程序类加载器
Java 9中类加载器层次结构的变化是什么?它是如何工作的?
我有一些java9模块使用的第三方库不是Java9模块,只是一个简单的实用工具jar.
但是,编译器抱怨它无法从我的实用程序中找到包.
我应该怎么做module-info.java才能使用我的第三方库?
我已经看过几篇在Java 9中简要提到自包含应用程序的在线演示文稿,但我有一个问题需要我解决.
使用新模块系统,您现在只允许包含运行应用程序所需的最少代码.但是,希望运行应用程序的系统是否仍然需要JRE,或者是否可以包含在程序中的基本模块中?
我怀疑它是后者,因为下载最新版Java 的页面(这里)仍显示版本8_151.
TL; DR - 使用Java 9,是否可以创建一个可以在没有安装JRE/Java的系统上执行的自包含可执行文件?
java-9 ×10
java ×7
java-platform-module-system ×5
java-module ×2
classloader ×1
jlink ×1
maven ×1
modularity ×1
scala ×1
scala-2.12 ×1
tools.jar ×1