New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JAXB Implementation not found in Java 11 when using Failsafe with Retries & Spring Boot #953
Comments
First proposal seems a bit more appropriate from my point of view. |
Although the second option is a good idea anyway because the common pool is
a poor choice for io bound workloads.
|
@whiskeysierra can you give a bit more highlight on why it's "poor choice"? |
https://dzone.com/articles/be-aware-of-forkjoinpoolcommonpool
The core issue is, that it's a shared global fixed-size thread pool and IO
usually blocks.
|
I didn't look too close on this yet, but at a first glance it didn't look like IO is performed on the common pool. It looked like the task in the common pool was instantly completed because |
It turns out that
Would be a breaking change. Using |
would you be able to create non breaking change utilising second approach? |
At this point, I'm not sure what even the correct fix is. We could:
(1) Would fix the issue I'm seeing, but it feels to me like there is something deeper going on here. For (2), we'd need to have the (3) and (4) also rely on the assumption that there is no need for having two separate Thread Pools for Failsafe and the actual request execution. I don't know enough about Failsafe and Riptide though to judge if this assumption is correct. |
Regarding (2), the Failsafe plugin currently takes an optional scheduler, right? But no executor. |
That's right, I got the classes confused. However it looks like I feel I should also document our workaround in case someone else has this problem: We're essentially running fix (1). We added this class: public class JaxbForkJoinWorkerThreadFactory implements ForkJoinWorkerThreadFactory {
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
ForkJoinWorkerThread thread = new JaxbForkJoinWorkerThread(pool);
thread.setContextClassLoader(Thread.currentThread().getContextClassLoader());
return thread;
}
static class JaxbForkJoinWorkerThread extends ForkJoinWorkerThread {
protected JaxbForkJoinWorkerThread(ForkJoinPool pool) {
super(pool);
}
}
} And configured this ThreadFactory in System.setProperty("java.util.concurrent.ForkJoinPool.common.threadFactory",JaxbForkJoinWorkerThreadFactory::class.qualifiedName!!) In our case we also needed to override the default parallelism of the ForkJoinPool to force Failsafe to use the common pool. System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", Math.max(2, Runtime.getRuntime().availableProcessors()).toString()) It's all super hacky, but it works. But I will be able to sleep easier at night if we can remove this code and get this fixed in Riptide ;) |
Could we have a default /**
* @see <a href="https://github.com/zalando/riptide/issues/953">JAXB + ForkJoinPool</a>
*/
@API(status = EXPERIMENTAL)
@AllArgsConstructor
private final class PreserveContextClassLoader implements TaskDecorator {
private final ClassLoader loader = Thread.currentThread().getContextClassLoader();
@Override
public <T> ContextualSupplier<T> decorate(final ContextualSupplier<T> supplier) {
final Span span = tracer.activeSpan();
return context -> {
Thread.currentThread().setContextClassLoader(loader);
return supplier.get(context);
};
}
} |
I can not reproduce it locally, however I experience this bug on production containerised environment. Could JRE version influence appearance of this bug? |
If you're using Java 8 locally but 9+ in production then yes. I believe
they stopped binding JAXB with Java 9 or maybe 10.
…On Tue, 26 Jan 2021, 19:43 Kirill Bazarov, ***@***.***> wrote:
I can not reproduce it locally, however I experience this bug on
production containerised environment. Could JRE version influence
appearance of this bug?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#953 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADI7HJPBXLLYXKOQN6PN53S34EMFANCNFSM4OQX3FRA>
.
|
I was able to reproduce it locally. I can confirm both circuit breaker and retries cause the bug. |
Can you note down the steps to reproduce it here? |
The application is built with Spring Boot and following libraries versions: I have the following Riptide configuration:
And the following call:
Enabling circuit breaker and retires or any of will cause an exception:
|
@whiskeysierra how soon can we apply a |
I haven't tested it yet, that was just an idea.
…On Wed, 27 Jan 2021, 16:12 Kirill Bazarov, ***@***.***> wrote:
@tobias-bahls <https://github.com/tobias-bahls> how did you apply your
solution to a Spring Boot? It packs an uber jar file in a specific way, and
the JaxbForkJoinWorkerThreadFactory class is not copied to a jar root.
@whiskeysierra <https://github.com/whiskeysierra> how soon can we apply a
TaskDecorator solution? Do you still see any drawbacks of that?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#953 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AADI7HLSAAWBGJGANUKOKB3S4AUMPANCNFSM4OQX3FRA>
.
|
@whiskeysierra do you have any preference in:
I don't have any strong opinion, but I could have invested some time into PR. |
@whiskeysierra I have created PR from your idea with task decorator. However I have no idea how to test it currently. |
@whiskeysierra when it's going to be released? |
@buzzlighty sorry, I missed this fix. I will take care and cut release till the end of this week |
Unfortunately we experience the same issue again. |
When using
riptide-soap
together with retries fromriptide-failsafe
in Java 11 on a packaged Spring Boot jar, the call fails withjavax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
despite the correct JARs being in the classpath.Description
In this specific combination:
riptide-soap
riptide-failsafe
with retries enabledThe call to create a
JAXBContext
with the aforementioned message. If retries are disabled, everything works as expected.The root cause of the issue seems like that Failsafe is using
ForkJoinPool.commonPool()
internally, resulting us in hitting spring-projects/spring-boot#15737.Possible Fix
I can think of two options:
JAXBContext.newInstance()
. This requires us to switch to creatingJAXBContext
withcontextPath
instead of the class to be bound.Executor
to Failsafe that creates threads with the proper context class loader.I don't know which of these options is better, but I'd be happy to implement the change if there is some consensus.
Steps to Reproduce
I can provide a sample project if needed
Your Environment
The text was updated successfully, but these errors were encountered: