我在Windows 10上运行Eclipse 2018-09(4.9.0).我正在使用Open JDK 11 GA.我有一个Maven项目被指定为使用Java 8源代码.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
Run Code Online (Sandbox Code Playgroud)
在命令行上使用Maven 3.5.3编译很好.使用Eclipse Eclipse 2018-09(4.9.0)编译也很好.
我将编译Java版本更改为Java 11:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
Run Code Online (Sandbox Code Playgroud)
使用Maven 3.5.3在命令行上仍然可以正常构建.但是在Eclipse 2018-09中,我在整个地方都遇到了错误:
'<>' operator is not allowed for source level below 1.7Constructor references are allowed only at source level 1.8 or aboveDefault methods are allowed only at source level 1.8 or above你明白了.
我已经习惯Alt+F5在Eclipse中更新我的Maven项目(和子项目).我做了一个完整的清洁和重建.
因为这在命令行上使用Maven编译得很好,这必然是一个Eclipse问题,不是吗?当然,Eclipse不支持所有新的Java 11功能,但此代码没有Java 11特定功能.怎么了?
我尝试使用regexp和(使用大量)输入使用jshell 重新创建正则表达式拒绝服务攻击:(a+)+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!a
Pattern.compile("(a+)+")
.matcher("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!")
.matches()
Run Code Online (Sandbox Code Playgroud)
但每次尝试时,这都很快完成.Java中的regexp实现与其他实现不同吗?或链接的维基百科页面错了?
(顺便说一句.我正在使用Java 11,如果那是相关的)
编辑:看起来它与Java版本有关,当我在Java 8上尝试它时,它会挂起,但在Java 9和11中它立即可用.这些版本之间的变化可能会对此产生什么影响?Java中的所有正则表达式都是安全的吗?
是否有特定的Java JEP改变了regexp实现?我想知道什么样的regexp仍然是新Java的问题.
在Java 11中,不再支持与GC日志记录有关的许多JVM arg。如果我们仍然要使用GC日志记录,可以用什么替换它们?特别是,这与以下JVM参数有关:
-Xlog:gc:work/logs/gc.log
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCApplicationStoppedTime
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles
-XX:GCLogFileSize
Run Code Online (Sandbox Code Playgroud)
谢谢。
我正在开发一个小型库,出于明显的原因,我想使用所有Java 11功能(我现在猜不到的模块除外)来生成代码,但是我希望该库与Java 8及更高版本兼容。
当我尝试这个:
javac -source 11 -target 1.8 App.java
Run Code Online (Sandbox Code Playgroud)
我收到以下消息:
warning: source release 11 requires target release 11
Run Code Online (Sandbox Code Playgroud)
...当我查看字节码时,我看到该类的版本为0x37(Java 11):
$ xxd App.class
00000000: cafe babe 0000 0037 ...
Run Code Online (Sandbox Code Playgroud)
Java 8无法加载它:
Exception in thread "main" java.lang.UnsupportedClassVersionError: App has been
compiled by a more recent version of the Java Runtime (class file version 55.0),
this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at …Run Code Online (Sandbox Code Playgroud) 我正在尝试让一个可以在我的机器上完美运行的应用程序在docker上运行,这是我的docker文件:
FROM openjdk:11-jre-slim
VOLUME /tmp
ADD someJar.jar someJar.jar
ADD lib lib
ADD config.properties config.properties
ENTRYPOINT ["java", "-javaagent:lib/aspectjweaver-1.9.2.jar",
"-javaagent:lib/spring-instrument-5.1.6.RELEASE.jar", "--module-path",
"lib/javafx-sdk-11.0.2", "--add-modules=javafx.controls", "-
Dprism.verbose=true", "-jar","someJar.jar"]
Run Code Online (Sandbox Code Playgroud)
我还尝试将其基于高山openjdk11版本,其结果相同:
FROM adoptopenjdk/openjdk11:alpine
VOLUME /tmp
RUN apk update && apk add libx11 mesa-gl gtk+3.0 && apk update
ADD someJar.jar someJar.jar
ADD lib lib
ADD config.properties config.properties
ENTRYPOINT ["java", "-javaagent:lib/aspectjweaver-1.9.2.jar", "-javaagent:lib/spring-instrument-5.1.6.RELEASE.jar", "--module-path", "lib", "--add-modules=javafx.controls", "-Dprism.verbose=true", "-jar","someJar.jar"]
Run Code Online (Sandbox Code Playgroud)
The lib folder contains the linux flavor of the openJFX runtime (.so files and .jar files). I am developing this on …
有时需要允许不安全的HTTPS连接,例如在一些应该与任何站点一起使用的Web爬行应用程序中.我在旧的HttpsURLConnection API中使用了一个这样的解决方案,最近被JDK 11中的新HttpClient API取代了.使用这个新API允许不安全的HTTPS连接(自签名或过期证书)的方法是什么?
UPD:我尝试的代码(在Kotlin中,但直接映射到Java):
val trustAllCerts = arrayOf<TrustManager>(object: X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate>? = null
override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
})
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, SecureRandom())
val sslParams = SSLParameters()
// This should prevent host validation
sslParams.endpointIdentificationAlgorithm = ""
httpClient = HttpClient.newBuilder()
.sslContext(sslContext)
.sslParameters(sslParams)
.build()
Run Code Online (Sandbox Code Playgroud)
但在发送时我有异常(尝试使用自签名证书的localhost):
java.io.IOException: No name matching localhost found
Run Code Online (Sandbox Code Playgroud)
使用IP地址而不是localhost会出现"无主题替代名称存在"异常.
在对JDK进行一些调试之后,我发现sslParams在抛出异常的地方真的被忽略了,并且使用了一些本地创建的实例.进一步调试显示,影响主机名验证算法的唯一方法是将jdk.internal.httpclient.disableHostnameVerification系统属性设置为true.这似乎是一个解决方案.SSLParameters在上面的代码中没有任何影响,所以这部分可以被丢弃.使其仅在全局配置看起来像新的HttpClient API中的严重设计缺陷.
我遇到了一个有趣的场景.由于某种原因strip(),空格字符串(仅包含空格)明显快trim()于Java 11.
基准
public class Test {
public static final String TEST_STRING = " "; // 3 whitespaces
@Benchmark
@Warmup(iterations = 10, time = 200, timeUnit = MILLISECONDS)
@Measurement(iterations = 20, time = 500, timeUnit = MILLISECONDS)
@BenchmarkMode(Mode.Throughput)
public void testTrim() {
TEST_STRING.trim();
}
@Benchmark
@Warmup(iterations = 10, time = 200, timeUnit = MILLISECONDS)
@Measurement(iterations = 20, time = 500, timeUnit = MILLISECONDS)
@BenchmarkMode(Mode.Throughput)
public void testStrip() {
TEST_STRING.strip();
}
public static void main(String[] args) throws …Run Code Online (Sandbox Code Playgroud) 我的 Dockerfile:
FROM frolvlad/alpine-glibc:latest
ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/java
ENV JAVA_HOME=/usr/java/jdk-11.0.6
ENV PATH=$JAVA_HOME/bin:$PATH
Run Code Online (Sandbox Code Playgroud)
当我java -version在容器中运行命令时,我得到了这个段错误:

我怎么解决这个问题?
Java SE 11 的JLS §5.2包含一些 Java 8 的 JLS 没有的新类型转换案例,请参阅列表中的第 4 项和第 5 项:
赋值上下文允许使用以下之一:
- 身份转换
- 扩大原始转换
- 扩大参考转换
- 一个扩大的参考转换,然后是一个拆箱转换
- 扩展引用转换,然后是拆箱转换,然后是扩展基元转换
- 拳击转换
- 一个装箱转换,然后是一个扩大的参考转换
- 拆箱转换
- 一个拆箱转换,然后是一个扩大的原始转换
我不明白列表中的案例 4和案例 5。谁能用例子给我一些解释?如果可能,还请说明其实际用途。
更新:
正如@Naman 所评论的,这里是更改 JLS 的提议 - JDK-8166326:5.2:允许在拆箱前加宽,这是自 Java-9 以来生效的。在报告中,它提到:
这种行为对于与 capture 的互操作性尤其重要:各种现有程序都希望能够将 a 的元素
List<? extends Integer>视为整数。Run Code Online (Sandbox Code Playgroud)List<? extends Integer> li = null; int i = li.get(0);
这可能暗示着这次 JLS 的改变确实有实际的必要性。但我还是不明白为什么 <? extends Integer> 很重要。什么是与捕获的互操作性意味着,它为什么如此重要?这些现有的各种程序是什么样的?它们是 Java …
今天我在玩 OOM 错误,我发现了一些我自己无法解释的东西。
我尝试分配一个大于堆的数组,预期会出现“请求的数组大小超出 VM 限制”错误,但我收到了“ Java 堆空间”错误。
根据JDK 11 文档“3 Troubleshoot Memory Leaks > 了解 OutOfMemoryError 异常”:
线程 thread_name 中的异常:java.lang.OutOfMemoryError:请求的数组大小超出 VM 限制
原因:详细消息“请求的数组大小超出 VM 限制”表明应用程序(或该应用程序使用的 API)试图分配大于堆大小的数组。例如,如果应用程序尝试分配 512 MB 的数组,但最大堆大小为 256 MB,则将抛出 OutOfMemoryError,原因是“请求的数组大小超出 VM 限制”。
代码 :
public class MemOverflow {
public static void main(final String[] args) {
System.out.println("Heap max size: " + (Runtime.getRuntime().maxMemory() / 1024 / 1024) + "MB");
long[] array = new long[100_000_000]; // ~800MB
System.out.println(array.length);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码按预期工作,堆足够大以存储我的数组:
$ javac MemOverflow.java && …Run Code Online (Sandbox Code Playgroud) java ×10
java-11 ×10
docker ×2
alpine-linux ×1
autoboxing ×1
eclipse ×1
heap-memory ×1
javac ×1
javafx ×1
jls ×1
logging ×1
maven ×1
openjfx ×1
performance ×1
regex ×1
security ×1
string ×1