[QFJ-712] ConcurrentModificationException in the toString method Created: 30/Oct/12  Updated: 16/Dec/19  Resolved: 12/Nov/12

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.2
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Igor Bakhtoiarov Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I've found in my logs this exception:

java.util.ConcurrentModificationException
at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1100)
at java.util.TreeMap$ValueIterator.next(TreeMap.java:1145)
at quickfix.FieldMap.calculateTotal(FieldMap.java:612)
at quickfix.Message.checkSum(Message.java:160)
at quickfix.Message.toString(Message.java:134)



 Comments   
Comment by Christoph John [ 30/Oct/12 ]

Do you have some more information? What did you do to provoke this? Does this happen often or rarely? Can you attach some more context information from the logs? Maybe some lines before and after it happened?

Thank you

Comment by Christoph John [ 30/Oct/12 ]

On first glance this could be caused by the usage of java.text.DecimalFormat which is not synchronized. Did you call toString() on the same message concurrently?

Comment by Christoph John [ 30/Oct/12 ]

On the other hand it looks like a concurrent access to the FieldMap/TreeMap. Do you operate with multiple threads on the same message (add/remove fields)?

Comment by Christoph John [ 12/Nov/12 ]

If you have any updates on this please head to the mailing list with a reference to this ticket.
http://www.quickfixj.org/support/

We will reopen the ticket in case this really is a bug.

Comment by wangweichao [ 15/Feb/19 ]

Dear Chris,
May I know if this bug is fixed now? thanks.

Comment by Christoph John [ 26/Feb/19 ]

Hi wangweichao,

since this got closed as "not a bug" I assume it is not fixed. This problem most likely appeared due to a wrong usage of the toString() method from user code. But I can't tell for sure since no-one came back with a reproducable test case.
Did you experience something similar?

Chris.

Comment by Mike Starkie [ 12/Dec/19 ]

Hello,
This issue happens to me quite often. I can not use the native QFJ message types in my Fix application because it is written to be independent of any particular FIX engine.

Because of this, the first thing the application does, when the fromApp(Message...) is called is place the Message instance on a single application thread. Once our application thread has control of the Message instance it must convert it into a tag/value map (we don't use repeating groups). In order to do this, we use the Message.toString() method to obtain a string representation first. Once we have the string, we break it down into tag/value pairs.

The concurrent modification exceptions happens randomly during toString(). It seems that a QFJ API thread is accessing the method AFTER it has been handed to the application.

If this is the case, and I'm only speculating here because I don't know. But if it is the case, then this is a serious bug.

Once an object has been handed to the application, an API thread must NEVER be used on the instance going forward.

Again, this seems to be what is happening and I'm curious if it has been fixed.

I am using QFJ 1.6.7 on Linux with Java 8.

Comment by Christoph John [ 12/Dec/19 ]

Hi,

there is no version 1.6.7 of QFJ.
I don't have time currently to check whether or where QFJ might change the message. But this could also be a simple logging statement from either QFJ or from your application since this will also use the toString() method. However, I would either suggest you work on a clone of the message or even better use the Message.toRawString() method which will not change or recalculate the message. That method is only available in QFJ 2.1.0. But you could also use Reflection (evil ) to get the messageData String from the Message and use that.

Cheers,
Chris.

Comment by Mike Starkie [ 12/Dec/19 ]

Let me clarify. Once QFJ has passed an instance of a Message to an application via the fromApp() callback, a QFJ internal thread must never, ever be allowed to modify that Message instance going forward. Again, not sure if this is what is happening but if it is, please fix this.

Comment by Mike Starkie [ 12/Dec/19 ]

Ok. I meant 1.6.0. As least there is a solution. Hopefully, migrating to 2.1.1 will be easy. Thanks for the quick reply.

Comment by Christoph John [ 16/Dec/19 ]

Looking briefly at the code I cannot imagine where the message would be changed by QFJ after passing it to the fromApp() callback. In fact that callback is the last method that is called on the message before the next message is processed.

Generated at Mon Apr 29 07:54:49 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.