Skip to content

Commit c701e38

Browse files
authored
Initial stab at incorporating some Loom features into Helidon in a way that will work under JDK 11 or 16-loom-ea (helidon-io#2417)
Signed-off-by: Laird Nelson <laird.nelson@oracle.com>
1 parent d59a0b8 commit c701e38

3 files changed

Lines changed: 89 additions & 5 deletions

File tree

microprofile/server/src/main/java/io/helidon/microprofile/server/ServerCdiExtension.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.Set;
2828
import java.util.concurrent.ExecutionException;
2929
import java.util.concurrent.ExecutorService;
30+
import java.util.concurrent.Executors;
3031
import java.util.concurrent.TimeUnit;
3132
import java.util.concurrent.atomic.AtomicBoolean;
3233
import java.util.function.Supplier;
@@ -108,10 +109,34 @@ private void startServer(@Observes @Priority(PLATFORM_AFTER + 100) @Initialized(
108109

109110
// make sure all configuration is in place
110111
if (null == jaxRsExecutorService) {
111-
jaxRsExecutorService = ServerThreadPoolSupplier.builder()
112+
Config serverConfig = config.get("server");
113+
final java.lang.reflect.Method m;
114+
if (serverConfig.get("virtual-threads").asBoolean().orElse(false)) {
115+
java.lang.reflect.Method temp = null;
116+
try {
117+
temp = Executors.class.getDeclaredMethod("newVirtualThreadExecutor");
118+
} catch (final ReflectiveOperationException notLoomEarlyAccess) {
119+
temp = null;
120+
} finally {
121+
m = temp;
122+
}
123+
} else {
124+
m = null;
125+
}
126+
if (m != null) {
127+
jaxRsExecutorService = () -> {
128+
try {
129+
return (ExecutorService) m.invoke(null);
130+
} catch (final ReflectiveOperationException reflectiveOperationException) {
131+
throw new IllegalStateException(reflectiveOperationException.getMessage(), reflectiveOperationException);
132+
}
133+
};
134+
} else {
135+
jaxRsExecutorService = ServerThreadPoolSupplier.builder()
112136
.name("server")
113-
.config(config.get("server.executor-service"))
137+
.config(serverConfig.get("server.executor-service"))
114138
.build();
139+
}
115140
}
116141

117142
// redirect to the first page when root is accessed (if configured)

pom.xml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,5 +1456,34 @@ helidon-parent,helidon-dependencies,helidon-bom,helidon-se,helidon-mp,io.grpc,he
14561456
</plugins>
14571457
</build>
14581458
</profile>
1459+
<profile>
1460+
<id>loom</id>
1461+
<activation>
1462+
<jdk>16-loom</jdk>
1463+
</activation>
1464+
<build>
1465+
<pluginManagement>
1466+
<plugins>
1467+
<plugin>
1468+
<groupId>org.apache.maven.plugins</groupId>
1469+
<artifactId>maven-compiler-plugin</artifactId>
1470+
<configuration>
1471+
<source>16</source>
1472+
<target>16</target>
1473+
<release>16</release>
1474+
</configuration>
1475+
</plugin>
1476+
<plugin>
1477+
<groupId>org.apache.maven.plugins</groupId>
1478+
<artifactId>maven-javadoc-plugin</artifactId>
1479+
<configuration>
1480+
<source>16</source>
1481+
<release>16</release>
1482+
</configuration>
1483+
</plugin>
1484+
</plugins>
1485+
</pluginManagement>
1486+
</build>
1487+
</profile>
14591488
</profiles>
14601489
</project>

webserver/jersey/src/main/java/io/helidon/webserver/jersey/AsyncExecutorProvider.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
package io.helidon.webserver.jersey;
1818

19+
import java.util.Objects;
1920
import java.util.concurrent.ExecutorService;
21+
import java.util.concurrent.Executors;
2022
import java.util.function.Supplier;
2123

2224
import io.helidon.common.configurable.ThreadPoolSupplier;
@@ -30,23 +32,51 @@ class AsyncExecutorProvider implements ExecutorServiceProvider {
3032
private final Supplier<ExecutorService> executorServiceSupplier;
3133

3234
AsyncExecutorProvider(Supplier<ExecutorService> supplier) {
33-
this.executorServiceSupplier = supplier;
35+
this.executorServiceSupplier = Objects.requireNonNull(supplier);
3436
}
3537

3638
static ExecutorServiceProvider create(Config config) {
37-
return new AsyncExecutorProvider(ThreadPoolSupplier.builder()
39+
Config asyncExecutorServiceConfig = config.get("async-executor-service");
40+
final java.lang.reflect.Method m;
41+
if (asyncExecutorServiceConfig.get("virtual-threads").asBoolean().orElse(false)) {
42+
java.lang.reflect.Method temp = null;
43+
try {
44+
temp = Executors.class.getDeclaredMethod("newVirtualThreadExecutor");
45+
} catch (final ReflectiveOperationException notLoom) {
46+
temp = null;
47+
} finally {
48+
m = temp;
49+
}
50+
} else {
51+
m = null;
52+
}
53+
if (m != null) {
54+
return new AsyncExecutorProvider(() -> {
55+
try {
56+
return (ExecutorService) m.invoke(null);
57+
} catch (final ReflectiveOperationException reflectiveOperationException) {
58+
throw new IllegalStateException(reflectiveOperationException.getMessage(), reflectiveOperationException);
59+
}
60+
});
61+
} else {
62+
return new AsyncExecutorProvider(ThreadPoolSupplier.builder()
3863
.corePoolSize(1)
3964
.maxPoolSize(10)
4065
.prestart(false)
4166
.threadNamePrefix("helidon-jersey-async")
42-
.config(config.get("async-executor-service"))
67+
.config(asyncExecutorServiceConfig)
4368
.build());
69+
}
4470
}
4571

4672
static ExecutorServiceProvider create(ExecutorService executor) {
4773
return new AsyncExecutorProvider(() -> executor);
4874
}
4975

76+
static ExecutorServiceProvider create(Supplier<ExecutorService> executorServiceSupplier) {
77+
return new AsyncExecutorProvider(executorServiceSupplier);
78+
}
79+
5080
@Override
5181
public ExecutorService getExecutorService() {
5282
return executorServiceSupplier.get();

0 commit comments

Comments
 (0)