Skip to content

Commit 24b2465

Browse files
authored
Remove Reflective Virtual Thread Lookup (#687)
* remove reflective virtual thread lookup we already have a multi-release jar * Update VirtualThreadExecutor.java * fix test
1 parent 0ee148c commit 24b2465

File tree

5 files changed

+70
-80
lines changed

5 files changed

+70
-80
lines changed

http-client/pom.xml

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<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">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
35
<modelVersion>4.0.0</modelVersion>
46
<parent>
57
<groupId>io.avaje</groupId>
@@ -95,66 +97,48 @@
9597

9698
<build>
9799
<plugins>
98-
99-
<plugin> <!-- Multi-Release with 21 -->
100-
<groupId>org.apache.maven.plugins</groupId>
101-
<artifactId>maven-jar-plugin</artifactId>
102-
<version>3.5.0</version>
103-
<configuration>
104-
<archive>
105-
<manifestEntries>
106-
<Multi-Release>true</Multi-Release>
107-
</manifestEntries>
108-
</archive>
109-
</configuration>
110-
</plugin>
111-
100+
<!-- Multi-Release with 21 -->
112101
<plugin>
113102
<groupId>org.apache.maven.plugins</groupId>
114103
<artifactId>maven-compiler-plugin</artifactId>
115-
<version>3.14.1</version>
104+
<configuration>
105+
<annotationProcessorPaths>
106+
<path>
107+
<groupId>io.avaje</groupId>
108+
<artifactId>avaje-inject-generator</artifactId>
109+
<version>12.0</version>
110+
</path>
111+
</annotationProcessorPaths>
112+
</configuration>
116113
<executions>
117114
<execution>
118-
<id>default-testCompile</id>
119-
<configuration>
120-
<annotationProcessorPaths>
121-
<path>
122-
<groupId>io.avaje</groupId>
123-
<artifactId>avaje-inject-generator</artifactId>
124-
<version>12.0</version>
125-
</path>
126-
</annotationProcessorPaths>
127-
</configuration>
128-
</execution>
129-
<!-- Compile for base version Java 11 -->
130-
<execution>
131-
<id>base</id>
132-
<goals>
133-
<goal>compile</goal>
134-
</goals>
135-
<configuration>
136-
<release>11</release>
137-
<compileSourceRoots>
138-
<compileSourceRoot>${project.basedir}/src/main/java</compileSourceRoot>
139-
</compileSourceRoots>
140-
</configuration>
141-
</execution>
142-
<!-- Compile for Java 21 -->
143-
<execution>
144-
<id>java21</id>
115+
<id>compile-java-21</id>
116+
<phase>compile</phase>
145117
<goals>
146118
<goal>compile</goal>
147119
</goals>
148120
<configuration>
149121
<release>21</release>
150122
<compileSourceRoots>
151-
<compileSourceRoot>${project.basedir}/src/main/java21</compileSourceRoot>
123+
<compileSourceRoot>
124+
${project.basedir}/src/main/java21</compileSourceRoot>
152125
</compileSourceRoots>
153-
<outputDirectory>${project.build.outputDirectory}/META-INF/versions/21</outputDirectory>
126+
<multiReleaseOutput>true</multiReleaseOutput>
154127
</configuration>
155128
</execution>
156129
</executions>
157130
</plugin>
131+
<plugin>
132+
<groupId>org.apache.maven.plugins</groupId>
133+
<artifactId>maven-jar-plugin</artifactId>
134+
<configuration>
135+
<archive>
136+
<manifestEntries>
137+
<Multi-Release>true</Multi-Release>
138+
</manifestEntries>
139+
</archive>
140+
</configuration>
141+
</plugin>
158142

159143
<!-- generated by avaje inject -->
160144
<plugin>

http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.avaje.http.client;
22

3-
import java.lang.invoke.MethodHandles;
4-
import java.lang.invoke.MethodType;
53
import java.net.Authenticator;
64
import java.net.CookieHandler;
75
import java.net.CookieManager;
@@ -15,8 +13,6 @@
1513
import java.util.Optional;
1614
import java.util.Set;
1715
import java.util.concurrent.Executor;
18-
import java.util.concurrent.ExecutorService;
19-
import java.util.concurrent.Executors;
2016
import java.util.function.Function;
2117

2218
import javax.net.ssl.SSLContext;
@@ -55,8 +51,7 @@ final class DHttpClientBuilder implements HttpClient.Builder, HttpClient.Builder
5551
private final Set<String> suppressed = new HashSet<>();
5652

5753
private void configureRetryHandler(BeanScope beanScope) {
58-
beanScope.getOptional(RetryHandler.class)
59-
.ifPresent(this::setRetryHandler);
54+
beanScope.getOptional(RetryHandler.class).ifPresent(this::setRetryHandler);
6055
}
6156

6257
private void setRetryHandler(RetryHandler retryHandler) {
@@ -108,8 +103,8 @@ private java.net.http.HttpClient defaultClient() {
108103
}
109104
if (executor != null) {
110105
builder.executor(executor);
111-
} else if (Integer.getInteger("java.specification.version") >= 21) {
112-
builder.executor(virtualThreadExecutor());
106+
} else if (Runtime.version().feature() >= 21) {
107+
builder.executor(JDK21Functions.getExecutor());
113108
}
114109
if (proxy != null) {
115110
builder.proxy(proxy);
@@ -129,17 +124,6 @@ private java.net.http.HttpClient defaultClient() {
129124
return builder.build();
130125
}
131126

132-
private static ExecutorService virtualThreadExecutor() {
133-
try {
134-
return (ExecutorService)
135-
MethodHandles.lookup()
136-
.findStatic(Executors.class, "newVirtualThreadPerTaskExecutor", MethodType.methodType(ExecutorService.class))
137-
.invokeExact();
138-
} catch (Throwable e) {
139-
return null;
140-
}
141-
}
142-
143127
/**
144128
* Create a reasonable default BodyAdapter if avaje-jsonb or Jackson are present.
145129
*/
@@ -192,8 +176,7 @@ private DHttpClientContext buildClient() {
192176
buildIntercept());
193177
}
194178

195-
DHttpClientBuilder() {
196-
}
179+
DHttpClientBuilder() {}
197180

198181
@Override
199182
public HttpClient.Builder client(java.net.http.HttpClient client) {
@@ -377,5 +360,4 @@ public Duration requestTimeout() {
377360
public RetryHandler retryHandler() {
378361
return retryHandler;
379362
}
380-
381363
}

http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import io.avaje.applog.AppLog;
44

5-
import java.lang.invoke.MethodHandles;
6-
import java.lang.invoke.MethodType;
75
import java.lang.reflect.Type;
86
import java.net.http.HttpHeaders;
97
import java.net.http.HttpRequest;
@@ -124,9 +122,8 @@ public HttpClient.Metrics metrics() {
124122
public HttpClient.Metrics metrics(boolean reset) {
125123
if (reset) {
126124
return new DMetrics(metricResTotal.sumThenReset(), metricResError.sumThenReset(), metricResBytes.sumThenReset(), metricResMicros.sumThenReset(), metricResMaxMicros.getThenReset());
127-
} else {
128-
return new DMetrics(metricResTotal.sum(), metricResError.sum(), metricResBytes.sum(), metricResMicros.sum(), metricResMaxMicros.get());
129125
}
126+
return new DMetrics(metricResTotal.sum(), metricResError.sum(), metricResBytes.sum(), metricResMicros.sum(), metricResMaxMicros.get());
130127
}
131128

132129
void metricsString(int stringBody) {
@@ -395,14 +392,6 @@ String maxResponseBody(String body) {
395392
@Override
396393
public void close() {
397394
this.closed = true;
398-
if (Integer.getInteger("java.specification.version") >= 21) {
399-
try {
400-
MethodHandles.lookup()
401-
.findVirtual(java.net.http.HttpClient.class, "close", MethodType.methodType(void.class))
402-
.invokeExact(httpClient);
403-
} catch (Throwable t) {
404-
throw new IllegalStateException("Failed to close java.net.http.HttpClient instance");
405-
}
406-
}
395+
JDK21Functions.closeClient(httpClient);
407396
}
408397
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.avaje.http.client;
2+
3+
import java.net.http.HttpClient;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
7+
final class JDK21Functions {
8+
private JDK21Functions() {}
9+
10+
// only executed in tests
11+
static ExecutorService getExecutor() {
12+
return Executors.newCachedThreadPool();
13+
}
14+
15+
static void closeClient(HttpClient client) {
16+
// no-op
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.avaje.http.client;
2+
3+
import java.net.http.HttpClient;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
7+
final class JDK21Functions {
8+
private JDK21Functions() {}
9+
10+
static ExecutorService getExecutor() {
11+
return Executors.newVirtualThreadPerTaskExecutor();
12+
}
13+
14+
static void closeClient(HttpClient client) {
15+
client.close();
16+
}
17+
}

0 commit comments

Comments
 (0)