OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.16k stars 597 forks source link

Fix integration of virtual threads into threading bundle #28268

Closed KyleAure closed 6 months ago

KyleAure commented 6 months ago

Problem Description

Currently, there's a product bug in Liberty where the com.ibm.ws.threading bundle can be activated before the internal virtualThreadOps service is available. This arises due to the inadequate integration of the virtualThreadOps service, leading to concerns regarding Java version compatibility.

Background Information

Efforts have been made to integrate virtual threads in Liberty, with discussions revolving around how to ensure the availability of the virtualThreadOps service to the com.ibm.ws.threading bundle. Previous attempts, such as activating virtualThreadOps via an auto feature, have faced challenges and opposition. Options like using a multi-release bundle and separate implementations of virtualThreadOps have been explored but require careful consideration.

Proposed Solutions

Option 1: Reflection

Involves placing implementations of virtualThreadOps directly in com.ibm.ws.threading. Requires the use of reflection to access Java 21 methods, leading to complexity and potential performance issues. This is the most straightforward solution, but has a lot of drawbacks Example: https://github.com/OpenLiberty/open-liberty/compare/integration...KyleAure:27339-virtualThreadOps-reflection?expand=1

Option 2: Separate Bundles

Implements virtualThreadOps in separate bundles, allowing different Java version compatibility. Provides more flexibility for future expansion of virtual thread support. Ensures these bundles are started as part of the kernel to ensure availability to com.ibm.ws.threading. Unknown if the kernel boot feature can support require-java:="" declaration. Example: https://github.com/OpenLiberty/open-liberty/compare/integration...KyleAure:27339-virtualThreadOps-native?expand=1

Option 3: Multi-Release Bundle

Utilizes a multi-release JAR to manage Java version-specific implementations. Simplifies deployment and maintenance by packaging Java 8 and Java 21 bytecode separately. Offers clear differentiation between Java versions within the JAR structure. Example: https://github.com/OpenLiberty/open-liberty/compare/integration...KyleAure:27339-virtualThreadOps-multirelease?expand=1

Option 4: Dynamic Service Activation

Use two service components implementing VirtualThreadOps directly in the threading bundle that are activated based on the java.version condition. The two implementations would be in two different packages where the Java 21 version is pulled in from a separate project, compiling to Java 21 APIs. But we make sure the osgi.ee for threading remains compatible with Java 8. There would be no need for MR JARs to replace classes based on Java versions.

Example: https://github.com/OpenLiberty/open-liberty/compare/integration...KyleAure:27339-virtualThreadOps-dynamic-activation?expand=1

tjwatson commented 6 months ago

I will not be able to join the design call. Of Options 1-3 I think MR would be the best option. But I dislike the obfuscation of class replacement/hiding/adding for MR JARs because I think it makes things a bit more obscure for debugging and diagnostics in the field.

Option 4 would use two service components implementing VirtualThreadOps directly in the threading bundle that are activated based on the java.version condition. The two implementations would be in two different packages where the Java 21 version is pulled in from a separate project, compiling to Java 21 APIs. But we make sure the osgi.ee for threading remains compatible with Java 8. There would be no need for MR JARs to replace classes based on Java versions.

The two component model would work better for things like our diagnostics because it would show the two components and which one is enabled based on the java.version condition versus being hidden behind class replacement of MR JARs.

KyleAure commented 6 months ago

Most people were in favor of Option 4 due to serviceability and as an ongoing pattern for future comparability issues due to java levels in the future.