Details
-
Improvement
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
3.21.0
-
None
-
None
-
Unknown
Description
org.apache.camel.dataformat.bindy.BindyAbstractFactory.link() calls org.apache.camel.util.ReflectionHelper.setField() :
public static void setField(Field f, Object instance, Object value) { try { boolean oldAccessible = f.isAccessible(); boolean shouldSetAccessible = !Modifier.isPublic(f.getModifiers()) && !oldAccessible; if (shouldSetAccessible) { f.setAccessible(true); } f.set(instance, value); if (shouldSetAccessible) { f.setAccessible(oldAccessible); } } catch (Exception ex) { throw new UnsupportedOperationException("Cannot inject value of class: " + value.getClass() + " into: " + f); // breakpoint } }
In a concurrent situation, access violation occurs due to race condition:
Thread A: invokes check the accessibility and set "shouldSetAccessible" to true.
Thread A: invokes f.setAccessible(true);
Thread B: invokes check the accessibility and set "shouldSetAccessible" to false.
Thread A: invokes f.set(instance, value and f.setAccessible(oldAccessible);
Thread B: invokes f.set(instance, value); and java.lang.IllegalAccessException occurs.
- Following exception will occur.
java.lang.UnsupportedOperationException: Cannot inject value of class: class com.mycompany.MyModel2 into: private com.mycompany.MyModel2 com.mycompany.MyModel.myModel2 at org.apache.camel.util.ReflectionHelper.setField(ReflectionHelper.java:192) at org.apache.camel.dataformat.bindy.BindyAbstractFactory.link(BindyAbstractFactory.java:150) at org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat.lambda$consumeFile$0(BindyCsvDataFormat.java:263) at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1845) at java.base/java.util.stream.ReferencePipeline$Head.forEachOrdered(ReferencePipeline.java:772) at org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat.unmarshal(BindyCsvDataFormat.java:183) at org.apache.camel.support.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:76) at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:477) at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:181) at org.apache.camel.impl.engine.DefaultReactiveExecutor.schedule(DefaultReactiveExecutor.java:54) at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:482) at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.done(RedeliveryErrorHandler.java:416) at org.apache.camel.processor.ThreadsProcessor$ProcessCall.run(ThreadsProcessor.java:87) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833)