我已对此进行了编辑,以使原始帖子的内容保持最新。
我想尝试JEP 428:结构化并发(孵化器)中定义的新Project Loom功能
我的 pom.xml 中有
<properties>
<maven.compiler.executable>${env.JAVA_HOME}/bin/javac</maven.compiler.executable>
<maven.compiler.source>19</maven.compiler.source>
<maven.compiler.target>19</maven.compiler.target>
</properties>
. . .
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<compilerArgs>
<arg>--add-modules=jdk.incubator.concurrent</arg>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)
其中JAVA_HOME指向 JDK 19,但是当我尝试通过构建时,mvn compile我得到
[ERROR] C:\Users\ERIC\Documents\git\loom-lab\laboratory\src\main\java\net\kolotyluk\loom\Structured.java:3:20: error: package jdk.incubator.concurrent is not visible
[ERROR] C:\Users\ERIC\Documents\git\loom-lab\laboratory\src\main\java\net\kolotyluk\loom\Structures.java:3:20: error: package jdk.incubator.concurrent is not visible
. . .
Run Code Online (Sandbox Code Playgroud)
很多人在这方面帮助了我,显然他们可以让它发挥作用,但由于某种原因,我无法开始mvn compile工作。
不过,我可以让代码在 IntelliJ 下编译和运行。当我可以让 IntelliJ 编译时,我从来没有无法让 Maven 编译。通常,情况恰恰相反。
我正在使用 Java 19。我尝试使用新引入的虚拟线程,如下所示:
public static void main(String[] args) {
System.out.println("Started with virutal threads");
try (ExecutorService virtualService = Executors.newVirtualThreadPerTaskExecutor()) {
virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 1"));
virtualService.submit(() -> System.out.println("[" + Thread.currentThread().getName() + "] virtual task 2"));
}
System.out.println("Finished");
}
Run Code Online (Sandbox Code Playgroud)
该程序的输出是:
Started with virutal threads
[] virtual task 2
[] virtual task 1
Finished
Run Code Online (Sandbox Code Playgroud)
为什么 Thread.currentThread().getName() 没有任何名称?
后续问题:如何识别彼此之间的虚拟线程?(如何识别它们)所以输出看起来像
[thread-1] virtual task 2
[thread-0] virtual task 1
Run Code Online (Sandbox Code Playgroud) 我很难理解压缩指针在 Java 19 中的工作原理,感谢帮助。
在 Java 11 中,对于小于 32GiB(压缩指针)的堆,引用大小为 4,对于更大的堆,引用大小为 8。在 Java 19 中,即使对于更大的堆,它们似乎也占用 4 个字节(如何?)。
细节:
Java 版本:OpenJDK Java 11.0.12 和 OpenJDK Java 19.0.1
命令行:
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms41g -Xmx41g -XX:+AlwaysPreTouch
-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC -Xlog:gc -Xlog:gc+heap+coops -Xms31g -Xmx31g -XX:+AlwaysPreTouch
代码: https: //github.com/cornelcreanga/fun/blob/master/src/main/java/com/ccreanga/various/RandomAllocate.java - 代码取自https://shipilev.net/jvm/anatomy -夸克/23-压缩参考/
使用 Java 11 和 19 运行此代码,您可以看到,对于 > 32 GiB 的堆,Java 19 中的内存大小低于 Java 11 中的内存大小。对于较小的堆,大小几乎相同。
我有一个Idea Intellij这样的项目:
测试.java:
public class Test {
public static void main(String[] args) {
System.out.println("Test");
}
}
Run Code Online (Sandbox Code Playgroud)
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.target>20</maven.compiler.target>
<maven.compiler.source>20</maven.compiler.source>
</properties>
</project>
Run Code Online (Sandbox Code Playgroud)
智能理念
File -> Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler
Run Code Online (Sandbox Code Playgroud)
File -> Project Structure -> Project
Run Code Online (Sandbox Code Playgroud)
File -> Project Structure -> Modules -> Sources
Run Code Online (Sandbox Code Playgroud)
File -> Project Structure -> Modules -> Dependencies
Run Code Online (Sandbox Code Playgroud)
尝试运行时Test.java出现错误:
Error:java: error: release version …Run Code Online (Sandbox Code Playgroud) 我从这里下载了 JDK19 的候选版本https://jdk.java.net/19/以尝试一下那里实现的新记录模式,但我遇到了一些问题。在我的测试中,我写了一个基于密封接口加记录的Optional版本,方式如下:
package tests.patterns;
import java.util.Objects;
public class TestRecordPatter
{
public static void main(final String[] args)
{
final Opt<String> opt1 = computeAnswer(23);
final String answer1 = switch (opt1) {
case Opt.Some<String>(String ans) -> ans;
case Opt.None __ -> "no answer";
default -> throw new IllegalStateException("This should not happen"); // A
};
System.out.println(answer1);
final Opt<String> opt2 = computeAnswer(35);
final Object answer2 = switch (opt2) { // B
case Opt.Some<String>(var ans) -> ans; // C
case Opt.None __ -> …Run Code Online (Sandbox Code Playgroud) 我一直在使用 Lombok 并且对它非常满意,这让我的懒惰避免了编写样板代码。但有一些关于龙目岛的令人担忧的信息,例如:
\n我在这里读到,Lombok 完全依赖于 JDK 中的一个漏洞,即一个非法的非公共 API,在某些时候,如果关闭该漏洞,将导致 Lombok 停止工作。--add-open人们甚至看到 Lombok 开发人员与 OpenJDK 开发人员争论,以保持 JDK 非公共 API 的开放性,或者留下一个选项,使他们能够在其关闭(和--illegal-access标记)时撬开它。但到目前为止,Lombok 甚至可以使用v1.18.26处理Java\xc2\xa019。
许多人说,如果出于任何原因您决定放弃 Lombok,那么您可以轻松地使用 de-lombok。然而,有一篇文章描述 de-lombok 可能不太好。
\n所以,我的问题是:
\nLombok 会停止工作吗?还是Java没有堵住那些非公开API的漏洞?
\n使用另一个注释处理器会如何导致 Lombok 失败?
\n有没有办法知道哪个平台线程正在承载当前虚拟线程或将虚拟线程固定到平台线程并在JDK19中获取其线程本地?我想在虚拟线程中重用一些对象,比如Golang中的sync.Pool。
我是一名大学讲师,我正在修改关于 Java 反射的讲座。其他几年,当我讲授抑制访问检查的可怕之处时,我向您展示了您可以设置一个 SecurityManager 并执行类似的操作
if ("suppressAccessChecks".equals(p.getName())){
StackTraceElement[] st = Thread.currentThread().getStackTrace();
if(.. st ..) { throw new SecurityException(); }
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以允许列入白名单的反序列化器仅调用suppressAccessChecks。然而,现在他们正在弃用 SecurityManager。我认为新的模块系统应该在这里有所帮助,但我找不到解释如何支持上面白名单反序列化器的想法的资源。
有什么提示吗?
我正在查看https://openjdk.org/projects/jdk/19/,这似乎表明 OpenJDK 现在已于 2022 年 9 月 20 日正式可用。但是,当我查看当前的 Maven 映像时 ( https://hub .docker.com/_/maven),我找到 openJDK 17 (https://hub.docker.com/layers/library/maven/3.8.4-openjdk-17/images/sha256-d07c45c45755f0f90b779bad869467e602f1bfff4d0b5eb1ff73f2882bc38187)并打开JDK 18(https ://hub.docker.com/layers/library/maven/3.8.7-openjdk-18/images/sha256-1936d70bb3415a0d7e822ed484cdb4974593b195091c145b52ba7775003dc3f0?context=explore)但我没有看到 openJdk-19。我搜索了“openjdk” https://hub.docker.com/_/maven/tags?page=1&name=openjdk并查看了“最新”,但我找不到 Java 19。是否有这样的 openjdk maven 工件可能在不同的命名方案?我有什么遗漏的吗?
我在使用 Java 19 的 Maven 插件时遇到错误。Java 18 运行良好。我该如何解决这个问题?
我在 Centos 7.9.2009 上的 Docker 容器中运行。当在 Ubuntu 20.0 - kernel 5.15.0-52-generic 上的同一容器中进行测试时,它可以正常工作。
堆栈跟踪如下。
Caused by: java.io.IOException: Function not implemented
Oct 28 12:12:49 at sun.nio.ch.FileChannelImpl.transferFrom0 (Native Method)
Oct 28 12:12:49 at sun.nio.ch.FileChannelImpl.transferFromDirectlyInternal (FileChannelImpl.java:804)
Oct 28 12:12:49 at sun.nio.ch.FileChannelImpl.transferFromDirectly (FileChannelImpl.java:833)
Oct 28 12:12:49 at sun.nio.ch.FileChannelImpl.transferFrom (FileChannelImpl.java:935)
Oct 28 12:12:49 at org.codehaus.plexus.util.FileUtils.doCopyFile (FileUtils.java:1077)
Oct 28 12:12:49 at org.codehaus.plexus.util.FileUtils.copyFile (FileUtils.java:1049)
Run Code Online (Sandbox Code Playgroud)
使用的版本
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Java version: 19, vendor: Eclipse Adoptium, runtime: /opt/java/openjdk
OS name: "linux", …Run Code Online (Sandbox Code Playgroud) 我java.net.http.HttpClient.newHttpClient()在 Java 19 (Temurin) 下使用,并sendAsync(...)在同一实例上执行来自不同步骤的请求。我认为这是可以的,正如 javadoc 所说:
一旦构建,HttpClient 就是不可变的......
但是,某些请求会失败并显示以下信息:
java.io.IOException: HTTP/1.1 header parser received no bytes
Run Code Online (Sandbox Code Playgroud)
奇怪的是,这取决于我的请求的速度:
我为它写了一个测试:
private final HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://..."))
.setHeader("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofByteArray("[]".getBytes()))
.build();
@ParameterizedTest
@ValueSource(ints = {3, 5})
void httpClientTest(int intervalSeconds) throws Exception {
HttpClient httpClient = HttpClient.newHttpClient();
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
Thread.sleep(Duration.ofSeconds(intervalSeconds));
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofByteArray()).get();
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试过以下操作:
curl在命令行上执行相同的操作。无论我尝试什么时间间隔,都没有请求失败。所以应该不是服务器的问题。HttpClient.newHttpClient() …java-19 ×11
java ×8
maven ×3
project-loom ×2
adoptopenjdk ×1
docker ×1
java-11 ×1
java-module ×1
jvm ×1
jvm-hotspot ×1
linux ×1
lombok ×1
record ×1