Skip to content

Conversation

@radhakrishnan10192
Copy link

@radhakrishnan10192 radhakrishnan10192 commented Aug 19, 2025

ResteasyJackson2Provider initializes the default ObjectMapper from this change, which is initialized using ObjectMapper.findAndRegisterModules() this internally trying to load the classes using service loader, which is a blocking call. This is a blocking call in reactive flow which is flagged by Blockhound.

This fix would make the initialization only once and reused without affecting the reactive flow.

@radhakrishnan10192 radhakrishnan10192 requested a review from a team as a code owner August 19, 2025 16:20
@radhakrishnan10192
Copy link
Author

@jamezp I have tried this in local and it seems to be fixing the blocking execution in the reactor flow. WDYT about this?

@jamezp
Copy link
Member

jamezp commented Aug 19, 2025

@radhakrishnan10192 What does the issue seem to be? I see from the JIRA that it's blocking, but I'm not following why that would be an issue.

@radhakrishnan10192
Copy link
Author

@jamezp When http write operation is performed from 6.2.11 version, default object mapper is initialised using ObjectMapper.findAndRegisterModules() which does classpath scanning via ServiceLoader. This opens JARs and reads their contents. That’s blocking I/O, and when it happens on a non‑blocking/reactor thread during a RESTEasy write, BlockHound flags it (your stack shows RandomAccessFile → JarURLConnection → ServiceLoader).

here is a sample trace i have got

0 = {StackTraceElement@22552} "reactor.blockhound.BlockHound$Builder.lambda$new$0(BlockHound.java:258)" 1 = {StackTraceElement@22560} "reactor.blockhound.BlockHound$Builder.lambda$install$8(BlockHound.java:488)" 2 = {StackTraceElement@22561} "reactor.blockhound.BlockHoundRuntime.checkBlocking(BlockHoundRuntime.java:89)" 3 = {StackTraceElement@22562} "java.base/java.io.RandomAccessFile.readBytes(RandomAccessFile.java)" 4 = {StackTraceElement@22563} "java.base/java.io.RandomAccessFile.read(RandomAccessFile.java:405)" 5 = {StackTraceElement@22564} "java.base/java.io.RandomAccessFile.readFully(RandomAccessFile.java:469)" 6 = {StackTraceElement@22565} "java.base/java.util.zip.ZipFile$Source.readFullyAt(ZipFile.java:1478)" 7 = {StackTraceElement@22566} "java.base/java.util.zip.ZipFile$ZipFileInputStream.initDataOffset(ZipFile.java:922)" 8 = {StackTraceElement@22567} "java.base/java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:938)" 9 = {StackTraceElement@22568} "java.base/java.util.zip.ZipFile$ZipFileInflaterInputStream.fill(ZipFile.java:455)" 10 = {StackTraceElement@22569} "java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)" 11 = {StackTraceElement@22570} "java.base/java.io.InputStream.readNBytes(InputStream.java:506)" 12 = {StackTraceElement@22571} "java.base/java.util.jar.JarFile.getBytes(JarFile.java:814)" 13 = {StackTraceElement@22572} "java.base/java.util.jar.JarFile.checkForSpecialAttributes(JarFile.java:1004)" 14 = {StackTraceElement@22573} "java.base/java.util.jar.JarFile.isMultiRelease(JarFile.java:388)" 15 = {StackTraceElement@22574} "java.base/java.util.jar.JarFile.getEntry(JarFile.java:510)" 16 = {StackTraceElement@22575} "java.base/sun.net.www.protocol.jar.URLJarFile.getEntry(URLJarFile.java:131)" 17 = {StackTraceElement@22576} "java.base/sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:135)" 18 = {StackTraceElement@22577} "java.base/sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:175)" 19 = {StackTraceElement@22578} "java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.parse(ServiceLoader.java:1172)" 20 = {StackTraceElement@22579} "java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1213)" 21 = {StackTraceElement@22580} "java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1228)" 22 = {StackTraceElement@22581} "java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)" 23 = {StackTraceElement@22582} "java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)" 24 = {StackTraceElement@22583} "java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)" 25 = {StackTraceElement@22584} "com.fasterxml.jackson.databind.ObjectMapper.findModules(ObjectMapper.java:1161)" 26 = {StackTraceElement@22585} "com.fasterxml.jackson.databind.ObjectMapper.findModules(ObjectMapper.java:1145)" 27 = {StackTraceElement@22586} "com.fasterxml.jackson.databind.ObjectMapper.findAndRegisterModules(ObjectMapper.java:1195)" 28 = {StackTraceElement@22587} "org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider._locateMapperViaProvider(ResteasyJackson2Provider.java:366)" 29 = {StackTraceElement@22588} "com.fasterxml.jackson.jakarta.rs.base.ProviderBase.locateMapper(ProviderBase.java:900)" 30 = {StackTraceElement@22589} "org.jboss.resteasy.plugins.providers.jackson.ResteasyJackson2Provider.writeTo(ResteasyJackson2Provider.java:226)"

@jamezp jamezp merged commit 4b0ae34 into resteasy:main Dec 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants