[QFJ-1000] can't pass target destination URL (SocketConnectHost) to proxy server Created: 09/Feb/21  Updated: 09/Feb/21

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.4
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: leaf Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows



 Description   

i am using quickfixj to connect with target URL using proxy , the proxy protocol is socks ,
after checked with our proxy team , they said the destination URL (SocketConnectHost) is not passed to proxy , which means not send url to which proxy need to connect .

below is my quickfixj configure sample:

ProxyType=socks
ProxyHost=*************
ProxyPort=1080
ProxyVersion=5

SocketConnectHost=********
SocketConnectPort=******



 Comments   
Comment by Christoph John [ 09/Feb/21 ]

Did you try with a newer version? 1.6.4 is rather old and there have been proxy related fixes in the last versions.





[QFJ-999] Issue with infinite replay request Created: 03/Feb/21  Updated: 07/Feb/21  Resolved: 07/Feb/21

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

Type: Bug Priority: Default
Reporter: Dan Marques Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: Reconnect, resend
Environment:

Java 8 / Linux


Attachments: Text File issue-with-gw-restart-test.txt    

 Description   

I believe I've seen evidence of some sort of issue with infinite replay requests.

I've attached an the annotated log of the situation. The log is from "EXCHANGE", which is a QFJ 2.1.0 application; the other party of the session, "BROKER_GATEWAY", is not QFJ. Both applications are on the same host, so the message time stamps correlate.

Essentially, what occurs in this scenario is that there is a disconnect - and while the FIX session is disconnected, EXCHANGE generates 3 execution reports (er...10, er...11, and er...12). When the session reconnects, EXCHANGE sends a logon with a sqn 12 that is greater than what BROKER_GATEWAY was expected (it was expecting sqn 11), and follows with sqn 13 (er...11) and sqn 14 (er...12)

While EXCHANGE is sending those "queued" messages, BROKER_GATEWAY issues a resend-request, for messages starting at sqn 11 and with an infinite length.

EXCHANGE responds by replaying sqns 11 (er...10), 12 (admin msg as a gap-fill), and 13 (er...11), but never replays 14 (er...12) It isn't until 30 seconds later, that another message, a heartbeat, from EXCHANGE with sqn 15 triggers a second replay request, and 14 (er...12) is replayed.

It seems as if there is some sort of race, where the resend request arrives after sqn 14 was "triggered" to be sent, but before the internal state used to prepare a resent request has been updated.



 Comments   
Comment by Christoph John [ 05/Feb/21 ]

Thanks for the detailed and annotated log. I will try to create a unit test with this.

Comment by Christoph John [ 05/Feb/21 ]

Please correct me if I get it wrong but here is my interpretation of the log. To me everything looks correct from QFJ perspective.

EXCHANGE gets the ResendRequest after sending out seqno 13, so seqno 14 is a message not affected by resend processing. What BROKER_EXCHANGE side should do is queue any messages that they cannot yet process due to seqno-too-high issues. After the resend processing is complete, the other side should process the queued messages.

In my opinion only report with seqno 11 from the EXCHANGE was generated during disconnection. If seqno 13 and 14 were also resent from the message store (where they reside when there is a disconnection) they would get sent with 43/PossDup and 122/OrigSendingTime as a result from a ResendRequest.
Moreover, you write that EXCHANGE has seqno 10 before the disconnection and sends 12 on Logon. So only seqno 11 could have been created during disconnection.
Could it be that the reports that originated from seqno 13 and 14 were created shortly after or at the moment the FIX session came back up? They have no TransactTime, so I cannot tell.

What do you think?

Comment by Dan Marques [ 05/Feb/21 ]

I think you are correct about the timing of 13 and 14 (being generated after the reconnect), but I don't think the log shows QFJ behaving correctly.

It seems to me that the correct behavior for QFJ, upon receiving a resend request from 11 to infinity, would be to satisfy that request before sending any new messages. So, in our example, if QFJ got the request before sending 14, it should replay 11, 12 and 13, and then send 14. If on the other hand, it got the request after sending 14, it should have replayed 11, 12, 13, and 14.

What we see instead, is it sending 14, following by a replay of 11, 12, and 13. To me, this looks like some sort of race condition, where 14 is "being sent' right as the request comes in - and there is race between the sending code updating the "highest-sqn-counter", and the replay response code reading that value.

EXCHANGE gets the ResendRequest after sending out seqno 13, so seqno 14 is a message not affected by resend processing. What BROKER_EXCHANGE side should do is queue any messages that they cannot yet process due to seqno-too-high issues. After the resend processing is complete, the other side should process the queued messages.

While queuing 14 would "hide" this bug, it seems like QFJ is imposing behavior on the receiving application which isn't mandated by the FIX 4.2 spec. In fact, it seem to run contrary to the following (FIX 4.2 with Errata 20010501, page 30) :

Note: it is imperative that the receiving application process messages in sequence order, e.g. if
message number 7 is missed and 8-9 received, the application should ignore 8 and 9 and ask for a
resend of 7-9, or, preferably, 7-0 (0 represents infinity). This latter approach is strongly recommended
to recover from out of sequence conditions as it allows for faster recovery in the presence of certain
race conditions when both sides are simultaneously attempting to recover a gap.

The quote above says nothing about queuing 8 and 9, and instead says that those messages should be "ignored" and either explicitly (7 - 9) or implicitly (7 - 0) requested for a resend. As the receiver is going to process messages one at a time, when it determines 7 is missing (upon receiving 8), it will not have any knowledge of 9 - it doesn't know if 9 has already been read from the (local) socket, on the wire, in the sender's message store, or yet to be generated by the sender application.

This is completely analogous to our example: 11 is missing, and 12-14 are received. The receiver only knows that 11 is missing when it receives 12, it knows nothing yet about 13 and 14. As soon as that gap is detected, it asks for a resend, from 12 - infinity, as per the recommended approach.

From you description (i.e. if there isn't a bug), it seems that QFJ treats 13 differently from 14, it resends 13 but not 14, based on when it gets the resend-request. However, it impossible for the receiver to know that QFJ is going to treat those differently - when it requested the resend (after receiving 12) it there is no way for it to know that (from QFJ's point of view) 13 had been sent but 14 hadn't. For the receiver to correctly handle QFJs behavior it seems that it would need to queue both 13 and 14. That seems clearly outside the behavior recommended by the spec.

Comment by Christoph John [ 06/Feb/21 ]

Let me first comment on your statements:

It seems to me that the correct behavior for QFJ, upon receiving a resend request from 11 to infinity, would be to satisfy that request before sending any new messages.

Why should QFJ do that? On large message backlogs this could lead to QFJ only satisfying the ResendRequest and queueing all current messages. Instead, new messages could be interleaved with old ones. Of course, the receiving side would need to queue the newer messages until the gap is filled. But this is common practice (see further below in my comment).

So, in our example, if QFJ got the request before sending 14, it should replay 11, 12 and 13, and then send 14. If on the other hand, it got the request after sending 14, it should have replayed 11, 12, 13, and 14.

This will not work in situations when new messages are generated "at the same time" and concurrent ResendRequest processing is going on.
Upon reception of a ResendRequest, QFJ will simply determine the current outgoing sequence number and resend up to that message. You can imagine that the current outgoing sequence number is changing rapidly when sending out multiple messages after each other. There is no need to impose any kind of locking on sending out messages just because a ResendRequest is received.

Now to the specification part:
Firstly, In my opinion the quote from the spec "if message number 7 is missed and 8-9 received, the application should ignore 8 and 9" one should read "ignore" as "not process at the moment".

And although we are talking about a FIX4.2 connection, the session-level specification has since been refined and clarified. That is why you should always check up session-level stuff in the most current spec. However, even the relevant part I mentioned is in the FIX4.2 spec. Please see page 18 (or search for "queue" )

It is also recommended that an engine should store out of sequence messages in a temporary queue and process them in order when the gap is closed. This prevents generating resend requests for n->m, n->m+1, n->m+2, ... which can result in many resent PossDupFlag=Y messages.

By the way, there also is a FIX session state matrix which lists various states of the connection. However, it is not contained in the FIX4.2 spec. IIRC it was in the FIX4.4 spec. Or even better, you can check it online here: https://www.fixtrading.org/standards/fix-session-layer-online/#fix-session-state-matrix

Relevant parts are 11 and 12:

11 Receive MsgSeqNum(34) Too High -
Receive too high of MsgSeqNum(34) from counterparty, queue message, and send ResendRequest(35=2).

12 Awaiting/ Processing Response to ResendRequest(35=2) -Process requested MsgSeqNum(34) with PossDupFlag(43)=Y resent messages and/or SequenceReset(35=4) gap fill messages from counterparty. Queue incoming messages with MsgSeqNum(34) too high.

conclusion
I think the other FIX engine should be corrected to handle this scenario. However, it seems in the worst case it will resynchronize after the next received message. So it might not be worth the trouble (depending on the effort needed). Are you able/allowed to tell which FIX engine this is? (would be handy for my internal list of specialties of FIX engines when analyzing problems with counterparties)

By the way, you might want to look at using NextExpectedMsgSeqNum on Logon (if your counterparty supports it), since this will eliminate the additional ResendRequest roundtrip on Logon and hence also the "racy" conditions. However, as I just realized it is only available from FIX4.4 and up.

If you still have questions please feel free to ask.

Cheers,
Chris.

Comment by Dan Marques [ 07/Feb/21 ]

Chris,

Thanks for your response.

As to your point:

In my opinion the quote from the spec "if message number 7 is missed and 8-9 received, the application should ignore 8 and 9" one should read "ignore" as "not process at the moment".

If your interpretation was what the spec's authors intended, I don't see why they would explicitly state that the receiver should "ask for a resend of 7-9". Under your interpretation, it would need a resend of 7 only, as it could then consume 8 and 9 from the queue.

As to the portion of the spec you referenced:

It is also recommended that an engine should store out of sequence messages in a temporary queue and process them in order when the gap is closed.

That behavior is explicitly described as "recommended", as opposed to "required" or "mandatory" or some similar language. Therefore an application that does not store those message can still be correct.

That said, the second sentence of that quote is illustrative.

This prevents generating resend requests for n->m, n->m+1, n->m+2, ... which can result in many resent PossDupFlag=Y messages.

What I now think is, if QFJ's behavior is correct with regard to the spec, a connecting application which chose not to store out of sequence messages would need to issue multiple, overlapping, resend requests, until it was caught up. For example, in my original log, upon receiving sqn 14, the receiver application should have issued a second request for 11 - 0. As that would have arrived at the QFJ sender after 14 was sent, it would have initiated a second replay, this time from 11- 14. As per that quote, messages 11, 12 and 13 would have been resent twice - safe, but inefficient.

Again, thanks for your time.

Dan

Comment by Christoph John [ 07/Feb/21 ]

Hi Dan,

the reason why a ResendRequest for a single message should be avoided is explained in the next sentence in the spec:

This latter approach is strongly recommended to recover from out of sequence conditions as it allows for faster recovery in the presence of certain race conditions when both sides are simultaneously attempting to recover a gap.

So yes, in this part the spec does not explicitly state that the message should be queued but rather focuses on how to avoid race conditions between two parties which both are doing gap fills.

You are right that the other FIX engine still works in this case. As I said the other FIX engine should be corrected and not must be corrected. And as I also said the situation corrects itself after the next message.

Do you think that this issue can be closed?

Thanks,
Chris.

Comment by Dan Marques [ 07/Feb/21 ]

Chris,

You can close it.

Thanks.

Dan





[QFJ-998] Infinite resend request not sending up to the latest sent message Created: 03/Feb/21  Updated: 03/Feb/21  Resolved: 03/Feb/21

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

Type: Bug Priority: Default
Reporter: Dan Marques Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None


 Description   

I believe I've seen evidence of some sort of race condition. Log to follow



 Comments   
Comment by Dan Marques [ 03/Feb/21 ]

Sorry, I though I could instantiate a issue and then edit it from another computer (corporate firewall was preventing the "Create" pop-up from working).

Please close this and I'll create a separate ticket.





[QFJ-997] Http proxy doesnt reconnect upon lost fix session Created: 04/Dec/20  Updated: 26/Jan/22

Status: Open
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Krys Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: http, initiator, proxy, reconnection


 Description   

Fix engine (initiator) doesnt reconnect upon the acceptor's restart when http proxy is being used. It keeps displaying "Pending connection not established after 270734 ms.", which is a consequence of not reconnecting at all. Is there any workaround for http proxy to trigger reconnection?

We have configured ReconnectInterval, ProxyType=http, ProxyVersion=1.1.

If we change proxy type to socks we are seeing the reconnect attempt due to /org/apache/mina/proxy/ProxyConnector.java:181, but would be nice to have the same functionality for http proxy. I also cant see any obvious way to set reconnectionNeeded variable that would potentially trigger the reconnection which i have tested by resetting it myself with a debugger.



 Comments   
Comment by Christoph John [ 05/Dec/20 ]

I am not aware of any special handling which could stop reconnecting from working only for http proxy... Could it be that the http connection is still considered "active" on the proxy? Could you please check that with "netstat" or some other tool which lists open sockets.
Could you please also create a stack dump when QFJ is in the state of "Pending connection not established..."

Comment by Krys [ 07/Dec/20 ]

Unlike http proxy, i am observing socks proxy reconnecting, probably due to this:

if (proxyIoSession.getRequest() instanceof SocksProxyRequest || proxyIoSession.isReconnectionNeeded())

{ return conFuture; }

Unless i need to configure http proxy with something else to get it reconnected.
we are not seeing any outbound connection in this scenario, although the same tcp port remains open.
In the state of "Pending connection...", there are two QFJ threads:

"QFJ Message Processor" #35 daemon prio=5 os_prio=0 tid=0x000000002b144800 nid=0xb090 waiting on condition [0x000000002fb8e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)

  • parking to wait for <0x00000005d05d60d8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
    at quickfix.mina.QueueTrackers$1.poll(QueueTrackers.java:45)
    at quickfix.mina.SingleThreadedEventHandlingStrategy.getMessage(SingleThreadedEventHandlingStrategy.java:122)

"QFJ Timer" #34 daemon prio=5 os_prio=0 tid=0x000000002b144000 nid=0xa3a8 in Object.wait() [0x000000002f77f000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.apache.mina.core.future.DefaultIoFuture.await0(DefaultIoFuture.java:218)

  • locked <0x00000005d0640f10> (a org.apache.mina.core.future.DefaultConnectFuture)
    at org.apache.mina.core.future.DefaultIoFuture.awaitUninterruptibly(DefaultIoFuture.java:174)
    at quickfix.mina.initiator.IoSessionInitiator$ConnectTask.pollConnectFuture(IoSessionInitiator.java:232)
    at quickfix.mina.initiator.IoSessionInitiator$ConnectTask.run(IoSessionInitiator.java:207)
  • locked <0x00000005d05fdd80> (a quickfix.mina.initiator.IoSessionInitiator$ConnectTask)

QFJ Timer doesnt stop on breakpoints in IoSessionInitiator.ConnectTask#connect(), SocketChannelImpl#connect() or Net#connect() anymore.

Let me know if anything else would be useful to check.

Comment by Christoph John [ 14/Dec/20 ]

Unlike http proxy, i am observing socks proxy reconnecting, probably due to this:

if (proxyIoSession.getRequest() instanceof SocksProxyRequest || proxyIoSession.isReconnectionNeeded())
{ return conFuture; } 

Where is that code from? If that is from MINA then it could also be a MINA bug.

Comment by Krys [ 14/Dec/20 ]

That is right. it comes from MINA core: org.apache.mina.proxy.ProxyConnector#connect0:181

Comment by Christoph John [ 15/Dec/20 ]

So if I understood you right you could trigger the reconnection by setting isReconnectionNeeded to true in the debugger? If yes, then it should be a MINA bug, shouldn't it?

Comment by Krys [ 16/Dec/20 ]

Correct, when i set the re-connection needed with a debugger it does the job. In this case, we close this JIRA, right?

Comment by Christoph John [ 16/Dec/20 ]

It would be good if you could open a MINA issue and link to this issue. Let me know if I should open the issue against MINA. Thanks so far

Comment by Krys [ 14/Jan/21 ]

I would appreciate if you would open the issue with them.

Comment by Christoph John [ 26/Jan/22 ]

https://issues.apache.org/jira/browse/DIRMINA-1159





[QFJ-996] Daily session start and end at different time Created: 15/Sep/20  Updated: 15/Sep/20  Resolved: 15/Sep/20

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

Type: Other Priority: Default
Reporter: Gaurav Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi
I want to start and stop session daily but at different time, for example

1.Session start at 9:30 UTC on Monday and stops at 9:28 UTC on Tuesday
2. On Tuesday session starts at 10:30 and stop on Sunday 10:28

How do I achieve the above in quick fix.



 Comments   
Comment by Christoph John [ 15/Sep/20 ]

Please use the mailing list to ask for help:
https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-995] Can I change the sequence of FIX message tags? How to do it? Created: 11/Aug/20  Updated: 28/Aug/20  Resolved: 28/Aug/20

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Task Priority: Critical
Reporter: Dhanashri Panchputre Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: sequence,
Environment:

Windows 10


Attachments: Microsoft Word Sample AE Adv.xls    

 Description   

Can I change the sequence of FIX message tags? How to do it?
I am using AE type and version FIX 5.0 SP1.
I want to do the sequencing because tags are not getting parsed in sequence.
Message type AE contains group tag hierarchy as : 552 -> 54 -> 453,448,447,452.
So 54 is a group tag and 453,448,447,452 are subgroup tags. I am getting a problem with manipulating the subgroup tags. So I want those tags in sequence.
Can anyone help?



 Comments   
Comment by Christoph John [ 28/Aug/20 ]

Please use the mailing list for help requests. Thanks.
https://sourceforge.net/projects/quickfixj/lists/quickfixj-users





[QFJ-994] quickfixj 2.2.0 dependency is not in Maven Created: 21/Apr/20  Updated: 21/Apr/20  Resolved: 21/Apr/20

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

Type: Bug Priority: Major
Reporter: Luis Ibanez Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

When cloning the repo master branch and trying to build the examples. The pom file is trying to download the quickfixj version 2.2.0-SNAPSHOT that doesn't exist in Maven.



 Comments   
Comment by Christoph John [ 21/Apr/20 ]

2.2.0 is not released yet. The SNAPSHOT versions are not uploaded to Maven. But when you cloned the whole repo and do a full build you do not need to download it. Sounds strange to me. The build on the build server is fine so seems to be an issue in your environment.
Did you try to build from the topmost directory and not only the examples?

Comment by Luis Ibanez [ 21/Apr/20 ]

Only from the examples:

<parent>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-examples</artifactId>
<version>2.2.0-SNAPSHOT</version>
</parent>

Comment by Christoph John [ 21/Apr/20 ]

OK, never tried that. It should work when you build the full project. Then the examples will be built also.

Comment by Luis Ibanez [ 21/Apr/20 ]

I mean I changed to 2.1.1 and that was all.

But then why the master is not linked to the published version? Just cloning and building is going to fail.

Comment by Luis Ibanez [ 21/Apr/20 ]

Just tried from topmost and it is still the same problem:

error trying to resolve:
org.quickfixj:quickfixj-codegenerator:2.2.0-SNAPSHOT
on QuickFIX/J Core engine

Comment by Christoph John [ 21/Apr/20 ]

The master branch contains the current development version which will be released at some time. At that point in time the master branch will be set to the next SNAPSHOT version.

Cloning and building works for most people I guess.

The project is built daily, e.g. here: https://travis-ci.com/github/quickfix-j/quickfixj/builds/161204879

Just cloned and built on my machine, it works. Linux with OpenJDK8.

# mvn clean package -Dmaven.javadoc.skip=true -DskipTests -PskipBundlePlugin
...
[INFO] Reactor Summary for QuickFIX/J Parent 2.2.0-SNAPSHOT:
[INFO] 
[INFO] QuickFIX/J Parent .................................. SUCCESS [  0.137 s]
[INFO] QuickFIX/J Code Generator Maven Plugin ............. SUCCESS [  3.296 s]
[INFO] QuickFIX/J Dictionary Generator .................... SUCCESS [  0.692 s]
[INFO] QuickFIX/J Core engine ............................. SUCCESS [03:40 min]
[INFO] QuickFIX/J Message classes for various FIX specs ... SUCCESS [  0.004 s]
[INFO] QuickFIX/J Message classes for FIX 4.0 ............. SUCCESS [  1.320 s]
[INFO] QuickFIX/J Message classes for FIX 4.1 ............. SUCCESS [  0.838 s]
[INFO] QuickFIX/J Message classes for FIX 4.2 ............. SUCCESS [  0.959 s]
[INFO] QuickFIX/J Message classes for FIX 4.3 ............. SUCCESS [  0.829 s]
[INFO] QuickFIX/J Message classes for FIX 4.4 ............. SUCCESS [  0.951 s]
[INFO] QuickFIX/J Message classes for FIX 5.0 ............. SUCCESS [  1.155 s]
[INFO] QuickFIX/J Message classes for FIX 5.0 SP1 ......... SUCCESS [  1.345 s]
[INFO] QuickFIX/J Message classes for FIX 5.0 SP2 ......... SUCCESS [  1.527 s]
[INFO] QuickFIX/J Message classes for FIXT 1.1 ............ SUCCESS [  0.795 s]
[INFO] QuickFIX/J Message classes for all FIX specs ....... SUCCESS [  2.524 s]
[INFO] QuickFIX/J Examples ................................ SUCCESS [  0.002 s]
[INFO] QuickFIX/J Examples - Executor ..................... SUCCESS [  3.656 s]
[INFO] QuickFIX/J Examples - Order Match .................. SUCCESS [  3.406 s]
[INFO] QuickFIX/J Examples - Banzai ....................... SUCCESS [  3.394 s]
[INFO] QuickFIX/J All runtime modules ..................... SUCCESS [ 12.103 s]
[INFO] QuickFIX/J Distribution ............................ SUCCESS [  4.598 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  04:25 min
[INFO] Finished at: 2020-04-21T12:38:43+02:00




[QFJ-993] AbstractSocketAcceptor attempts to create SocketDescriptor for template session Created: 15/Apr/20  Updated: 19/Jun/20  Resolved: 19/Jun/20

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

Type: Bug Priority: Default
Reporter: abeel Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

configuration: quickfix.properties
[DEFAULT]
UseDataDictionary=Y

[SESSION]
AcceptorTemplate=Y
ConnectionType=acceptor
BeginString=FIX.4.4

Code:

    public synchronized void start() {
        try {
            final SLF4JLogFactory logger = new SLF4JLogFactory(this.sessionSettings);

            this.acceptor = new SocketAcceptor(this.application,
                                               this.messageStoreFactory,
                                               this.sessionSettings,
                                               logger,
                                               this.msgFactory);

            this.acceptor.setSessionProvider(new InetSocketAddress("0.0.0.0", 50000),
                                             new DynamicAcceptorSessionProvider(
                                                     this.sessionSettings,
                                                     new SessionID("FIX.4.4", "SENDCOMPID", "TARGETCOMPID"),
                                                     this.application,
                                                     this.messageStoreFactory,
                                                     logger,
                                                     this.msgFactory));
            this.acceptor.start();
        } catch (ConfigError ex) {
            log.error("Failed to start QuickFIX-J socket acceptor.", ex);
            this.acceptor = null;
        }
    }

Throws:

quickfix.ConfigError: SocketAcceptPort not defined
at quickfix.SessionSettings.getString(SessionSettings.java:149) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.SessionSettings.getLong(SessionSettings.java:229) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.mina.acceptor.AbstractSocketAcceptor.getAcceptorSocketDescriptor(AbstractSocketAcceptor.java:189) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.mina.acceptor.AbstractSocketAcceptor.createSessions(AbstractSocketAcceptor.java:230) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.mina.acceptor.AbstractSocketAcceptor.startAcceptingConnections(AbstractSocketAcceptor.java:96) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.SocketAcceptor.initialize(SocketAcceptor.java:108) ~[quickfixj-core-2.1.1.jar:2.1.1]
at quickfix.SocketAcceptor.start(SocketAcceptor.java:102) ~[quickfixj-core-2.1.1.jar:2.1.1]

Issue seems to be with this code

quickfix.mina.acceptor.AbstractSocketAcceptor
private void createSessions(SessionSettings settings) throws ConfigError, FieldConvertError {
        HashMap<SessionID, Session> allSessions = new HashMap<>();
        for (Iterator<SessionID> i = settings.sectionIterator(); i.hasNext();) {
            SessionID sessionID = i.next();
            String connectionType = settings.getString(sessionID,
                    SessionFactory.SETTING_CONNECTION_TYPE);

            boolean isTemplate = false;
            if (settings.isSetting(sessionID, Acceptor.SETTING_ACCEPTOR_TEMPLATE)) {
                isTemplate = settings.getBool(sessionID, Acceptor.SETTING_ACCEPTOR_TEMPLATE);
            }

            if (connectionType.equals(SessionFactory.ACCEPTOR_CONNECTION_TYPE)) {
                AcceptorSocketDescriptor descriptor = getAcceptorSocketDescriptor(settings, sessionID);
                if (!isTemplate) {
                    Session session = sessionFactory.create(sessionID, settings);
                    descriptor.acceptSession(session);
                    allSessions.put(sessionID, session);
                }
            }
        }
        setSessions(allSessions);

        if (socketDescriptorForAddress.isEmpty()) {
            throw new ConfigError("No acceptor sessions found in settings.");
        }
    }

// attempts to create descriptor for a session template

if (connectionType.equals(SessionFactory.ACCEPTOR_CONNECTION_TYPE)) {
* AcceptorSocketDescriptor descriptor = getAcceptorSocketDescriptor(settings, sessionID);*
if (!isTemplate) {



 Comments   
Comment by Christoph John [ 19/Jun/20 ]

Hmm, could you please elaborate where you see the problem? IMHO even dynamic sessions need a SocketAcceptPort to know on which port sessions should get accepted. The address that you assign to a session provider is just to do a lookup for a specific address when a connection comes in. It does not mean that you do not need to specify a SockketAcceptPort. What is the problem of specifying that port in your config?

I am closing this for now. Feel free to reopen if you think there still is a problem.





[QFJ-992] quickfixj 2.1.1 has dependency convergence error for org.apache.maven:maven-artifact:3.5.0 Created: 06/Mar/20  Updated: 09/Mar/20

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrew Peter Marlow Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ


 Description   

the maven plugin enforcer shows that quickfixj has a dependency convergence error for org.apache.maven:maven-artifact:3.5.0. Here is the output:

Dependency convergence error for org.apache.maven:maven-artifact:3.5.0 paths to dependency are:
+-project-that-uses-quickfixj
+-org.quickfixj:quickfixj-all:2.1.1
+-org.quickfixj:quickfixj-codegenerator:2.1.1
+-org.apache.maven:maven-plugin-api:3.5.0
+-org.apache.maven:maven-artifact:3.5.0
and
+-project-that-uses-quickfixj
+-org.quickfixj:quickfixj-all:2.1.1
+-org.quickfixj:quickfixj-codegenerator:2.1.1
+-org.apache.maven:maven-project:2.2.1
+-org.apache.maven:maven-artifact-manager:2.2.1
+-org.apache.maven:maven-artifact:2.2.1
and
+-project-that-uses-quickfixj
+-org.quickfixj:quickfixj-all:2.1.1
+-org.quickfixj:quickfixj-codegenerator:2.1.1
+-org.apache.maven:maven-project:2.2.1
+-org.apache.maven:maven-artifact:2.2.1



 Comments   
Comment by Christoph John [ 06/Mar/20 ]

Thanks for the report. Under which cicrumstances does this cause an issue?

Comment by Andrew Peter Marlow [ 07/Mar/20 ]

The maven enforcer plugin is being used to report on inconsistent component versions. By default the plugin treats all such inconsistencies as errors, so by default such inconsistencies would make the build fail. This behaviour is configurable so it is possible just to get a report of the issues without making the build fail. But I want such inconsistencies to be flagged as serious issues because some of these inconsistencies involve components that show up on Black Duck security scans. The software I am working on is subject to a corporate decree that the software gets through Black Duck without raising any flags. This job is made harder when the number of flags raised is larger due to the same component appearing multiple times at different versions due to these dependency convergence errors.

My aim is to report any such dependency convergence errors that I find via enforcer. If they are then all fixed (there are only a few) then we could set the flag such that any such errors are fatal, so as to detect any regressions as soon as they occur. Without such fixes I will have to write a script that processes the enforcer output and checks any issues against a list of exceptions. This quickfixj issue would have to be such as exception. It just makes ultimate the job of dealing with Black Duck scans harder.

Comment by Christoph John [ 09/Mar/20 ]

Understood. If you would like you could also open a pull request on the quickfixj project on github. https://github.com/quickfix-j/quickfixj
I am also in favour of making the build fail on enforcer errors.





[QFJ-991] Add information about quickfixj-codegenerator maven plugin to documentation Created: 20/Feb/20  Updated: 08/Jun/20

Status: Open
Project: QuickFIX/J
Component/s: Documentation, Message Generation
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Max Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

"Customizing Message Code Generation" article doesn't have information quickfixj-codegenerator.

Maven is standard de facto tool for building java application. And using of quickfixj-codegenerator is the most convenient way for using own dictionary.

So I suggest to add example of using this plugin for maven. Text may be like this:

If you are using the Maven build system, you can also use quickfixj-codegenerator:

<build>
<plugins>
<plugin>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-codegenerator</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>fixt11</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<dictFile>path/to/your/dictionary/file/FIXT11.xml</dictFile>
<packaging>quickfix.fixt11</packaging>
<fieldPackage>quickfix.field</fieldPackage>
</configuration>
</execution>
<execution>
<id>fix50sp2</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<dictFile>path/to/your/dictionary/file/FIX50SP2.modified.xml</dictFile>
<packaging>quickfix.fix50sp2</packaging>
<fieldPackage>quickfix.field</fieldPackage>
</configuration>
</execution>
[...]
</plugin>
[...]
</plugins>
</build>



 Comments   
Comment by Christoph John [ 08/Jun/20 ]

Good idea, maybe you could open a PR if you have the time.

Thanks





[QFJ-990] QUickfix 1.15.1 C++ version is inconsistent with VS2017 Created: 17/Feb/20  Updated: 17/Feb/20  Resolved: 17/Feb/20

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

Type: Bug Priority: Default
Reporter: Janardhanan Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None
Environment:

Windows



 Description   

Hi, I have downloaded quickfix engine 1.15.1 and compiled for windows with VS2017 and while running the application the quickengine source is randomly populating different values for the variables. I have disabled the compiler optimization which resolved some issues but breaks in different places. Please advice.

Thanks



 Comments   
Comment by Christoph John [ 17/Feb/20 ]

It seems you are using C++ QuickFIX, not QuickFIX/J (written in Java).
Please use the QuickFIX mailing list for such requests: https://sourceforge.net/projects/quickfix/lists/quickfix-developers

Thanks





[QFJ-989] Acceptor Resetting the connection just after Login Created: 24/Dec/19  Updated: 28/Dec/19

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

Type: Bug Priority: Default
Reporter: Anurag Ajmera Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-988 Session reset happens after logon Closed

 Description   

We are using fix acceptor (version 1.6.4). The acceptor resets the connection from initiators many times when logon is received. Can someone please help?

2019-12-01 23:10:00,712 |FIXT.1.1:SENDER->RECEIVER: 8=FIXT.1.1|9=74|35=A|56=SENDER|49=RECEIVER|52=20191201-23:10:00|34=1|108=60|98=0|1137=9|10=045|
2019-12-01 23:10:00,718 |FIXT.1.1:SENDER->RECEIVER: Accepting session FIXT.1.1:SENDER->RECEIVER from /(IP ADDRESS):(PORT)
2019-12-01 23:10:00,723 |FIXT.1.1:SENDER->RECEIVER: Acceptor heartbeat set to 60 seconds
2019-12-01 23:10:00,725 |FIXT.1.1:SENDER->RECEIVER: Setting DefaultApplVerID (1137=9) from Logon
2019-12-01 23:10:00,734 |FIXT.1.1:SENDER->RECEIVER: Refreshing message/state store at logon
2019-12-01 23:10:00,751 |FIXT.1.1:SENDER->RECEIVER: Received logon
2019-12-01 23:10:00,754 |FIXT.1.1:SENDER->RECEIVER: Responding to Logon request
2019-12-01 23:10:00,761 |FIXT.1.1:SENDER->RECEIVER: 8=FIXT.1.1|9=78|35=A|34=1|49=SENDER|52=20191201-23:10:00.761|56=RECEIVER|98=0|108=60|1137=9|10=253|
2019-12-01 23:10:04,859 |FIXT.1.1:SENDER->RECEIVER: Session state is not current; resetting FIXT.1.1:SENDER->RECEIVER
2019-12-01 23:10:04,865 |FIXT.1.1:SENDER->RECEIVER: 8=FIXT.1.1|9=59|35=5|34=2|49=SENDER|52=20191201-23:10:04.865|56=RECEIVER|10=155|
2019-12-01 23:10:04,877 |FIXT.1.1:SENDER->RECEIVER] Disconnecting: Session reset



 Comments   
Comment by Christoph John [ 24/Dec/19 ]

Do you only see this on FIXT.1.1 sessions or also on others?
And you are absolutely sure you are using version 1.6.4?

Comment by Anurag Ajmera [ 24/Dec/19 ]

Hi Christoph, yes we are using version 1.6.4 from maven repository. Also, we are seeing this issue in Fix version 4.4 as well.

Comment by Christoph John [ 24/Dec/19 ]

I am afraid I cannot help you unless you are able to reproduce this with a current QFJ version, i.e. 2.1 or 2.1.1.

Comment by Christoph John [ 28/Dec/19 ]

Could it be that your system is either heavily loaded or your QFJ process is constantly garbage collecting or something like that? Between the sending of the Logon reply and the "resetting session" message are four seconds delay?!

What is your StartTime and EndTime set to? Can you post the entry from your log where it says: "Session SENDER->RECEIVER schedule is "...





[QFJ-988] Session reset happens after logon Created: 23/Dec/19  Updated: 24/Dec/19  Resolved: 23/Dec/19

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

Type: Bug Priority: Major
Reporter: Anurag Ajmera Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-926 Session reset happens after logon Closed
Relates
is related to QFJ-989 Acceptor Resetting the connection jus... Open

 Description   

scenario:

application is handling several FIX sessions (initiators)
app started in the off time – FIX sessions are successfully created and reset

{{11 May 23:40:10.450 INFO (Thread-3) Session FIX.4.4:SENDER_ONE->TARGET schedule is THU 04:05:00-UTC - THU 20:30:00-UTC
11 May 23:40:10.452 INFO (Thread-3) Session state is not current; resetting FIX.4.4:SENDER_ONE->TARGET
11 May 23:40:10.459 INFO (Thread-3) Created session: FIX.4.4:SENDER_ONE->TARGET

11 May 23:40:10.501 INFO (Thread-3) Session FIX.4.4:SENDER_TWO->TARGET schedule is THU 04:07:00-UTC - THU 20:30:00-UTC
11 May 23:40:10.502 INFO (Thread-3) Session state is not current; resetting FIX.4.4:SENDER_TWO->TARGET
11 May 23:40:10.509 INFO (Thread-3) Created session: FIX.4.4:SENDER_TWO->TARGET
}}

on the next day logons are initiated according to session’s schedules

but the first session reset is happened in the middle of message handling:
(which is result in re-logon and “MsgSeqNum too low” issue)

  1. SENDER_ONE
    12 May 06:05:00.932 INFO (QFJ Timer) Initiated logon request
    12 May 06:05:01.145 INFO (QFJ Message Processor) Received logon
    12 May 06:05:01.149 INFO (QFJ Message Processor) Sent ResendRequest FROM: 1 TO: 2385
    12 May 06:05:01.150 INFO (QFJ Message Processor) Logon has been established: FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:01.156 INFO (QFJ Message Processor) Session state is not current; resetting FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:01.168 INFO (QFJ Message Processor) Session has been logged out: FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:16.928 INFO (QFJ Timer) Initiated logon request
    12 May 06:05:17.160 INFO (QFJ Message Processor) Received logout request: MsgSeqNum too low, expecting 4 but received 1

on other hand second session starts normally (reset happens before logon):

  1. SENDER_TWO
    12 May 06:07:00.929 INFO (QFJ Timer) Session state is not current; resetting FIX.4.4:SENDER_TWO->TARGET
    12 May 06:07:00.930 INFO (QFJ Timer) Initiated logon request
    12 May 06:07:01.103 INFO (QFJ Message Processor) Received logon
    12 May 06:07:01.103 INFO (QFJ Message Processor) Sent ResendRequest FROM: 1 TO: 2612
    12 May 06:07:01.103 INFO (QFJ Message Processor) Logon has been established: FIX.4.4:SENDER_TWO->TARGET

I guess the problem is how session reset is handled in Session::next() method:
look like sometimes the previous session time check is happenning less then 1 sec ago – it is skipped – and as a result session reset is accured already after logon



 Comments   
Comment by Anurag Ajmera [ 23/Dec/19 ]

Hi, we are using 1.6.4 version of quick fix and we are still this issue in our acceptor. Could you please help here?

Comment by Christoph John [ 23/Dec/19 ]

It does not make much sense to clone an issue for an already fixed problem. If you are still facing this problem with QFJ 1.6.4 then it is probably a different issue. So please open a new issue with logs from your problem.
Thanks,
Chris.





[QFJ-987] JPMS: Change field classes generation to resolve split package issue Created: 23/Sep/19  Updated: 05/Jun/20

Status: In Progress
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Vlad Mureșan Assignee: Vlad Mureșan
Resolution: Unresolved Votes: 0
Labels: Message, QuickfixJ

Issue Links:
Duplicate
is duplicated by QFJ-985 Java Modules Closed

 Description   

The new module system available since JDK 9 does not allow duplicate packages on the module path.
As a result an application that depends on more than one messages version will have a split package issue, since quickfix.field exists in all quickfixj-messages-<version> jars.

The packaging needs to be changed in order to avoid duplicate packages used by different quickfixj modules.



 Comments   
Comment by Vlad Mureșan [ 23/Sep/19 ]

I analysed a little bit the situation and I see the following potential solutions:

  1. Generate a quickfixj-fields jar to be used as dependency by the other messages jars. This way the jar can be imported only once and split package issue is avoided.
    Advantage: avoid code duplication, avoid split package issue
  2. Generate  quickfix.<version>.fields packages instead of quickfix.fields. This means that each quickfixj-messages-<version> jar will have its own fields package and the component should make sure to consume the fields from its corresponding package.
    Disadvantage: the common fields between FIX versions will be generated once for each messages version jar, so there is some code duplication. However, this means that the messages between versions are completely decoupled between FIX versions.
    I don't know if this solution is feasible, since the impact is quite big (this won't be backward compatible for client applications already using the quickfix.fields package). As a workaround for this a quickfix.fields package can be generated in the messages-all jar.

I would go for first solution to also keep the impact as low as possible and avoid code duplication. What do you think?
Please let me know if you have other preferences. I'll wait for your feedback before doing any actual changes.

Cheers,
Vlad

Comment by Gili [ 24/Sep/19 ]

Hi Vlad,

I'm just an end-user. You discuss possible solutions, but can you explain outline the existing situation? I understand that modules cannot import the same package from multiple sources but it's not clear to me why the existing design exports the same packages/classes from multiple JARs. Can you please break that down? It would help us understand the proposed solutions and maybe even come up with others. Thank you.

Comment by Christoph John [ 25/Sep/19 ]

Hi Gili,

I have to admit that I don't recall exactly why the module structure was done this way. Maybe it was the easiest way at that time when we migrated the modules from Ant to Maven or to OSGi.

Cheers,
Chris.

Comment by Marcin L [ 02/Apr/20 ]

This is a tough one.

1) creating a separate module for fields

Seems like relatively easy solution, but I don't think there is much benefit of doing this one as the core structure problem remains. This might be only feasible to get JPMS working. BTW. Do you have a branch version (or module descriptors) of what you were trying to do?

2) each message module should has it's own version of fields

I agree with you. Even though this might be a duplication of fields I think this is the right way as this decouples fields for each version of FIX dictionaries.

  • fields are different (some are missing, some are added)
  • enum values for certain fields are different (mostly added as FIX version increases, but possibly they can be removed)

PROBLEM

quickfix-core code already depends on classes from quickfix.field package. Moreover, the code base is dependent (need to be available at run-time) on fields from different FIX versions all together e.g. SessionRejectReason (added in 4.2). They are somewhat "protected" by the code to use them only when specific FIX version is used - still they all need to be in class path at run-time.

This is the reason why code generator plugin generates fields in a very specific order as the code generator plugin does not override field classes that have been created. Currently this super set is assembled into each Maven module quickfixj-messages-fix**, so even if an application is dependent on quickfixj-messages-fix40 it will contain fields from different FIX versions such as SessionRejectReason, otherwise things will fail at run-time e.g.

quickfix.Message#parseBody
throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, field.getTag());

I don't see an easy way of splitting this, but probably a way to go would be to abandon anaemic domain model and message modules would need to contain logic, so quickfix-core would delegate the logic depending on which version of FIX is being used. Also unit tests in quickfix-core are heavy dependent on fields and messages from different FIX versions.

Comment by Grigor Iliev [ 05/Jun/20 ]

I ran into same issue while trying to launch app from IDE. I was able to workaround it using the following maven configuration:

<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-all</artifactId>
<version>2.1.1</version>
<exclusions>
<exclusion>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-messages-all</artifactId>
</exclusion>
<exclusion>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-codegenerator</artifactId>
</exclusion>
<exclusion>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-dictgenerator</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.3</version>
</dependency>

Note that quickfixj-all/pom.xml uses maven-shade-plugin to copy everything from quickfixj-core, quickfixj-messages-all, quickfixj-codegenerator and quickfixj-dictgenerator to single fat jar. Thus, dependencies to these jars are not need. Maybe quickfixj-all/pom.xml should be updated to use optional dependencies instead? I.e.

<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-core</artifactId>
<version>$

{project.version}

</version>
<optional>true</optional>
</dependency>

But in this case transitive dependencies should be explicitly specified in quickfixj-all/pom.xml. I.e.

<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.1.3</version>
</dependency>

If quickfixj-all/pom.xml is updated in this way, the aforementioned workaround won't be needed.





[QFJ-986] Publish sources for quickfixj-core Created: 17/Sep/19  Updated: 18/Sep/19  Resolved: 17/Sep/19

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

Type: Improvement Priority: Default
Reporter: Gili Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

The source-code of quickfixj-core (and maybe others?) are not published to Maven Central, making it harder for developers to use this library.

Please publish the source-code using https://bitbucket.org/simpligility/ossrh-pipeline-demo/src/4a6fdd4432e5625e62602559a133530e9ffa408a/pom.xml#lines-63 as an example.



 Comments   
Comment by Christoph John [ 17/Sep/19 ]

We publish to Sonatype repo and if I am not mistaken it goes to Maven Central from there. Also the sources. E.g. https://repo1.maven.org/maven2/org/quickfixj/quickfixj-core/2.1.1/quickfixj-core-2.1.1-sources.jar

Comment by Gili [ 18/Sep/19 ]

You're right. I'm able to download the sources now. I'm not sure why this failed before. Thanks!





[QFJ-985] Java Modules Created: 17/Sep/19  Updated: 23/Sep/19  Resolved: 23/Sep/19

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

Type: Bug Priority: Default
Reporter: Gili Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-987 JPMS: Change field classes generation... In Progress

 Description   

Java Modules (jigsaw) does not allow users to load JAR files that export the same package.

Mutually-exclusive JAR files (e.g. FIX42, FIX44 JAR files) are allowed to export the same package, but users cannot import quickfixj-core and quickfixj-messages-fix44 simultaneously because they export the same package. Doing so results in the following compile-time error message:

the unnamed module reads package quickfix.field from both quickfixj.messages.fix44 and quickfixj.core
module quickfixj.messages.fix44 reads package quickfix.field from both quickfixj.core and quickfixj.messages.fix44
module quickfixj.core reads package quickfix.field from both quickfixj.messages.fix44 and quickfixj.core

Please refactor the artifacts so JAR files that must be imported together do not export the same package.



 Comments   
Comment by Gili [ 17/Sep/19 ]

It looks like someone else reported the same issue last week: https://sourceforge.net/p/quickfixj/mailman/message/36761417/

Comment by Christoph John [ 17/Sep/19 ]

As already written on the mailing list: it would be appreciated if someone could investigate or even better solve this and open a PR.

Thanks,
Chris.





[QFJ-984] The order of the tags constructing a message is mixed Created: 21/Aug/19  Updated: 21/Aug/19  Resolved: 21/Aug/19

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Other Priority: Minor
Reporter: Pavel Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I construct a message in the following way:

quickfix.fix44.MarketDataRequest message = new quickfix.fix44.MarketDataRequest();
        
        char zero = '0';
        char one = '1';
        message.setField(new quickfix.field.MDReqID("EURUSD")); // 262
        message.setField(new quickfix.field.SubscriptionRequestType(one)); // 263
        message.setField(new quickfix.field.MarketDepth(1)); // 264
        message.setField(new quickfix.field.MDUpdateType(0)); // 265            

        message.setField(new quickfix.field.NoMDEntryTypes(2)); // 267
        message.setField(new quickfix.field.MDEntryType(zero)); // 269        
        message.setField(new quickfix.field.MDEntryType(one)); // 269

        message.setField(new quickfix.field.NoRelatedSym(1)); // 146
        message.setField(new quickfix.field.SecurityID("4001")); // 48
        message.setField(new quickfix.field.SecurityIDSource("8")); // 22
        
        Session.sendToTarget(message, senderCompID, marketTargetCompID); 

I also load a dictionary in which tags 146, 48 and 22 are after tag 269. But the message sent to the trader looks like this:

8=FIX.4.4^A9=121^A35=V^A34=2^A49=USERNAME^A52=20190821-11:11:42.045^A56=TRADER^A22=8^A48=4001^A146=1^A262=EURUSD^A263=1^A264=1^A265=0^A267=2^A269=1^A10=191^A

The confusing thing is that tags 146, 48 and 22 are mixed and moved before tag 262 even though the dictionary doesn't allow that.

I have two suggestion why this may happen:

  • Quickfix/J mixes the tags because of an issue or because I miss some configuration.
  • The dictionary provided by the trader is not loaded and I use some defaultdictionary which brings me to this issue.

I don't know if that would help but here is the cfg file:

[DEFAULT]
ConnectionType=initiator
BeginString=FIX.4.4

StartTime=08:30:00
EndTime=21:30:00
ReconnectInterval=5
HeartBtInt=5
LogonTimeout=60

FileStorePath=target/data/sessions/
FileLogPath=target/data/logs/

SenderCompID=USERNAME
UseDataDictionary=Y
SocketUseSSL=Y


[SESSION]
TargetCompID=TRADER
SocketConnectHost=URL_OF_THE_TRADER
SocketConnectPort=443
DataDictionary=/var/quickfixj/automated/DICTIONARY.xml


 Comments   
Comment by Christoph John [ 21/Aug/19 ]

Please do not post to mailing list and open a bug. Mailing list is the correct place to ask.

Thank you

Comment by Pavel [ 21/Aug/19 ]

Ok, I didn't know which is the right place because I was't sure if this is a bug or a general question.

Comment by Christoph John [ 21/Aug/19 ]

No problem





[QFJ-983] SLF4JLog is suffixing category with session ID instead of prefixing it. Created: 10/Aug/19  Updated: 29/Nov/19  Resolved: 29/Nov/19

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.1
Fix Version/s: 2.2.0

Type: Bug Priority: Minor
Reporter: Simon Ogbamichael Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: slf4jlog
Environment:

N/A



 Description   

The property SLF4JLogPrependSessionID "Controls whether session ID is prepended to log message." This property is passed down to SLF4J and used in the method quickfix.SLF4JLog#getLogger.

Based on the property name and description, one would think that the Session ID will appear as prefix of category. But the method getLogger suffixes category with session ID instead of prefixing it. I think this is a bug.

Bug:

private Logger getLogger(SessionID sessionID, String category, String defaultCategory, String logPrefix) {
    return LoggerFactory.getLogger((category != null
            ? substituteVariables(sessionID, category)
            : defaultCategory) + logPrefix);
}

Proposed Fix:

private Logger getLogger(SessionID sessionID, String category, String defaultCategory, String logPrefix) {
    return LoggerFactory.getLogger(logPrefix + (category != null
            ? substituteVariables(sessionID, category)
            : defaultCategory));
}

Thanks!



 Comments   
Comment by Christoph John [ 12/Aug/19 ]

Hi Simon Ogbamichael,

thanks for the issue. This was discussed briefly some weeks ago on the mailing list but never made it into a JIRA issue. If you'd like you can open a pull request with your proposed fix at https://github.com/quickfix-j/quickfixj/pulls

Thanks,
Chris.

Comment by Christoph John [ 12/Aug/19 ]

https://sourceforge.net/p/quickfixj/mailman/message/36714538/

Comment by Christoph John [ 29/Nov/19 ]

This change has been reverted in https://github.com/quickfix-j/quickfixj/pull/234





[QFJ-982] Using the same dictionary file with different settings on different sessions causes problems Created: 02/Aug/19  Updated: 15/Jun/20

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: 3.0.0

Type: Bug Priority: Default
Reporter: Philip Whitehouse Assignee: Philip Whitehouse
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-877 Multiple sessions with same dictionary Closed
Relates
relates to QFJ-981 Validation settings do not get applie... Closed

 Description   

[Affects all vaguely recent versions]

The DefaultSessionFactory stores a cache DataDictionary objects based on the file name of that object.

createDataDictionary fetches a DataDictionary object based on the file name and then applies settings to it based on the session.

Because it applies the settings to and returns the DataDictionary object in the cache, not a copy of it, when a different session uses a dictionary from the same file, it will also have the settings applied.

This means that configuration that's supposed to be session specific is not.

What we should do is instead have a `SessionDataDictionarySettings` object to encapsulate the settings. Then when using the data dictionary, pass in the relevant settings for the session the message is being validated for.

This would allow us to gain the advantages of reusing DataDictionary objects (lower memory usage) with the configuration settings required.

It will however likely involve API changes.



 Comments   
Comment by Christoph John [ 05/Aug/19 ]

Hi Philip Whitehouse,
funny, I also stumbled over this a few days ago while investigating https://github.com/quickfix-j/quickfixj/pull/224 / QFJ-981. Didn't get to investigate very far but IIRC the only settings that might differ are validation options

    checkFieldsOutOfOrder
    checkFieldsHaveValues
    checkUserDefinedFields
    checkUnorderedGroupFields
    allowUnknownMessageFields

so I thought I would just use the path plus the validation options as key for the cache in DefaultSessionFactory. Of course that means that there might be several DDs with different validation options. But on the other hand, I do not know if this really is a big downside. Of course depends how much sessions with the same dictionary and different validation options one might have in one VM.
Your proposed solution is of course a little more sophisticated since we would only have one instance of a DD, however as you said there might be API changes.

What do you think?
Thanks,
Chris.

Comment by Philip Whitehouse [ 14/Aug/19 ]

The problem with multiple copies of the same DataDictionary is that they are a massive memory hog given the size of them (especially once you add all the service packs).

I agree it's just the validation options however. My VMs generally run lots of sessions with the same dictionary so I'm keen to avoid an unexpected RAM usage increase from fixing the bug.

The other side to it is a proxy layer we have allowing you to live-reload the dictionary file to correct issues. I might try to upstream this at the same time.

This is likely to be something I have time to proof-of-concept relatively soon as currently the bug provides run-time unreliability on what will actually be applied to validate a given message.
Which is fairly ugly in terms of potential impact.

Comment by Christoph John [ 14/Aug/19 ]

OK, so did I understand you correctly that you are going to take a stab on this?
Or do you want me to do it?

Sorry, non-native english speaker here, so it's sometimes hard for me to get the nuances.

Thanks,
Chris.





[QFJ-981] Validation settings do not get applied when no explicit AppDataDictionary is specified Created: 19/Jul/19  Updated: 15/Jun/20  Resolved: 15/Jun/20

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-982 Using the same dictionary file with d... Open

 Description   

From mailing list https://sourceforge.net/p/quickfixj/mailman/message/36618317/

[Quickfixj-users] Session validation settings have no effect for FIXT unless AppDataDictionary is set explicitly
From: Ilya Kurnosov <kurniliya@gm...> - 2019-03-21 08:50:46

Hello! I ran into some interesting behavior with quickfixj 2 today. My
question is if it's intentionally designed this way? And, if yes, if
someone could explain the reasoning behind it?

The behavior I see is that all the session validation settings:

  • Session.SETTING_VALIDATE_FIELDS_HAVE_VALUES
    ("ValidateFieldsHaveValues")
  • Session.SETTING_VALIDATE_FIELDS_OUT_OF_ORDER
    ("ValidateFieldsOutOfOrder")
  • Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS
    ("ValidateUnorderedGroupFields")
  • Session.SETTING_VALIDATE_USER_DEFINED_FIELDS
    ("ValidateUserDefinedFields")
  • Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS ("AllowUnknownMsgFields")

have exactly no effect on the validation of FIXT application messages
unless one also explicitly sets "AppDataDictionary" option
(Session.SETTING_APP_DATA_DICTIONARY).
I observe this behavior in tests, but the code in
DefaultSessionFactory#processFixtDataDictionaries looks rather unambiguous
too (
https://github.com/quickfix-j/quickfixj/blob/QFJ_RELEASE_2_1_1/quickfixj-core/src/main/java/quickfix/DefaultSessionFactory.java#L283).
It looks like DefaultSessionFactory#createDataDictionary (the only place
using those Validate* and AllowUnknownMsgFields settings) is called to
create app dictionary IIF AppDataDictionary is present.

Is this behavior intentional?

problem

The default application dictionary is loaded if it is not specified but the validation settings do not get applied. This would only work if method DefaultSessionFactory#createDataDictionary got called.



 Comments   
Comment by Christoph John [ 29/Nov/19 ]

Closing since already solved with QFJ-982.





[QFJ-980] NPE during message parsing if repeating group's first tag is undefined Created: 19/Jul/19  Updated: 17/Jun/20  Resolved: 19/Jul/19

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.4, 2.1.1
Fix Version/s: 2.2.0

Type: Bug Priority: Major
Reporter: Emil Rakadjiev Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

If a message contains a repeating group in which the first tag is not defined in the dictionary, a NullPointerException is thrown while parsing the message/group.

To reproduce, you can use this FIX string with the standard 4.2 dictionary.
It contains an undefined tag (9876) as the first tag of the NoAllocs (78) repeating group.

8=FIX.4.2|9=130|35=D|34=2|49=SND1|52=20190719-04:56:39.042|56=TGT1|11=1|78=1|9876=npe|79=a|80=1|21=1|55=x|54=1|60=20190719-04:56:53.826|38=1|40=1|10=169|

Here is the stack trace for 1.6.4:

Exception in thread "main" java.lang.NullPointerException
	at quickfix.Message.checkFieldValidation(Message.java:662)
	at quickfix.Message.parseGroup(Message.java:633)
	at quickfix.Message.parseBody(Message.java:559)
	at quickfix.Message.parse(Message.java:470)
	at quickfix.Message.fromString(Message.java:453)
	[...]

and for 2.1.1:

Exception in thread "main" java.lang.NullPointerException
	at quickfix.Message.checkFieldValidation(Message.java:748)
	at quickfix.Message.parseGroup(Message.java:711)
	at quickfix.Message.parseBody(Message.java:637)
	at quickfix.Message.parse(Message.java:548)
	at quickfix.Message.fromString(Message.java:531)
	[...]


 Comments   
Comment by Christoph John [ 19/Jul/19 ]

Hi Emil,

thanks for the report. If I am not mistaken the problem will be solved by the following PR: https://github.com/quickfix-j/quickfixj/pull/222
I will merge this in due course. But I don't know when the next patch release will be built. But maybe you can build your own for the time being.

Cheers,
Chris.

Comment by Emil Rakadjiev [ 19/Jul/19 ]

Hello Chris,

Thank you for the quick reply!
I hadn't seen that PR on GitHub, sorry.
It does fix the issue, so all is good.

Thanks again and cheers!

Comment by Christoph John [ 19/Jul/19 ]

Hi Emil,
no problem, you're welcome.
Cheers
Chris.





[QFJ-979] Oracle schema definitions missing from the latest releases Created: 11/Jun/19  Updated: 24/Apr/21  Resolved: 01/Jan/21

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 2.0.0, 2.1.1
Fix Version/s: 2.3.0

Type: Bug Priority: Default
Reporter: Beirti O'Nunain Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Looking in the QuickFixJ 2.x releases, it looks like the SQL schema definitions for oracle are missing some tables which are defined for other databases. (event_log, messages_log)

I can't find any documentation which suggests that they aren't required for Oracle. I can craft them manually but am curious why they're omitted.



 Comments   
Comment by Beirti O'Nunain [ 11/Jun/19 ]

I'm guessing that this is the correct SQL? (Oracle 12 identity columns)

CREATE TABLE EVENT_LOG (
id NUMBER GENERATED ALWAYS AS IDENTITY,
time TIMESTAMP NOT NULL,
beginstring VARCHAR2(8) NOT NULL,
sendercompid VARCHAR2(64) NOT NULL,
sendersubid VARCHAR2(64) NOT NULL,
senderlocid VARCHAR2(64) NOT NULL,
targetcompid VARCHAR2(64) NOT NULL,
targetsubid VARCHAR2(64) NOT NULL,
targetlocid VARCHAR2(64) NOT NULL,
session_qualifier VARCHAR2(64) NOT NULL,
text VARCHAR2(4000) NOT NULL,
PRIMARY KEY (id)
);

CREATE TABLE MESSAGES_LOG (
id NUMBER GENERATED ALWAYS AS IDENTITY,
time TIMESTAMP NOT NULL,
beginstring CHAR(8) NOT NULL,
sendercompid VARCHAR2(64) NOT NULL,
sendersubid VARCHAR2(64) NOT NULL,
senderlocid VARCHAR2(64) NOT NULL,
targetcompid VARCHAR2(64) NOT NULL,
targetsubid VARCHAR2(64) NOT NULL,
targetlocid VARCHAR2(64) NOT NULL,
session_qualifier VARCHAR2(64) NOT NULL,
text VARCHAR2(4000) NOT NULL,
PRIMARY KEY (id)
);

Comment by Beirti O'Nunain [ 11/Jun/19 ]

Getting errors on session initialization. It seems to be attempting to insert without specifying all parameters required by the table. I've not had this issue in MSSQL

private void loadCache() throws SQLException, IOException {
Connection connection = null;
PreparedStatement query = null;
PreparedStatement insert = null;
ResultSet rs = null;
try {
connection = dataSource.getConnection();
query = connection.prepareStatement(SQL_GET_SEQNUMS);
setSessionIdParameters(query, 1);
rs = query.executeQuery();
if (rs.next())

{ cache.setCreationTime(SystemTime.getUtcCalendar(rs.getTimestamp(1))); cache.setNextTargetMsgSeqNum(rs.getInt(2)); cache.setNextSenderMsgSeqNum(rs.getInt(3)); }

else

{ insert = connection.prepareStatement(SQL_INSERT_SESSION); int offset = setSessionIdParameters(insert, 1); insert.setTimestamp(offset++, new Timestamp(cache.getCreationTime().getTime())); insert.setInt(offset++, cache.getNextTargetMsgSeqNum()); insert.setInt(offset, cache.getNextSenderMsgSeqNum()); insert.execute(); }

} finally

{ JdbcUtil.close(sessionID, rs); JdbcUtil.close(sessionID, query); JdbcUtil.close(sessionID, insert); JdbcUtil.close(sessionID, connection); }

}

{{Caused by: java.lang.RuntimeException: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("SKYROAD"."FIX_SESSIONS"."SENDERSUBID")

at quickfix.JdbcStoreFactory.create(JdbcStoreFactory.java:47) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.Session.<init>(Session.java:492) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:206) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.mina.SessionConnector.createSession(SessionConnector.java:169) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:187) ~[quickfixj-core-2.0.0.jar:2.0.0]
... 16 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-01400: cannot insert NULL into ("SKYROAD"."SESSIONS"."SENDERSUBID")

at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1150) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.OraclePreparedStatement.execute(OraclePreparedStatement.java:4901) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at oracle.jdbc.driver.OraclePreparedStatementWrapper.execute(OraclePreparedStatementWrapper.java:1385) ~[ojdbc7-12.1.0.2.0.jar:12.1.0.2.0]
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) ~[tomcat-dbcp-7.0.47.jar:7.0.47]
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172) ~[tomcat-dbcp-7.0.47.jar:7.0.47]
at quickfix.JdbcStore.loadCache(JdbcStore.java:139) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.JdbcStore.<init>(JdbcStore.java:86) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.JdbcStoreFactory.create(JdbcStoreFactory.java:45) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.Session.<init>(Session.java:492) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:206) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.mina.SessionConnector.createSession(SessionConnector.java:169) ~[quickfixj-core-2.0.0.jar:2.0.0]
at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:187) ~[quickfixj-core-2.0.0.jar:2.0.0]
... 16 more}}

Comment by Beirti O'Nunain [ 11/Jun/19 ]

Following up with our DBA, it seems you can skip specificying a 'not null' column in MSSQL but not in Oracle. I guess nobody is using Oracle with QuickFixJ?!

Comment by Christoph John [ 08/Jul/19 ]

Hi,
yes, that may be the case. I have the assumption that the JDBC store is used pretty rarely. But I might be wrong. Just my personal impression.
Cheers,
Chris.

Comment by Christoph John [ 08/Jul/19 ]

I don't know if it fixes your problem, but did you try setting JdbcSessionIdDefaultPropertyValue? See https://www.quickfixj.org/usermanual/2.1.0/usage/configuration.html
At least it mentions "Oracle".

Comment by Beirti O'Nunain [ 10/Jul/19 ]

Sad times friend! I've been using the mssql one in production for a few months and find it great for managing searching and archiving of raw logs. Just set up the oracle one now too and it seems to be going ok. Fingers crossed?!

Comment by Christoph John [ 16/Jul/19 ]

So did the JdbcSessionIdDefaultPropertyValue work for you?
If you'd like you can open a PR here to supply the missing schema definitions. https://github.com/quickfix-j/quickfixj/pulls

Thanks and best regards,
Chris.

Comment by Beirti O'Nunain [ 14/Mar/20 ]

Hi Chris,

Apologies for the very late reply. I ended up giving up on Oracle. Everything's been running swimmingly on MSSQL in our production setup with 20 or so applications sharing a database so I've left it there. If I get stuck having to use Oracle in the future I'll revisit and submit a PR with the schema defs once I get it working.

Cheers,
Beirti

Comment by Christoph John [ 15/Mar/20 ]

OK, thanks for the update.

Comment by Christoph John [ 01/Jan/21 ]

Fixed by https://github.com/quickfix-j/quickfixj/pull/349





[QFJ-978] RESENDREQUEST (35=2) present in 'messages' log, Not present in 'event' log Created: 23/May/19  Updated: 16/Sep/19  Resolved: 16/Sep/19

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Chandrabose J Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: ResendRequest,


 Description   

We receive 35=2 (RESENDREQUEST) from clinet, but its only logged in *.messages log.
Not present in *.event log. we expect following message should be present in event log at least - 'Received ResendRequest FROM:'. or any validation failure message from 'verify' method.

But no clue in *.event log.



 Comments   
Comment by Christoph John [ 08/Jul/19 ]

Hmm, hard to tell without some example log lines. But your QFJ version is rather old. Did you try a newer one? IIRC there were problems with ignored ResendRequests on older versions.
Cheers,
Chris.





[QFJ-977] ResendRequest message ( 35=2) received from Sender was ignored in QuickFIXJ Created: 21/May/19  Updated: 08/Jul/19

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Lantony Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, ResendRequest,, sequence,
Environment:

Linux



 Description   

Fix session was interrupted due to network issue... Both side FIX processes ( Client, Sender) did not know about the n/w issue. The Client side was continuously sending logon request to other side... Once the n/w issue was resolved the connectivity was established. However, the sequence was not in sync at this time . Hence , The sender sent resend request (35=2) immediately after successful logon response.
But this 35=2 request was not processed by quick fix engine at my side ( Client side). I can see the message in quickfix messages.log arrived from sender but not traceability on what had happened with this message.
Only what i can see , the Client side ( fix engine) sent 35=2 for which the sender has responded with sequencereset i.e., 35=4. I think , the sender on the other side responded well with the Admin messages sent by my quickFix engine.

the problem is why my fix engine (i.e., the client ) did not respond to 35=2 resent request given by sender ? . I am expecting my Fix engine should have responed with 35=4 like my Sender's engine . I am using QuickfixEngineJ 1.5.3

Some one kindly help please. The below the sequence of FIX messaged traced in messages.log/

Response from Sender:
8=FIXT.1.19=72 35=A 34=75098 49=456 52=20190516-23:30:20.382 56=123 98=0 108=30 1137=9 10=178

Resent request from sender ( problem where I did not respond for this message)
8=FIXT.1.19=66 35=2 34=75099 49=456 52=20190516-23:30:20.38256=123 7=74910 16=0 10=154

Resent request from Client (i.e., by my quick fix engine )
8=FIXT.1.19=66 35=2 34=74963 49=123 52=20190516-23:30:20.436 56=456 7=75019 16=0 10=154

reset request responded by sender:
8=FIXT.1.19=99 35=434=75019 43=Y 49=456 52=20190516-23:30:20.489 56=123 122=20190516-23:30:20.489 36=75100 123=Y 10=043



 Comments   
Comment by Lantony [ 22/May/19 ]

Small Correction , The environment is Windows , not Linux.

Comment by Christoph John [ 08/Jul/19 ]

Hi,
I cannot tell from the log file why this is not working. Have you tried with a newer version? Yours is rather old. But I guess the problem cannot be reproduced reliably?

Cheers,
Chris.





[QFJ-976] GarbledMessage without MsgType Created: 16/May/19  Updated: 17/Jun/20  Resolved: 30/Jul/19

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.1
Fix Version/s: 2.2.0

Type: Bug Priority: Default
Reporter: Hampus Bergström Assignee: Wojciech Zankowski
Resolution: Fixed Votes: 0
Labels: None


 Description   

I think there is an issue with letting garbledMessages(when the new RejectGarbledMessage property is set to Y) through the AbstractIoHandler. Its being passed here: https://github.com/quickfix-j/quickfixj/blob/master/quickfixj-core/src/main/java/quickfix/mina/AbstractIoHandler.java#L142 and if the reason is that the message is garbled because of missing MsgType it will crash here: https://github.com/quickfix-j/quickfixj/blob/master/quickfixj-core/src/main/java/quickfix/mina/initiator/InitiatorIoHandler.java#L64. Which means that the sequencenumber won't be incremented and the purpose with the property is neglected.

<20190516-14:30:21, FIX.4.4:SCILA5MD->FIXRFQTRADE, error> (Processing garbled message: Missing or garbled message type in 8=FIX.4.49=8034=149=FIXRFQTRADE52=20190516-14:29:47.67156=SCILA5MD98=0108=30141=Y10=174)
<20190516-14:30:32, FIX.4.4:SCILA5MD->FIXRFQTRADE, error> (quickfix.FieldNotFound: Field was not found in message, field=35
quickfix.FieldNotFound: Field was not found in message, field=35
at quickfix.FieldMap.getField(FieldMap.java:223)
at quickfix.FieldMap.getString(FieldMap.java:237)
at quickfix.mina.initiator.InitiatorIoHandler.processMessage(InitiatorIoHandler.java:64)
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:142)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:858)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:947)
at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:398)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:234)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:947)
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:109)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:535)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:703)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:659)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:648)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:68)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1120)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)



 Comments   
Comment by Christoph John [ 08/Jul/19 ]

Good catch. Do you have time for providing a pull request with a fix? https://github.com/quickfix-j/quickfixj/pulls

Cheers,
Chris.

Comment by Wojciech Zankowski [ 29/Jul/19 ]

I have created a pull request: https://github.com/quickfix-j/quickfixj/pull/225





[QFJ-975] my program is not getting username and password from config file Created: 25/Apr/19  Updated: 08/Jul/19  Resolved: 08/Jul/19

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 2.1.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Deepak Sharma Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: logon


 Description   

Hi, I am trying to connect third party fix engine Aphelion using their their port,ip,SenderCompID ,TargetCompID, username and password but I am facing issue if I try to get username and pwd from config file. my program is working fine if I send username and explicitly programaticaly.
I do not want to do it programaticaly as Calypso is providing "Fix Engine" using Quickfixj so I just wanted to pass all the values from config.

.



 Comments   
Comment by Christoph John [ 08/Jul/19 ]

QFJ does not support getting username and password from config file out of the box.





[QFJ-974] Session+FileStore reset fails indefinitely when stream closed Created: 23/Apr/19  Updated: 06/Jun/21

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: amichair Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

If the FileStore stream is closed for any unexpected reason, the reset will fail indefinitely even if the original cause is fixed (or was just a transient error), since it will continue to try and flush/closed the failed stream, instead of truly resetting and opening a new one.

In our case the error was triggered by the disk being full (space was then freed up), but any reason for closing the stream could get the store stuck in this unrecoverable state. Perhaps the store reset mechanism should be made more robust so that it really tries to reset even in this unexpected state rather than require the application to be restarted manually.

quickfix.RuntimeError: java.io.IOException: Stream Closed
at quickfix.SessionState.reset(SessionState.java:384)
at quickfix.Session.resetState(Session.java:2624)
at quickfix.Session.nextLogon(Session.java:2116)
at quickfix.Session.next(Session.java:1026)
at quickfix.Session.next(Session.java:1204)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.doRun(ThreadPerSessionEventHandlingStrategy.java:222)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$ThreadAdapter.run(ThreadPerSessionEventHandlingStrategy.java:146)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at quickfix.FileStore.close(FileStore.java:218)
at quickfix.FileStore.close(FileStore.java:209)
at quickfix.FileStore.closeAndDeleteFiles(FileStore.java:223)
at quickfix.FileStore.initialize(FileStore.java:101)
at quickfix.FileStore.reset(FileStore.java:405)
at quickfix.SessionState.reset(SessionState.java:382)
... 7 more Suppressed: java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
... 13 more



 Comments   
Comment by Sergei [ 06/Jun/21 ]

13:35:17.885 QFJ Timer ERROR quickfix.SocketInitiator.run:356 - Error during timer processing
quickfix.RuntimeError: java.io.IOException: Stream Closed
at quickfix.SessionState.reset(SessionState.java:384)
at quickfix.Session.resetState(Session.java:2624)
at quickfix.Session.generateLogon(Session.java:2003)
at quickfix.Session.next(Session.java:1918)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:350)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.DataOutputStream.flush(DataOutputStream.java:123)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at quickfix.FileStore.close(FileStore.java:218)
at quickfix.FileStore.close(FileStore.java:209)
at quickfix.FileStore.closeAndDeleteFiles(FileStore.java:223)
at quickfix.FileStore.initialize(FileStore.java:101)
at quickfix.FileStore.reset(FileStore.java:405)
at quickfix.SessionState.reset(SessionState.java:382)
... 11 common frames omitted
Suppressed: java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at java.io.FilterOutputStream.close(FilterOutputStream.java:159)
... 17 common frames omitted

Same issue

What file might be the problem? - java.io.FileOutputStream.writeBytes





[QFJ-973] Provide configuration to turn off checksum validation Created: 20/Mar/19  Updated: 17/Jun/20  Resolved: 14/Aug/19

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

Type: Improvement Priority: Default
Reporter: Frank Peter Michler Assignee: Wojciech Zankowski
Resolution: Fixed Votes: 0
Labels: None


 Description   

Recently, I have experienced a QuickFIX/J based application ignoring or rejecting messages with an invalid checksum (depending on the setting of the RejectGarbledMessage property). On the other hand, these messages featured the required structure for further processing.

So I have decided to provide an enhancement which allows the FIX Engine to process messages with invalid checksum as ordinary messages having passed validation. This enhancement will be provided as a configuration option controlled by the property ProcessMessageWithInvalidChecksum. By default, this property will be set to 'N' such that Messages with invalid checksum will be either ignored or rejected as before.

In particular, it will only be possible to set either RejectGarbledMessage or ProcessMessageWithInvalidChecksum to 'Y' for a specific session. If both properties are set to 'Y' at once, a ConfigError will be thrown.



 Comments   
Comment by Christoph John [ 08/Jul/19 ]

Hi,
sorry for the delayed reply. Could you please open a pull request for this?
Thanks,
Chris.

Comment by Frank Peter Michler [ 08/Jul/19 ]

Hi Christoph,

currently I do not have time to work on this task. So can I do the pull request when I start to do so? I assume that the pull request has to be done via github.

In addition, can you also tell me how to assign this Task to myself?

Best regards,

Frank

Comment by Christoph John [ 08/Jul/19 ]

Hi Frank,

oh sorry. I thought you already implemented it since you wrote:

So I have decided to provide an enhancement which allows the FIX Engine to process messages

You are right, pull requests can be opened here: https://github.com/quickfix-j/quickfixj/pulls

I have added you to the developer group so you should be able to assign this task to yourself. Maybe a re-login is necessary.

Cheers,
Chris.

Comment by Wojciech Zankowski [ 29/Jul/19 ]

Pull request created, to review: https://github.com/quickfix-j/quickfixj/pull/227

Comment by Christoph John [ 29/Jul/19 ]

Thanks, already commented there. Will assign you this ticket.





[QFJ-972] Log initiator address on connection attempt Created: 11/Mar/19  Updated: 08/Jul/19

Status: Open
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 2.0.0, 2.1.0, 2.1.1
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Colin DuPlantis Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All


Attachments: Text File patch.txt    

 Description   

When using multiple SocketConnectHost/SocketConnectPort combinations, it would be nice to be able to see which combo was being used for the connection attempt.



 Comments   
Comment by Colin DuPlantis [ 11/Mar/19 ]

Tried to add a PR via github:

remote: Permission to quickfix-j/quickfixj.git denied to colinduplantis.
fatal: unable to access 'https://github.com/quickfix-j/quickfixj.git/': The requested URL returned error: 403
Comment by Colin DuPlantis [ 11/Mar/19 ]

It looks like this have been implemented as of 1.6.3 (and perhaps earlier). I noticed this in 1.5.3. Probably ok to disregard.

Comment by Christoph John [ 08/Jul/19 ]

Maybe this is the change you mentioned

https://github.com/quickfix-j/quickfixj/blob/045be5c09f872b1bf7b1a8ed2904efd0030c59bd/quickfixj-core/src/main/java/quickfix/mina/initiator/InitiatorIoHandler.java#L57

Cheers,
Chris.





[QFJ-971] Intermittently we receive the "Required Tag Missing" error for existing fields Created: 08/Mar/19  Updated: 17/Jun/20  Resolved: 23/Dec/19

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: 2.2.0

Type: Bug Priority: Default
Reporter: Michael Efis Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: Message

Issue Links:
Duplicate
is duplicated by QFJ-835 Required tag missing, field=447 Closed

 Description   

Hello QuickFix support,

Could you advise on the following issue, please?

We receive intermittent "Required Tag Missing" error while parsing incoming fix messages, even though the missing field is present in the message. For example in the following message the tag 447 is present on the message, and yet sometimes we receive “Required Tag Missing, field=447” while parsing it.

8=FIX.4.4|9=284|35=F|49=TEST_49|56=TEST_56|34=420|52=20190302-07:31:57.079|115=TEST3|116=TEST_116|11=TEST_11|41=TEST_41|55=TEST_55|48=TEST_48|22=4|54=2|60=20190302-07:31:56.933|38=TEST_38|207=TEST_207|454=3|455=TEST_455_1|456=TEST_456_1|455=TEST_455_2|456=TEST_456_2|455=TEST_455_3|456=TEST_456_3|453=1|448=TEST_448|447=D|452=3|10=XXX|

This issue has been observed with cancel messages and it normally happens after application startup. We do use a data dictionary, and 99.8% of the time such cancellation messages work fine. We use quick fix version 1.5.3. (quickfixj-core-1.5.3.jar and quickfixj-msg-fix44-1.5.3.jar)

Could you take a look at it?

Many thanks
Michael



 Comments   
Comment by Christopher Hurst [ 08/Mar/19 ]

Hi,

It might be a different problem and we use a different version of FIX but ..

I think we saw the same thing a year back (my memory is slightly hazy) but like you say its intermittent and would stop happening after a while and not be reproducible . It only occurred for us in E2E tests on VMs so we just so it was not important as it would go away (We only use QFJ as part of a test tool)

The message logs always saw the correct tags indicated as missing, it may well have been the same tag you quote (I can't remember the message) and we validated the offending FIX with an external tool (all fine).

I managed to hack quickfix to serialise on failure the message then reloaded it in a test bed but could find nothing wrong with the object.

Eventually the problem just stopped happening and wasn't reproducible , though it does seem to come back periodically but not often enough to debug it properly,

Comment by Michael Efis [ 18/Mar/19 ]

The same issue has been observed with other message types

Comment by Christoph John [ 08/Jul/19 ]

I am afraid we cannot analyse this without a reproducible test case.

Comment by Michael Efis [ 08/Jul/19 ]

Christopher,

I appreciate that without knowing someone else's code, it's difficult to say where the problem is.

In our case we send strings with messages directly to QuickFix, where we get the intermittent errors. There is basically nothing in between. If we could reliably reproduce this error, then we would have known the root cause of the issue and then probably we could create a reliable, testable workaround (for example some sort re-try mechanism) without involving quick fix support.

Unfortunately this error is too unpredictable and we can't reliably test any of our solutions.

The symptoms that we see (intermittent errors on the application startup) look similar to a concurrency issue around QuickFix initialization. However, without full understanding of the QuickFix code we cannot be sure if this is the case. This is where we would appreciate help from QuickFix support.

Thanks
Michael

Comment by Christoph John [ 08/Jul/19 ]

Hi,
I also answered this on the mailing list:

Hi,

unfortunately I do not have a solution but also did see such problems with a client of ours and it was also the exact same tag 447 that was the problem (although another message type). The application was already running for several hours.
We also could not reproduce it. It just appeared once every few months... :-/

Cheers,
Chris.

At least for our client it was no startup issue.

Comment by Christoph John [ 05/Sep/19 ]

Hi Michael Efis,

would it be possible to see the code snippet how you send the message strings to QFJ as you mentioned above? Are you using MessageUtils.parse() or another method? How does the party group in your data dictionary look like?

Thanks,
Chris.

Comment by Christoph John [ 20/Dec/19 ]

See issue and pull request by AndreyNudko:
https://github.com/quickfix-j/quickfixj/issues/240
https://github.com/quickfix-j/quickfixj/pull/241





[QFJ-970] SSL hand shake failed Created: 12/Feb/19  Updated: 26/Feb/19  Resolved: 26/Feb/19

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

Type: Bug Priority: Major
Reporter: dai, lianjie Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: ssl
Environment:

JDK8



 Description   

Our side it's client side, we only receive the messages from the server side, not sending any mesages from our side. So server side give us one certificate to use the SSL encryption(we generate the trust store by our selfservles), in our dev env and UAT env is good. But for the production it's bad.

Then we try to resolve the issue, we find when prod env validate the keyusage, client and server side decide to use RSA, RSA need to validate the 3 key usages, but our certification only have 1 key usage. The SSL hand shake failed.

Error Class: X509TrustManagerWrapper, method: checkServerTrusted()

Could you please help to check this issue? Thank you for your help.

ERROR MESSAGE:
adding as trusted cert:
Subject: CN=Root Certification Authority, OU=Sysadmin Team, O=360 Treasury Systems AG, C=DE
Issuer: CN=Root Certification Authority, OU=Sysadmin Team, O=360 Treasury Systems AG, C=DE
Algorithm: RSA; Serial number: 0x2ec09da74e9247da
Valid from Fri Dec 23 22:04:34 CST 2016 until Mon Dec 23 22:04:34 CST 2030

adding as trusted cert:
Subject: CN=Issuing Certification Authority, OU=Sysadmin Team, O=360 Treasury Systems AG, C=DE
Issuer: CN=Root Certification Authority, OU=Sysadmin Team, O=360 Treasury Systems AG, C=DE
Algorithm: RSA; Serial number: 0x4158dfbd6b0a96bb
Valid from Fri Dec 23 22:05:53 CST 2016 until Sat Dec 23 22:05:53 CST 2023

trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session

      • ClientHello, TLSv1.2
        RandomCookie: GMT: 1526460512 bytes = { 58, 213, 205, 241, 212, 73, 219, 161, 144, 98, 52, 91, 241, 165, 108, 180, 251, 112, 36, 206, 93, 44, 219, 44, 154, 111, 191, 171 }

        Session ID: {}
        Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
        Compression Methods:

        { 0 }

        Extension elliptic_curves, curve names:

        {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}

        Extension ec_point_formats, formats: [uncompressed]
        Extension signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
        ***
        [write] MD5 and SHA1 hashes: len = 239
        0000: 01 00 00 EB 03 03 5B FC F0 60 3A D5 CD F1 D4 49 ......[..`:....I
        0010: DB A1 90 62 34 5B F1 A5 6C B4 FB 70 24 CE 5D 2C ...b4[..l..p$.],
        0020: DB 2C 9A 6F BF AB 00 00 64 C0 24 C0 28 00 3D C0 .,.o....d.$.(.=.
        0030: 26 C0 2A 00 6B 00 6A C0 0A C0 14 00 35 C0 05 C0 &.*.k.j.....5...
        0040: 0F 00 39 00 38 C0 23 C0 27 00 3C C0 25 C0 29 00 ..9.8.#.'.<.%.).
        0050: 67 00 40 C0 09 C0 13 00 2F C0 04 C0 0E 00 33 00 g.@...../.....3.
        0060: 32 C0 2C C0 2B C0 30 00 9D C0 2E C0 32 00 9F 00 2.,.+.0.....2...
        0070: A3 C0 2F 00 9C C0 2D C0 31 00 9E 00 A2 C0 08 C0 ../...-.1.......
        0080: 12 00 0A C0 03 C0 0D 00 16 00 13 00 FF 01 00 00 ................
        0090: 5E 00 0A 00 34 00 32 00 17 00 01 00 03 00 13 00 ^...4.2.........
        00A0: 15 00 06 00 07 00 09 00 0A 00 18 00 0B 00 0C 00 ................
        00B0: 19 00 0D 00 0E 00 0F 00 10 00 11 00 02 00 12 00 ................
        00C0: 04 00 05 00 14 00 08 00 16 00 0B 00 02 01 00 00 ................
        00D0: 0D 00 1C 00 1A 06 03 06 01 05 03 05 01 04 03 04 ................
        00E0: 01 04 02 03 03 03 01 03 02 02 03 02 01 02 02 ...............
        NioProcessor-2, WRITE: TLSv1.2 Handshake, length = 239
        [Raw write]: length = 244
        0000: 16 03 03 00 EF 01 00 00 EB 03 03 5B FC F0 60 3A ...........[..`:
        0010: D5 CD F1 D4 49 DB A1 90 62 34 5B F1 A5 6C B4 FB ....I...b4[..l..
        0020: 70 24 CE 5D 2C DB 2C 9A 6F BF AB 00 00 64 C0 24 p$.],.,.o....d.$
        0030: C0 28 00 3D C0 26 C0 2A 00 6B 00 6A C0 0A C0 14 .(.=.&.*.k.j....
        0040: 00 35 C0 05 C0 0F 00 39 00 38 C0 23 C0 27 00 3C .5.....9.8.#.'.<
        0050: C0 25 C0 29 00 67 00 40 C0 09 C0 13 00 2F C0 04 .%.).g.@...../..
        0060: C0 0E 00 33 00 32 C0 2C C0 2B C0 30 00 9D C0 2E ...3.2.,.+.0....
        0070: C0 32 00 9F 00 A3 C0 2F 00 9C C0 2D C0 31 00 9E .2...../...-.1..
        0080: 00 A2 C0 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 ................
        0090: 00 FF 01 00 00 5E 00 0A 00 34 00 32 00 17 00 01 .....^...4.2....
        00A0: 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 18 ................
        00B0: 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 11 ................
        00C0: 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 0B ................
        00D0: 00 02 01 00 00 0D 00 1C 00 1A 06 03 06 01 05 03 ................
        00E0: 05 01 04 03 04 01 04 02 03 03 03 01 03 02 02 03 ................
        00F0: 02 01 02 02 ....
        [Raw read]: length = 5
        0000: 16 03 03 00 51 ....Q
        [Raw read]: length = 81
        0000: 02 00 00 4D 03 03 5B FC F0 60 AE 8D 17 B5 8E 84 ...M..[..`......
        0010: CF D5 5C 73 E2 E2 9F 4C 6E DE 5A F6 70 84 DC 26 ..\s...Ln.Z.p..&
        0020: BD 46 7C D7 F9 1B 20 B7 8F 74 A3 FE 3A 4A CA 76 .F.... ..t..:J.v
        0030: 42 16 15 1C 42 05 DF 71 05 EC D2 19 06 51 B2 37 B...B..q.....Q.7
        0040: D3 45 74 78 DA EE 45 00 3D 00 00 05 FF 01 00 01 .Etx..E.=.......
        0050: 00 .
        NioProcessor-2, READ: TLSv1.2 Handshake, length = 81

      • ServerHello, TLSv1.2
        RandomCookie: GMT: 1526460512 bytes = { 174, 141, 23, 181, 142, 132, 207, 213, 92, 115, 226, 226, 159, 76, 110, 222, 90, 246, 112, 132, 220, 38, 189, 70, 124, 215, 249, 27 }

        Session ID:

        {183, 143, 116, 163, 254, 58, 74, 202, 118, 66, 22, 21, 28, 66, 5, 223, 113, 5, 236, 210, 25, 6, 81, 178, 55, 211, 69, 116, 120, 218, 238, 69}

        Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA256
        Compression Method: 0
        Extension renegotiation_info, renegotiated_connection: <empty>
        ***
        %% Initialized: [Session-1, TLS_RSA_WITH_AES_256_CBC_SHA256]

    • TLS_RSA_WITH_AES_256_CBC_SHA256
      [read] MD5 and SHA1 hashes: len = 81
      0000: 02 00 00 4D 03 03 5B FC F0 60 AE 8D 17 B5 8E 84 ...M..[..`......
      0010: CF D5 5C 73 E2 E2 9F 4C 6E DE 5A F6 70 84 DC 26 ..\s...Ln.Z.p..&
      0020: BD 46 7C D7 F9 1B 20 B7 8F 74 A3 FE 3A 4A CA 76 .F.... ..t..:J.v
      0030: 42 16 15 1C 42 05 DF 71 05 EC D2 19 06 51 B2 37 B...B..q.....Q.7
      0040: D3 45 74 78 DA EE 45 00 3D 00 00 05 FF 01 00 01 .Etx..E.=.......
      0050: 00 .
      [Raw read]: length = 5
      0000: 16 03 03 06 17 .....
      [Raw read]: length = 1559
      0000: 0B 00 06 13 00 06 10 00 06 0D 30 82 06 09 30 82 ..........0...0.
      0010: 03 F1 A0 03 02 01 02 02 08 08 86 A7 7C 19 C2 57 ...............W
      0020: F7 30 0D 06 09 2A 86 48 86 F7 0D 01 01 0B 05 00 .0...*.H........
      0030: 30 71 31 0B 30 09 06 03 55 04 06 13 02 44 45 31 0q1.0...U....DE1
      0040: 20 30 1E 06 03 55 04 0A 0C 17 33 36 30 20 54 72 0...U....360 Tr
      0050: 65 61 73 75 72 79 20 53 79 73 74 65 6D 73 20 41 easury Systems A
      0060: 47 31 16 30 14 06 03 55 04 0B 0C 0D 53 79 73 61 G1.0...U....Sysa
      0070: 64 6D 69 6E 20 54 65 61 6D 31 28 30 26 06 03 55 dmin Team1(0&..U
      0080: 04 03 0C 1F 49 73 73 75 69 6E 67 20 43 65 72 74 ....Issuing Cert
      0090: 69 66 69 63 61 74 69 6F 6E 20 41 75 74 68 6F 72 ification Author
      00A0: 69 74 79 30 1E 17 0D 31 37 30 37 32 35 30 37 31 ity0...170725071
      00B0: 32 31 35 5A 17 0D 31 39 30 37 32 35 30 37 31 32 215Z..1907250712
      00C0: 31 35 5A 30 81 95 31 0B 30 09 06 03 55 04 06 13 15Z0..1.0...U...
      00D0: 02 44 45 31 0F 30 0D 06 03 55 04 08 0C 06 48 65 .DE1.0...U....He
      00E0: 73 73 65 6E 31 1A 30 18 06 03 55 04 07 0C 11 46 ssen1.0...U....F
      00F0: 72 61 6E 6B 66 75 72 74 20 61 6D 20 4D 61 69 6E rankfurt am Main
      0100: 31 20 30 1E 06 03 55 04 0A 0C 17 33 36 30 20 54 1 0...U....360 T
      0110: 72 65 61 73 75 72 79 20 53 79 73 74 65 6D 73 20 reasury Systems
      0120: 41 47 31 16 30 14 06 03 55 04 0B 0C 0D 53 79 73 AG1.0...U....Sys
      0130: 61 64 6D 69 6E 20 54 65 61 6D 31 1F 30 1D 06 03 admin Team1.0...
      0140: 55 04 03 0C 16 33 36 30 54 20 50 72 6F 64 20 53 U....360T Prod S
      0150: 53 4C 20 45 6E 64 70 6F 69 6E 74 30 82 01 22 30 SL Endpoint0.."0
      0160: 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82 ...*.H..........
      0170: 01 0F 00 30 82 01 0A 02 82 01 01 00 BB D7 1C EE ...0............
      0180: 6B 4D F3 B8 25 8D 65 6E 92 FE 28 14 BE AA 07 BD kM..%.en..(.....
      0190: C1 96 96 74 14 29 75 EA 9E 8D 64 FF 76 A5 BB 51 ...t.)u...d.v..Q
      01A0: BC 47 F0 36 40 88 F9 8F 90 6C 98 F9 3B EA 6E 81 [email protected]..;.n.
      01B0: F2 08 EA AF 06 E1 01 5E 71 23 E7 86 E0 27 FB D5 .......^q#...'..
      01C0: E8 2F AF 08 6A F5 DF 99 2B CF E7 FC 03 34 31 6D ./..j...+....41m
      01D0: 2F BA CA 60 40 74 29 37 5A 0D A6 AC 9F 6B 54 86 /..`@t)7Z....kT.
      01E0: 59 21 05 8C 34 5D DC B0 F0 86 BB BA 93 8B 16 34 Y!..4].........4
      01F0: F6 65 51 12 E8 DE F1 7D F2 54 79 65 5F EC 41 CB .eQ......Tye_.A.
      0200: E8 9F BF 3E 34 CA A6 92 AC FE 5C 92 A7 7A 1D 52 ...>4.....\..z.R
      0210: B2 E9 82 DA CA D7 BA C4 73 85 1A 18 B9 A4 57 30 ........s.....W0
      0220: FD 77 9C AB 7C DE 5D 0B 03 78 6A 5D D2 C8 68 39 .w....]..xj]..h9
      0230: 19 F0 4E 4B C0 B1 84 D1 EE DE 9A A1 F0 4F E7 85 ..NK.........O..
      0240: 1A B5 C0 A6 C6 76 5C 31 F2 8B D6 EC DF 07 E7 05 .....v\1........
      0250: 2F 77 DC 9C 29 31 1C 01 ED 61 EE BF 1B DF BB 8C /w..)1...a......
      0260: 52 19 D6 A0 AB 77 04 FB 34 BF 76 D9 8F 55 BC C8 R....w..4.v..U..
      0270: 8E F5 46 1D 6E 2D 13 D1 B9 5E 90 91 02 03 01 00 ..F.n-...^......
      0280: 01 A3 82 01 7E 30 82 01 7A 30 0C 06 03 55 1D 13 .....0..z0...U..
      0290: 01 01 FF 04 02 30 00 30 1F 06 03 55 1D 23 04 18 .....0.0...U.#..
      02A0: 30 16 80 14 E4 4B DF C0 AA 47 AD B3 B9 4A A6 29 0....K...G...J.)
      02B0: E5 42 9C F3 3F E7 13 43 30 4C 06 08 2B 06 01 05 .B..?..C0L..+...
      02C0: 05 07 01 01 04 40 30 3E 30 3C 06 08 2B 06 01 05 .....@0>0<..+...
      02D0: 05 07 30 02 86 30 68 74 74 70 3A 2F 2F 70 6B 69 ..0..0http://pki
      02E0: 2E 33 36 30 74 2E 63 6F 6D 2F 63 65 72 74 73 2F .360t.com/certs/
      02F0: 33 36 30 74 2D 73 75 62 72 6F 6F 74 2D 63 61 2D 360t-subroot-ca-
      0300: 30 31 2E 63 65 72 30 3F 06 03 55 1D 20 04 38 30 01.cer0?..U. .80
      0310: 36 30 34 06 08 2A 82 14 82 68 01 02 04 30 28 30 604..*...h...0(0
      0320: 26 06 08 2B 06 01 05 05 07 02 01 16 1A 68 74 74 &..+.........htt
      0330: 70 3A 2F 2F 70 6B 69 2E 33 36 30 74 2E 63 6F 6D p://pki.360t.com
      0340: 2F 70 6F 6C 69 63 79 30 1D 06 03 55 1D 25 04 16 /policy0...U.%..
      0350: 30 14 06 08 2B 06 01 05 05 07 03 02 06 08 2B 06 0.............
      0360: 01 05 05 07 03 01 30 3F 06 03 55 1D 1F 04 38 30 ......0?..U...80
      0370: 36 30 34 A0 32 A0 30 86 2E 68 74 74 70 3A 2F 2F 604.2.0..http://
      0380: 70 6B 69 2E 33 36 30 74 2E 63 6F 6D 2F 63 72 6C pki.360t.com/crl
      0390: 2F 33 36 30 74 2D 73 75 62 72 6F 6F 74 2D 63 61 /360t-subroot-ca
      03A0: 2D 30 31 2E 63 72 6C 30 1D 06 03 55 1D 0E 04 16 -01.crl0...U....
      03B0: 04 14 50 6B 3A 75 C0 DE 02 2D 53 3D BF CD 09 84 ..Pk:u...-S=....
      03C0: 98 86 82 AE 30 10 30 2B 06 03 55 1D 10 04 24 30 ....0.0+..U...$0
      03D0: 22 80 0F 32 30 31 37 30 37 32 35 30 37 31 32 31 "..2017072507121
      03E0: 35 5A 81 0F 32 30 31 38 30 37 32 35 30 37 31 32 5Z..201807250712
      03F0: 31 35 5A 30 0E 06 03 55 1D 0F 01 01 FF 04 04 03 15Z0...U........
      0400: 02 07 80 30 0D 06 09 2A 86 48 86 F7 0D 01 01 0B ...0...*.H......
      0410: 05 00 03 82 02 01 00 13 50 BA 85 34 92 93 1D 22 ........P..4..."
      0420: 75 A9 FD 28 24 A7 47 17 90 0C 8B 59 05 2A F9 F0 u..($.G....Y.*..
      0430: F8 7D 99 4F 8F 75 BF D1 C4 3F E7 A7 98 CE D3 58 ...O.u...?.....X
      0440: 88 13 83 E5 EB 3E 60 4E 83 AA 80 FC 2E 7B 01 60 .....>`N.......`
      0450: 07 83 A6 C1 31 DB E1 0A C5 43 EE 27 17 08 8F 4F ....1....C.'...O
      0460: 8B AB 65 7A D7 C8 D3 AD A8 75 B7 62 E7 53 01 DC ..ez.....u.b.S..
      0470: 33 BB B7 2C 96 D5 3F 20 FC 69 FE 3D C1 5E CB 44 3..,..? .i.=.^.D
      0480: AB F8 BE 7B 99 01 79 BB 57 A4 94 D1 C5 11 04 65 ......y.W......e
      0490: 75 8D F8 F0 9F A6 2C E4 8A 51 B0 01 9D 2F DF 31 u.....,..Q.../.1
      04A0: 9A B8 8E D7 3C B4 62 76 3C DD 2A 0C 35 F2 C7 0B ....<.bv<.*.5...
      04B0: 20 D5 58 73 06 20 3C D1 6B 63 96 37 6E EA 1B 65 .Xs. <.kc.7n..e
      04C0: BF 6B 5E AB 4C CA D6 91 7E CD BC ED 84 CC B9 D9 .k^.L...........
      04D0: AB 25 80 93 28 FD 85 FE 21 8E 0F 2D 3D 22 91 05 .%..(...!..-="..
      04E0: A7 59 72 03 20 E8 D6 10 7E CF B0 34 7F 79 3B 47 .Yr. ......4.y;G
      04F0: C5 10 C1 09 EC FC 4A 3E BC 21 F0 FB 7F CF 4C C0 ......J>.!....L.
      0500: 4B 98 1B 7E 3B 06 92 51 73 F4 35 60 D8 7B 72 42 K...;..Qs.5`..rB
      0510: 87 3F BF 9D 4A 55 EB 40 24 57 F6 16 7B 4E 39 BB .?..JU.@$W...N9.
      0520: E5 61 40 C2 D9 2B A7 5B 81 09 C2 69 35 F8 A1 A2 .a@..+.[...i5...
      0530: A7 BA 67 42 7C A3 C5 E6 9E AC 3A C3 8C 6F EB 53 ..gB......:..o.S
      0540: 0A 65 39 67 64 C6 EC 7B 57 7B 9E 54 AE E4 2E A3 .e9gd...W..T....
      0550: 05 E9 0B 10 97 BF BC 47 CA F6 C7 1B 24 A6 CD D9 .......G....$...
      0560: B7 B7 6F A1 D0 31 21 F4 F7 1D E6 42 1C 53 E5 22 ..o..1!....B.S."
      0570: F6 D4 67 36 B0 0B 5C 69 7A B3 F3 31 F3 DA 48 DB ..g6..\iz..1..H.
      0580: EF 7A 1B 99 A4 AE 65 4E 5A 3D 5B 87 9D 1C A6 1A .z....eNZ=[.....
      0590: 1C 07 0D 8A 79 15 AD D1 8D 87 22 6A D2 2B D3 DC ....y....."j.+..
      05A0: 9C 55 05 FB 88 7B 91 15 ED EE 30 30 DE A6 79 B8 .U........00..y.
      05B0: E9 49 B7 AA DA CB 3C 4C 4E FE FB 44 93 F6 15 9A .I....<LN..D....
      05C0: 04 A9 18 E1 51 82 05 CE 43 4E 99 C7 14 FA 1B 8C ....Q...CN......
      05D0: F6 D8 2C 88 E7 33 98 02 4A 0E 41 C0 F5 88 6E 57 ..,..3..J.A...nW
      05E0: CF 59 F8 14 7F E0 51 DA 28 4E 39 C6 D1 0C B6 05 .Y....Q.(N9.....
      05F0: A1 72 9C 7D 68 6F E0 D5 F9 F3 0B 87 7E AF 79 EC .r..ho........y.
      0600: C1 46 68 BC CE 91 98 47 1C F8 9D 02 CF 82 27 D2 .Fh....G......'.
      0610: 64 1D FC C8 DC F2 C8 d......
      NioProcessor-2, READ: TLSv1.2 Handshake, length = 1559
      • Certificate chain
        chain [0] = [
        [
        Version: V3
        Subject: CN=360T Prod SSL Endpoint, OU=Sysadmin Team, O=360 Treasury Systems AG, L=Frankfurt am Main, ST=Hessen, C=DE
        Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun RSA public key, 2048 bits
modulus: 23712639208870547784934191030619387186574960001448184563206627792919596794770863916315542403970126901173207460879435287069014771623470331049929375045431124035167295456775590846384585558930676280801332442931483209242576237017576066124335085690849009132657890501481937293890660164877270727104316253459785959195876890654110642093619312253053142562293031483654484631881868891371699187919798922793667210760211106397007627967008550144244902921525222408109884089361945984512779871487391974953810469509555802158583127744803376858365706377038448938877003235243384520886173915777511443225158149320165300692093957485459943624849
public exponent: 65537
Validity: [From: Tue Jul 25 15:12:15 CST 2017,
To: Thu Jul 25 15:12:15 CST 2019]
Issuer: CN=Issuing Certification Authority, OU=Sysadmin Team, O=360 Treasury Systems AG, C=DE
SerialNumber: [ 0886a77c 19c257f7]

Certificate Extensions: 7
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: E4 4B DF C0 AA 47 AD B3 B9 4A A6 29 E5 42 9C F3 .K...G...J.).B..
0010: 3F E7 13 43 ?..C
]
]

[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:false
PathLen: undefined
]

[3]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
[CertificatePolicyId: [1.2.276.360.1.2.4]
[PolicyQualifierInfo: [
qualifierID: 1.3.6.1.5.5.7.2.1
qualifier: 0000: 16 1A 68 74 74 70 3A 2F 2F 70 6B 69 2E 33 36 30 ..http://pki.360
0010: 74 2E 63 6F 6D 2F 70 6F 6C 69 63 79 t.com/policy

]] ]
]

[4]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
clientAuth
serverAuth
]

[5]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
]

[6]: ObjectId: 2.5.29.16 Criticality=false
PrivateKeyUsage: [
From: Tue Jul 25 15:12:15 CST 2017, To: Wed Jul 25 15:12:15 CST 2018]

[7]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 50 6B 3A 75 C0 DE 02 2D 53 3D BF CD 09 84 98 86 Pk:u...-S=......
0010: 82 AE 30 10 ..0.
]
]

Unparseable certificate extensions: 2
[1]: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
Unparseable AuthorityInfoAccess extension due to
java.io.IOException: invalid URI name (host portion is not a valid DNS name, IPv4 address, or IPv6 address):http://pki.360t.com/certs/360t-subroot-ca-01.cer

0000: 30 3E 30 3C 06 08 2B 06 01 05 05 07 30 02 86 30 0>0<..+.....0..0
0010: 68 74 74 70 3A 2F 2F 70 6B 69 2E 33 36 30 74 2E http://pki.360t.
0020: 63 6F 6D 2F 63 65 72 74 73 2F 33 36 30 74 2D 73 com/certs/360t-s
0030: 75 62 72 6F 6F 74 2D 63 61 2D 30 31 2E 63 65 72 ubroot-ca-01.cer

[2]: ObjectId: 2.5.29.31 Criticality=false
Unparseable CRLDistributionPoints extension due to
java.io.IOException: invalid URI name (host portion is not a valid DNS name, IPv4 address, or IPv6 address):http://pki.360t.com/crl/360t-subroot-ca-01.crl

0000: 30 36 30 34 A0 32 A0 30 86 2E 68 74 74 70 3A 2F 0604.2.0..http:/
0010: 2F 70 6B 69 2E 33 36 30 74 2E 63 6F 6D 2F 63 72 /pki.360t.com/cr
0020: 6C 2F 33 36 30 74 2D 73 75 62 72 6F 6F 74 2D 63 l/360t-subroot-c
0030: 61 2D 30 31 2E 63 72 6C a-01.crl

]
Algorithm: [SHA256withRSA]
Signature:
0000: 13 50 BA 85 34 92 93 1D 22 75 A9 FD 28 24 A7 47 .P..4..."u..($.G
0010: 17 90 0C 8B 59 05 2A F9 F0 F8 7D 99 4F 8F 75 BF ....Y.*.....O.u.
0020: D1 C4 3F E7 A7 98 CE D3 58 88 13 83 E5 EB 3E 60 ..?.....X.....>`
0030: 4E 83 AA 80 FC 2E 7B 01 60 07 83 A6 C1 31 DB E1 N.......`....1..
0040: 0A C5 43 EE 27 17 08 8F 4F 8B AB 65 7A D7 C8 D3 ..C.'...O..ez...
0050: AD A8 75 B7 62 E7 53 01 DC 33 BB B7 2C 96 D5 3F ..u.b.S..3..,..?
0060: 20 FC 69 FE 3D C1 5E CB 44 AB F8 BE 7B 99 01 79 .i.=.^.D......y
0070: BB 57 A4 94 D1 C5 11 04 65 75 8D F8 F0 9F A6 2C .W......eu.....,
0080: E4 8A 51 B0 01 9D 2F DF 31 9A B8 8E D7 3C B4 62 ..Q.../.1....<.b
0090: 76 3C DD 2A 0C 35 F2 C7 0B 20 D5 58 73 06 20 3C v<.*.5... .Xs. <
00A0: D1 6B 63 96 37 6E EA 1B 65 BF 6B 5E AB 4C CA D6 .kc.7n..e.k^.L..
00B0: 91 7E CD BC ED 84 CC B9 D9 AB 25 80 93 28 FD 85 ..........%..(..
00C0: FE 21 8E 0F 2D 3D 22 91 05 A7 59 72 03 20 E8 D6 .!..-="...Yr. ..
00D0: 10 7E CF B0 34 7F 79 3B 47 C5 10 C1 09 EC FC 4A ....4.y;G......J
00E0: 3E BC 21 F0 FB 7F CF 4C C0 4B 98 1B 7E 3B 06 92 >.!....L.K...;..
00F0: 51 73 F4 35 60 D8 7B 72 42 87 3F BF 9D 4A 55 EB Qs.5`..rB.?..JU.
0100: 40 24 57 F6 16 7B 4E 39 BB E5 61 40 C2 D9 2B A7 @$W...N9..a@..+.
0110: 5B 81 09 C2 69 35 F8 A1 A2 A7 BA 67 42 7C A3 C5 [...i5.....gB...
0120: E6 9E AC 3A C3 8C 6F EB 53 0A 65 39 67 64 C6 EC ...:..o.S.e9gd..
0130: 7B 57 7B 9E 54 AE E4 2E A3 05 E9 0B 10 97 BF BC .W..T...........
0140: 47 CA F6 C7 1B 24 A6 CD D9 B7 B7 6F A1 D0 31 21 G....$.....o..1!
0150: F4 F7 1D E6 42 1C 53 E5 22 F6 D4 67 36 B0 0B 5C ....B.S."..g6..\
0160: 69 7A B3 F3 31 F3 DA 48 DB EF 7A 1B 99 A4 AE 65 iz..1..H..z....e
0170: 4E 5A 3D 5B 87 9D 1C A6 1A 1C 07 0D 8A 79 15 AD NZ=[.........y..
0180: D1 8D 87 22 6A D2 2B D3 DC 9C 55 05 FB 88 7B 91 ..."j.+...U.....
0190: 15 ED EE 30 30 DE A6 79 B8 E9 49 B7 AA DA CB 3C ...00..y..I....<
01A0: 4C 4E FE FB 44 93 F6 15 9A 04 A9 18 E1 51 82 05 LN..D........Q..
01B0: CE 43 4E 99 C7 14 FA 1B 8C F6 D8 2C 88 E7 33 98 .CN........,..3.
01C0: 02 4A 0E 41 C0 F5 88 6E 57 CF 59 F8 14 7F E0 51 .J.A...nW.Y....Q
01D0: DA 28 4E 39 C6 D1 0C B6 05 A1 72 9C 7D 68 6F E0 .(N9......r..ho.
01E0: D5 F9 F3 0B 87 7E AF 79 EC C1 46 68 BC CE 91 98 .......y..Fh....
01F0: 47 1C F8 9D 02 CF 82 27 D2 64 1D FC C8 DC F2 C8 G......'.d......

]
***
NioProcessor-2, fatal error: 46: General SSLEngine problem
sun.security.validator.ValidatorException: KeyUsage does not allow key encipherment
%% Invalidated: [Session-1, TLS_RSA_WITH_AES_256_CBC_SHA256]
NioProcessor-2, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
NioProcessor-2, WRITE: TLSv1.2 Alert, length = 2
NioProcessor-2, fatal: engine already closed. Rethrowing javax.net.ssl.SSLHandshakeException: General SSLEngine problem
NioProcessor-2, called closeOutbound()
NioProcessor-2, closeOutboundInternal()
[Raw write]: length = 7
0000: 15 03 03 00 02 02 2E .......
NioProcessor-2, called closeInbound()
NioProcessor-2, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
NioProcessor-2, called closeOutbound()
NioProcessor-2, closeOutboundInternal()



 Comments   
Comment by Christoph John [ 26/Feb/19 ]

I think this is more a Java SSL problem than a QFJ problem. However, all that I found about this problem on Google suggests that the certificate needs to be generated with enabled "Key Encipherment". Your counterparty should be able to provide you with this.
If you have anything to add to this then please use the mailing list. https://sourceforge.net/projects/quickfixj/lists/quickfixj-users

Thanks,
Chris.





[QFJ-969] Thread Safety FileStore.set Created: 28/Jan/19  Updated: 28/Jan/19

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Yanick Salzmann Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: Message, QuickfixJ


 Description   

When seeking for optimizations for file sync I have come across the FileStore.set method and was wondering about its thread safety. I labelled this issue as improvement, because I am not sure if it is maybe already been taken care of somewhere else, however lets look at this method:

https://github.com/quickfix-j/quickfixj/blob/045be5c09f872b1bf7b1a8ed2904efd0030c59bd/quickfixj-core/src/main/java/quickfix/FileStore.java#L364

As you can see, at the very beginning of the function the offset inside the RandomAccessFile is taken as the message offset. The actual writing of the information happens after many more instructions, one of them even including a synchronization on a file descriptor.

According to my understanding the offset obtained on line 365 could easily be outdated by the time the message is written at line 377. Of course it is possible, that synchronization is supposed to be happening outside of the set method, however I do not see any contract enforcing this in MessageStore.set.

Should this method not be thread safe to avoid potential data inconsitencies?



 Comments   
Comment by Christoph John [ 28/Jan/19 ]

Hi Yanick Salzmann,

as far as I am aware the MessageStore.set() method is only accessed from Session.sendRaw() where it is guarded by a lock. But yeah, in theory it could happen that it is accessed concurrently. It seems like this could happen especially on shutdown. See QFJ-762.
There is another issue QFJ-552 which provides a wrapper around a MessageStore that one could use.

Cheers,
Chris.





[QFJ-968] SessionState messageQueue causing out of memory exception Created: 06/Jan/19  Updated: 11/Jan/19

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.0.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Ryan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Java 8



 Description   

The issues is based on my observation and investigation. Please correct me if I misunderstood it, thanks!

Scenario:

  • We use SocketInitiator to connect to vendor server and consume data.
  • ResendRequestChunkSize is set to 5000.
    Now assume our process is down for several hours, and 10 million messages are queued up on the vendor side. Once we get connected again, we will send about 2000 resend requests with batch size of 5000 to catch up to the latest message. In between of every two batches, vendor sends latest messages to us, which have much higher sequence number, and are added to the messageQueue in SessionState. They will not be processed until all the 10 million messages have been received by us, which means the memory will keep expanding during our "catching up" time. And this will eventually cause out of memory issue.

Proposed Solution:

Not limiting messageQueue size could be risky. My understanding is that messageQueue should only store temporary out of order messages, and if there are say 100,000 messages in it, there must be something wrong. Therefore options should be provided to discard newer messages instead of keep eating up the memory.

My proposal is to:

  1. Change LinkedHashMap to TreeMap. Even it may slow things down a little bit, O(lg n) should work fine given the size of messageQueue is normally very small. Even when it grows up, sequence number ordered entries should be beneficial.
  2. Update enqueue method to limit the size of messageQueue. If the queue is full, then add the new message and remove the entry with highest sequence number.
  3. Update dequeueMessagesUpTo method.

If you think this could work, I would be happy to submit a PR, thanks!



 Comments   
Comment by Christoph John [ 08/Jan/19 ]

I am not sure I understand fully: when you want to limit the queue size and discard messages if the queue is full, then why do you do a resend request for that many messages anyway? You could then just not do any resends (e.g. reset to seqnum 1)?

Apart from that: if you are transmitting millions of messages in a few hours then I am not sure if FIX is the right choice of protocol. I assume that some kind of volatile data is transmitted (e.g. market data) which in turn leads to the question why you need resends at all if the data is outdated in the meantime anyway.

Or did I misunderstand something?

Thanks,
Chris.

Comment by Ryan [ 09/Jan/19 ]

Hi Chris - Thank you for the reply! Let me try to give more details.

1. The reason we want to persist these messages is for future analysis. Normally the system works perfectly fine, but we want to handle the rarely happened situation where there is an issue and the system is down in the middle of the day. When that happens, we do need to send resend requests to catch up the outdated data.

2. My understanding is that there are two queues involved:

  • eventQueue in Session which is a bounded blocking queue
  • messageQueue in SessionState which is a map and not bounded

Every message has to go through the eventQueue, but only messages with higher seqNum will be put into messageQueue. Let's assume the batch size is 20 and consider the following event sequence:

  • initiator -> acceptor: expect 501, but seeing 10000, request resending of 501-520
  • acceptor -> initiator: resend 501-520, done
  • acceptor -> initiator: new messages 10001, 10002, 10003
  • initiator -> acceptor: request resending of 521-540
  • acceptor -> initiator: resend 521-540, done
  • acceptor -> initiator: new messages 10004, 10005
    ...

In the given sequence, messages 501-540 will be handled correctly, but 10001-10005 will be added to messageQueue and will not be touched until all messages 501-10000 have been requested and processed.

My proposal is to limit the size of the messageQueue (the map) to prevent the unbounded growing. For example if we set the limit to 4 messages, then the message 10005 and later messages will not be added to the messageQueue. When the initiator finishes handling messages 501-10004, it will expect 10005, but since it's discarded, initiator will try to request messages from 10005 to 10024 and move on.

This scenario will happen only when both of the following conditions are satisfied:

  • resend batch size is set.
  • new messages are coming in when the acceptor resends the messages.

Hope this better explained the scenario.

Thanks,
Ryan

Comment by Ryan [ 09/Jan/19 ]

BTW this is not a blocking issue for us, just want to report what we've observed during the development.

Comment by Christoph John [ 11/Jan/19 ]

Hi Ryan,

after thinking a little more about it I think it should work the way you said, i.e. if we limited the size of the queued messages QFJ will request them anyway as soon as it has dequeued all messages.

I have the following questions:
1. Why should this only be active when resend batch size is set? IMHO it could also happen that new messages are interleaved with resent messages. But of course that depends on how the counterparty has implemented their resend processing.
2. Why do you want to change the LinkedHashMap to TreeMap? Just because of the size limitation? Wouldn't a simple check if the allowed size has been reached (and then not queueing the message) be sufficient?
3. In the description you said "If the queue is full, then add the new message and remove the entry with highest sequence number." Why? I thought the idea was to not add the message?

Thanks,
Chris.

Comment by Christoph John [ 11/Jan/19 ]

Of course it will lead to massive number of messages since messages will be re-requested multiple times if the counterparty already sent them and we re-request them because we did not put them to the queue.

Comment by Ryan [ 11/Jan/19 ]

Hi Chris,

Let me pull the example sequence from above and try to explain my understanding:

  • initiator -> acceptor: expect 501, but seeing 10000, request resending of 501-520
  • acceptor -> initiator: resend 501-520, done
  • acceptor -> initiator: new messages 10001, 10002, 10003
  • initiator -> acceptor: request resending of 521-540
  • acceptor -> initiator: resend 521-540, done
  • acceptor -> initiator: new messages 10004, 10005
  • ...
    1. Totally agree that the limit can and should be applied for both batch and non-batch. Normally non-batch request won't cause this problem because of the acceptor logic. Let's take the same example, instead of using a batch of 20, if we send the resend request as 501-infinity, then messages 501-10000 will be added to the acceptor's send buffer. Now if new messages 10001-10005 appears on the acceptor side, they will only be appended to the end of the buffer, which means initiator will not see them until 501-10000 are received and processed. But if the acceptor takes another strategy of handling resend request, then non-batch may hit the same memory expanding problem. So I think you are right that we should limit the size of messageQueue in all cases.
    2 & 3. Generally speaking, we care more about the message sequence (MsgSeqNum) but not the insertion sequence. More specifically, let's assume the messageQueue is full with messages 10001-10004, and there is a temporary out of order message 542 coming in. Since we care more about 542 but not 10004 at this time, evicting 10004 would be the only option if we want to keep 542 and not expanding the queue size. By this way the TreeMap messageQueue will still work even after it's full.
    4. If the size limit is to be added, it should definitely be configurable so that user can choose between memory expanding and massive resend requests.

Thanks,
Ryan





[QFJ-967] FileStoreMaxCachedMsgs incorrect in documentation Created: 06/Dec/18  Updated: 07/Dec/18  Resolved: 07/Dec/18

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

Type: Bug Priority: Default
Reporter: mark zeldis Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

In https://www.quickfixj.org/usermanual/2.0.0/usage/configuration.html

It says the default for FileStoreMaxCachedMsgs is 10k. I believe that this isn't true. It's Integer.MAX_VALUE.



 Comments   
Comment by Christoph John [ 07/Dec/18 ]

Hi,

why do you think it is Integer.MAX_VALUE? Here are the relevant sections of code:

Here the FileStore is initialized with a default of maxCachedMsgs = 10000 :
https://github.com/quickfix-j/quickfixj/blob/045be5c09f872b1bf7b1a8ed2904efd0030c59bd/quickfixj-core/src/main/java/quickfix/FileStoreFactory.java#L67

Here is the code in FileStore where the messageIndex is kept at the size of maxCachedMsg:
https://github.com/quickfix-j/quickfixj/blob/045be5c09f872b1bf7b1a8ed2904efd0030c59bd/quickfixj-core/src/main/java/quickfix/FileStore.java#L192

Cheers,
Chris.





[QFJ-966] Initiator Logout does not appear in QFJ log file on connection reset Created: 03/Dec/18  Updated: 03/Dec/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Daniel Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: fromAdmin, initiator, logout
Environment:

linux



 Description   

I think this is an old issue, but still seems to be a problem with the latest version of quickfixj 2.1.0.

After my initiator sends a Logon message, the acceptor immediately sends back a Logout Message followed by closing the connection. Looking at the tcpdump, it is clear why the connection is closed

x.x.x.x.56988 > x.x.x.x.25265: Flags [P.], cksum 0x9863 (incorrect -> 0xe431), seq 1:104, ack 1, win 21, length 103
E.....@[email protected].(.7.>..+P....c..8=FIX.4.2.9=81.35=A.34=1161.49=XXX.52=20181130-15:08:36.259.56=**.98=0.108=10.554=**.10=026.
15:08:36.336321 IP (tos 0x60, ttl 48, id 0, offset 0, flags [DF], proto TCP (6), length 188)
x.x.x.x.x > x.x.x.x.56988: Flags [P.], cksum 0xdd5d (correct), seq 1:149, ack 104, win 4096, length 148
E`[email protected]...>..+(.8YP....]..8=FIX.4.2.9=0124.35=5.34=552397.49=XXX.52=20181130-15:08:36.298.56=XXX.789=469881.58=MsgSeqNum too low, expecting 469881 but received 1161.10=079.

The problem is that fromAdmin is never called before onLogout because of the connection reset following the logout message. IE: it is not in the QFJ log file but I can see it in the tcp dump.

The initiator stack trace (ie connection reset) looks like

"..."
"\tat quickfix.Session.disconnect(Session.java:2028)"
"\tat quickfix.mina.AbstractIoHandler.exceptionCaught(AbstractIoHandler.java:84)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.exceptionCaught(DefaultIoFilterChain.java:828)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextExceptionCaught(DefaultIoFilterChain.java:590)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1100(DefaultIoFilterChain.java:48)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.exceptionCaught(DefaultIoFilterChain.java:937)"
"\tat org.apache.mina.core.filterchain.IoFilterAdapter.exceptionCaught(IoFilterAdapter.java:102)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextExceptionCaught(DefaultIoFilterChain.java:590)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1100(DefaultIoFilterChain.java:48)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.exceptionCaught(DefaultIoFilterChain.java:937)"
"\tat org.apache.mina.core.filterchain.IoFilterAdapter.exceptionCaught(IoFilterAdapter.java:102)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextExceptionCaught(DefaultIoFilterChain.java:590)"
"\tat org.apache.mina.core.filterchain.DefaultIoFilterChain.fireExceptionCaught(DefaultIoFilterChain.java:580)"
"\tat org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:729)"
"\tat org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:659)"
"\tat org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:648)"
"\tat org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:68)"
"\tat org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1120)"
"\tat org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)"
"\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)"
"\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)"
"\tat java.base/java.lang.Thread.run(Thread.java:844)"

and all I receive on the initiator side is

"Initiated logon request"
"Disconnecting: Socket exception (/x.x.x.x:25265): java.io.IOException: Connection reset by peer"
"onLogout: FIX.4.2:XXX->XXX"

message from Christoph John

So this seems to be a special case that is not covered by the unit test.
The problem is that the session is disconnected the "hard way" through the IOException, not waiting for messages to be processed that might still be in flight. This might have to be changed in the AbstractIoHandler to behave similar to the sessionClosed() callback.

But this is only a first quick analysis. Of course this has to be made reproducable in a unit test and then fixed.






[QFJ-965] Regression when using non-default charset Created: 22/Nov/18  Updated: 11/Jan/19  Resolved: 24/Nov/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: 2.1.1

Type: Bug Priority: Default
Reporter: amichair Assignee: amichair
Resolution: Fixed Votes: 0
Labels: None


 Description   

The optimizations in commit 6229d0722d8c6f6e7b2b251772a92caf2f4bdc25 cause a regression where using fields with a non-default charset such as UTF-8 causes message corruption (even if the charset is properly set via CharsetSupport.setCharset()).

Further, the test that caught this regression (MessageTest.testMessageWithEncodedField via its helper method) was modified in the same commit to work around the test failure, so that the test passes but the bug still occurs in real applications..

I will submit a PR shortly with a fix.



 Comments   
Comment by Christoph John [ 22/Nov/18 ]

Hi amichair

good catch. I did not spot this when working on the original commit :-/

Do you think that this is the same issue as QFJ-956?

Thanks
Chris.

Comment by amichair [ 22/Nov/18 ]

I'm not sure I understand what the issue in QFJ-956 is exactly, it sounds like it might be a general issue of how to configure the charset the same as the counter-party. I don't see an immediate connection to the code that was fixed here, but maybe I misunderstood what the reporter there meant.

Comment by amichair [ 23/Nov/18 ]

For reference, here is the PR.





[QFJ-964] SessionSettings gets cleared intermittently Created: 21/Nov/18  Updated: 11/Jan/19  Resolved: 24/Nov/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.0.0, 2.1.0
Fix Version/s: 2.1.1

Type: Bug Priority: Default
Reporter: Alex Wibowo Assignee: Alex Wibowo
Resolution: Fixed Votes: 0
Labels: None


 Description   

We have been using DynamicAcceptorSessionProvider in our project for quite sometime now, together with ThreadedSocketAcceptor.
After a recent upgrade to Quickfix 2.1.0 (from 1.5.3), we saw some errors that I believe is caused by Quickfix being unable to find the session settings.
The stack trace looks like below:


2018-11-19 00:01:13,236|| ERROR |||| org.quickfixj.QFJException: quickfix.ConfigError: Missing ConnectionType | NioProcessor-23 | q.m.a.AcceptorIoHandler
org.quickfixj.QFJException: quickfix.ConfigError: Missing ConnectionType
at quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:153) ~[quickfixj-core-2.1.0.jar:2.1.0]
at quickfix.mina.acceptor.AcceptorIoHandler.findQFSession(AcceptorIoHandler.java:118) ~[quickfixj-core-2.1.0.jar:2.1.0]
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:129) ~[quickfixj-core-2.1.0.jar:2.1.0]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:997) ~[mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:437) [mina-core-2.0.19.jar:?]
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:256) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:121) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:634) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231) [mina-core-2.0.19.jar:?]
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) [mina-core-2.0.19.jar:?]
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64) [mina-core-2.0.19.jar:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0-zing_18.06.0.0]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0-zing_18.06.0.0]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0-zing_18.06.0.0]
Caused by: quickfix.ConfigError: Missing ConnectionType
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:102) ~[quickfixj-core-2.1.0.jar:2.1.0]

I find this very strange, as we definitely have the session configuration, and the session configuration specifies the 'ConnectionType' (which is an 'acceptor').



 Comments   
Comment by Alex Wibowo [ 21/Nov/18 ]

Here is another variant of the failure. But I think the underlying cause is the same:

org.quickfixj.QFJException: quickfix.ConfigError: Session not found
          at quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:153) ~[quickfixj-core-2.1.0.jar:2.1.0]
          at quickfix.mina.acceptor.AcceptorIoHandler.findQFSession(AcceptorIoHandler.java:118) ~[quickfixj-core-2.1.0.jar:2.1.0]
          at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:129) ~[quickfixj-core-2.1.0.jar:2.1.0]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:997) ~[mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
          at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:437) [mina-core-2.0.19.jar:?]
          at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:256) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:121) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:634) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231) [mina-core-2.0.19.jar:?]
          at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) [mina-core-2.0.19.jar:?]
          at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64) [mina-core-2.0.19.jar:?]
          at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_172]
          at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_172]
          at java.lang.Thread.run(Thread.java:748) [?:1.8.0_172]
Caused by: quickfix.ConfigError: Session not found
          at quickfix.SessionSettings.getSessionProperties(SessionSettings.java:165) ~[quickfixj-core-2.1.0.jar:2.1.0]
          at quickfix.SessionSettings.getSessionProperties(SessionSettings.java:186) ~[quickfixj-core-2.1.0.jar:2.1.0]
          at quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:140) ~[quickfixj-core-2.1.0.jar:2.1.0]
          ... 24 more
Comment by Alex Wibowo [ 21/Nov/18 ]

I probably should also mention how the session settings look like.
Roughly, it is like below (configured in Spring xml):

<bean id="quickfixConfiguration" class="com.foobar.quickfix.QuickfixjConfiguration">
    <property name="defaultSettings">
        <util:map>
            <!-- Custom Properties -->
            <entry key="ResourceName" value="dapi"/>
            <entry key="AsynchronousLogging" value="N"/>
            <entry key="AsynchronousLoggerMaxPoolSize" value="1"/>
            <entry key="AsynchronousLoggerQueueCapacity" value="100"/>
            <entry key="AsynchronousLoggerThreadNamePrefix" value="QuickfixAsynchronousFileLogger-"/>
            <!-- End of custom properties -->

            <entry key="TimeZone" value="UTC"/>
            <entry key="StartDay" value="Sunday"/>
            <entry key="StartTime" value="7:00:00"/>
            <entry key="EndDay" value="Friday"/>
            <entry key="EndTime" value="17:00:00"/>
            <entry key="NonStopSession" value="N"/>
            <entry key="ConnectionType" value="acceptor"/>
            <entry key="HeartBtInt" value="30"/>
            <entry key="UseDataDictionary" value="Y"/>
            <entry key="ThreadModel" value="ThreadPerSession"/>
            <entry key="UseJmx" value="Y"/>
            <entry key="FileStorePath" value="/home/wibowoa/var/lib/myApp"/>
            <entry key="FileLogPath" value="logs/fixlog"/>
            <entry key="FileIncludeTimeStampForMessages" value="Y"/>
            <entry key="FileIncludeMilliseconds" value="Y"/>
            <entry key="CheckLatency" value="Y"/>
            <entry key="BeginString" value="FIX.4.2"/>
            <entry key="AcceptorTemplate" value="Y"/>
            <entry key="TargetCompID" value="*"/>
        </util:map>
    </property>
    <property name="sessionSettings">
        <util:map>
            <entry key="FIX.4.2:FOOBAR_PRICING->*">
                <util:map>
                    <entry key="PersistMessages" value="N"/>
                    <entry key="SocketAcceptPort" value="7565"/>
                    <entry key="DataDictionary" value="fix/FIX42-PRICING-2.4.xml"/>
                    <entry key="ResetOnLogon" value="Y"/>
                    <entry key="MaxLatency" value="120"/>
                </util:map>
            </entry>
            <entry key="FIX.4.2:FOOBAR_TRADING->*">
                <util:map>
                    <entry key="PersistMessages" value="Y"/>
                    <entry key="SocketAcceptPort" value="7566"/>
                    <entry key="DataDictionary" value="fix/FIX42-TRADING-2.4.xml"/>
                    <entry key="ResetOnLogon" value="N"/>
                    <entry key="MaxLatency" value="1"/>
                </util:map>
            </entry>
        </util:map>
    </property>
</bean>

then this gets loaded into SessionSettings:

public final class QuickfixjConfiguration {
    private Map<Object, Object> defaultSettings;
    private Map<SessionID, Map<Object, Object>> sessionSettings;


    public void setDefaultSettings(final Map<Object, Object> defaultSettings) {
        this.defaultSettings = defaultSettings;
    }

    public Map<SessionID, Map<Object, Object>> getSessionSettings() {
        return sessionSettings;
    }

    public void setSessionSettings(final Map<SessionID, Map<Object, Object>> sessionSettings) {
        this.sessionSettings = sessionSettings;
    }

    public SessionSettings createSessionSettings() throws ConfigError {
        final SessionSettings settings = new SessionSettings();
        if(defaultSettings != null && !defaultSettings.isEmpty()) {
            settings.set(new Dictionary(null, defaultSettings));
        }
        if(sessionSettings != null && !sessionSettings.isEmpty()) {
            for (Map.Entry<SessionID, Map<Object, Object>> sessionSetting : sessionSettings.entrySet()) {
                settings.set(sessionSetting.getKey(), new Dictionary("session", sessionSetting.getValue()));
            }
        }
        return settings;
    }

}
...
QuickfixJConfiguration foobar =... (injected as spring)
SessionSettings settings = foobar.createSessionSettings();

  final MessageFactory messageFactory = new DefaultMessageFactory();
        final LogFactory logFactory = ...
        final MessageStoreFactory messageStoreFactory = new CustomFileStoreFactory(settings);
final Acceptor acceptor =  new ThreadedSocketAcceptor(application, messageStoreFactory, settings, logFactory, messageFactory);

  for (final SessionID sessionID : (Iterable<SessionID>)(settings::sectionIterator)) {
                 final int acceptPort = (int) settings.getLong(sessionID, Acceptor.SETTING_SOCKET_ACCEPT_PORT);
                 if (settings.getBool(sessionID, Acceptor.SETTING_ACCEPTOR_TEMPLATE)) {
                                            final AcceptorSessionProvider dynamicAcceptorSessionProvider = new DynamicAcceptorSessionProvider(settings, sessionID, application, messageStoreFactory, logFactory, messageFactory);
                                            acceptor.setSessionProvider(new InetSocketAddress(acceptPort), dynamicAcceptorSessionProvider);
                   }
}

Comment by Alex Wibowo [ 21/Nov/18 ]

PR for this issue is here: https://github.com/quickfix-j/quickfixj/pull/216





[QFJ-963] ConcurrentModificationException when using DynamicAcceptorSessionProvider Created: 19/Nov/18  Updated: 11/Jan/19  Resolved: 24/Nov/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: 2.1.1

Type: Bug Priority: Default
Reporter: Alex Wibowo Assignee: Alex Wibowo
Resolution: Fixed Votes: 0
Labels: None


 Description   

We have recently upgraded from quickfixj 1.5.3 to 2.1.0, and saw the following error:

java.util.ConcurrentModificationException: null
        at java.util.HashMap$HashIterator.nextNode(HashMap.java:1442) ~[?:1.8.0-zing_18.06.0.0]
        at java.util.HashMap$KeyIterator.next(HashMap.java:1466) ~[?:1.8.0-zing_18.06.0.0]
        at java.util.AbstractCollection.finishToArray(AbstractCollection.java:232) ~[?:1.8.0-zing_18.06.0.0]
        at java.util.AbstractCollection.toArray(AbstractCollection.java:143) ~[?:1.8.0-zing_18.06.0.0]
        at java.util.ArrayList.<init>(ArrayList.java:178) ~[?:1.8.0-zing_18.06.0.0]
        at quickfix.mina.SessionConnector.getSessions(SessionConnector.java:160) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at org.quickfixj.jmx.mbean.connector.ConnectorAdmin.registerSessions(ConnectorAdmin.java:178) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at org.quickfixj.jmx.mbean.connector.ConnectorAdmin.lambda$postRegister$0(ConnectorAdmin.java:170) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) ~[?:1.8.0-zing_18.06.0.0]
        at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327) ~[?:1.8.0-zing_18.06.0.0]
        at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263) ~[?:1.8.0-zing_18.06.0.0]
        at quickfix.mina.SessionConnector.addDynamicSession(SessionConnector.java:166) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at quickfix.mina.acceptor.DynamicAcceptorSessionProvider.getSession(DynamicAcceptorSessionProvider.java:150) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at com.anz.axle.direct.connectafix.quickfix.QuickfixAcceptor$1.getSession(QuickfixAcceptor.java:107) ~[spdee-direct-connectafix-4.1798.jar:?]
        at quickfix.mina.acceptor.AcceptorIoHandler.findQFSession(AcceptorIoHandler.java:118) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:129) ~[quickfixj-core-2.1.0.jar:2.1.0]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:997) ~[mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
        at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flush(ProtocolCodecFilter.java:437) [mina-core-2.0.19.jar:?]
        at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:256) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:1114) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:121) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:641) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:634) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:539) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$1200(AbstractPollingIoProcessor.java:68) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1242) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.process(AbstractPollingIoProcessor.java:1231) [mina-core-2.0.19.jar:?]
        at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:683) [mina-core-2.0.19.jar:?]
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64) [mina-core-2.0.19.jar:?]

which seems like a bug in quickfixj itself. Looking at how the map inside SessionConnector get set... it looks like it is just a HashMap from AbstractSocketAcceptor#createSessions().
Shouldnt it use a concurrent map instead?



 Comments   
Comment by Christoph John [ 19/Nov/18 ]

Hi Alex Wibowo,

how often does this occur? Every time when adding a Session? Or only from time to time?
I am not sure if the problem is caused by the intermediate call to ConnectorAdmin.registerSessions().

Cheers,
Chris.

Comment by Alex Wibowo [ 19/Nov/18 ]

Not that often. I think we've seen it only today after we upgraded to 2.1.0

Comment by Christoph John [ 19/Nov/18 ]

Hmkay, best would be if we had a reproducer. Just tried to reproduce it but didn't have any luck yet.

Comment by Christoph John [ 19/Nov/18 ]

I mean there are of course ways around the CME but first I'd like to reproduce it to be on the safe side.

Comment by Alex Wibowo [ 19/Nov/18 ]

Apology for asking the obvious... but you tried establishing with more than 1 session, yeah? I was able to reproduce it using 50 connections just now..

Comment by Christoph John [ 19/Nov/18 ]

Yeah, more than 1 but not 50.

Comment by Christoph John [ 19/Nov/18 ]

Tried to reproduce using two threads and creating 1000 sessions concurrently but to no avail. Seems like I'm missing something specific to your configuration...





[QFJ-962] FieldMap.setField(int key, Field<?> field) does not properly convert values Created: 15/Nov/18  Updated: 15/Jun/20

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: 3.0.0

Type: Bug Priority: Default
Reporter: amichair Assignee: Wojciech Zankowski
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-428 FieldMap.setField(int key, Field<?> f... Closed

 Description   

QFJ-428 made the generic setField(int key, Field<?> field) method public, claiming this will avoid having to use a switch statement and call each type-specific overload explicitly.

However, this is misleading and introduces a bug, since the two are not equivalent.

Specifically, the type-specific overloads do proper type conversions on the value, while the generic setField does not. For example, if you pass a DoubleField with a very large or small value, it will convert it into a string in scientific notation (with exponent) which is invalid in the FIX protocol, whereas calling the type-specific setField(DoubleField field) will properly use the DoubleConverter to convert it correctly.

When this method was non-public this was less of a problem, assuming its internal usages are correct (I don't know if this is the case, but assume it is). However making it public now creates a pitfall for anyone using this method in client code which will likely result in a bug on some data.

The solution would be to either implement it fully with proper type conversion (e.g. using the switch statement from QFJ-428), or at the very least, to add a javadoc to this method that warns about using it and clearly states that it does not do proper type conversion, so users will be able to decide whether this is what they really intend to do or not.



 Comments   
Comment by Christoph John [ 16/Nov/18 ]

Hi amichair,

maybe we should add the javadoc comment as you suggested and provide an additional method, say setFieldConverted(int key, Field<?> field) , so users can choose which method suits them best.

Cheers,
Chris.

Comment by Christoph John [ 16/Nov/18 ]

Briefly had a look at this. What about making Field abstract (According to a comment in the class it is only non-abstract to have JNI compatibility. But that was like 10 years ago.) and adding an abstract convertToString() method that does the necessary conversion in the subclasses? Example for BooleanField:

    @Override
    public String convertToString() {
        return BooleanConverter.convert(getValue());
    }

Then we can call in FieldMap:

    public void setField(int key, Field<?> field) {
        setString(key, field.convertToString());
    }

That way we can ensure that we always have a conversion method for a field and don't need a lengthy if-else statement.

What do you think?

Comment by amichair [ 22/Nov/18 ]

Encapsulating the converters inside the Field classes sounds like a good idea regardless of this issue or of Field being abstract

I have't delved into this one yet, but perhaps instead of convertToString, maybe toString itself should just do this properly?

Comment by Wojciech Zankowski [ 29/Jul/19 ]

Pull request created with implementation of the idea: https://github.com/quickfix-j/quickfixj/pull/226





[QFJ-961] Constructors for UtcDate/Time fields should return date in UTC Created: 12/Nov/18  Updated: 11/Jan/19  Resolved: 13/Nov/18

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

Type: Bug Priority: Minor
Reporter: Julia Ilyutovich Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

TransactTime (tag 60) should be in UTC. Default constructor for TransactTime() should return date in UTC. Instead, it uses default local time (LocalDateTime.now()):

public UtcTimeStampField(int field)

{ super(field, LocalDateTime.now()); }

As a result, the constructed object is not in UTC.



 Comments   
Comment by Christoph John [ 12/Nov/18 ]

Just saw that other constructors in the same class are also affected.

Comment by Christoph John [ 12/Nov/18 ]

And also other fields like UtcTimeField... :-/





[QFJ-960] Watermarks should not be activated when neither queue size nor watermarks are configured Created: 10/Nov/18  Updated: 11/Jan/19  Resolved: 12/Nov/18

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

Type: Bug Priority: Major
Reporter: Mr. Bald Assignee: Mr. Bald
Resolution: Fixed Votes: 0
Labels: None


 Description   

When creating an initiator or an acceptor (both synchronous and thread-per-session) without specifying either queue size or watermarks, the watermark tracker is still created and is working incorrectly immediately blocking the reads (queue size 0 is > upper watermark of -1).

Watermarks should only be activated when the queue size is not specified and both lower and upper watermarks are configured to values > 0.

Pull request (code change + tests) - https://github.com/quickfix-j/quickfixj/pull/213



 Comments   
Comment by Mr. Bald [ 10/Nov/18 ]

Christoph John - could you please check if it can be included into 2.2.0?

Comment by Christoph John [ 10/Nov/18 ]

Hi Mr. Bald,

thanks for the PR.
Just to understand the problem: this can only happen when using the Builder (and forgetting to set a watermark size) or when I pass 0 as watermark size into the constructor of the connector, right?

I am maybe considering releasing a 2.1.1 with this fix and the one from https://github.com/quickfix-j/quickfixj/pull/211 (QFJ-953).

Cheers,
Chris.

Comment by Mr. Bald [ 11/Nov/18 ]

Christoph John - correct, it happens when you either pass 0/-1. But also when you specify neither a queue nor watermarks (which must have been a valid use case before the watermarks introduction, which I broke it with the original watermarks change). Basically everything causing `EventHandlingStrategy(xxx, -1, -1)` or `EventHandlingStrategy(null, 0, 0)`. 2.1.1 - even better.





[QFJ-959] Fix session could stuck forever in acceptor mode. Created: 07/Nov/18  Updated: 16/Nov/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Dmitry Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Repetitive error: Multiple logons/connections for this session are not allowed
when client try to reconnect to server. (see server logs below)

Looks like session was not cleared correctly after exception.
Exception

Nov  6 06:47:32 aemulator: java.io.IOException: Broken pipe
Nov  6 06:47:32 aemulator: at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
Nov  6 06:47:32 aemulator: at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
Nov  6 06:47:32 aemulator: at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
Nov  6 06:47:32 aemulator: at sun.nio.ch.IOUtil.write(IOUtil.java:65)
Nov  6 06:47:32 aemulator: at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
Nov  6 06:47:32 aemulator: at org.apache.mina.transport.socket.nio.NioProcessor.write(NioProcessor.java:384)
Nov  6 06:47:32 aemulator: at org.apache.mina.transport.socket.nio.NioProcessor.write(NioProcessor.java:47)
Nov  6 06:47:32 aemulator: at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.writeBuffer(AbstractPollingIoProcessor.java:1107)
Nov  6 06:47:32 aemulator: at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.flushNow(AbstractPollingIoProcessor.java:994)
Nov  6 06:47:32 aemulator: at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.flush(AbstractPollingIoProcessor.java:921)
Nov  6 06:47:32 aemulator: at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:688)
Nov  6 06:47:32 aemulator: at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
Nov  6 06:47:32 aemulator: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
Nov  6 06:47:32 aemulator: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
Nov  6 06:47:32 aemulator: at java.lang.Thread.run(Thread.java:748)

Server logs.

2018-11-07 13:06:56.731 +0000 ERROR [NioProcessor-471] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:06:57.736 +0000 ERROR [NioProcessor-472] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:06:58.740 +0000 ERROR [NioProcessor-473] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:06:59.780 +0000 ERROR [NioProcessor-474] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:07:01.446 +0000 ERROR [NioProcessor-475] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:07:03.446 +0000 ERROR [NioProcessor-476] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:07:05.446 +0000 ERROR [NioProcessor-477] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed
2018-11-07 13:07:07.446 +0000 ERROR [NioProcessor-478] quickfixj.errorEventFIX.4.4:emulator->TRADE:  - Multiple logons/connections for this session are not allowed


 Comments   
Comment by Christoph John [ 07/Nov/18 ]

Hi,

is the pasted stack trace complete? I can not gather much from it. There should also be log entries from QFJ along with the IOException. Can you post them?

I have never seen this behaviour before. Is it reproducible? Did it stop at some time or did it keep running like that?
When an exception occurs, the exceptionCaught() callback from the AbstractIoHandler should get notified and close the session.
Where are you running the QFJ session? Is it a plain Java process or are you running it inside an application server or Spring application?

Thanks,
Chris.

Comment by Christoph John [ 07/Nov/18 ]

And of course as always: would be better to first ask on the mailing list. We can clarify there if it really is a bug.

Comment by Dmitry [ 08/Nov/18 ]

Hi,

is the pasted stack trace complete? I can not gather much from it. There should also be log entries from QFJ along with the IOException. Can you post them?

We do not see another exceptions in log.

I have never seen this behaviour before. Is it reproducible? Did it stop at some time or did it keep running like that?

When an exception occurs, the exceptionCaught() callback from the AbstractIoHandler should get notified and close the session.

Where are you running the QFJ session? Is it a plain Java process or are you running it inside an application server or Spring application?

  • Reproducible from time to time.
  • This is Java plain application which use Spring Core inside.

I believe we found the way how to achieve this behavior. It is definitely not an expected working behavior, but as a result, quickfix could be stuck in some wrong state forever.

From time to time we have an issue with our HyperV cloud. Virtual machine is frozen for ~30-40 seconds. (it is testing environment)
During this time quickfix client tries to reconnect and send logon message.
When VM becomes alive, application throws an exception for TCP session and then try to handle new connection from client and process several logon messages for the same quickfix session.

Probably qfSession.hasResponder() keeps wrong state forever due to exception in Session.disconnect

  public void disconnect(String reason, boolean logError) throws IOException {
        try {
            final boolean logonReceived = state.isLogonReceived();
            final boolean logonSent = state.isLogonSent();

            synchronized (responderLock) {
                if (!hasResponder()) {
                    if (!ENCOUNTERED_END_OF_STREAM.equals(reason)) {
                        getLog().onEvent("Already disconnected: " + reason);
                    }
                    return;
                }
                final String msg = "Disconnecting: " + reason;
                if (logError) {
                    getLog().onErrorEvent(msg);
                } else {
                    getLog().onEvent(msg);
                }
                responder.disconnect();   // Maybe exception is here 
                setResponder(null);
            }


Comment by Christoph John [ 09/Nov/18 ]

Hi,

OK, if the whole VM froze for 30 seconds all sort of things can happen.

You are right: given the log message "Multiple logons/connections for this session are not allowed" it looks like the responder was not set to null.
But good that you can reproduce it. So you could checkout the code from github, tentatively wrap parts of the disconnect() method in a try block with cleanup of the responder in a finally-block and try to reproduce again.
But I would actually expect to see QFJ classes appear in the exception stack trace if something in that method failed. That is also why I was asking if this is a plain Java process. I don't know much about Spring but assume that some parts might run differently than in a "normal" Java process. E.g. sometimes Exceptions are swallowed if thrown in threads that are running as part of a thread pool.

When you say that the Exception might occur in or after responder.disconnect() is called then you should have something in your log file like "Disconnecting: " because that happens some lines above. Do you see something like that in your log file?
Could you maybe post the contents of your event log (including exceptions) around the freeze?

Thanks,
Chris.

Comment by Dmitry [ 16/Nov/18 ]

Hi,

I am sorry for late response.
We transferred our test environment from VM to hardware server.
So, logs were lost and currently we do not have similar issues.

Dmitry.

Comment by Christoph John [ 16/Nov/18 ]

OK, feel free to update the issue when you encounter problems again.





[QFJ-958] Sticky Connection : Quickfix keep on sending test request for not connected client Created: 25/Oct/18  Updated: 25/Oct/18  Resolved: 25/Oct/18

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

Type: Bug Priority: Major
Reporter: Zeeshan Ali Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

PROD



 Description   

HI Team,

I have FIX acceptor service written over quickfix/j. We are having an issue which needs urgent resolution as it is impacting our client.

1) In general scenarios where if our acceptor service does receive heartbeat from client in an active connection it sends three consecutive test request and if it does not get response from client , it simply drop the connection which is correct.

2) The problem is if our service receive a logon message (35=A) from client with certain delay assume 9 sec and by the time we response to that logon message it cross 10 sec window. Client timeout the connection as client side timeout window is 10 sec. But for our service since we have responded back to client it assume it as active connection and keep on sending test request through out day the day until we bounce the adaptor. It also does not allow any more connection to the same server.

please help.

Example

Client sent the logon message at 20181017-06:17:29.011
Our Forwarder service received logon at : 2018-10-17T06:17:38,003
Forwarder service forward the connection to backed fixadaptor service which was received by it at 2018-10-17 07:17:41,054
backed adaptor respons back within same time : 2018-10-17 07:17:41,054

But since overall window is more than 10 sec , it is being timed out at client side.

After this backed adaptor keep on sending test request even though there is no heartbeat from client



 Comments   
Comment by Christoph John [ 25/Oct/18 ]

Please use the mailing list for help requests. Thanks.
https://sourceforge.net/projects/quickfixj/lists/quickfixj-users

Comment by Zeeshan Ali [ 25/Oct/18 ]

Send an email , also subscribed





[QFJ-957] In case of disconnect relogin is not working Created: 16/Oct/18  Updated: 17/Oct/18  Resolved: 17/Oct/18

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

Type: Bug Priority: Default
Reporter: Bhavishya Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

JAVA 8



 Description   

My application is sending logon request and getting logon response and session get logged in perfectly at first time . After some time session get disconnected due to heartbeat timeout and my application send login again and acceptor send login response within same second but my initiator don't get connected after 10 second it send another login request. Ideally it should not send login request again.

Event logs are

20181015-13:36:34: Sent test request TEST

20181015-13:37:01: Disconnecting: Timed out waiting for heartbeat

20181015-13:37:02: Initiated logon request

20181015-13:37:13: Disconnecting: Timed out waiting for logon response

20181015-13:37:32: Disconnecting: Socket exception (/192.168.40.29:31815): java.io.IOException: Connection reset by peer

20181015-13:38:02: Initiated logon request

Message logs

8=FIX.4.2^A9=69^A35=A^A34=1064^A49=test^A52=20181015-13:37:02.570^A56=test^A98=0^A108=30^A10=075^A
8=FIX.4.2^A9=000593^A35=A^A34=001527^A43=N^A52=20181015-13:37:02^A49=test^A56=test^A98=0^A108=30^A6247=prod^A6272=AMEX/OPT,CBOE/OPT,PHLX/OPT,PSE/OPT,DTB/OPT,ISE/OPT,BELFOX/OPT,GLOBEX/FOP,MONEP/OPT,SOFFEX/OPT,FTA/OPT,ASX/OPT,BOX/OPT,ECBOT/FOP,IBCX/BAG,BATS/OPT,NASDAQOM/OPT,ICEEU/OPT^A6382=S3^A6387=s3.amazonaws.com^A6386=0WWXP5X5ZAMQC93NZR82^A6492=1^A6541=1^A6530=1^A6550=1^A6560=1/Maximize Rebate,9/Prefer Rebate,11/Prefer Fill,12/Maximize Fill,2/Primary Exchange,3/Highest Volume Exchange With Rebate,4/High Volume Exchange With Lowest Fee^A6749=1/Maximize Rebate,9/Prefer Rebate,11/Prefer Fill,12/Maximize Fill^A8035=5bc41694.^A10=210^A
8=FIX.4.2^A9=69^A35=A^A34=1065^A49=test^A52=20181015-13:38:02.569^A56=test^A98=0^A108=30^A10=085^A
8=FIX.4.2^A9=000593^A35=A^A34=001528^A43=N^A52=20181015-13:38:02^A49=test^A56=test^A98=0^A108=30^A6247=prod^A6272=AMEX/OPT,CBOE/OPT,PHLX/OPT,PSE/OPT,DTB/OPT,ISE/OPT,BELFOX/OPT,GLOBEX/FOP,MONEP/OPT,SOFFEX/OPT,FTA/OPT,ASX/OPT,BOX/OPT,ECBOT/FOP,IBCX/BAG,BATS/OPT,NASDAQOM/OPT,ICEEU/OPT^A6382=S3^A6387=s3.amazonaws.com^A6386=0WWXP5X5ZAMQC93NZR82^A6492=1^A6541=1^A6530=1^A6550=1^A6560=1/Maximize Rebate,9/Prefer Rebate,11/Prefer Fill,12/Maximize Fill,2/Primary Exchange,3/Highest Volume Exchange With Rebate,4/High Volume Exchange With Lowest Fee^A6749=1/Maximize Rebate,9/Prefer Rebate,11/Prefer Fill,12/Maximize Fill^A8035=5bc41694.^A10=212^A

As you can see we send login request at 20181015-13:37:02.570 and get response at 20181015-13:37:02 then still it send one more login request.
Any help would be really appreciated

I have removed actual SendercompId and Target comp Id

I am using camel 2.14.1 and quickfixh 1.5.3. I have raised in mailing list but no reply and this is production issue so please pardon me.



 Comments   
Comment by Christoph John [ 17/Oct/18 ]

Well, asking on the mailing list is the preferred way. And it took slightly more than one hour for a reply on the mailing list.
For commercial support you could always contact one of the companies listed here: https://www.quickfixj.org/support/

One advice though: your QFJ version is rather old. Try updating first.
If you have any more questions please ask on the mailing list.

Thanks,
Chris.

Comment by Bhavishya [ 17/Oct/18 ]

I have tried upgrading on 2.0.0 but still facing same issue

Comment by Bhavishya [ 17/Oct/18 ]

It's has been more than one day but still no reply

Comment by Christoph John [ 17/Oct/18 ]

Two things:

  • your mail client does not seem to work correctly. There were replies. You can also check here: https://sourceforge.net/p/quickfixj/mailman/quickfixj-users/
  • this is an open source project so reply times may vary. If commercial support and low response times are needed you have the options listed in my first comment.




[QFJ-956] Checksum validation of incoming messages is not correct in some cases Created: 04/Oct/18  Updated: 24/Nov/18  Resolved: 24/Nov/18

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

Type: Bug Priority: Default
Reporter: Valery Fadeev Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-789 Fully support alternate encodings (ch... Open

 Description   

This code validates the checksum of incoming messages:

Message.java:

private void validateCheckSum(*String* messageData) throws InvalidMessage {
        try {
            // Body length is checked at the protocol layer
            final int checksum = trailer.getInt(CheckSum.FIELD);
            if (checksum != *MessageUtils.checksum(messageData)*) {
                // message will be ignored if checksum is wrong or missing
                throw MessageUtils.newInvalidMessageException("Expected CheckSum=" + MessageUtils.checksum(messageData)
                        + ", Received CheckSum=" + checksum + " in " + messageData, this);
            }
        } catch (final FieldNotFound e) {
            throw MessageUtils.newInvalidMessageException("Field not found: " + e.field + " in " + messageData, this);
        }
    }

And in MessageUtils calculation ends up here:

public static int checksum(*Charset charset*, String data, boolean isEntireMessage) {
        if (CharsetSupport.isStringEquivalent(charset)) { // optimization - skip charset encoding
            int sum = 0;
            int end = isEntireMessage ? data.lastIndexOf("\00110=") : -1;
            int len = end > -1 ? end + 1 : data.length();
            for (int i = 0; i < len; i++) {
                sum += data.charAt(i);
            }
            return sum & 0xFF; // better than sum % 256 since it avoids overflow issues
        }
        return checksum(*data.getBytes(charset)*, isEntireMessage);
    }

So the problem here is that calculation happens NOT on raw network bytes but on a java String that is later transformed to bytes using CharsetSuport's charset, which can be not the same what original message producer used, and produce different bytes.

So in practice this can cause to situation where message with correct checksum will be ignored because was read by QFJ using incorrect charset.

Looks like I'm witnessing this situation. Use case is to use non-unicode symbol in message and different charsets on producer-consumer sides.



 Comments   
Comment by Christoph John [ 08/Oct/18 ]

Hmm, I am not 100% sure about this but IIRC the only encoding that has to be supported by FIX is ISO-8859-1. But not sure to be honest.
Of course most FIX engines support other charsets but I guess you'll have to check with your counterparty which charset to use. I guess you already discovered how you can change the charset: https://www.quickfixj.org/usermanual/2.1.0//usage/charset.html
Double byte charsets should also work qith QFJ for some time now. But never tested it by myself.

Cheers,
Chris.

Comment by amichair [ 22/Nov/18 ]

iirc the proper way is to support encoded fields, which many engines don't (including QFJ, I believe there's an issue open for that somewhere). Treating full messages as being strings in a different charset, and setting this charset globally, is not by the spec, but it's a practical workaround that is used in several engines (including QFJ).

You have to check with your counter-party what charset/encoding they use and make sure they also apply it globally to the full messages on their side, and set it in CharsetSupport on your side, and that should work. If they do use individual encoded fields, and you find yourself contributing an implementation of it for QFJ, that would be great

btw the reason the global workaround works is because the other fields and the FIX messages themselves (tag numbers, delimiters etc.) are all in ASCII, and nearly all charset encodings are backwards-compatible with ASCII, so they remain intact during the conversions and all is well. This is true for most multibyte encodings (which use one or more bytes per character) such as UTF-8 as well. However, this is not true of double-byte charsets, since by definition they use two bytes per character whereas ASCII uses one byte per character, so the conversions will mess up the parsing of the FIX message structure.

If you search JIRA for all the older bugs that mention charsets and encodings and the ones they link to, you'll get a better picture of what works and what doesn't work and why (that's what I did at the time).

Comment by Christoph John [ 24/Nov/18 ]

Closing as duplicate of QFJ-789.





[QFJ-955] getHeader() and getTrailer() not behaving correctly Created: 27/Sep/18  Updated: 28/Sep/18  Resolved: 28/Sep/18

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

Type: Bug Priority: Default
Reporter: Simon Assignee: Christoph John
Resolution: Won't Fix Votes: 0
Labels: QuickfixJ
Environment:

Windows, JDK8


Attachments: Java Source File NewFixMessagePrinter .java     Java Source File OldFixMessagePrinter.java    

 Description   

Hi,
Don't know if this a bug or we are not using the API correctly.
But since 2.1.0 we observe strange behavior concering the checksum and bodylength field.

JUnit Test:

@Test
public void testBodyLengthAndChecksum() throws FieldNotFound

{ TradeCaptureReport tradeCaptureReport = new TradeCaptureReport(); tradeCaptureReport.set(new Instrument(new Symbol("[N/A]"))); System.out.println(tradeCaptureReport.toString()); Header header = tradeCaptureReport.getHeader(); System.out.println(header.getString(9)); Trailer trailer = tradeCaptureReport.getTrailer(); System.out.println(trailer.getString(10)); }

2.0.0 ====>>>

8=FIX.4.49=1535=AE55=[N/A]10=072
15
072

2.1.0 ====>>>

8=FIX.4.49=1535=AE55=[N/A]10=072
100
000

Any help would be much appreciated.

Greetings,
Simon.



 Comments   
Comment by Simon [ 27/Sep/18 ]

Please correct description: -behavong + behaving
Thx

Comment by Christoph John [ 27/Sep/18 ]

Thanks for including a quick test!

The calculation of length and checksum has been changed to be calculated in a StringBuffer instead of changing the Message instance every time when calling toString(). This works without problems since the result of toString() will be sent on the wire. Also you can retrieve body length and checksum when you receive a message since then the message will be parsed using Message.fromString().
See https://github.com/quickfix-j/quickfixj/pull/39 and https://github.com/quickfix-j/quickfixj/pull/42

Here is how you could retrieve body length and checksum from a message that you created:

    @Test
    public void testBodyLengthAndChecksum() throws FieldNotFound, InvalidMessage {
        TradeCaptureReport tradeCaptureReport = new TradeCaptureReport();
        tradeCaptureReport.set(new Instrument(new Symbol("[N/A]")));
        System.out.println(tradeCaptureReport.toString());
        
        Message newMessage = new Message();
        newMessage.fromString(tradeCaptureReport.toString(), null, false);
        System.out.println(newMessage.getHeader().getString(9));
        System.out.println(newMessage.getTrailer().getString(10));
        System.out.println(MessageUtils.checksum(tradeCaptureReport.toString()));
    }

This might look a little cumbersome but actually I wonder what the use case behind this is? Why do you need to know the body lenght and checksum of a message that you just created?

Cheers,
Chris.

P.S.: Please use the mailing list if unsure if it is a bug or not. Thanks

Comment by Simon [ 27/Sep/18 ]

Hi Chris,

thanks for that fast reply.

The use case is we save a pretty print version of a fix message in the database, therefore we have a "prettyPrinter" utility class that wasn't working correctly after update to 2.1.0.
I found it a while ago by googling and adapted it a bit. Attached it to issue, if anyone is interested. (the code is pretty ugly, but does the job)
Also attached the new version...

Greetings,
Simon.

Comment by Simon [ 27/Sep/18 ]

Hi Chris,

could you remove the file "FixMessagePrinter.java" ?

Thanks

Comment by Christoph John [ 28/Sep/18 ]

Done.
Will close this ticket now.

For further discussion please use the mailing list (maybe with a link to this issue).

Thanks,
Chris.

Comment by Christoph John [ 28/Sep/18 ]

P.S.: I found a slightly nicer alternative...

        System.out.println(MessageUtils.getStringField( tradeCaptureReport.toString(), 9 ));
        System.out.println(MessageUtils.getStringField( tradeCaptureReport.toString(), 10 ));




[QFJ-954] sendRaw ignores return value of set call Created: 18/Sep/18  Updated: 18/Sep/18

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

Type: Bug Priority: Default
Reporter: Philip Whitehouse Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The documentation for MessageStore.set() says:

     * @return true is successful, false otherwise
     * @throws IOException IO error

However the return code is pointless. set is called by SessionState.set which is in turned called by Session.sendRaw, which does the following:

            if (num == 0) {
                final int msgSeqNum = header.getInt(MsgSeqNum.FIELD);
                if (persistMessages) {
                    state.set(msgSeqNum, messageString);
                }
                state.incrNextSenderMsgSeqNum();
            }
            return result;

So the return code is just pointless.

Throwing an exception on the other hand, does cause the return value of sendRaw (and hence Session.send to change.

Perhaps if it returns false Session.sendRaw should return false. (We may still want to call incrNextSenderMsgSeqNum however.)



 Comments   
Comment by Christoph John [ 18/Sep/18 ]

Hi Philip Whitehouse,

I am not entirely sure but I might be that the return code is a relict from the C++ implementation.
... digging through the code ...

Here is the comment of the Session.send() method:

   /**
     * Send a message to a counterparty. Sequence numbers and information about the sender
     * and target identification will be added automatically (or overwritten if that
     * information already is present).
     *
     * The returned status flag is included for
     * compatibility with the JNI API but it's usefulness is questionable.
     * In QuickFIX/J, the message is transmitted using asynchronous network I/O so the boolean
     * only indicates the message was successfully queued for transmission. An error could still
     * occur before the message data is actually sent.
     *
     * @param message the message to send
     * @return a status flag indicating whether the write to the network layer was successful.
     */

I think I already analyzed this some time ago. What I found more special was that the message is actually sent first and then persisted which might leave a little gap when there is a crash. The .NET and C++ implementations do persist first and send afterwards.

Chris.

Comment by Philip Whitehouse [ 18/Sep/18 ]

The comment about the return indicating a successful network write however is also broken however.

In the case of set throwing an IOException instead of returning false it will return false despite having already written to the network.

So it's definitely 'special'.

Comment by Christoph John [ 18/Sep/18 ]

You could turn on synchronous writes if you want to make sure that the message was really sent. But as you said, the usage of the return code is somewhat inconsistent.





[QFJ-953] withQueueWatermarks always throws exception Created: 11/Sep/18  Updated: 11/Jan/19  Resolved: 20/Sep/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 2.1.0
Fix Version/s: 2.1.1

Type: Bug Priority: Default
Reporter: Mariusz B Assignee: Mariusz B
Resolution: Fixed Votes: 0
Labels: None


 Description   

Following code snippet:
{{
int lower = 10;
int upper = 20;
return SocketAcceptor.newBuilder()
.withQueueWatermarks(lower, upper)
.build();
}}

always ends up with exception:

{{
11:15:17 Caused by: quickfix.ConfigError: invalid queue watermarks, required: 0 <= lower watermark < upper watermark
11:15:17 at quickfix.AbstractSessionConnectorBuilder.withQueueWatermarks(AbstractSessionConnectorBuilder.java:58)
}}}

Method withQueueWatermarks should verify parameters instead of class fields.



 Comments   
Comment by Christoph John [ 11/Sep/18 ]

Hi Mariusz B,

thanks for the report. Are you able to create a pull request with the fix?
https://github.com/quickfix-j/quickfixj

Thanks,
Chris.





[QFJ-952] FIX Heartbeat message not sent Created: 07/Aug/18  Updated: 13/Aug/18  Resolved: 13/Aug/18

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

Type: Bug Priority: Default
Reporter: harinath Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, session
Environment:

fis-java-openshift
JBoss Fuse Integration Services 2.0 Java S2I images.



 Description   

I am using FIX4.4 and QuickFIX/ v1.0.0 for its implementation.

I came across a situation where i had subscribed for Market Data and was successfully receiving Snapshot message then suddenly all communication with the Market Session stopped and i didn't receive any more snapshot from the server on the Market Data Session.

When i asked the support they said that they didn't receive any heartbeat from my end after sending the TEST Request messages. so they closed the connection. But some time we didn't see the TEST request in our log file even they sent out.

we configured heartbeat value is 45 secs.

My Questions are:

What might have caused the system to not send out a Heartbeat message?

Using QuickFIX/J how can i ensure my periodic heartbeat message?

Whats the best time interval for heartbeat? (Mine is currently set to 60 seconds)

For Processing Marketdata will take 10-15min if we don't have any session disconnection.

So if we increase heartbeat value, is there any issue?

we Processing marketdata for every 4 hour per day and during this marketdata processing only we are disconnecting sessions.



 Comments   
Comment by harinath [ 08/Aug/18 ]

one correction here, we are using FIX4.4 and QuickFIX/ v1.5.2.

Comment by Christoph John [ 13/Aug/18 ]

a) you are using a rather old QFJ version
b) please direct such general questions to the mailing list

Thanks,
Chris.





[QFJ-951] Not respecting the Required flag for a field in a component if that component is inside of a group Created: 29/Jun/18  Updated: 16/Mar/20  Resolved: 16/Mar/20

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.2, 1.6.3, 1.6.4, 2.0.0
Fix Version/s: 2.1.0

Type: Bug Priority: Default
Reporter: Sergio Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I have a dictionary which is defined as follows (stripped some stuff out for simplicity)

<message name="QuoteRequest" msgtype="R" msgcat="app">
<field name="QuoteReqID" required="Y"/>
<group name="NoRelatedSym" required="Y">
<component name="Instrument" required="Y"/>
</group>
<field name="Text" required="N"/>
</message>
...
<message name="Quote" msgtype="S" msgcat="app">
<field name="QuoteReqID" required="Y"/>
<component name="Instrument" required="Y"/>
</message>
...
<component name="Instrument">
<field name="Symbol" required="Y"/>
<field name="SecurityID" required="N"/>
<field name="SecurityIDSource" required="N"/>
<field name="Product" required="N"/>
<field name="SecurityType" required="N"/>
<field name="SecuritySubType" required="N"/>
<field name="SecurityXMLLen" required="N"/>
<field name="SecurityXML" required="N"/>
<field name="SecurityXMLSchema" required="N"/>
</component>

From inside the java code, If I run the following code to see if field 55 ("Symbol") is listed as required in the R msg, it returns false:

GroupInfo gi = dictionary.getGroup("R", 146);
boolean requiredInRMsg = gi.getDataDictionary().isRequiredField("R", 55);

If I run the following code to see if field 55 ("Symbol") is listed as required in the S msg, it returns true:

GroupInfo gi = dictionary.getGroup("S", 146);
boolean requiredInRMsg = gi.getDataDictionary().isRequiredField("S", 55);

It appears that quickfix is not respecting the Required flag for a field in a component if that component is inside of a group.



 Comments   
Comment by Christoph John [ 02/Jul/18 ]

Hi Sergio,

could you please check if this fixes your problem: https://github.com/quickfix-j/quickfixj/pull/148

Thanks,
Chris.





[QFJ-950] Provide configuration to have garbled messages rejected instead of ignoring them Created: 07/Jun/18  Updated: 02/Aug/18  Resolved: 02/Aug/18

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

Type: New Feature Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

In FIX it is legal to ignore a message under certain circumstances. Since FIX is an optimistic protocol it expects that some errors are transient and will correct themselves with the next message transmission. Therefore the sequence number is not incremented and a resend request is issued on the next received message that has a higher sequence number than expected.

In the case that the error is not transient, the current behaviour is not optimal because not consuming a message sequence number can lead to follow-up problems since QFJ will wait for the message to be resent and queue all subsequent messages until the resend request has been satisfied.
So we need an enhancement which will reject invalid messages, consume a message sequence number and keep the normal message flow in place.

NOTE: This will only apply to messages that reach the engine and are not failing basic validity checks. E.g. messages that do not start with "8=FIX", or have no checksum set will be ignored as before. See FIX session protocol spec, chapter "What constitutes a garbled message".

Examples of messages that will be rejected instead of ignored:

  • incorrect checksum
  • repeating group count field contains no valid integer
  • no SOH delimiter found in field

This will be implemented as a configuration option. Default behaviour will be as before, i.e. message will be ignored and not rejected.






[QFJ-949] SSL Handshake failed on Java 8 Created: 02/May/18  Updated: 18/Jun/18  Resolved: 18/Jun/18

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

Type: Bug Priority: Critical
Reporter: hemant Assignee: Unassigned
Resolution: Not a bug Votes: 1
Labels: QuickfixJ


 Description   

Hello,

We are using QuickfixJ configuration i.e. SocketUseSSL=Y.
It is not working while running application on java 8 whereas it was working fine on Java 7.
QuickfixJ version: 1.6.3

Trace:

08:15:50:522324|0250-00076:INFO [quickfix.mina.initiator.InitiatorIoHandler] - MINA session created for , class org.apache.mina.transport.socket.nio.NioSocketSession,
08:15:50:528519|0208-00076:FIX:

{Disconnecting: Socket exception : javax.net.ssl.SSLHandshakeException: SSL handshake failed.}

Thread

{NioProcessor-8}

Thanks
Hemant



 Comments   
Comment by Vivek Singh [ 15/Jun/18 ]

I am facing this issue wherein after upgrading from quickfix-core jar from version 1.6.2 to 1.6.3 I started getting this exception.

Upon checking the debug level logs of application found following exception:
javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1666)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1634)
at sun.security.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:1561)
at org.apache.mina.filter.ssl.SslHandler.destroy(SslHandler.java:213)
at org.apache.mina.filter.ssl.SslFilter.sessionClosed(SslFilter.java:473)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:504)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$900(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.sessionClosed(DefaultIoFilterChain.java:927)
at org.apache.mina.core.filterchain.IoFilterAdapter.sessionClosed(IoFilterAdapter.java:88)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextSessionClosed(DefaultIoFilterChain.java:504)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireSessionClosed(DefaultIoFilterChain.java:497)
at org.apache.mina.core.service.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:245)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeNow(AbstractPollingIoProcessor.java:587)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeSessions(AbstractPollingIoProcessor.java:544)
at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$800(AbstractPollingIoProcessor.java:68)
at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1128)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Comment by Vivek Singh [ 15/Jun/18 ]

Just to add, we are using FIX.4.4 without any CA certification / jks file.

Comment by Vivek Singh [ 18/Jun/18 ]

Heamant,
Just check the debug level logs of SSL and see which version client is trying to use to communicate to server.

It is possible that client is using some lower version (like SSLv2) and server supports higher versions (like TLSv1.2). In this case server will reject the connection and handshake will fail.

To enable SSL logging give following argument while starting your application -Djavax.net.debug=ssl. It will pring all SSL logs in STDOUT.

Just check your logs to see what version client is using while sending handshake call to server.

If you find that what i am saying is true then use EnabledProtocols=<VersionThatServerSupports> attribute in your fix setting.
For Example: EnabledProtocols=TLSv1.2

This property will make sure that your client is using the specified version for handshake.

Comment by Christoph John [ 18/Jun/18 ]

Is this now solved? However, this belongs onto the mailing list. I doubt that this is a bug since many people are using SSL with Java 8.
Closing.





[QFJ-948] Storing messages using ODBC Created: 05/Apr/18  Updated: 06/Apr/18  Resolved: 06/Apr/18

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

Type: Bug Priority: Blocker
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I am trying to build a C++ application using quickfix, using quickfix i would like to store all messages using odbc store factory, however, when i am trying to initiate odbcstorefactory, compiler is giving me an error stating
"OdbcStore.h included, but HAVE_ODBC not defined"

Any idea on this error?



 Comments   
Comment by Christoph John [ 06/Apr/18 ]

I think you realized in the meantime that your problem is with QuickFIX and not QuickFIX/J (i.e. Java, not C).





[QFJ-947] Logout message with additional field is not logged Created: 26/Mar/18  Updated: 27/Mar/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.4
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Nikolai Kulakov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux



 Description   

I came across a situation where a Logout messages that have some additional field are not logged anywhere, so it seems that the connection is breaking before the Logout message receiving. Only from our counterparty I found out that they are sending a Logout messages indeed, and my own network traffic analyzing confirmed it.
Logged messages:

8=FIX.4.2^A9=80^A35=A^A34=1^A49=fxw2^A52=20180326-14:16:20.879^A56=JLQD^A98=0^A108=30^A554=password^A10=215^A
8=FIX.4.2^A9=80^A35=A^A34=2^A49=fxw2^A52=20180326-14:16:23.840^A56=JLQD^A98=0^A108=30^A554=password^A10=207^A
...

Logged events:

<2018-03-26 10:16:19.751 -0400> <Session FIX.4.2:fxw2->JLQD:MARKET_DATA schedule is weekly, SUN 21:30:00-UTC - SUN 21:00:00-UTC (weekly, SUN 17:30:00-EDT - SUN 17:00:00-EDT)>
<2018-03-26 10:16:19.752 -0400> <Created session: FIX.4.2:fxw2->JLQD:MARKET_DATA>
<2018-03-26 10:16:19.833 -0400> <Configured socket addresses for session: [/some_ip:port]>
<2018-03-26 10:16:19.863 -0400> <MINA session created: local=/172.20.30.34:33369, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/some_ip:port>
<2018-03-26 10:16:20.882 -0400> <Initiated logon request>
<2018-03-26 10:16:20.885 -0400> <Disconnecting: Socket exception (/some_ip:port): java.io.IOException: Connection reset by peer>
<2018-03-26 10:16:22.888 -0400> <MINA session created: local=/172.20.30.34:33372, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/some_ip:port>
<2018-03-26 10:16:23.842 -0400> <Initiated logon request>
<2018-03-26 10:16:23.845 -0400> <Disconnecting: Socket exception (/some_ip:port): java.io.IOException: Connection reset by peer>
...

I read a pure network traffic and had seen that immediately after out Logon we actually receive the following Logout messages:

8=FIX.4.2^A9=0109^A35=5^A34=88^A49=JLQD^A52=20180326-14:16:20.886^A56=fxw2^A789=51^A58=MsgSeqNum too low, expecting 51 but received 1^A10=075^A
8=FIX.4.2^A9=0109^A35=5^A34=89^A49=JLQD^A52=20180326-14:16:23.846^A56=fxw2^A789=51^A58=MsgSeqNum too low, expecting 51 but received 2^A10=076^A
...

I think, this incoming Logout messages must be logged as well as our outcoming Logon messages, but this does not happen. I set logging level to the minimal possible values, but this did not help: there are no this Logout messages anywhere.
The additional tag 789 was added to FIX dictionary, so I think it should be processed correctly. But at any case, whether this Logout message valid or not, it should be presented in logs.
Thanks!



 Comments   
Comment by Nikolai Kulakov [ 26/Mar/18 ]

Of course, it would be great to see this Logout messages not only in the logs, but and in the quickfix.Application#fromAdmin as it usually happens - it allows us to handle this Logout message and set the expected sequence number (I already did this with some other counterparties).

Comment by Christoph John [ 26/Mar/18 ]

I think the problem is that the session is disconnected at 2018-03-26 10:16:20.885 (see event log) but the Logout message is coming in at 20180326-14:16:20.886 (SendingTime on message in your network log). This means the session is disconnected 1ms before the counterparty sends the Logout message (given that both your and the counterparty's clock is in sync).

This can't be a general problem because this kind of disconnection (message seqnum too low) happens quite often with some counterparties and the messages show up in the log files. I don't know of any occurrences with current QuickFIX/J versions.

So unless we can reproduce this in a unit test we cannot do anything about it.

Sorry, but I can only repeat my statement from the other issues: please please please write to the mailing list before opening possible "bug" tickets. That way we can clarify if there really is a bug before issues are opened which in the end is saving your and our time.

Thanks,
Chris.

Comment by Nikolai Kulakov [ 27/Mar/18 ]

Please, take a look to this network dump of the incoming messages (on the our side):

10:16:19.846538 IP some_ip.port > our_ip.port: Flags [S.], seq 28365822, ack 2573233766, win 32000, options [mss 1380,nop,wscale 8], length 0
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  0030 0000 4000 3406 90c8 cfef 1bda ac14  [email protected].........
        0x0020:  1e22 6204 8259 01b0 d3fe 9960 6e66 7012  ."b..Y.....`nfp.
        0x0030:  7d00 8f83 0000 0204 0564 0103 0308       }........d....
10:16:20.885507 IP some_ip.port > our_ip.port: Flags [P.], seq 1:134, ack 103, win 4096, length 133
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  00ad 0000 4000 3406 904b cfef 1bda ac14  [email protected]......
        0x0020:  1e22 6204 8259 01b0 d3ff 9960 6ecc 5018  ."b..Y.....`n.P.
        0x0030:  1000 216b 0000 383d 4649 582e 342e 3201  ..!k..8=FIX.4.2.
        0x0040:  393d 3031 3039 0133 353d 3501 3334 3d38  9=0109.35=5.34=8
        0x0050:  3801 3439 3d4a 4c51 4401 3532 3d32 3031  8.49=JLQD.52=201
        0x0060:  3830 3332 362d 3134 3a31 363a 3230 2e38  80326-14:16:20.8
        0x0070:  3836 0135 363d 6678 7732 0137 3839 3d35  86.56=fxw2.789=5
        0x0080:  3101 3538 3d4d 7367 5365 714e 756d 2074  1.58=MsgSeqNum.t
        0x0090:  6f6f 206c 6f77 2c20 6578 7065 6374 696e  oo.low,.expectin
        0x00a0:  6720 3531 2062 7574 2072 6563 6569 7665  g.51.but.receive
        0x00b0:  6420 3101 3130 3d30 3735 01              d.1.10=075.
10:16:20.885543 IP some_ip.port > our_ip.port: Flags [R.], seq 134, ack 103, win 0, length 0
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  0028 0000 4000 3406 90d0 cfef 1bda ac14  .([email protected].........
        0x0020:  1e22 6204 8259 01b0 d484 9960 6ecc 5014  ."b..Y.....`n.P.
        0x0030:  0000 3711 0000 0000 0000 0000            ..7.........
10:16:22.887575 IP some_ip.port > our_ip.33372: Flags [S.], seq 4175399090, ack 3053759955, win 32000, options [mss 1380,nop,wscale 8], length 0
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  0030 0000 4000 3406 90c8 cfef 1bda ac14  [email protected].........
        0x0020:  1e22 6204 825c f8df 88b2 b604 add3 7012  ."b..\........p.
        0x0030:  7d00 878b 0000 0204 0564 0103 0308       }........d....
10:16:23.845393 IP some_ip.port > our_ip.33372: Flags [P.], seq 1:134, ack 103, win 4096, length 133
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  00ad 0000 4000 3406 904b cfef 1bda ac14  [email protected]......
        0x0020:  1e22 6204 825c f8df 88b3 b604 ae39 5018  ."b..\.......9P.
        0x0030:  1000 1b6f 0000 383d 4649 582e 342e 3201  ...o..8=FIX.4.2.
        0x0040:  393d 3031 3039 0133 353d 3501 3334 3d38  9=0109.35=5.34=8
        0x0050:  3901 3439 3d4a 4c51 4401 3532 3d32 3031  9.49=JLQD.52=201
        0x0060:  3830 3332 362d 3134 3a31 363a 3233 2e38  80326-14:16:23.8
        0x0070:  3436 0135 363d 6678 7732 0137 3839 3d35  46.56=fxw2.789=5
        0x0080:  3101 3538 3d4d 7367 5365 714e 756d 2074  1.58=MsgSeqNum.t
        0x0090:  6f6f 206c 6f77 2c20 6578 7065 6374 696e  oo.low,.expectin
        0x00a0:  6720 3531 2062 7574 2072 6563 6569 7665  g.51.but.receive
        0x00b0:  6420 3201 3130 3d30 3736 01              d.2.10=076.
10:16:23.845427 IP some_ip.port > our_ip.33372: Flags [R.], seq 134, ack 103, win 0, length 0
        0x0000:  000c 2909 731b 001f 9edf 3ebf 0800 4500  ..).s.....>...E.
        0x0010:  0028 0000 4000 3406 90d0 cfef 1bda ac14  .([email protected].........
        0x0020:  1e22 6204 825c f8df 8938 b604 ae39 5014  ."b..\...8...9P.
        0x0030:  0000 2f19 0000 0000 0000 0000            ../.........
...

As I see, there are constantly repeating 3 records:

  1. Probably, a connect message.
  2. Then, about one second later, the Logout message.
  3. Then, immediately, one more message, probably disconnect.

I think that the time between our and the counterparty sides is not so good synchronized to rely on this (in fact, we have some problems with time synchronization on the used machine).
I guess, the problem may be in the too little delay between receiving the Logout and the disconnect messages. Also, it can be in the using of non-standard tag 789. Of course, it can be in something else, but it exists - that is the reason because I wrote this in the issues tracker, not to bother you, of course.

Thanks and my apologize if I'm using not the best procedure of issues notifying,
Nikolai.

Comment by Christoph John [ 27/Mar/18 ]

Hi Nikolai,
there is no need to apologize. I just wanted to stress the fact that it is hard to fix issues that cannot be reproduced reliably. We would need some kind of reproducable unit test to look deeper into this issue. I must admit that I never heard of this problem before but of course this does not mean that it is not possible to happen. May be related to a couple of things.

Thanks,
Chris.





[QFJ-946] Improve misleading error message during Logon Created: 21/Mar/18  Updated: 26/Mar/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.4
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Nikolai Kulakov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux



 Description   

It seems that the network connection between my company and our partner is very fast and the QuickFix/J engine suppose that their answering Logon message is coming before we send our Logon message:

8=FIX.4.2^A9=86^A35=A^A34=1^A49=fxw2^A52=20180321-14:09:01.447^A56=JLQD^A98=0^A108=30^A141=Y^A554=password^A10=253^A
8=FIX.4.2^A9=0065^A35=A^A34=317^A49=JLQD^A52=20180321-14:09:01.453^A56=fxw2^A98=0^A108=30^A10=119^A
8=FIX.4.2^A9=86^A35=A^A34=1^A49=fxw2^A52=20180321-14:09:04.413^A56=JLQD^A98=0^A108=30^A141=Y^A554=password^A10=249^A
8=FIX.4.2^A9=0065^A35=A^A34=318^A49=JLQD^A52=20180321-14:09:04.417^A56=fxw2^A98=0^A108=30^A10=123^A
8=FIX.4.2^A9=86^A35=A^A34=1^A49=fxw2^A52=20180321-14:09:07.413^A56=JLQD^A98=0^A108=30^A141=Y^A554=password^A10=252^A
8=FIX.4.2^A9=0065^A35=A^A34=319^A49=JLQD^A52=20180321-14:09:07.416^A56=fxw2^A98=0^A108=30^A10=126^A
etc

<2018-03-21 10:09:00.329 0400> <Session FIX.4.2:fxw2>JLQD:MARKET_DATA schedule is weekly, SUN 21:30:00-UTC - SUN 21:00:00-UTC (weekly, SUN 17:30:00-EDT - SUN 17:00:00-EDT)>
<2018-03-21 10:09:00.330 0400> <Created session: FIX.4.2:fxw2>JLQD:MARKET_DATA>
<2018-03-21 10:09:00.409 -0400> <Configured socket addresses for session: [/some_ip:port]>
<2018-03-21 10:09:00.444 -0400> <MINA session created: local=/172.20.30.34:57198, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/some_ip:port>
<2018-03-21 10:09:01.453 -0400> <Initiated logon request>
<2018-03-21 10:09:01.462 -0400> <Received logon>
<2018-03-21 10:09:01.462 -0400> <Disconnecting: Received logon response before sending request>
<2018-03-21 10:09:03.461 -0400> <MINA session created: local=/172.20.30.34:57200, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/some_ip:port>
<2018-03-21 10:09:04.417 -0400> <Initiated logon request>
<2018-03-21 10:09:04.421 -0400> <Received logon>
<2018-03-21 10:09:04.421 -0400> <Disconnecting: Received logon response before sending request>
<2018-03-21 10:09:06.468 -0400> <MINA session created: local=/172.20.30.34:57202, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/some_ip:port>
<2018-03-21 10:09:07.415 -0400> <Initiated logon request>
<2018-03-21 10:09:07.419 -0400> <Received logon>
<2018-03-21 10:09:07.419 -0400> <Disconnecting: Received logon response before sending request>
etc.

So, I do not see any way to establish the connection.



 Comments   
Comment by Nikolai Kulakov [ 21/Mar/18 ]

After further investigation of the problem, I guess that the problem is not in the speed of the connection, but in the fact that we set ResetSeqNumFlag=Y in the our Logon message but in the answering Logon message it is not presented (so, the priority of the problem can be lowered).

The code that is generating this error is in the method quickfix.Session#nextLogon:

        // Check for proper sequence reset response
        if (state.isResetSent() && !state.isResetReceived()) {
            disconnect("Received logon response before sending request", true);
        }

It can be a problem indeed, but the disconnect message seems totally misleading for me.
Also, I do not see any benefits to break down the connection in this case (we sent ResetSeqNumFlag but did not received it in the answer).

Comment by Christoph John [ 21/Mar/18 ]

I don't know but what sense does it make to reset the sequence numbers only on one side? So I guess the check might have a point. Unless I'm missing something.

Comment by Nikolai Kulakov [ 21/Mar/18 ]

Just a real situation: our partner is ready to reset the sequence number on the one side only. It seems that using ResetSeqNumFlag for this purpose it is not nice by FIX standards, but also it is a fact that this situation is not related with the "Received logon response before sending request".
Also, it is not clear for me why dropping down the connection is better than working.

Comment by Christoph John [ 21/Mar/18 ]

I think it does not make sense to open a bug ticket for every counterparty that does not conform to normal FIX standard.
If the counterparty wanted that you reset your sequence numbers I guess they should be sending you tag 141 in their Logon. At least IMHO.
Why are you sending 141? Does the counterparty require you to do so?

IMHO the best would be to direct such questions to the mailing list. Please post follow up questions and your answers there.
https://sourceforge.net/projects/quickfixj/lists/quickfixj-users

Thanks

Comment by Nikolai Kulakov [ 21/Mar/18 ]

John, I agree that it is no sence to open a bug ticket for a counetrparty that does not conform regular FIX standard (of course, I'll discuss this situation with them directly). But the ticket is about another thing and I'm really sorry if I'm describing it not clear.
The problem is that the engine is disconnecting with "Received logon response before sending request" when there is no such situation (logon response is coming after sending request).
Thank you for the patience.





[QFJ-945] Not able to send logon message with SSL certificate using Stunnel Created: 17/Mar/18  Updated: 17/Mar/18  Resolved: 17/Mar/18

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation, Networking
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Critical
Reporter: Zeeshan Ali Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

UAT/Test


Attachments: Zip Archive StunnelConnectionDetails.zip    

 Description   

Hello All,

I am a new developer and trying to connect to our own environment using quickfix/N.
The logon connection has to go through SSL certificate. I have configured stunnel for that and used different methods as well, but still the logon message is going without certificate. I have attached all the logs and certificates and configuration files . Appreciate if you could help me with this . I am stuck with this from a very long time.



 Comments   
Comment by Zeeshan Ali [ 17/Mar/18 ]

I have attached
1) Stunnel configuration file
2) QuickFix N config file
3) stunnel log
4) quickfix n logs
5) our fix engine logs

Comment by Christoph John [ 17/Mar/18 ]

This is the bug tracker. Please write to the mailing list for help requests. It should have said so when you opened this issue.
Apart from that: QFJ natively supports SSL. You do not need Stunnel.





[QFJ-944] Misleading error message when receiving Logon with tag RawData without RawDataLength Created: 13/Mar/18  Updated: 16/Mar/18  Resolved: 16/Mar/18

Status: Resolved
Project: QuickFIX/J
Component/s: Engine, Metadata/Specs
Affects Version/s: 1.6.4
Fix Version/s: 2.0.1

Type: Improvement Priority: Default
Reporter: Nikolai Kulakov Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

Real connection to GDAX (Coinbase) exchange.



 Description   

I encountered a problem that after receiving a Logon message from the GDAX cryptocurrency exchange, the connection is breaking down with only one strange explaining string in event log messages:
<2018-03-13 07:13:22.789 -0400> <Invalid LOGON message, disconnecting: Tag 95 not found in 8=FIX.4.2^A9=167^A35=A^A52=20180313-11:13:22.778^A49=Coinbase^A56=an_id^A34=1^A96=some_data^A98=0^A108=30^A554=password^A8013=Y^A10=032^A>
It is obviously no tag 95 in the message, so from the first look it seems very strange that engine is trying to find it. As I found out after code debugging, the problem is that the tag 96 is defined as DATA in the standard FIX42 dictionary and for the type QuickFIX/J engine is looking for the previous tag: this logic is coded in the method quickfix.Message#extractField.
I hotfixed my problem by changing the tag 96 type from DATA to STRING in the FIX dictionary, but it seems that it is too difficult to come to.

1) I think, the FIX engine should check the previous tag presence before getting it, and in the case of absence, do extracting as with usual string.
2) At any case, the log message should be more clear than simple "Tag <unknown tag> not found in <messageData>".



 Comments   
Comment by Christoph John [ 13/Mar/18 ]

Hmm, tag 96 can contain any data, e.g. also SOH character. Not knowing the length of that tag can lead to parsing errors, especially on multi byte charsets.
I am reluctant to change stuff which is not FIX compliant. Do they mention the reason of not using tag 95 somewhere?

Comment by Nikolai Kulakov [ 13/Mar/18 ]

No, they do not mention.
You are right that not knowing the length of that tag can lead to parsing errors, but it is the fact that with current logic it is not working at all. So I think one of the ideas can be implemented:
1) Write some warning/error message but try to parse as if it is a string;
2) Introduce an option like "validateDataFieldsHaveLengthField" and try to parse if it is set to 'N';
3) Leave the logic as it is, but write a more clear error message. I really thought that it is QuickFIX/J engine error that it is trying to get a tag that is not presented in the message.
Thanks!

Comment by Christoph John [ 14/Mar/18 ]

I think improving the error message is the only thing we can do at the moment. There is a workaround as you mentioned (changing the field to STRING). You could also set UseDataDictionary=N as long as GDAX does not use repeating groups.
Feel free to open a separate issue or even a pull request for option 2.

Thanks,
Chris.

Comment by Christoph John [ 14/Mar/18 ]

What about this?

throw new InvalidMessage("Did not find length field " + e.field + " required to parse data field " + tag + " in " + messageData);
Comment by Nikolai Kulakov [ 14/Mar/18 ]

Yes, it is much clearer. Thanks!

Comment by Christoph John [ 14/Mar/18 ]

https://github.com/quickfix-j/quickfixj/pull/181

Comment by Christoph John [ 16/Mar/18 ]

BTW, I have asked GDAX support if they can add the RawDataLength tag for better FIX compliance and they agreed to do so in the future.
Until then please try with UseDataDictionary=N. They only seem to send one repeating group NoMiscFees with one instance as a response to the OrderStatusRequest. So not using the dictionary might very well work.

Chris.





[QFJ-943] Blocking queue writes from the MINA event loop causing delayed sends, missing heartbeats, spurious disconnects Created: 25/Jan/18  Updated: 02/Aug/18  Resolved: 06/Mar/18

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.6.4
Fix Version/s: 2.1.0

Type: Bug Priority: Major
Reporter: Mr. Bald Assignee: Mr. Bald
Resolution: Fixed Votes: 0
Labels: None
Environment:

any, reproduced on x86_64 Windows, Linux, Mac OS X, Oracle JVM 1.8



 Description   

AbstractPollingIoProcessor read buffer drain loop may block for substantial time.
This is because the QuickFIXj/MINA read filter chain eventually ends up in one of EventHandlingStrategy implementations (thread-per-session or shared), which in turn write messages into a fixed capacity blocking queue.

Reproduction - set up a NewOrderSingle generator and a simple Acceptor with delay of 20ms between subsequent ack ExecutionReport responses and a queue size of 1000. Pumping of 2000 NewOrderSingle messages into such Acceptor should be enough to see that execution reports are blocked at the Acceptor end until the sender stops sending new messages and the read queue of the Acceptor unblocks.

General idea of the fix - use watermarks-based queue instead of blocking queue. I'll do a github pull request shortly.



 Comments   
Comment by Christoph John [ 25/Jan/18 ]

Hi Mr. Bald,
you can specify the size of the blocking queue via the constructor of the EventHandlingStrategy. This will of course not prevent the original problem.
Please open PR against master then. Thanks in advance.
Chris.

Comment by Mr. Bald [ 28/Jan/18 ]

Pull request: https://github.com/quickfix-j/quickfixj/pull/168





[QFJ-942] Connectors sometimes hanging in call to dispose() when stop() was called Created: 15/Jan/18  Updated: 17/Oct/18  Resolved: 19/Mar/18

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-916 Reconnection feature does not work un... Closed

 Description   

We should first close all managed sessions before trying to dispose the connector.
NB: This might have some overlaps with https://issues.apache.org/jira/browse/DIRMINA-1076.






[QFJ-941] MessageCracker omits some data on MarketDataSnapshotFullRefresh response. Created: 12/Jan/18  Updated: 15/Jan/18  Resolved: 15/Jan/18

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

Type: Bug Priority: Critical
Reporter: Aro Kondo Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

windows 10 pro, Eclipse Version: Oxygen.2 Release (4.7.2), FIX4.4



 Description   

MessageCracker seems having a problem missing a part of the original data.

I have implemented MessageCracker and overidden MarketDataSnapshotFullRefresh response to display received messages like below.

 

@Override
 public final void onMessage(quickfix.fix44.MarketDataSnapshotFullRefresh message, SessionID sessionID) {
	logger.info(message.toString());
|

Also I have let my application output log and compared both messages.

 

Here is the comparison.

 

// from MessageCracker
8=FIX.4.49=14235=W34=1349=OneZero_Q52=20180112-05:25:14.23856=BANANA_Q55=USDJPY262=4268=2269=0270=87.122271=1000000276=A282=Binary299=1982254110=224

 

 

// from application logger
8=FIX.4.49=20135=W34=1349=OneZero_Q52=20180112-05:25:14.23856=BANANA_Q55=USDJPY262=4268=2269=0270=87.122271=1000000276=A282=Binary299=19822541269=1270=87.122271=1000000276=A282=Binary299=1982254210=254

Despite TAG268 equals 2, offer data is omitted.

Any thoughts?

 



 Comments   
Comment by Aro Kondo [ 15/Jan/18 ]

Sorry guys, I have solved this problem. Dictionary discrepancy caused this strange behavior.





[QFJ-940] Event log omits parts of received message in case of validation errors Created: 08/Jan/18  Updated: 08/Feb/18  Resolved: 08/Feb/18

Status: Resolved
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 2.0.1

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

problem

When there are messages rejected and they contain repeating groups (for example) that could not be parsed there is a message similar to this in the event log:
Rejecting invalid message: quickfix.FieldException: Out of order repeating group members, field=447: 8=FIX.4.49=14235=AE34=649=XXX52=20171120-08:21:48.09656=YYY22=448=abc55=[N/A]552=12668=12669=02670=910=168

The log shows the message up to the point where the parsing failed. This makes the analysis difficult since one has to consult the message log additionally to the event log.

solution

Log the messageData (which is the original message String) instead of the parsed Message.






[QFJ-937] MaxScheduledWriteRequests is ineffective Created: 13/Oct/17  Updated: 19/Mar/18  Resolved: 19/Mar/18

Status: Resolved
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.6.4
Fix Version/s: 2.0.1

Type: Bug Priority: Major
Reporter: David Gibbs Assignee: David Gibbs
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File 0001-change-implementation-to-max-scheduled-write-bytes.patch    
Issue Links:
Relates
relates to QFJ-833 Add Slow Consumer Protection Closed

 Description   

Due to a defect in Apache Mina 2.0.16 MaxScheduledWriteRequests is inefective.
MaxScheduledWriteBytes would work.
A bug fix is in progress see : https://issues.apache.org/jira/browse/DIRMINA-1057
For a demonstration of the defect see https://github.com/david-gibbs-ig/mina-test-case
See also MAILING LIST.



 Comments   
Comment by David Gibbs [ 13/Oct/17 ]

Attached is a patch for IoSessionResponderTest that just extends coverage a little. It does not demonstrate this defect.
See https://github.com/david-gibbs-ig/mina-test-case for an integration test that demonstrates the mina issue with quickfixj codec.
: quickfix.mina.message.FIXProtocolCodecFactory

Comment by David Gibbs [ 16/Oct/17 ]

The bug fix for this will be in mina 2.0.17.

Comment by Christoph John [ 23/Oct/17 ]

Hi David Gibbs,

Attached is a patch for IoSessionResponderTest that just extends coverage a little. It does not demonstrate this defect.

hmm, the test testMaxScheduledWriteBytesExceeded is failing for me.

???

Comment by David Gibbs [ 23/Oct/17 ]

My mistake, you can see I was working with MaxScheduledWriteBytes rather than MaxScheduledWriteMessages (as in the master branch).
Leave that with me, I'll line it up with master.
Apache Mina 2.0.17 is not yet released.

Comment by Christoph John [ 26/Oct/17 ]

I'm still unsure if we should wait for MINA 2.0.17 to be released and rather put this issue into QFJ 2.0.1? Even if MINA 2.0.17 was released in October there is not much time left to test QFJ with the new MINA version since I'd like to have QFJ 2.0.0 released in a few weeks the latest.
What do you think?

Edit: there are also still some issues open to be fixed for MINA 2.0.17.

Cheers,
Chris.

Comment by Christoph John [ 06/Nov/17 ]

OK, timeout. Putting this into 2.0.1 since MINA is still not released.

Comment by Christoph John [ 13/Mar/18 ]

Can be closed once https://github.com/quickfix-j/quickfixj/pull/177 has been merged.

Comment by David Gibbs [ 15/Mar/18 ]

Excellent !





[QFJ-936] Repeating Group issue Created: 12/Oct/17  Updated: 12/Oct/17  Resolved: 12/Oct/17

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.0.0 Final
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Ramesh Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

Linux



 Description   

Hi All,

I am Using quickfix 5.0 version,

When i working with this environment, i saw 447 tag appears again,

so i added this group in the executionreport messagetrype in datadictionary.even after adding this one also i am seeing same isue, i set all of them in config file. can anyone suggest me.

<group name='NoPartyIDs' required='N' >
<field name='PartyID' required='N' />
<field name='PartyIDSource' required='N' />
<field name='PartyRole' required='N' />
</group>

ValidateFieldsOutOfOrder=N
UseDataDictionary = Y
ValidateLengthAndChecksum=N
TransportDataDictionary=.xxx.xml



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

This is the bug tracker. Please use the mailing list to ask for help (just as it says before creating a ticket): https://sourceforge.net/projects/quickfixj/lists/quickfixj-users





[QFJ-935] 2017-09-27 05:47:16.3724 FIX event IO Error: IO Error: Unable to get file pointer position from D:\FixStore\XYZ.body Created: 28/Sep/17  Updated: 28/Sep/17  Resolved: 28/Sep/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1, 2.0.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Sumit Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, performance, session
Environment:

LIVE QuickFix 4.4



 Description   

Hi Team,

We have got the below message
2017-09-27 05:47:16.3724 FIX event IO Error: IO Error: Unable to get file pointer position from D:\FixStore\XYZ.body

several times for 20 secs approx

after this we got => FIX event Socket Error: Connection reset by peer.
and then => FIX event Disconnecting.
=> FIX event Logon contains ResetSeqNumFlag=Y, reseting sequence numbers to 1
=> FIX event Received logon request.

When analyzed further found the below piece of code:
int offset = ftell( m_msgFile );
if ( offset < 0 )
throw IOException( "Unable to get file pointer position from " + m_msgFileName );

But I did not able to find out the route cause/scenario due to which this happened.

Could anyone help me out on this?

Thank you,
Sumit Gupta



 Comments   
Comment by Christoph John [ 28/Sep/17 ]

This looks like C# code to me. So you probably want to ask the quickfix/n people on the mailing list or on their github page.





[QFJ-934] Message with nested repeating group and missing delimiter tag is silently ignored Created: 21/Sep/17  Updated: 22/Nov/17  Resolved: 22/Nov/17

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

problem

When a message is received that has a repeating group inside another repeating group and the first group is missing the group delimiter, the message is silently ignored. The reason for this is that an InvalidMessage Exception is thrown and the sequence number is not incremented. Normally, this is OK for messages that have a wrong checksum or length because it is expected that the problem "corrects itself". However, a missing repeating group delimiter should be considered a user or FIX engine problem and we should hence reject the message with a meaningful description.






[QFJ-933] FieldNotFound when Logon without HeartBtInt is received - message is ignored Created: 21/Sep/17  Updated: 22/Nov/17  Resolved: 22/Nov/17

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

problem

When an Acceptor receives a Logon message that has not HeartBtInt set, there is a FieldNotFoundException thrown and the message is silently ignored.

We should reject the message with a Logout message and a meaningful error description. This should also apply when Exceptions of type IncorrectDataFormat or IncorrectTagValue are thrown.






[QFJ-932] quickfix.ConfigError: No fields found for empty message type depends on XML format Created: 04/Sep/17  Updated: 13/Mar/18  Resolved: 13/Mar/18

Status: Resolved
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.6.4
Fix Version/s: 2.0.1

Type: Bug Priority: Default
Reporter: Jon Freedman Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None


 Description   

Compare the following two XML fragments from a data dictionary, the first produces an error and the second is fine

    <message name="XMLnonFIX" msgtype="n" msgcat="Session"/>

Results in

Caused by: quickfix.ConfigError: No fields found: msgType=n
	at quickfix.DataDictionary.load(DataDictionary.java:1021) ~[quickfixj-core-1.6.4.jar:1.6.4]
    <message name="XMLnonFIX" msgtype="n" msgcat="Session">
    </message>





[QFJ-931] QuickFixJ 1.6.4 version can't populate SecurityXml and SecurityXmlLen for message type AE for FIX 4.4 version Created: 09/Aug/17  Updated: 14/Aug/17  Resolved: 14/Aug/17

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.6.4
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Sankar Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Unable to generate tags SecurityXml and SecurityXmlLen tags (1185 & 1184) for message type 35=AE for FIX 4.4 version and using QuickFixJ libraries 1.6.4



 Comments   
Comment by Sankar [ 10/Aug/17 ]

There is an alternative way to assign SecurityXml as below.

TradeCaptureReport message = new TradeCaptureReport();
String fpml = "<xml/fpml here>";
message.setString(1185, fpml);

Comment by Christoph John [ 14/Aug/17 ]

SecurityXML is not included in FIX4.4 TradeCaptureReport message per the FIX spec.





[QFJ-930] FIXSettings not set for new DataDictionary objects created by DefaultDataDictionaryProvider Created: 18/Jul/17  Updated: 29/Jan/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Sachin Agrawal Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File quickfix_930.rar    

 Description   

While DefaultSessionsFactory.processFixtDataDictionaries adds ApplicationDictionary to dataDictionaryProvider it uses beginStringQualifier only.

While method of MessageUtils
(Message parse(Session session, String messageString) throws InvalidMessage)

method used session,messageString both to get the ApplVerId. this results in mismatched key inside DefaultDataDictionaryProvider and DefaultDataDictionaryPovider need to create a new DataDictionary but FIX sesion settings are not set here at all, which are set by DefaultSessionsFactory while executing processFixtDataDictionaries inside createDataDictionary.

Please let me know in case this is intentional.



 Comments   
Comment by Christoph John [ 18/Jul/17 ]

I am sorry, but I cannot follow your description. Could you maybe describe the problem with some code examples or a unit test?
Thanks,
Chris.

Comment by Sachin Agrawal [ 19/Jul/17 ]

Thanks Chris for looking into,i now try to be more specific.

Please look into DeafultSessionFactory.processFixtDataDictionaries, we find following piece of code, please note here that toApplVerID is used to create the instance of ApplVerID before the applicationDictionary is added to the datadictionaryProvider.

final DataDictionary dd = createDataDictionary(sessionID, settings, key,
                            beginStringQualifier);
dataDictionaryProvider.addApplicationDictionary(MessageUtils.toApplVerID(beginStringQualifier), dd);

and createDataDictionary method reads the settings

private DataDictionary createDataDictionary(SessionID sessionID, SessionSettings settings,
            String settingsKey, String beginString) throws ConfigError, FieldConvertError {
        final String path = getDictionaryPath(sessionID, settings, settingsKey, beginString);
        final DataDictionary dataDictionary = getDataDictionary(path);

        if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_FIELDS_OUT_OF_ORDER)) {
            dataDictionary.setCheckFieldsOutOfOrder(settings.getBool(sessionID,
                    Session.SETTING_VALIDATE_FIELDS_OUT_OF_ORDER));
        }

        if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_FIELDS_HAVE_VALUES)) {
            dataDictionary.setCheckFieldsHaveValues(settings.getBool(sessionID,
                    Session.SETTING_VALIDATE_FIELDS_HAVE_VALUES));
        }

        if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS)) {        	
            boolean chkUnorderedGrpFields = settings.getBool(sessionID,
                    Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS);
            settings.getLogger().error("Msg SttString "+Session.SETTING_VALIDATE_UNORDERED_GROUP_FIELDS +" value "+ chkUnorderedGrpFields +" dataDictionary " +dataDictionary.toString() +" beginString "+beginString);
			dataDictionary.setCheckUnorderedGroupFields(chkUnorderedGrpFields);
        }

        if (settings.isSetting(sessionID, Session.SETTING_VALIDATE_USER_DEFINED_FIELDS)) {
            dataDictionary.setCheckUserDefinedFields(settings.getBool(sessionID,
                    Session.SETTING_VALIDATE_USER_DEFINED_FIELDS));
        }

        if (settings.isSetting(sessionID, Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS)) {
            dataDictionary.setAllowUnknownMessageFields(settings.getBool(sessionID,
                    Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS));
        }

        return dataDictionary;
    }

Please note that DefaultDataDictionaryProvider uses ApplVerID as the key of the map.

While there is a method called MessageUtils.parse(Session session, String messageString), which uses getApplVerID(session, messageString) to create the ApplVerId and uses the same to fetch the applicationDictionary from dataDictionaryProvider.

MessageUtils.parse(Session session, String messageString)
.....
final String beginString = getStringField(messageString, BeginString.FIELD);
		final String msgType = getMessageType(messageString);

		ApplVerID applVerID;

		if (FixVersions.BEGINSTRING_FIXT11.equals(beginString))
		{
			applVerID = getApplVerID(session, messageString);
		}
		else
		{
			applVerID = toApplVerID(beginString);
		}
		final MessageFactory messageFactory = session.getMessageFactory();

		final DataDictionaryProvider ddProvider = session.getDataDictionaryProvider();
		final DataDictionary sessionDataDictionary = ddProvider == null ? null : ddProvider.getSessionDataDictionary(beginString);
		final DataDictionary applicationDataDictionary = ddProvider == null ? null : ddProvider.getApplicationDataDictionary(applVerID);
....

So when an application message is received a new DataDictionary is created by DefaultDataDictionaryProvider, look at method

 public DataDictionary getApplicationDataDictionary(ApplVerID applVerID) 

so the problem is that this new DataDictionary created by DefaultdataDictionaryProvider does not copy the FIX configurations i.e. settings. Hence even though the application dev has set the settings they are not picked while parsing messages.

Please ask further clarifications.

Thanks,
Sachin

Comment by Christoph John [ 19/Jul/17 ]

Hi,

I have changed https://github.com/quickfix-j/quickfixj/blob/master/quickfixj-core/src/test/java/quickfix/DefaultSessionFactoryTest.java (method testFixtDataDictionaryConfiguration) slightly to set "AllowUnknownMessageFields" to true.

 @Test
    public void testFixtDataDictionaryConfiguration() throws Exception {
        SessionID sessionID = new SessionID(FixVersions.BEGINSTRING_FIXT11, "SENDER", "TARGET");
        setUpDefaultSettings(sessionID);
        settings.setBool(sessionID, Session.SETTING_USE_DATA_DICTIONARY, true);
        settings.setString(sessionID, Session.SETTING_TRANSPORT_DATA_DICTIONARY, "FIXT11.xml");
        settings.setString(sessionID, Session.SETTING_DEFAULT_APPL_VER_ID, "FIX.4.2");
        settings.setString(sessionID, Session.SETTING_APP_DATA_DICTIONARY, "FIX42.xml");
        settings.setString(sessionID, Session.SETTING_APP_DATA_DICTIONARY + "." + FixVersions.BEGINSTRING_FIX40, "FIX40.xml");
        settings.setString(sessionID, Session.SETTING_ALLOW_UNKNOWN_MSG_FIELDS, "Y");   // added

        Session session = factory.create(sessionID, settings);

        DataDictionaryProvider provider = session.getDataDictionaryProvider();
        assertThat(provider.getSessionDataDictionary(sessionID.getBeginString()),
                is(notNullValue()));
        final DataDictionary applicationDataDictionary = provider.getApplicationDataDictionary(new ApplVerID(ApplVerID.FIX42));

        assertThat(applicationDataDictionary,
                is(notNullValue()));
        assertThat(provider.getApplicationDataDictionary(new ApplVerID(ApplVerID.FIX40)),
                is(notNullValue()));
        
        System.err.println("XXXX " + provider.getSessionDataDictionary(sessionID.getBeginString()).isAllowUnknownMessageFields() );
        System.err.println("XXXX " + applicationDataDictionary.isAllowUnknownMessageFields() );
        
        quickfix.fixt11.Logon logon = new quickfix.fixt11.Logon(new EncryptMethod(EncryptMethod.NONE_OTHER), new HeartBtInt(30),
                new DefaultApplVerID(ApplVerID.FIX42));
        MessageUtils.parse(session, logon.toString());

This gives the following as output:

XXXX true
XXXX true

So the setting is picked up by both dictionaries.

Then I stepped into MessageUtils.parse(session, logon.toString()) with the debugger and could also see that the setting is true on the applicationDataDictionary.

So maybe I am taking a different code path than you? BTW I tested it on master, i.e. with version 1.7.0-SNAPSHOT.

Cheers,
Chris.

Comment by Sachin Agrawal [ 20/Jul/17 ]

Hi Chris,

I understand in your use case a new dictionary is never created, but there are some configurations in which a scenario occurs which creates a new dictionary by DefaultDataDictionaryProvider, then the settings will not be copied.
so to solve the problem we have 2 options

1) I correct the Fix configurations so that a new dictionary is never created.
2) Somehow set the session settings on each datadictionary created by DefaultDataDictionaryProvider

I see you are suggesting option 1.

--Regards,
Sachin

Comment by Christoph John [ 20/Jul/17 ]

Hi,

when there are such configurations then please give an example configuration. Otherwise I don't know how to reproduce the problem.

Thanks,
Chris.

Comment by Sachin Agrawal [ 29/Jan/18 ]

Attached is the zip src files with change

Add fix for correctly reading the settings in all the cases, i.e. whenever DataDictionary object is created from SessionFactory or MessageUtils.parse
    a) Update interface DataDictionaryProvider.java add DataDictionary getApplicationDataDictionary(SessionID sessionId, ApplVerID applVerID);
    b) Update DefaultDataDictionaryProvider
        1) add field SessionSettings
        2) add another constructor with SessionSettings, update old constructors to initialize field settings
        3) add implementation of new method getApplicationDataDictionary(SessionID sessionId, ApplVerID applVerID); which also readSettings\
        4) add public static method fillSettings
        5) add local method readSettings which calls static method fillsettings which is extracted from DefaultSessionFactory
    c) Update DefaultSessionFactory
        1) Update method create use new Constructor added for DefaultDataDictionaryProvider, pass settings.
        2) Update method createDataDictionary remove filling of settings locally and call DefaultDataDictionaryProvider.fillSettings instead
    d) Update MessageUtils, by updating method parse(Session session, String messageString) throws InvalidMessage so that appDataDictionary is fetched from ddProvider by also passing SessionID
    e) Update Session. next(Message message, boolean isProcessingQueuedMessages) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
            IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage, so that getApplicationDataDictionary is called with sessionID param as well.

Comment by Sachin Agrawal [ 29/Jan/18 ]

only improvement the changes i uploaded have is that whereever the DataDictionary object is created, the existing settings of  current session are always applied on DataDictionary created.

Comment by Christoph John [ 29/Jan/18 ]

Thanks for the file. Are you maybe able to generate a patch or even better open a pull request on github?
Thanks,
Chris.





[QFJ-929] FieldException on Logon message is handled incorrectly Created: 03/Jul/17  Updated: 27/Jul/17  Resolved: 04/Jul/17

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

When there is a FieldException on a Logon message (e.g. mandatory field not set or field specified without a value) it is tried to reject the message with a session-level reject.
This of course fails because no session is established yet:

quickfix.SessionException: Tried to send a reject while not logged on

Moreover, the session is not disconnected.

This should be changed so that a Logout message with a descriptive error text is sent back to the counterparty and the session should be disconnected directly afterwards.






[QFJ-928] SequenceReset not processed when out of order messages received Created: 21/Jun/17  Updated: 12/Nov/18  Resolved: 12/Nov/18

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

Type: Bug Priority: Blocker
Reporter: Yang Cheng Assignee: Unassigned
Resolution: Duplicate Votes: 2
Labels: None

Issue Links:
Duplicate
duplicates QFJ-814 Sequence Reset Fails Closed
is duplicated by QFJ-927 Message sequence number mismatch and ... Closed

 Description   

Please see issue below, other tags removed. M-DAQ received sequence numbers 3->7->4->5->8->9 which is in wrong order and missing 34=6
2017-06-19 16:01:45,176 [SocketConnectorIoProcessor-1.0] INFO incoming A52=20170619-08:01:44.789^ A34=325463
2017-06-19 16:01:45,177 [SocketConnectorIoProcessor-1.0] INFO incoming A52=20170619-08:01:44.973^ A34=325467
2017-06-19 16:01:45,177 ERROR quickfixj.errorEvent MsgSeqNum too high, expecting 325464 but received 325467: A34=325467
2017-06-19 16:01:45,177 Enqueued at pos 325467:
2017-06-19 16:01:45,177 [QFJ Message Processor] INFO incoming A52=20170619-08:01:44.830^ A34=325464
2017-06-19 16:01:45,177 [QFJ Message Processor] INFO incoming A52=20170619-08:01:44.854^ A34=325465
2017-06-19 16:01:45,177 [SocketConnectorIoProcessor-1.0] INFO incoming A52=20170619-08:01:44.997^ A34=325468
2017-06-19 16:01:45,177 [QFJ Message Processor] INFO incoming A52=20170619-08:01:45.004^ A34=325469

After M-DAQ got 7, M-DAQ enqueued 7 and publish out resend request for 4-6.
2017-06-19 16:01:45,179 outgoing A35=2 A7=325464 (RESEND REQUEST)
2017-06-19 16:01:45,179 Sent ResendRequest FROM: 325464 TO: 325466

At the same time M-DAQ proceeded 4,5 and the next incoming sequence number expected is 6 now.
2017-06-19 16:01:45,179 ERROR quickfixj.errorEvent MsgSeqNum too high, expecting 325466 but received 325468: A34=325468

M-DAQ enqueued 8 again and not sending resend request due to sent already.
2017-06-19 16:01:45,179 [QFJ Message Processor] INFO quickfixj.event - FIX.4.4:M-DAQ->Client: Enqueued at pos 325468: A34=325468
2017-06-19 16:01:45,179 [QFJ Message Processor] INFO quickfixj.event - FIX.4.4:M-DAQ->Client: Already sent ResendRequest FROM: 325464 TO: 325466. Not sending another.

Same as 8, and following incoming 9,10,11,12,13,14,15 M-DAQ just enqueued every coming new message and wait for 6.

Client finally ack the resend request and send M-DAQ ask reset from 4 to 16, but Quickfix/J does not process this as its still expect 6.
2017-06-19 16:01:45,513 [SocketConnectorIoProcessor-1.0] INFO quickfixj.msg.incoming - FIX.4.4:M-DAQ->Client: 8=FIX.4.4^A9=86^A35=4^A34=325464^A43=Y^A56=M-DAQ^A49=Client^A52=20170619-08:01:45.351^A123=Y^A36=325476^A10=214^A
2017-06-19 16:01:45,532 [SocketConnectorIoProcessor-1.0] INFO quickfixj.msg.incoming - FIX.4.4:M-DAQ->Client: A34=325476
2017-06-19 16:01:45,532 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4:M-DAQ->Client: MsgSeqNum too high, expecting 325466 but received 325476: A34=325476

For the following incoming messages keep enqueued and keep expecting 6
2017-06-19 16:01:45,532 [QFJ Message Processor] INFO quickfixj.event - FIX.4.4:M-DAQ->Client: Enqueued at pos 325476: A34=325476
2017-06-19 16:01:45,540 [SocketConnectorIoProcessor-1.0] INFO quickfixj.msg.incoming - FIX.4.4:M-DAQ->Client: A34=325477
2017-06-19 16:01:45,540 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4:M-DAQ->Client: MsgSeqNum too high, expecting 325466 but received 325477: A34=325477
2017-06-19 16:01:45,540 [QFJ Message Processor] INFO quickfixj.event - FIX.4.4:M-DAQ->Client: Enqueued at pos 325477: A34=325477
...

The question is, is this a known bug and has it been solved already?



 Comments   
Comment by Yang Cheng [ 21/Jun/17 ]

Similar issue here http://www.quickfixj.org/jira/browse/QFJ-814





[QFJ-927] Message sequence number mismatch and reset not working correctly cause Out of Memorry issue Created: 20/Jun/17  Updated: 12/Nov/18  Resolved: 12/Nov/18

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

Type: Bug Priority: Blocker
Reporter: Yang Cheng Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-928 SequenceReset not processed when out ... Closed

 Comments   
Comment by Yang Cheng [ 21/Jun/17 ]

Please refet to http://www.quickfixj.org/jira/browse/QFJ-928 has more detailed description





[QFJ-926] Session reset happens after logon Created: 23/May/17  Updated: 23/Dec/19  Resolved: 03/Jul/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: 1.6.4

Type: Bug Priority: Major
Reporter: Nickolay Dul Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-988 Session reset happens after logon Closed

 Description   

scenario:

application is handling several FIX sessions (initiators)
app started in the off time – FIX sessions are successfully created and reset

{{11 May 23:40:10.450 INFO (Thread-3) Session FIX.4.4:SENDER_ONE->TARGET schedule is THU 04:05:00-UTC - THU 20:30:00-UTC
11 May 23:40:10.452 INFO (Thread-3) Session state is not current; resetting FIX.4.4:SENDER_ONE->TARGET
11 May 23:40:10.459 INFO (Thread-3) Created session: FIX.4.4:SENDER_ONE->TARGET

11 May 23:40:10.501 INFO (Thread-3) Session FIX.4.4:SENDER_TWO->TARGET schedule is THU 04:07:00-UTC - THU 20:30:00-UTC
11 May 23:40:10.502 INFO (Thread-3) Session state is not current; resetting FIX.4.4:SENDER_TWO->TARGET
11 May 23:40:10.509 INFO (Thread-3) Created session: FIX.4.4:SENDER_TWO->TARGET
}}

on the next day logons are initiated according to session’s schedules

but the first session reset is happened in the middle of message handling:
(which is result in re-logon and “MsgSeqNum too low” issue)

  1. SENDER_ONE
    12 May 06:05:00.932 INFO (QFJ Timer) Initiated logon request
    12 May 06:05:01.145 INFO (QFJ Message Processor) Received logon
    12 May 06:05:01.149 INFO (QFJ Message Processor) Sent ResendRequest FROM: 1 TO: 2385
    12 May 06:05:01.150 INFO (QFJ Message Processor) Logon has been established: FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:01.156 INFO (QFJ Message Processor) Session state is not current; resetting FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:01.168 INFO (QFJ Message Processor) Session has been logged out: FIX.4.4:SENDER_ONE->TARGET
    12 May 06:05:16.928 INFO (QFJ Timer) Initiated logon request
    12 May 06:05:17.160 INFO (QFJ Message Processor) Received logout request: MsgSeqNum too low, expecting 4 but received 1

on other hand second session starts normally (reset happens before logon):

  1. SENDER_TWO
    12 May 06:07:00.929 INFO (QFJ Timer) Session state is not current; resetting FIX.4.4:SENDER_TWO->TARGET
    12 May 06:07:00.930 INFO (QFJ Timer) Initiated logon request
    12 May 06:07:01.103 INFO (QFJ Message Processor) Received logon
    12 May 06:07:01.103 INFO (QFJ Message Processor) Sent ResendRequest FROM: 1 TO: 2612
    12 May 06:07:01.103 INFO (QFJ Message Processor) Logon has been established: FIX.4.4:SENDER_TWO->TARGET

I guess the problem is how session reset is handled in Session::next() method:
look like sometimes the previous session time check is happenning less then 1 sec ago – it is skipped – and as a result session reset is accured already after logon



 Comments   
Comment by Nickolay Dul [ 23/May/17 ]

I guess the problem is how session reset is handled in Session::next() method:
look like sometimes the previous session time check is happenning less then 1 sec ago – it is skipped – and as a result session reset is accured already after logon

if (sessionSchedule != null && !sessionSchedule.isNonStopSession()) {
    // Only check the session time once per second at most. It isn't
    // necessary to do for every message received.
    final long now = SystemTime.currentTimeMillis();
    if ((now - lastSessionTimeCheck) >= 1000L) {
        lastSessionTimeCheck = now;
        if (!isSessionTime()) {
            if (state.isResetNeeded()) {
                reset(); // only reset if seq nums are != 1
            }
            return; // since we are outside of session time window
        } else {
            resetIfSessionNotCurrent(sessionID, now);
        }
    }
}
Comment by Nickolay Dul [ 23/May/17 ]

extra question:
according to log Session::next() can be called from different threads
so why lastSessionTimeCheck field is not volatile?

12 May 06:05:00.932 INFO (QFJ Timer) Initiated logon request
12 May 06:05:01.156 INFO (QFJ Message Processor) Session state is not current; resetting FIX.4.4:SENDER_ONE->TARGET
Comment by Nickolay Dul [ 23/May/17 ]

still have no reliable fix for this (just because not very familiar with QuickFIX/J code)

perhaps we should add additional check - like:

if ((now - lastSessionTimeCheck) >= 1000L || (!state.isLogonReceived() && state.isLogonSendNeeded())) {
Comment by Christoph John [ 03/Jul/17 ]

Hi Nickolay Dul,
I looked at this. Your proposed fix seems to correct the problem but only for Initiators. Will take a further look.
Cheers,
Chris.

Comment by Christoph John [ 03/Jul/17 ]

Is now corrected for initiators and acceptors.





[QFJ-925] Unable to reset sequence number on end of the session Created: 12/May/17  Updated: 12/May/17  Resolved: 12/May/17

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

Type: Other Priority: Critical
Reporter: hemant Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hello,

I am developing an adapter for FIX market.
As per our requirement, we want to maintain sequence number in case adapter gets restarts mid of the day. But we want to reset the sequence at a specific timing(market end of trading time).

We are using quick fix configurations:
StartTime: <some value>
EndTime: <some value>
ResetOnLogon: N

But sequence number does not get reset at the start of new session. Please suggest.

Thanks
Hemant



 Comments   
Comment by Christoph John [ 12/May/17 ]

Please use the mailing list for help requests.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Also post your config there.





[QFJ-924] unable to subscribe secuirty defintion Response for composite markets using Startegy Perefrence=1 Created: 26/Apr/17  Updated: 26/Apr/17  Resolved: 26/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.6.3
Fix Version/s: None

Type: Other Priority: Default
Reporter: LakshmiBoppana Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

Hi Team,
We are sending Security Definition request from our application with below values
SecurityRequestType=101
Strategy Preference=1
Markets=317,134,60,133

iam looking for composite spreads Security definition response i.e we are testing API 3.2 changes for composite vdissemination.
We are getting below response in our logs

ICE:WEBICE: 8=FIX.4.49=61935=UDS49=ICE34=70752=20170424-10:18:18.37856=3857=69322=247375320=OP008323=455=507819148=WMJ SQJ0017.M001722=8207=IFEU9048=WMJ 800 5078191167=MLEG541=20170501107=Freight Futures (USD) - TC5 - Q2 17326=17762=800996=mt9064=060=20161210-21:33:46.3459013=0.00019014=1.09083=4.09084=09061=32449030=39091=TC5 MEGulf-JP9092=19040=0.00019041=1.09100=USD9101=USD / mt9185=2.09022=39024=1.09205=19215=1555=3600=5038896609=FUT624=1623=19623=19624=19566=39567=1600=5052858609=FUT624=1623=19623=19624=19566=39567=1600=5070156609=FUT624=1623=19623=19624=19566=39567=110=077

But we are getting the below error in our logs
Error occurred while cracking the received message
quickfix.UnsupportedMessageType
at quickfix.fixt11.MessageCracker.onMessage(MessageCracker.java:29)

in response i coukld see that 35 has value'UDS' ,so can you please confirm whether i need to difine <message name="SecurityDefinition" msgtype="UDS" msgcat="app"> in my datadictionary? or <message name="SecurityDefinition" msgtype="d" msgcat="app"> should be fine where msgtype='d'?



 Comments   
Comment by Christoph John [ 26/Apr/17 ]

Please use the mailing list. https://lists.sourceforge.net/lists/listinfo/quickfixj-users
This is the bug tracker.





[QFJ-923] FileStore is leaking file handles Created: 20/Apr/17  Updated: 27/Jul/17  Resolved: 19/Jul/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.2, 1.6.3
Fix Version/s: 1.6.4

Type: Bug Priority: Critical
Reporter: Constantin Florescu Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: Reconnect, logon, timeout
Environment:

All


Issue Links:
Relates
relates to QFJ-552 Message Stores expected to be thread ... Open
relates to QFJ-762 Message stores can become corrupted o... Open

 Description   

The FileStore like all the other stores are not synchronized.
The access to this store, at times, can be done by 2 threads concurrently.

When a session is about to be estabilished, logon request is sent to the server, if the request is not answered by the server in within the timeout period the connection is closed and the reconnect timer starts.

The problem is that when the Timeout Timer [QFJ Timer] fires it also releases [QFJ Message Processor] thread which tries to process EndOfFille/Stream event, both threads will try to reset the MessageStore on next().

During the reset() the FileStore is (re)initialized which causes the following actions: close existing files, open the files, read stores.

When done in parallel, one thread may try to open or read while the other is closing the files resulting in:
1. Read corrupted data from message stores
2. Leak file handles

Some proof:
16:18:28.763 [QFJ Timer] INFO quickfix.FileStore - initialize() called from.
at quickfix.FileStore.initialize(FileStore.java:111) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:465) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2503) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1968) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1808) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:278) [quickfixj-core-1.6.2.jar:1.6.2]

And from:
16:18:28.788 [QFJ Message Processor] INFO quickfix.FileStore - initialize() called from.
at quickfix.FileStore.initialize(FileStore.java:111) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:465) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2503) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1968) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:882) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1109) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:144) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:91) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:125) [quickfixj-core-1.6.2.jar:1.6.2]

Out of file handles:
ERROR [QFJ Timer] quickfix.SocketInitiator Error during timer processing
quickfix.RuntimeError: java.io.FileNotFoundException: [/..../Session].header (Too many open files)
at quickfix.SessionState.reset(SessionState.java:384) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2499) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1967) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1808) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:278) [quickfixj-core-1.6.2.jar:1.6.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_74]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_74]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_74]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_74]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_74]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_74]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_74]
Caused by: java.io.FileNotFoundException: [/.../Session].header (Too many open files)
at java.io.FileOutputStream.open0(Native Method) ~[?:1.8.0_74]
at java.io.FileOutputStream.open(FileOutputStream.java:270) ~[?:1.8.0_74]
at java.io.FileOutputStream.<init>(FileOutputStream.java:213) ~[?:1.8.0_74]
at java.io.FileOutputStream.<init>(FileOutputStream.java:133) ~[?:1.8.0_74]
at quickfix.FileStore.initializeMessageIndex(FileStore.java:198) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.initializeCache(FileStore.java:121) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.initialize(FileStore.java:116) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:442) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) ~[quickfixj-core-1.6.2.jar:1.6.2]
... 11 more



 Comments   
Comment by Constantin Florescu [ 20/Apr/17 ]

It is related to:
http://www.quickfixj.org/jira/browse/QFJ-762
http://www.quickfixj.org/jira/browse/QFJ-552

Comment by Christoph John [ 21/Apr/17 ]

Hi, I'm wondering if this specific issue (leaking file handles) can be fixed like QFJ-645, i.e. only allowing one reset at a time. Of course, this is no solution for the missing synchronization.
But in the next release the synchronization should be introduced anyway, see https://github.com/quickfix-j/quickfixj/pull/75

Comment by Constantin Florescu [ 24/Apr/17 ]

Unfortunately QFJ-645 won't solve my problem.

The synchronized function reset() in class Session is not called in my case. (See stack traces)
In my case resetState() should be synchronized to avoid the problem.

Comment by Christoph John [ 24/Apr/17 ]

I know that QFJ-645 won't solve your problem. I was just trying to suggest that QFJ-923 could be fixed in a similar way (NB: without synchronization).

Comment by Constantin Florescu [ 24/Apr/17 ]

Sorry, I misunderstood you. "can be fixed like QFJ-645". Ofcourse it would.
BTW, compareAndSet is a way to synchronize, but let's not get into philosophical discussions.

The following updated resetState() method fixes my problem. I just hope there are no other places where the "Stores" are accessed concurrently.

    private void resetState() {
        if (!isResettingState.compareAndSet(false, true)) {
            return;
        }
        try {
            state.reset();
            stateListener.onReset();
        } finally {
            isResettingState.set(false);
        }
    }
Comment by Christoph John [ 24/Apr/17 ]

OK, I meant literally the keyword "synchronize"
As said, there is a pull request that should address the synchronization of the filestore at least.

Comment by Constantin Florescu [ 24/Apr/17 ]

For me it is not urgent because I have a work around.
It was for others to let them know there is an issue and what to do.

About the aforementioned pull request #75, it contains only one file, FileLog, however the issue is in FileStore (MessageStore implementors in general).

Is this the right pull request?

Comment by Christoph John [ 24/Apr/17 ]

Sorry, you are completely right. I did not remember correctly that the pull request is only about the FileLog.
Is your workaround to use a custom message store with synchronized methods?

Comment by Constantin Florescu [ 24/Apr/17 ]

No. It is just synchronizing the resetState as above.

The downside is that I do not know if that is the only concurrency issue when accessing a MessageStore.
The upside is that the MessageStore is mostly unsynchronized which means no performance hit.





[QFJ-921] Support receiving higher resolution timestamps Created: 07/Apr/17  Updated: 27/Jul/17  Resolved: 11/Apr/17

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

Type: New Feature Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-873 Support processing higher resolution ... Closed

 Description   

Also see related issue QFJ-873 which will support sending, receiving and processing higher resolution timestamps on the message objects.

QFJ-921 will merely deal with accepting messages with timestamps up to picosecond precision. Internally, QFJ will still use milliseconds.






[QFJ-920] LogOff FIX Message(35=5) is not send by initiator on stop Created: 04/Apr/17  Updated: 04/Apr/17  Resolved: 04/Apr/17

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

Type: Bug Priority: Blocker
Reporter: hemant Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: QuickfixJ

Issue Links:
Duplicate
duplicates QFJ-885 SocketInitiator::stop() can't send ou... Closed

 Description   

Hello,

Whenever we stop the FIX initiator LogOff FIX message was not sent. It was working fine in previous versions as
In previous version(1.6.1)

public void stop(boolean forceDisconnect) {
logoutAllSessions(forceDisconnect); -> Logout session
stopSessionTimer(); ->Stop timer
....

In version 1.6.3.
public void stop(boolean forceDisconnect) {
+ stopInitiators(); -> which eventually invokes stopSessionTimer();
logoutAllSessions(forceDisconnect); -> As we stop the timer so Session.next() never get invoke and results that we did not send LogOut Fix Message(35=5)






[QFJ-919] Upgrade to FIX 5.0.SP3 - EP206 Created: 03/Apr/17  Updated: 04/Apr/17  Resolved: 03/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.6.3
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Anna Maria Cochetti Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-873 Support processing higher resolution ... Closed

 Description   

SP3 has been approved on November 30, 2015 to adjust timestamps to a granularity up to nanoseconds. This is a requirement for MIFID II reporting.
See "MiFiD II - Clock Synchronization Working Group
Global Technical Committee
TimeStamp Datatypes Enhancements"
Quickfix needs to upgrade before the end of 2017



 Comments   
Comment by Christoph John [ 04/Apr/17 ]

Hi Anna Maria Cochetti, there was already an issue QFJ-873 for this topic. Feel free to add any points there.
Thanks,
Chris.





[QFJ-918] Initiator failover funtion Created: 03/Apr/17  Updated: 03/Apr/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.3
Fix Version/s: None

Type: Other Priority: Default
Reporter: Cheng Guo Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

Linux



 Description   

Hi,
I just learn the QuickFIXJ, and thinking if QuickFIXJ could support the below failover/ HA scenario, or if you could give me some suggestion for the custom dev?
We act as Initiator to connect to the external acceptor, as the Initiator, we want to deploy to two servers, one as the primary which is active, the other is the backup, and non-active.
Primary will be communicating with external acceptor, meanwhile, by HA module, the secondary sync with the primary at the seq number, msg, etc.. Once primary is down, secondary will take over the primary role, and connect to the external.
Checked the document, seems QuickFIX support the acceptor failover, but dont have the initiator case?
could you help let me know how address this? thanks.

by the way, i also developing to send the FIX msg to IBM MQ, could you suggest if QuickFIXJ has the persistence module/ api to store the un-delivery msg if MQ down, and then send out once MQ is up?



 Comments   
Comment by Christoph John [ 03/Apr/17 ]

You'll need to implement the HA functionality by yourself. You could use a database, synced file system or clustered in-memory cache to store the session information. But the whole failover decision has to be implemented by your application.

Since JIRA is the bug tracker you could ask on the mailing list whether anyone has already implemented something similar: https://lists.sourceforge.net/lists/listinfo/quickfixj-users
If you need production or implementation support please check: http://www.quickfixj.org/support/

Thanks,
Chris.





[QFJ-917] Race condition between SocketAcceptorIoProcessor & QFJ Message Processor Created: 08/Mar/17  Updated: 27/Jul/17  Resolved: 29/Mar/17

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3
Fix Version/s: 1.6.4

Type: Bug Priority: Default
Reporter: Paul Rowe Assignee: Paul Rowe
Resolution: Fixed Votes: 0
Labels: logout, session
Environment:

Linux



 Description   

We experienced a race condition where Application.onLogout() method was not called.

On a Session, we issue a logout from another thread. The counterparty will then respond with a logout message and disconnect. When this happens, there are two threads in play, the "QFJ Message Processor" thread that processes the counterparty logout message, and another "SocketAcceptorIoProcessor" thread spawned by Mina when the socket disconnects. Both of these threads ultimately fall into the Session.disconnect(String,boolean) method. The sequence of events go like this in Session.disconnect():

  1. "SocketAcceptorIoProcessor" sets the responder to null
  2. "QFJ Message Processor" sees that the responder is null and returns from Session.disconnect(). The body of the Session.disconnect() method is wrapped in a try..finally block, so when "QFJ Message Processor" exits this method via the return, it sets logonReceived and logonSent flags to false.
  3. "SocketAcceptorIoProcessor" reaches if statement that checks logonReceived and logonSent, these flags were false because "QFJ Message Processor" cleared them when it exited previously. As a result, Application.onLogout() is never executed.

I took a look at QFJ-803, QFJ-810 and QFJ-790 and they aren't quite the same issue as the one we experienced. I also pulled a latest copy of the QuickFix code from master, and it appears the current code could be potentially affected by this issue.

Can you please confirm if this is a current bug in the code and/or if it has been fixed by another jira that I did not see ?



 Comments   
Comment by Paul Rowe [ 08/Mar/17 ]

Relevant logs

[2017-02-28 22:30:00,118Z][INFO][QFJ Message Processor:0x19] Received logout response
[2017-02-28 22:30:00,119Z][INFO][SocketAcceptorIoProcessor-138.0:0x19] [FIX.4.4:TS->CLIENT] Disconnecting: IO Session closed
[2017-02-28 22:30:00,127Z][INFO][QFJ Message Processor:0x19] Already disconnected: Received logout response

It is a very subtle race condition that happens in the disconnect method. Just after the "SocketAcceptorIoProcessor" thread releases the responderSync lock, a context switch happens to the "QFJ Message Processor" thread. The "QFJ Message Processor" thread will see there is no responder, and returns through the finally block clearing the session state flags. After the return, there is a context switch back to the "SocketAcceptorIoProcessor" thread where it attempts to read the logon state flags, but they have been cleared by the other thread. The trick is getting a context switch to happen just after the responderSync synchronized block.

Comment by Christoph John [ 08/Mar/17 ]

Hi Paul Rowe,

there was a pull request just recently being created that should work around this issue: https://github.com/quickfix-j/quickfixj/pull/102
So it should be fixed with the next release.

Cheers,
Chris.

Comment by Paul Rowe [ 08/Mar/17 ]

Hi Chris, thanks for the response. I reviewed the pull request. The thing that I am currently struggling with now is a unit test. Any unit tests for this laying around ?

Comment by Christoph John [ 08/Mar/17 ]

Hi Paul Rowe,

I don't have a unit test ready. However, after browsing the existing ones it might be reproducible by the same technique as used in SessionResetTest. There is a PausableThreadPoolExecutor to which you can submit two threads. Each of the threads should then call Session.disconnect() concurrently. IMHO this should exhibit the problematic behaviour (maybe not always, though).

Cheers,
Chris.

Comment by Paul Rowe [ 08/Mar/17 ]

OK I will see if I can whip one up and if so I will also submit a pull request. Thanks.

Comment by Christoph John [ 08/Mar/17 ]

Great, thanks.

Comment by Paul Rowe [ 09/Mar/17 ]

I think the pull request generated by another QF user had issues (I commented on them there), so I generated my own pull request and submitted it to the QF team for review.





[QFJ-916] Reconnection feature does not work under some circumstances Created: 18/Feb/17  Updated: 17/Oct/18  Resolved: 17/Oct/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: 1.6.3
Fix Version/s: 2.1.0

Type: Bug Priority: Default
Reporter: Arsentii Nerushev Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: QuickfixJ, Reconnect
Environment:

Java 1.8.0u66 x64, Windows 8.1, no network proxy


Issue Links:
Relates
relates to QFJ-942 Connectors sometimes hanging in call ... Closed

 Description   

Had an application running from morning but on the evening checkup I observed strange behavior of the reconnection feature. I believe there was some connectivity issue, the application missed a heartbeat so the session had been disconnected and logged out. I don't really understand what happened next, but it seems the connection itself (with the remote host) was restored but the messages weren't going anywhere as the session's state wasn't 'logged on' at the moment, and the Engine wasn't trying to log the session on again.
I tried to reproduce the issue by manually closing the connection slightly before the heartbeat check, but the Engine had actually reset the connection after I opened it again seeing the disconnection message.

I've got some logs from both cases (see below). reconnectionInterval = 30.
I've noticed that in the second ("OK") case there is a line

"d.q.m.i.IoSessionInitiator [QFJ Timer] - [...] - reset IoConnector"

whereas there's none such in the first case, but a couple of hours of digging the quickfix/j's sources haven't brought me anywhere. The line appears when the reconnectionTask (which runs at a schedule with 1 second interval) of quickfix.mina.initiator.IoSessionInitiator is at the 'resetIoConnector()' method and the condition

ioSession != null && Boolean.TRUE.equals(ioSession.getAttribute("QFJ_RESET_IO_CONNECTOR"))

is true by the moment. So, either ioSession is null or its "reset" attribute is not set to true. The 'disconnect' method of quickfix.Session has a line 'responder.disconnect();' which leads us to quickfix.mina.IoSessionResponder's lines:

ioSession.closeOnFlush();
ioSession.setAttribute("QFJ_RESET_IO_CONNECTOR", Boolean.TRUE);

So, the attribute is definitely set, but as for the nullifying the ioSession's reference I can't really say anything. All I know is that the ioSession's reference is being read & written in quickfix.mina.initiator.IoSessionInitiator :: resetIoConnector() method at these two possible sections:

private void pollConnectFuture() {
            try {
                connectFuture.awaitUninterruptibly(CONNECT_POLL_TIMEOUT);
                if (connectFuture.getSession() != null) { // probably true
                    ioSession = connectFuture.getSession();
                    connectionFailureCount = 0;
                    lastConnectTime = System.currentTimeMillis();
                    connectFuture = null;
                } else {
                    fixSession.getLog().onEvent(
                            "Pending connection not established after "
                                    + (System.currentTimeMillis() - lastReconnectAttemptTime)
                                    + " ms.");
                }
            } catch (Throwable e) {
                handleConnectException(e);
            }
        }
}

and

        private void resetIoConnector() {
            if (ioSession != null && Boolean.TRUE.equals(ioSession.getAttribute("QFJ_RESET_IO_CONNECTOR"))) {
                try {
                    setupIoConnector();
                    log.info("[" + fixSession.getSessionID() + "] - reset IoConnector");
                    if (connectFuture != null) {
                        connectFuture.cancel();
                    }
                    connectFuture = null;
                    ioSession = null;
                } catch (Throwable e) {
                    log.error("[" + fixSession.getSessionID() + "] - Exception during resetIoConnector call", e);
                }
            }
        }

The latter one is definitely not the case as this method have never been invoked in the issue (we don't see the

"d.q.m.i.IoSessionInitiator [QFJ Timer] - [...] - reset IoConnector"

line in the log).

It's also unlikely that ioSession is set to null in the former section, as the value comes from connectFuture.getSession() which, if being null, would lead to logging of a "Pending connection not established" line. I thought maybe connectFuture.getSession() at some circumstances returns another IoSession object reference, for which there's no "QFJ_RESET_IO_CONNECTOR" attribute set, but it would be too weird for MINA. So, it's likely not the case, and the only reason the resetIoConnector()'s check fails is that the reconnectionTask's run() method is no more being invoked by ScheduledExecutor.

ioSession have also never been closed as it would fire the public void sessionClosed(IoSession ioSession) callback in quickfix.mina.AbstractIoHandler, which in our case it wouldn't, even though quickfix.Session :: disconnect -> quickfix.mina.IoSessionResponder :: disconnect ->
ioSession.closeOnFlush() has been invoked.

I know that a bug is hard to fix when you can't reproduce the issue, so I've instrumented the quickfix/j source code in some places, and if this issue comes again, there will be more information available.

Here's a chunk of the log from the issue:

18:05:08.608 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=60 35=0 34=987 49=mySenderCompID 52=20170216-15:04:44.955 56=FG 10=245 
18:05:08.608 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=61 35=0 49=FG 56=mySenderCompID 34=1031 52=20170216-15:05:02.450 10=004 
18:05:48.648 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=82 35=0 34=988 49=mySenderCompID 52=20170216-15:05:42.889 56=FG 112=20170216-15:03:21 10=049 
18:06:42.007 ERROR quickfixj.errorEvent [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Disconnecting: Timed out waiting for heartbeat
18:07:02.056 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=1 34=989 49=mySenderCompID 52=20170216-15:06:18.777 56=FG 112=TEST 10=024 
18:07:07.852 INFO  c.r.c.c.f.m.s.SessionManager [QFJ Message Processor]: the session has been logged out.
18:07:07.852 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: No responder, not sending message: 8=FIX.4.4 9=69 35=1 34=989 49=mySenderCompID 52=20170216-15:06:18.777 56=FG 112=TEST 10=024 
18:07:24.587 INFO  quickfixj.event [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: Already disconnected: Socket exception (/there-was-exchange-ip:port): java.io.IOException: Software caused connection abort
18:07:36.418 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: Sent test request TEST
18:10:45.383 ERROR quickfixj.errorEvent [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: quickfix.SessionException Logon state is not valid for message (MsgType=0)
18:11:53.890 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Already disconnected: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=0)
18:15:08.548 ERROR quickfixj.errorEvent [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: quickfix.SessionException Logon state is not valid for message (MsgType=1)
18:20:24.634 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Already disconnected: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=1)
18:27:38.224 ERROR quickfixj.errorEvent [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: quickfix.SessionException Logon state is not valid for message (MsgType=0)
18:29:40.972 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Already disconnected: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=0)

Here's a chunk of the log from the case when I manually switched off the connection:

00:57:35.829 INFO  q.DefaultSessionSchedule [main] - [FIX.4.4:mySenderCompID->FG] daily, 07:00:00-UTC - 07:00:00-UTC
00:57:35.858 INFO  quickfixj.event [main] - FIX.4.4:mySenderCompID->FG: Session FIX.4.4:mySenderCompID->FG schedule is daily, 07:00:00-UTC - 07:00:00-UTC
00:57:35.858 INFO  quickfixj.event [main] - FIX.4.4:mySenderCompID->FG: Created session: FIX.4.4:mySenderCompID->FG
00:57:35.858 INFO  c.r.c.c.f.m.s.SessionManager [main]: the session has been created.
00:57:35.865 INFO  q.mina.NetworkingOptions [main] - Socket option: SocketTcpNoDelay=true
00:57:35.870 INFO  q.mina.NetworkingOptions [main] - Socket option: SocketSynchronousWrites=false
00:57:35.870 INFO  q.mina.NetworkingOptions [main] - Socket option: SocketSynchronousWriteTimeout=30000
00:57:35.939 INFO  d.q.m.i.IoSessionInitiator [main] - [FIX.4.4:mySenderCompID->FG] [/there-was-exchange-ip:port]
00:57:35.940 INFO  quickfix.SocketInitiator [main] - SessionTimer started
00:57:35.943 INFO  quickfix.SocketInitiator [QFJ Message Processor] - Started QFJ Message Processor
00:57:35.988 INFO  q.m.i.InitiatorIoHandler [NioProcessor-2] - MINA session created for FIX.4.4:mySenderCompID->FG: local=/there-was-my-ip:60450, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/there-was-exchange-ip:port
00:57:36.975 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=71 35=A 34=35 49=mySenderCompID 52=20170218-21:57:36.965 56=FG 98=0 108=30 10=234 
00:57:36.980 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: Initiated logon request
00:57:37.003 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-2] - Processing a MESSAGE_RECEIVED for session 1
00:57:37.006 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=71 35=A 49=FG 56=mySenderCompID 34=35 52=20170218-21:58:55.258 98=0 108=30 10=231 
00:57:37.007 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 49=FG 56=mySenderCompID 34=36 52=20170218-21:58:55.258 7=33 16=0 10=119 
00:57:37.016 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received logon
00:57:37.016 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: MsgSeqNum too high, expecting 34 but received 35: 8=FIX.4.4 9=71 35=A 34=35 49=FG 52=20170218-21:58:55.258 56=mySenderCompID 98=0 108=30 10=231 
00:57:37.016 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Enqueued at pos 35: 8=FIX.4.4 9=71 35=A 34=35 49=FG 52=20170218-21:58:55.258 56=mySenderCompID 98=0 108=30 10=231 
00:57:37.017 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 34=36 49=mySenderCompID 52=20170218-21:57:37.017 56=FG 7=34 16=0 10=112 
00:57:37.017 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent ResendRequest FROM: 34 TO: 34
00:57:37.017 INFO  c.r.c.c.f.m.s.SessionManager [QFJ Message Processor]: the session has been logged on.
00:57:37.025 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Enqueued at pos 36: 8=FIX.4.4 9=69 35=2 34=36 49=FG 52=20170218-21:58:55.258 56=mySenderCompID 7=33 16=0 10=119 
00:57:37.025 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received ResendRequest FROM: 33 TO: infinity
00:57:37.028 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=102 35=4 34=33 43=Y 49=mySenderCompID 52=20170218-21:57:37.027 56=FG 122=20170218-21:57:37.027 36=37 123=Y 10=040 
00:57:37.028 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent SequenceReset TO: 37
00:57:37.033 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-2] - Processing a MESSAGE_RECEIVED for session 1
00:57:37.033 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=98 35=4 49=FG 56=mySenderCompID 34=34 43=Y 52=20170218-21:58:55.294 122=20170218-21:58:55 123=Y 36=37 10=072 
00:57:37.033 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 49=FG 56=mySenderCompID 34=37 52=20170218-21:58:55.294 7=33 16=0 10=120 
00:57:37.034 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: ResendRequest for messages FROM 34 TO 34 has been satisfied.
00:57:37.034 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received SequenceReset FROM: 34 TO: 37
00:57:37.034 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received ResendRequest FROM: 33 TO: infinity
00:57:37.035 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=102 35=4 34=33 43=Y 49=mySenderCompID 52=20170218-21:57:37.035 56=FG 122=20170218-21:57:37.035 36=37 123=Y 10=038 
00:57:37.035 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent SequenceReset TO: 37
00:57:37.099 INFO  OUTGOING [FIX Gate Mail Thread] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=139 35=D 34=37 49=mySenderCompID 52=20170218-21:57:37.097 56=FG 1=U51 11=0 38=1 40=2 44=17000 54=1 55=SRH7 59=0 60=20170219-00:57:37.096 1300=F 10=244 
00:57:37.125 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-2] - Processing a MESSAGE_RECEIVED for session 1
00:57:37.125 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=231 35=8 49=FG 56=mySenderCompID 34=38 52=20170218-21:58:55.377 37=0 198=F:0 526=$01$ 11=0 17=3617265603 150=8 39=8 103=99 55=SRH7 54=1 38=1 40=2 151=1 14=0 6=0 60=20170218-21:58:55.376 58=3;Session inactive. 20018=[51000-3617265603-0] 10=090 
00:57:42.123 DEBUG c.r.c.c.f.m.s.SessionManager [FIX Gate Mail Thread]: done processing an outgoing trading message.
00:57:42.131 INFO  OUTGOING [FIX Gate Mail Thread] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=117 35=q 34=38 49=mySenderCompID 52=20170218-21:57:42.122 56=FG 1=U51 11=1F 55=SRH7 60=20170219-00:57:42.122 530=1 1300=F 10=079 
00:57:42.149 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-2] - Processing a MESSAGE_RECEIVED for session 1
00:57:42.149 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=186 35=r 49=FG 56=mySenderCompID 34=39 52=20170218-21:59:00.409 11=1F 37=exec-201702181824434 530=1 531=1 533=0 58=0;Operation successful. 60=20170218-21:59:00.408 20018=[51000-3617265614-0] 10=123 
00:58:11.992 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-2] - Processing a MESSAGE_RECEIVED for session 1
00:58:11.992 INFO  INCOMING [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=59 35=0 49=FG 56=mySenderCompID 34=40 52=20170218-21:59:30.252 10=179 
00:58:12.948 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=59 35=0 34=39 49=mySenderCompID 52=20170218-21:58:12.941 56=FG 10=191 
00:58:42.948 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=59 35=0 34=40 49=mySenderCompID 52=20170218-21:58:42.941 56=FG 10=186 
00:58:57.948 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=68 35=1 34=41 49=mySenderCompID 52=20170218-21:58:57.941 56=FG 112=TEST 10=212 
00:58:57.949 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: Sent test request TEST
00:59:01.895 ERROR quickfixj.errorEvent [NioProcessor-2] - FIX.4.4:mySenderCompID->FG: Disconnecting: Socket exception (/there-was-exchange-ip:port): java.io.IOException: Connection reset by peer
00:59:01.903 INFO  c.r.c.c.f.m.s.SessionManager [NioProcessor-2]: the session has been logged out.
00:59:02.563 INFO  d.q.m.i.IoSessionInitiator [QFJ Timer] - [FIX.4.4:mySenderCompID->FG] - reset IoConnector
00:59:02.565 ERROR quickfixj.errorEvent [QFJ Timer] - FIX.4.4:mySenderCompID->FG: java.net.NoRouteToHostException during connection to /there-was-exchange-ip:port: java.net.NoRouteToHostException: No route to host: no further information (Next retry in 30000 milliseconds)
00:59:32.713 INFO  q.m.i.InitiatorIoHandler [NioProcessor-12] - MINA session created for FIX.4.4:mySenderCompID->FG: local=/there-was-my-ip:60459, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/there-was-exchange-ip:port
00:59:32.941 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=71 35=A 34=42 49=mySenderCompID 52=20170218-21:59:32.941 56=FG 98=0 108=30 10=224 
00:59:32.949 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: Initiated logon request
00:59:32.984 INFO  quickfix.Session [QFJ Message Processor] - [FIX.4.4:mySenderCompID->FG] Disconnecting: Encountered END_OF_STREAM
00:59:32.992 INFO  c.r.c.c.f.m.s.SessionManager [QFJ Message Processor]: the session has been logged out.
00:59:33.724 INFO  d.q.m.i.IoSessionInitiator [QFJ Timer] - [FIX.4.4:mySenderCompID->FG] - reset IoConnector
01:00:02.879 INFO  q.m.i.InitiatorIoHandler [NioProcessor-22] - MINA session created for FIX.4.4:mySenderCompID->FG: local=/there-was-my-ip:60480, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/there-was-exchange-ip:port
01:00:02.941 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=71 35=A 34=43 49=mySenderCompID 52=20170218-22:00:02.941 56=FG 98=0 108=30 10=209 
01:00:02.952 INFO  quickfixj.event [QFJ Timer] - FIX.4.4:mySenderCompID->FG: Initiated logon request
01:00:02.981 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-22] - Processing a MESSAGE_RECEIVED for session 3
01:00:02.991 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=71 35=A 49=FG 56=mySenderCompID 34=43 52=20170218-22:01:21.219 98=0 108=30 10=209 
01:00:02.992 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 49=FG 56=mySenderCompID 34=44 52=20170218-22:01:21.219 7=40 16=0 10=095 
01:00:02.992 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received logon
01:00:03.002 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: MsgSeqNum too high, expecting 41 but received 43: 8=FIX.4.4 9=71 35=A 34=43 49=FG 52=20170218-22:01:21.219 56=mySenderCompID 98=0 108=30 10=209 
01:00:03.002 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Enqueued at pos 43: 8=FIX.4.4 9=71 35=A 34=43 49=FG 52=20170218-22:01:21.219 56=mySenderCompID 98=0 108=30 10=209 
01:00:03.003 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 34=44 49=mySenderCompID 52=20170218-22:00:03.003 56=FG 7=41 16=0 10=086 
01:00:03.003 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent ResendRequest FROM: 41 TO: 42
01:00:03.003 INFO  c.r.c.c.f.m.s.SessionManager [QFJ Message Processor]: the session has been logged on.
01:00:03.003 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Enqueued at pos 44: 8=FIX.4.4 9=69 35=2 34=44 49=FG 52=20170218-22:01:21.219 56=mySenderCompID 7=40 16=0 10=095 
01:00:03.013 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received ResendRequest FROM: 40 TO: infinity
01:00:03.014 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=102 35=4 34=40 43=Y 49=mySenderCompID 52=20170218-22:00:03.014 56=FG 122=20170218-22:00:03.014 36=45 123=Y 10=249 
01:00:03.014 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent SequenceReset TO: 45
01:00:03.022 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-22] - Processing a MESSAGE_RECEIVED for session 3
01:00:03.022 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=98 35=4 49=FG 56=mySenderCompID 34=41 43=Y 52=20170218-22:01:21.270 122=20170218-22:01:21 123=Y 36=45 10=027 
01:00:03.022 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=2 49=FG 56=mySenderCompID 34=45 52=20170218-22:01:21.270 7=40 16=0 10=093 
01:00:03.022 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received SequenceReset FROM: 41 TO: 45
01:00:03.023 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Received ResendRequest FROM: 40 TO: infinity
01:00:03.023 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=102 35=4 34=40 43=Y 49=mySenderCompID 52=20170218-22:00:03.023 56=FG 122=20170218-22:00:03.023 36=45 123=Y 10=249 
01:00:03.023 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: Sent SequenceReset TO: 45
01:00:33.049 DEBUG o.a.m.f.c.ProtocolCodecFilter [NioProcessor-22] - Processing a MESSAGE_RECEIVED for session 3
01:00:33.049 INFO  INCOMING [NioProcessor-22] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=59 35=0 49=FG 56=mySenderCompID 34=46 52=20170218-22:01:51.258 10=182 
01:00:33.060 INFO  quickfixj.event [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: ResendRequest for messages FROM 41 TO 42 has been satisfied.
01:00:33.070 INFO  OUTGOING [QFJ Message Processor] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=59 35=0 34=45 49=mySenderCompID 52=20170218-22:00:33.070 56=FG 10=172 


 Comments   
Comment by Christoph John [ 20/Feb/17 ]

Hi Arsentii Nerushev,

thanks for the detailed description. I think it would also be sensible to have some stack traces when the issue occurs the next time.
One question regarding the chunk of log lines when the issue occurred: there were no more messages than what you pasted above? I.e. there was nothing going on except for the "Logon state is not valid" message every few minutes? To me it looks like the connection went down every couple of minutes.

Thanks,
Chris.

Comment by Arsentii Nerushev [ 20/Feb/17 ]

@Christoph John
No, there were no more messages besides those ones. I logged in on the machine around 6:20 PM to check how my app's doing and found this on the log. Maybe there was no connection to the remote FIX gate at the moment – sadly, I don't remember and I didn't restart the app to check it out. The Internet connection with the machine was definitely OK, as I could connect to it remotely.
So, I would understand if the log contained some lines about a broken connection and the Engine's heroic attempts to restore it ASAP, but, alas, – there were none.
If you have some recommendations about where I should place extra logging – I'm all ears.

Comment by Christoph John [ 21/Feb/17 ]

Hi Arsentii Nerushev,

what did you do to correct the issue in the problematic case? Did you have to restart the whole application? What are the memory settings for your application and how much memory do you have available?
It is just wild guesswork but from looking at the logs it seems to me that there might be something fishy with the whole java process. Maybe some heavy GC was going on, or the OS tried to swap something out to disk which took very long, or that a thread was completely stuck. The following message supports this assumption:

18:07:02.056 INFO  OUTGOING [QFJ Timer] - FIX.4.4:mySenderCompID->FG: 8=FIX.4.4 9=69 35=1 34=989 49=mySenderCompID 52=20170216-15:06:18.777 56=FG 112=TEST 10=024 

The log time stamp is 18:07:02 but the sending time on the message is 15:06:18, so almost a minute earlier. (I assume you are UTC+3)

When the problem occurs again I would like to take a look at the following:

  • several stack dumps with jstack <pid>
  • also output of jmap -heap <pid>
  • and output of jstat -gcutil <pid> 1000 10

Edit: I would also like to know how much memory, disk and swap is free at that moment. I don't know the commands for this on Windows, but I suppose you do.

Thanks,
Chris.

Comment by Christoph John [ 17/Oct/18 ]

I think this has been fixed with QFJ-942. Although I cannot tell without a stack trace.
Feel free to re-open when you have new information.





[QFJ-915] After sending TEST REQUEST message, FIXEngine can't be connected Created: 14/Feb/17  Updated: 15/Feb/17  Resolved: 15/Feb/17

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

Type: Bug Priority: Default
Reporter: Dai Shinohara Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: QuickfixJ, testRequest, timeout
Environment:

Java 1.7, RHEL 6.3



 Description   

We are using QuickFIX on the Initiator side.
Suddenly, QuickFIX sent TEST REQUEST.
Acceptor returned HEARTBEAT message immediately.
But QuickFIX didn't recognize HEARTBEAT message.
Therefore QuickFIX judged time-out.

After judging time-out, QuickFIX sent LOGON message.
Acceptor returned LOGON message immediately.
But QuickFIX didn't recognize LOGON message again.
Therefore QuickFIX judged time-out.

20170209-00:01:26: Sent test request TEST
20170209-00:02:20: Disconnecting: Timed out waiting for heartbeat
20170209-00:02:21: Initiated logon request
20170209-00:02:32: Disconnecting: Timed out waiting for logon response
20170209-00:02:33: Initiated logon request
20170209-00:02:43: Disconnecting: Timed out waiting for logon response
20170209-00:02:44: Initiated logon request
20170209-00:02:54: Disconnecting: Timed out waiting for logon response
20170209-00:02:55: Initiated logon request
20170209-00:03:05: Disconnecting: Timed out waiting for logon response

Acceptor message log:
2017 Feb 09 09:01:24.041.936 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:24.041,34=1195283,...
2017 Feb 09 09:01:24.203.275 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:01:24.203,34=1195284,...
2017 Feb 09 09:01:24.424.520 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:01:24.424,34=1195285,...
2017 Feb 09 09:01:25.012.688 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:01:25.012,34=1195286,...
2017 Feb 09 09:01:25.013.568 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:25.013,34=1195287,...
2017 Feb 09 09:01:25.109.057 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:01:25.108,34=1195288,...
2017 Feb 09 09:01:25.293.963 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:01:25.293,34=1195289,...
2017 Feb 09 09:01:25.525.713 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:25.525,34=1195290,...
2017 Feb 09 09:01:26.141.202 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:26.141,34=1195291,...
2017 Feb 09 09:01:26.270.703 [FIXRCV] 8=FIX.4.4,9=70,35=1,34=5411,49=...,52=20170209-00:01:26.270,56=...,112=TEST,10=146
2017 Feb 09 09:01:26.270.787 [FIXSND] 8=FIX.4.4,9=73,35=0,52=20170209-00:01:26.270,34=1195292,49=SCI,56=...,112=TEST,10=054
2017 Feb 09 09:01:26.424.711 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:01:26.424,34=1195293,...
2017 Feb 09 09:01:26.429.398 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:26.429,34=1195294,...
2017 Feb 09 09:01:26.641.169 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:01:26.641,34=1195295,...
2017 Feb 09 09:01:26.994.496 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:01:26.994,34=1195296,...
2017 Feb 09 09:01:26.994.933 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:01:26.994,34=1195297,...
2017 Feb 09 09:01:27.109.910 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:01:27.109,34=1195298,...
.
.
.
2017 Feb 09 09:02:18.992.329 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:02:18.992,34=1195523,...
2017 Feb 09 09:02:19.300.151 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:02:19.300,34=1195524,...
2017 Feb 09 09:02:19.310.049 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:02:19.309,34=1195525,...
2017 Feb 09 09:02:19.508.998 [FIXSND] 8=FIX.4.4,9=220,35=S,52=20170209-00:02:19.508,34=1195526,...
2017 Feb 09 09:02:19.720.621 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:02:19.720,34=1195527,...
2017 Feb 09 09:02:19.766.977 [FIXSND] 8=FIX.4.4,9=216,35=S,52=20170209-00:02:19.766,34=1195528,...
2017 Feb 09 09:02:19.888.979 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:02:19.888,34=1195529,...
2017 Feb 09 09:02:19.949.890 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:02:19.949,34=1195530,...
2017 Feb 09 09:02:20.050.769 [FIXSND] 8=FIX.4.4,9=218,35=S,52=20170209-00:02:20.050,34=1195531,...
2017 Feb 09 09:02:21.271.969 [FIXRCV] 8=FIX.4.4,9=76,35=A,34=1,49=...,52=20170209-00:02:21.271,56=...,98=0,108=60,141=Y,10=066
2017 Feb 09 09:02:21.312.495 [FIXSND] 8=FIX.4.4,9=76,35=A,52=20170209-00:02:21.312,34=1,49=SCI,56=JBKI-QUOTE01,98=0,108=60,141=Y,1

Initiator message log
8=FIX.4.4^A9=218^A35=S^A52=20170209-00:02:19.309^A34=1195525...
8=FIX.4.4^A9=220^A35=S^A52=20170209-00:02:19.508^A34=1195526...
8=FIX.4.4^A9=216^A35=S^A52=20170209-00:02:19.720^A34=1195527...
8=FIX.4.4^A9=216^A35=S^A52=20170209-00:02:19.766^A34=1195528...
8=FIX.4.4^A9=218^A35=S^A52=20170209-00:02:19.888^A34=1195529...
8=FIX.4.4^A9=218^A35=S^A52=20170209-00:02:19.949^A34=1195530...
8=FIX.4.4^A9=218^A35=S^A52=20170209-00:02:20.050^A34=1195531...
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:02:21.271^A56=...^A98=0^A108=60^A141=Y^A10=066^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:02:21.312^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=062^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:02:33.270^A56=...^A98=0^A108=60^A141=Y^A10=068^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:02:33.283^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=072^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:02:44.270^A56=...^A98=0^A108=60^A141=Y^A10=070^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:02:44.285^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=076^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:02:55.270^A56=...^A98=0^A108=60^A141=Y^A10=072^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:02:55.280^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=073^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:03:06.270^A56=...^A98=0^A108=60^A141=Y^A10=069^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:03:06.285^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=075^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:03:17.270^A56=...^A98=0^A108=60^A141=Y^A10=071^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:03:17.279^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=080^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:03:28.270^A56=...^A98=0^A108=60^A141=Y^A10=073^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:03:28.280^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=074^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:03:39.270^A56=...^A98=0^A108=60^A141=Y^A10=075^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:03:39.304^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=073^A
8=FIX.4.4^A9=76^A35=A^A34=1^A49=...^A52=20170209-00:03:50.270^A56=...^A98=0^A108=60^A141=Y^A10=068^A
8=FIX.4.4^A9=76^A35=A^A52=20170209-00:03:50.282^A34=1^A49=...^A56=...^A98=0^A108=60^A141=Y^A10=071^A

We hava 2 questions.
1.Why did QuickFIX send TEST REQUEST suddenly?
2.Is this problem settled by a newest version?



 Comments   
Comment by Christoph John [ 15/Feb/17 ]

Looks like a thread is hanging, but without a stack trace it is impossible to tell. When the issue occurs next time, please create a stack trace and attach it here.





[QFJ-914] Generate and package javadoc for release build Created: 14/Feb/17  Updated: 27/Jul/17  Resolved: 24/Jul/17

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

Type: Improvement Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

-------- Forwarded Message --------
Subject: Re: [Quickfixj-users] QuickFIX/J 1.6.3 Javadoc - Message classes appear to be missing
Date: Wed, 1 Feb 2017 09:16:59 -0700 (MST)
From: thannon <[email protected]>
Reply-To: [email protected]
To: [email protected]

QuickFIX/J Documentation: http://www.quickfixj.org/documentation/
QuickFIX/J Support: http://www.quickfixj.org/support/

I think it would be helpful for release builds. Having Javadoc is useful
with some IDEs, and particularly for those that are not as familiar with or
new to QF/J or those that only work with it occasionally.

Thank you.

Javadoc generation was disabled some time ago since it took quite long. We should re-enable it for release builds only.

Or more specifically: check that javadoc for field and message classes is included in the distribution release. At all other times one could build the packages with the option -Dmaven.javadoc.skip=true.






[QFJ-913] SSL warning when using default keystore (quickfixj.keystore) Created: 07/Feb/17  Updated: 10/May/18  Resolved: 09/May/18

Status: Closed
Project: QuickFIX/J
Component/s: Build, Networking
Affects Version/s: 1.6.0, 1.6.1, 1.6.2, 1.6.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: chenbaoyi Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

java version "1.8.0_92"
Java(TM) SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.92-b14, mixed mode)

Linux version 2.6.32-642.11.1.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) ) #1 SMP Fri Nov 18 19:25:05 UTC 2016



 Description   

[DEFAULT]
BeginString=FIX.4.3
ConnectionType=initiator
EndDay=xxxxx
StartDay=Sunday
EndTime=xxxxxx
StartTime=xxxxx
HeartBtInt=30
ResetOnLogon=Y
ResetOnLogout=N
ResetOnDisconnect=N
ReconnectInterval=xxxx
FileIncludeMilliseconds=Y
FileIncludeTimeStampForMessages=Y
FileLogPath=xxxxxx
FileStorePath=xxxxx
ValidateUserDefinedFields=N
ValidateFieldsHaveValues=N
ValidateFieldsOutOfOrder=N
ValidateUnorderedGroupFields=N
ValidateSequenceNumbers=N

[SESSION]
Username=xxxxx
Password=xxxxx
SenderCompID=xxx
TargetCompID=xxx
SocketUseSSL=Y
SocketConnectPort=xxxx
SocketConnectHost=xxx.xxx.xxx.xxx
DataDictionary=xxx.xml

using above setting
when connect to acceptor
console will log a warnning
SSLContextFactory.initializeKeyStore:111]quickfixj.keystore: keystore not found, using empty keystore

the root cause of this issue is when building quickfixj-1.6.3
quickfixj-core/pom.xml does not contains the /src/main/resources



 Comments   
Comment by Christoph John [ 07/Feb/17 ]

Why would you want to use the default keystore shipped with QFJ?

Comment by chenbaoyi [ 07/Feb/17 ]

cuz refer to http://www.quickfixj.org/quickfixj/usermanual/1.6.3/usage/secure_communications.html
The default usage of SSL just only need to set SocketUseSSL=Y

Comment by Christoph John [ 07/Feb/17 ]

OK, great. But believe me, in the real world you really should rely on an own certificate.

Comment by Piyush [ 09/May/18 ]

I am facing the issue with 1.6.4 version as well. Is the issue resolved?

Comment by Christoph John [ 09/May/18 ]

Actually, this is no bug. Just use a custom certificate and specify it using SocketKeyStore property.

Comment by Piyush [ 10/May/18 ]

But I don't have any custom certificate. How to solve this issue without custom certificate,

Comment by Christoph John [ 10/May/18 ]

Just create one: https://www.sslshopper.com/article-how-to-create-a-self-signed-certificate-using-java-keytool.html or https://discuss.pivotal.io/hc/en-us/articles/202652748-Generating-a-self-signed-SSL-certificate-using-the-Java-keytool-command-

But what do you want to use SSL for if you do not have a custom certificate?





[QFJ-912] Support use of externally supplied ThreadPools Created: 24/Jan/17  Updated: 27/Jul/17  Resolved: 31/Jan/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.3
Fix Version/s: 1.6.4

Type: New Feature Priority: Default
Reporter: James Olsen Assignee: James Olsen
Resolution: Fixed Votes: 0
Labels: None


 Description   

Currently when embedding QFJ inside a ResourceAdapter we end up with double the Threads running as we have to hand-off from QFJ ('dirty') Threads to the ResourceAdapter WorkManager ('clean') Threads before calling back into the EJB side of the container. Using 'clean' Threads for this is a requirement of the JCA/ResourceAdapter contracts.

To eliminate the extra Threads and hand-off context switching we need to be able to request QFJ to use the 'clean' Threads directly.



 Comments   
Comment by James Olsen [ 24/Jan/17 ]

Pull Request to come.





[QFJ-911] ResendRequests that fail to be sent are treated as sent Created: 03/Jan/17  Updated: 04/Jan/17

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

Type: Bug Priority: Default
Reporter: Philip Whitehouse Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

https://github.com/quickfix-j/quickfixj/blob/629b801446431f06e0426aebcf669a2eca341a69/quickfixj-core/src/main/java/quickfix/Session.java#L2349

The return value from sendRaw() is ignored. If the message fails to send then we will still log that we have sent a resend request and (more crucially) still treat ourselves as having sent one for the purposes of whether we should send another.

At best this is merely misleading but I think it can actually cause problems in certain cases.



 Comments   
Comment by Christoph John [ 04/Jan/17 ]

Hmm, I can only quote the comment on the send method:

The returned status flag is included for compatibility with the JNI API but it's usefulness is questionable.
In QuickFIX/J, the message is transmitted using asynchronous network I/O so the boolean
only indicates the message was successfully queued for transmission. An error could still
occur before the message data is actually sent.

If the connection is broken, then the next incoming message on re-logon will trigger another ResendRequest anyway.
What do you think?





[QFJ-910] MessageUtils.parse does not respect the dictionary order Created: 21/Dec/16  Updated: 21/Dec/16  Resolved: 21/Dec/16

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 2.0.0
Fix Version/s: None

Type: Bug Priority: Blocker
Reporter: anup singh Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

Hi Team,

I have a message which was not in order as dictionary but i try to use the MessageUtils.parse(messageFactory, dictionary, targetMessage.toString());

to re-ordered but it is still not respecting my dictionary order.can someone please help on this ?



 Comments   
Comment by Christoph John [ 21/Dec/16 ]

The field order is declared in the message class itself. You probably need to regenerate the message classes using your specific data dictionary.
For follow-up questions please use the mailing list. This is the bug tracker.
Chris.





[QFJ-909] Unexpected Behaviour for ValidateIncomingMessage=N Created: 08/Dec/16  Updated: 05/Apr/17  Resolved: 05/Apr/17

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

Type: Bug Priority: Default
Reporter: Justin Phung Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-169 Message parsing fails on messages wit... Closed
duplicates QFJ-791 An unexpected field in a repeating gr... Closed

 Description   

While configuring my fix engine I found out that the configuration tag ValidateIncomingMessage=N does not work as expected. My goal is to use the DataDictionary to recognize the message type. Still, while not validating incoming message I do not want my fix engine to bring the fix tags in the messages out of order.

Incoming fix messages

8=FIX.4.4|9=264|35=AR|34=510|49=OTCX-GLOX|52=20161208-09:13:54.258|56=GLOX-OTCX|15=CHF|17=201612081000000171|22=4|48=CH0000975372|55=[N/A]|150=0|207=BNO|487=0|571=14811884339561|572=201612081000085|856=1|552=1|54=7|526=TESTBIR2|453=1|448=trts01|447=D|452=7|802=1|523=sauer|803=25|10=230|
8=FIX.4.4|9=285|35=AR|34=511|49=OTCX-GLOX|52=20161208-09:13:54.263|56=GLOX-OTCX|15=CHF|17=201612081000000172|22=4|48=CH0000975372|55=[N/A]|150=F|207=BNO|487=0|571=14811884339561|572=201612081000085|856=1|880=OTC16L08A0000933|552=1|54=7|526=TESTBIR2|453=1|448=trts01|447=D|452=7|802=1|523=sauer|803=25|10=124|

Outgoing fix messages

8=FIX.4.4|9=271|35=AR|34=1040|49=OTCX-GLOX|52=20161208-09:13:54.308|56=GLOX-OTCX|15=CHF|17=201612081000000171|22=4|48=CH0000975372|54=7|55=[N/A]|150=0|207=BNO|447=D|448=trts01|452=7|453=1|487=0|523=sauer|526=TESTBIR2|552=1|571=Glox-201612081000001|572=201612081000085|802=1|803=25|856=1|10=222|
8=FIX.4.4|9=292|35=AR|34=1041|49=OTCX-GLOX|52=20161208-09:13:54.313|56=GLOX-OTCX|15=CHF|17=201612081000000172|22=4|48=CH0000975372|54=7|55=[N/A]|150=F|207=BNO|447=D|448=trts01|452=7|453=1|487=0|523=sauer|526=TESTBIR2|552=1|571=Glox-201612081000001|572=201612081000085|802=1|803=25|856=1|880=OTC16L08A0000933|10=116|



 Comments   
Comment by Justin Phung [ 08/Dec/16 ]

My configuration file:

[default]
FileStorePath=/home/fixswitch/quickfix/target/data/fixgatewayswitch/initiator
FileLogPath=/home/fixswitch/quickfix/log/initiator
ConnectionType=initiator
SocketConnectHost=localhost
StartTime=00:00:00
EndTime=23:55:00
HeartBtInt=30
ReconnectInterval=5
UseDataDictionary=Y
ValidateFieldsOutOfOrder=N
ValidateUserDefinedFields=N
ValidateIncomingMessage=N

Comment by Christoph John [ 05/Apr/17 ]

Should be fixed with one of the linked duplicate tickets.





[QFJ-908] -Dgenerator.decimal=true not working for existing fields Created: 18/Nov/16  Updated: 18/Nov/16  Resolved: 18/Nov/16

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

Type: Bug Priority: Major
Reporter: Vipin Chaudhary Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: generator.decimal


 Description   

when I am packaging code using -Dgenerator.decimal=true, the existing Price type field are not changing to BigDecima.

I want that all Price Type fields should take BigDecimal as input. As per the documentation this can be if we compile code using -Dgenerator.decimal=true option.

I used "package -Dgenerator.decimal=true -DskipAT=true" but still Price type fields constructor are taking double field.

I added some custom fields of Price type and those new custom fields constructor are taking BigDecimal value. So It seems that this(-Dgenerator.decimal=true) is working for new fields only.



 Comments   
Comment by Christoph John [ 18/Nov/16 ]

Could not reproduce with 1.6.3-SNAPSHOT and 1.7.0-SNAPSHOT respectively.





[QFJ-907] Dead sockets are not closed when SocketInitiator is stopped Created: 04/Nov/16  Updated: 17/Jul/17  Resolved: 17/Jul/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: Paul Rowe Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: File QFJ-907.patch    
Issue Links:
Duplicate
duplicates QFJ-849 SocketInitiator does not stop properly Closed

 Description   

Steps to reproduce:

1. Create a socket initiator that connects to a socket that does nothing
2. Start the initiator and observe that it connects to the socket
3. Stop the initiator before the reconnectinterval kicks in
4. Observe that the socket remains open

Background:

Recently we observed that during our session end schedule processing, a client will logoff on time ... we delay a bit, and then we close our socket initiator. In-between the time the client logged off and the time that we closed the socket initiator, a new socket connection was established to the client. This connection was "dead," e.g. it did not respond to FIX requests/responses. This dead socket remained connected until the next session start, where an additional socket was opened. Just after a new additional socket was opened, the client realized they had a dead connection open to us, and decided to close that dead connection.

We have special handling on SessionStateListener.onConnect() and SessionStateListener.onDisconnect(). When a new socket was created on the session start, SessionStateListener.onConnect() was called. This led us to believe everything was OK with this session. Then, when the dead socket was closed, SessionStateListener.onDisconnect() was called just after. This broke our internal logic because we thought this session was disconnected, when in fact it was operating normally.

To avoid this problem in the future, if rogue dead sockets are created, then it should be up to the initiator to close these sockets.



 Comments   
Comment by Paul Rowe [ 04/Nov/16 ]

QFJ-907.patch attached to this issue. This patch contains a unit test that replicates this issue and the corresponding fix that fixes this issue.

Comment by Christoph John [ 04/Nov/16 ]

Hi Paul Rowe,
thanks for the issue and the suggested fix.
Did you try this with a newer version, i.e. QFJ 1.6.2? From what I can gather from your attached patch it might have been fixed with QFJ-849. Could you please check?
https://github.com/quickfix-j/quickfixj/commit/305b60030268f2aade427633127b7d3bae79130f

Thanks,
Chris.

Comment by Christoph John [ 29/Mar/17 ]

Hi Paul Rowe, are you able to confirm?
Thanks,
Chris.





[QFJ-906] Compile QFJ 1.6.x against JDK7 and QFJ 1.7.x against JDK8 Created: 18/Oct/16  Updated: 13/Dec/16  Resolved: 10/Dec/16

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 1.6.3, 2.0.0

Type: Improvement Priority: Major
Reporter: Christoph John Assignee: Guido Medina
Resolution: Fixed Votes: 0
Labels: None


 Description   

We should compile at least against JDK7 for various reasons:

  • JDK6 is quite old now and end-of-life (actually, even JDK7 is)
  • some of the SSL tests do not work with JDK6 since it does not support all ciphers
  • MINA 2.0.15 is compiled against JDK7
  • some smaller improvements in the code could be made (multi-catch, diamond operator, ...)

Since there only is a 1.7.0-SNAPSHOT release now (i.e. no released version), we can simply compile against JDK8 there.



 Comments   
Comment by Guido Medina [ 18/Oct/16 ]

I can give you a big branch for both versions, with IntelliJ inspections to use JDK 7 diamond convention to avoid IDE warnings and stuff, I'll work on that, but it will have to be 1 change on master and two branches for code changes, basically I will split the changes in two:

  • POM changes on master merge-able to both 1.6 and 1.7
  • Code changes with inspections on both, can also take this opportunity for some reformatting.

Let me know if you agree.

Comment by Guido Medina [ 18/Oct/16 ]

I think you can re-create branch 1.6.x so that it is not diverted from 1.7? as both have as starting point JDK 1.7

Comment by Guido Medina [ 18/Oct/16 ]

Or create a 1.6.x called 'NEW_1_6_X'

Comment by Christoph John [ 18/Oct/16 ]

I already changed the POMs on the 1.6.x branch and the master branch to use JDK7 and JDK8 respectively some hours ago.

As I think about it: maybe your idea to create 1.6.x branch newly from master is not a bad idea. AFAIK there is only issue QFJ-833 that is resolved on 1.7.x but not on 1.6.x, but it should be no problem to have that change on 1.6.x also.

Edit: do you think it would make sense to have a master branch and then a 1.6 and 1.7 branch? Or is it sufficient to have 1.7 developed on master and only one branch for 1.6?

Comment by Christoph John [ 18/Oct/16 ]

Created https://github.com/quickfix-j/quickfixj/tree/QFJ_1_6_x_NEW

Comment by Guido Medina [ 18/Oct/16 ]

I think master should be the current snapshot which is 1.7.x and whatever is the previous version to have a branch,
in this case QFJ_1_6_x_NEW

Also always make changes on master and cherry pick to respective versions as much as possible, makes things easier and simpler.

Comment by Christoph John [ 18/Oct/16 ]

Re cherry-picking: yes, that's what I try most of the time.
Thanks in advance for your help, always appreciated.

Comment by Guido Medina [ 11/Dec/16 ]

Hi Chris,

Maybe I can introduce a JDK 7 optimization and rebase the JDK 8 code changes from it, so that the JDK 7 can be applied to both 1.6.x and 1.7.x

WDYT?

Comment by Guido Medina [ 11/Dec/16 ]

Nevermind, this was done already, so long ago I forgot:
https://github.com/quickfix-j/quickfixj/commit/629b801446431f06e0426aebcf669a2eca341a69

Comment by Christoph John [ 12/Dec/16 ]

Thanks





[QFJ-905] MULTIPLECHARVALUE not handled in FieldType since FIX 5.0. version Created: 23/Sep/16  Updated: 17/Jun/20  Resolved: 23/Mar/20

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 2.2.0

Type: Bug Priority: Default
Reporter: François Milot Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-881 FieldType.MultipleValueString are not... Closed

 Description   

I encountered an issue testing a simple order sending in FIX 5.0. SP2. I send an order with value 18=1 3 and got rejected because of IncorrectTagValue exception (in Session.next method while validating the message).

Problem is that isMultipleValueStringField method does return false for MULTIPLECHARVALUE type.



 Comments   
Comment by Christoph John [ 23/Sep/16 ]

As a workaround you could configure the field to be of type String or MultipleValueString (but with version 1.6.2 because of QFJ-881).

Comment by François Milot [ 23/Sep/16 ]

Hi Christophe,

First, thanks for your answer. I already implemented this workaround

Will wait for your fix.

Thanks again.





[QFJ-904] Maven central repo releases don't support using BigDecimal Created: 14/Sep/16  Updated: 15/Sep/16  Resolved: 15/Sep/16

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

Type: Improvement Priority: Default
Reporter: Rose Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-891 Upload release of BigDecimal versions... Open

 Description   

I was really happy to see quickfixj on Maven Central - thank you!

But unfortunately, the -bd jars to support using BigDecimal instead of Double aren't being published there.

Could you please update your build to publish the bd variants as well?



 Comments   
Comment by Christoph John [ 15/Sep/16 ]

We already have QFJ-891 for this. Please see comment there.





[QFJ-903] Infinite Loop on Malformed Message - Bad BodyLength (tag 9) Created: 13/Sep/16  Updated: 13/Dec/16  Resolved: 08/Oct/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.2
Fix Version/s: 1.6.3

Type: Bug Priority: Critical
Reporter: Adam MacDonald Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Java Source File Test.java    

 Description   

If two messages are received in a row with a malformed tag 9 - the fix engine enters an infinite loop of logging and eventually causes the JVM to crash with an OutOfMemory exception.

Sent the following message twice

8=FIX.4.4|9=A|35=D|49=ST|56=TS|34=3|52=20160830-14:21:45.472|11=Order32|1=Template1|21=1|55=VOD.L|48=VOD.L|22=5|167=CS|207=LSE|54=1|60=20160830-14:21:45.472|38=100|40=2|44=95|15=GBp|59=0|58=Staging|10=206|

Enter infinite loop in

quickfix.mina.message.FIXMessageDecoder#parseMessage

logging

quickfix.mina.message.FIXMessageDecoder - handleError - Length format error in message (last character:65)


 Comments   
Comment by Christoph John [ 15/Sep/16 ]

Thanks for the issue report and especially the test. We already have tests which cover the scenario like tag "9=123a" but not your scenario.





[QFJ-902] Logon rejected even though within session time (java.io.IOException: Stream Closed) Created: 06/Sep/16  Updated: 22/Nov/17  Resolved: 23/Oct/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 2.0.0

Type: Bug Priority: Major
Reporter: anurag jain Assignee: Christoph John
Resolution: Fixed Votes: 3
Labels: None
Environment:

Software:
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

Operating System:
Linux earth 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64 x86_64 x86_64 GNU/Linux



 Description   

From time to time we have seen certain fix connection can not login even though within the session times. Please see logs below:

[Session1 details]

2016-09-02 06:03:02,607 [main] INFO  quickfix.SessionSchedule - [FIX.4.4-MDAQOM_session1-session1_MDAQOM] daily, 23:00:00-UTC - 10:00:00-UTC
2016-09-02 06:03:02,607 [main] INFO  quickfixj.event - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Session FIX.4.4-MDAQOM_session1-session1_MDAQOM schedule is daily, 23:00:00-UTC - 10:00:00-UTC
2016-09-02 06:03:02,607 [main] INFO  quickfixj.event - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Session state is not current; resetting FIX.4.4-MDAQOM_session1-session1_MDAQOM
2016-09-02 06:03:02,607 [main] INFO  quickfixj.event - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Created session: FIX.4.4-MDAQOM_session1-session1_MDAQOM

[Session connects before allowed time of 7am Singapore time. First exception noticed]

2016-09-02 06:17:21,636 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Error Reading/Writing in MessageStore
java.io.IOException: Stream Closed
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:326)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at java.io.DataOutputStream.flush(DataOutputStream.java:123)
        at quickfix.FileStore.set(FileStore.java:430)
        at quickfix.SessionState.set(SessionState.java:310)
        at quickfix.Session.sendRaw(Session.java:2433)
        at quickfix.Session.generateLogout(Session.java:1339)
        at quickfix.Session.generateLogout(Session.java:1309)
        at quickfix.Session.next(Session.java:1036)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
        at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
        at java.lang.Thread.run(Thread.java:745)

2016-09-02 06:17:21,636 [QFJ Message Processor] WARN  quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Disconnecting: Logon rejected: quickfix.RejectLogon: Logon attempt not within session time

[Logon happened again this time the stack trace looked like this]

2016-09-02 06:17:26,635 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Error Reading/Writing in MessageStore
java.io.IOException: Stream Closed
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:326)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at java.io.DataOutputStream.flush(DataOutputStream.java:123)
        at quickfix.FileStore.set(FileStore.java:430)
        at quickfix.SessionState.set(SessionState.java:310)
        at quickfix.Session.sendRaw(Session.java:2433)
        at quickfix.Session.generateLogout(Session.java:1339)
        at quickfix.Session.generateLogout(Session.java:1309)
        at quickfix.Session.next(Session.java:1036)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
        at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
        at java.lang.Thread.run(Thread.java:745)

2016-09-02 06:17:26,635 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Stream Closed
java.io.IOException: Stream Closed
        at java.io.RandomAccessFile.seek0(Native Method)
        at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
        at quickfix.FileStore.storeSequenceNumbers(FileStore.java:439)
        at quickfix.FileStore.incrNextTargetMsgSeqNum(FileStore.java:333)
        at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:370)
        at quickfix.Session.next(Session.java:1039)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
        at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
        at java.lang.Thread.run(Thread.java:745)

2016-09-02 06:17:26,635 [QFJ Timer] ERROR quickfix.SocketAcceptor - Error during timer processing
quickfix.RuntimeError: java.io.IOException: Stream Closed
        at quickfix.SessionState.reset(SessionState.java:381)
        at quickfix.Session.resetState(Session.java:2451)
        at quickfix.Session.reset(Session.java:814)
        at quickfix.Session.next(Session.java:1749)
        at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:283)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Stream Closed
        at java.io.FileOutputStream.writeBytes(Native Method)
        at java.io.FileOutputStream.write(FileOutputStream.java:326)
        at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
        at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
        at java.io.DataOutputStream.flush(DataOutputStream.java:123)
        at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
        at quickfix.FileStore.closeOutputStream(FileStore.java:258)
        at quickfix.FileStore.close(FileStore.java:243)
        at quickfix.FileStore.deleteFiles(FileStore.java:263)
        at quickfix.FileStore.initialize(FileStore.java:107)
        at quickfix.FileStore.reset(FileStore.java:481)
        at quickfix.SessionState.reset(SessionState.java:379)
        ... 11 more

[Finally logon within the session time, even then the session could not connect]

2016-09-02 07:00:00,760 [SocketAcceptorIoProcessor-2.0] INFO  quickfixj.msg.incoming - FIX.4.4-MDAQOM_session1-session1_MDAQOM: 8=FIX.4.4^A9=169^A35=A^A34=1^A49=session1_MDAQOM^A52=20160901-23:00:00.820^A56=MDAQOM_session1^A98=0^A108=30^A141=Y^A553=session1^A554=<masked>^A10=028^A
2016-09-02 07:00:00,760 [SocketAcceptorIoProcessor-2.0] INFO  quickfixj.event - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Accepting session FIX.4.4-MDAQOM_session1-session1_MDAQOM from /192.168.10.16:60121
2016-09-02 07:00:00,760 [SocketAcceptorIoProcessor-2.0] INFO  quickfixj.event - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Acceptor heartbeat set to 30 seconds
2016-09-02 07:00:00,760 [QFJ Message Processor] WARN  quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Logon rejected: quickfix.RejectLogon: Logon attempt not within session time
2016-09-02 07:00:00,760 [QFJ Message Processor] INFO  quickfixj.msg.outgoing - FIX.4.4-MDAQOM_session1-session1_MDAQOM: 8=FIX.4.4^A9=108^A35=5^A34=1^A49=MDAQOM_session1^A52=20160901-23:00:00.760^A56=session1_MDAQOM^A58=Logon attempt not within session time^A10=071^A
2016-09-02 07:00:00,760 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Error Reading/Writing in MessageStore
java.io.IOException: Stream Closed
        at java.io.RandomAccessFile.getFilePointer(Native Method)
        at quickfix.FileStore.set(FileStore.java:422)
        at quickfix.SessionState.set(SessionState.java:310)
        at quickfix.Session.sendRaw(Session.java:2433)
        at quickfix.Session.generateLogout(Session.java:1339)
        at quickfix.Session.generateLogout(Session.java:1309)
        at quickfix.Session.next(Session.java:1036)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
        at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
        at java.lang.Thread.run(Thread.java:745)

2016-09-02 07:00:00,760 [QFJ Message Processor] ERROR quickfixj.errorEvent - FIX.4.4-MDAQOM_session1-session1_MDAQOM: Stream Closed
java.io.IOException: Stream Closed
        at java.io.RandomAccessFile.seek0(Native Method)
        at java.io.RandomAccessFile.seek(RandomAccessFile.java:557)
        at quickfix.FileStore.storeSequenceNumbers(FileStore.java:439)
        at quickfix.FileStore.incrNextTargetMsgSeqNum(FileStore.java:333)
        at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:370)
        at quickfix.Session.next(Session.java:1039)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
        at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
        at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
        at java.lang.Thread.run(Thread.java:745)

This happens endlessly. Finally we had to bounce to fix this. This has happened more frequently as we have on-boarded more users

Questions:

  • Please tell us what is causing the issue
  • Why does the stream closed issue happen so often?
  • Is this issue fixed in a later version?
  • Any workarounds ?

This is quite a critical item for us so would appreciate the turnaround, thanks!



 Comments   
Comment by anurag jain [ 06/Sep/16 ]

What I found out is the following:

  • The timer thread tries to reset the state if the session is outside the time. Resetting the state means the store underneath, in this case the FileStore, is deleting the files and creating new persistence files
  • At the same time a client logs in this is the QFJ Message Processor thread. This logon is also rejected as it is outside the session time. We try to increment the targetSequenceNumber when we try to send the logout
  • These two threads create a race on how they are accessing the persistence files, hence might corrupt the file?
  • Also the checkSessionTime will start failing as FileStore throws an exception and never manages to reset the creation time as a consequence

Has this been fixed already in 1.6.x?

Comment by Christoph John [ 06/Sep/16 ]

Hi,
what I can say off the top of my head is that QFJ-773 corrected the issue where the message store is reinitialised every second. This is fixed in 1.6.0. I would suggest to use QFJ 1.6.2 if you upgrade.
If you have further points then please write to the mailing list as suggested.
Thanks,
Chris.

Comment by anurag jain [ 08/Sep/16 ]

Hi Christoph, thanks a lot for getting back. I think this patch might not fix the issue that I am seeing.

There are two threads:

  • Timer Thread. The fix is to reset if the sequence numbers are > 1
  • Message Processor Thread. But in the case where a client logs in outside the session time, there can be a case where we reject the logon and send a logout. This increments the target sequence number

There can still be a race between Timer Thread and MessageProcessor thread

  • Client logins outside session time logout generated, targetSeqNum is 1
  • The timer thread tries to reset at time T
  • Client logins outside session time again and logout generated. Try to increment the targetSeqNum to 2 now at same time T
  • Now both these threads are touching the MessageStore. In case of a FileStore there can be a corruption still

I do not think this issue has been addressed even in 1.6.2

Comment by anurag jain [ 13/Sep/16 ]

Sorry can someone confirm the above please?

Comment by Christoph John [ 15/Sep/16 ]

Confirmed.

Comment by anurag jain [ 20/Sep/16 ]

Christoph could you recommend a good way to fix this? Or any workaround for now

Comment by Christoph John [ 20/Sep/16 ]

I cannot think of a workaround inside of QFJ at the moment. The only possibility I see is to prevent connections from outside during non-session time or do not start the service on your side. But I don't know how the infrastructure on your side supports this kind of workaround. E.g. you could start your processes by cron job at a later time.

IMHO the fix would be to not increment the sequence numbers outside of the session time window since it is useless. The seqnums would get reset once the session is inside the session time window anyway.
When the next connection attempt comes in and the counterparty comes in with too high a sequence number then the resend processing will take place.

Comment by anurag jain [ 21/Sep/16 ]

I agree. Do we just disconnect the counterparty outside the session window then? Currently we are sending a logout to them, I think we might have to stop sending any logouts and just disconnenct

Comment by anurag jain [ 21/Sep/16 ]

Is this going to be fixed in quickfix/j ? Any ETA would be appreciated thanks!

Comment by Christoph John [ 21/Sep/16 ]

Why do you think we should not send the counterparty a Logout? I would propose to send a Logout but always with seqnum 1. This is how it is done already implemented when being outside of the session time window. The only thing that would change is that we do not increment the seqnums internally. The incrementation is now being done but the seqnums are reset each second anyway. So no externally visible change there.

The session time feature is AFAIK not described in the official FIX spec so one cannot really lookup a best practice on what to do when a Logon outside of the session time is received. It is only stated that "if sending a Logout does not create risk or violate security, a Logout message should be sent with a descriptive text message."

I cannot give you an ETA on when this would be fixed. This is an open source project and this issue is not really critical. So you have the following options:

Cheers,
Chris.

Comment by Christoph John [ 23/Oct/17 ]

Fixed with https://github.com/quickfix-j/quickfixj/pull/146 by https://github.com/alexwibowo





[QFJ-901] Value is incorrect (out of range) for this tag:35 Created: 02/Sep/16  Updated: 02/Sep/16  Resolved: 02/Sep/16

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

Type: Bug Priority: Default
Reporter: SUNIL Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Comments   
Comment by Christoph John [ 02/Sep/16 ]

It is written in the JIRA header, on the frontpage and additionally when you create an JIRA issue: DO NOT SUBMIT HELP REQUESTS TO JIRA. INSTEAD USE THE MAILING LIST TO ASK FOR HELP!
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks





[QFJ-900] CLONE - Need help to clarify if QuickFix/J supports TLS Created: 08/Aug/16  Updated: 08/Aug/16  Resolved: 08/Aug/16

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

Type: Other Priority: Default
Reporter: vijayasree Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi

We are using QuickFix/J to connect to ICE Exchange to poll our exchange trades. ICE exchange has notified us they would be discontinuing the support of SSL protocol & would be migrating to TLS. Since we are using QuickFix/J API from our code, we are unsure about the impact we would be going to face. So we would like your help to confirm if QuickFix/J supports TLS, and the API is not tightly coupled to network protocols. Kindly help us clarify., Thanks in advance

Thanks & Regards
Vijayasree



 Comments   
Comment by Guido Medina [ 08/Aug/16 ]

As far as I'm aware of there is not tightly coupled to "encryption algorithms" (network protocol is still TCP which is what QFJ is using), I believe it tries to negotiate the encryption and agree on one if supported by the JDK

But don't trust my word for it, you should test it, to whomever you are connecting should provide you with a test environment with the new SSL encryption?

Hope that helps,

Guido.

Comment by Christoph John [ 08/Aug/16 ]

Please use the mailing list for help requests: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

JIRA is the bug tracker.

Comment by vijayasree [ 08/Aug/16 ]

Thanks for the help. Will note it for future. Didnt know how to contact in the first case

Thanks & Regards
Vijayasree





[QFJ-899] Need help to clarify if QuickFix/J supports TLS Created: 08/Aug/16  Updated: 08/Aug/16  Resolved: 08/Aug/16

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

Type: Other Priority: Default
Reporter: vijayasree Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi

We are using QuickFix/J to connect to ICE Exchange to poll our exchange trades. ICE exchange has notified us they would be discontinuing the support of SSL protocol & would be migrating to TLS. Since we are using QuickFix/J API from our code, we are unsure about the impact we would be going to face. So we would like your help to confirm if QuickFix/J supports TLS, and the API is not tightly coupled to network protocols. Kindly help us clarify., Thanks in advance

Thanks & Regards
Vijayasree



 Comments   
Comment by Christoph John [ 08/Aug/16 ]

Please use the mailing list for help requests: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

JIRA is the bug tracker.





[QFJ-898] auto reconnect fails? Created: 05/Aug/16  Updated: 08/Aug/16  Resolved: 08/Aug/16

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

Type: Bug Priority: Default
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

1.6.2 and mina 2.0.13


Issue Links:
Duplicate
duplicates QFJ-895 Reconnecting initiator does not work ... Closed

 Description   

initiator configured as such fails to keep trying to reconnect after disconnect. I'm investigating now but has anybody had a similar experience?

TimeZone=America/New_York
StartDay=Sunday
StartTime=00:00:00
EndDay=Sunday
EndTime=00:00:00
ResetOnLogon=Y
HeartBtInt=30
ReconnectInterval=0

DEBUG (2016-08-05 05:39:07,372) [QFJ Timer] (Connector) - ::StartSession -> Thu Aug 04 13:04:01 EDT 2016
DEBUG (2016-08-05 05:39:07,372) [QFJ Timer] (Connector) - ::StopSession -> Fri Aug 05 05:39:07 EDT 2016
DEBUG (2016-08-05 05:39:07,372) [QFJ Timer] (Connector) -

INFO (2016-08-05 05:39:07,653) [NioProcessor-2] (event) - FIX.4.4:xxxx: Already disconnected: Socket exception (xxxx): java.io.IOException: An established connection was aborted by the software in your host machine
INFO (2016-08-05 05:39:07,949) [NioProcessor-2] (event) - FIX.4.4:xxxx: Already disconnected: Socket exception (xxxx): org.apache.mina.core.write.WriteTimeoutException



 Comments   
Comment by Andre Mermegas [ 05/Aug/16 ]

sorry must be duplicate of 895, i didnt see it. any word on 1.6.3 release schedule? thanks all.

Comment by Christoph John [ 08/Aug/16 ]

No fixed date yet, sorry. But I hope during the next month.





[QFJ-897] AbstractSocketAcceptor does not stop its internal IoAcceptors correctly Created: 11/Jul/16  Updated: 13/Dec/16  Resolved: 11/Jul/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.2
Fix Version/s: 1.6.3

Type: Bug Priority: Default
Reporter: Uwe Guenther Assignee: Uwe Guenther
Resolution: Fixed Votes: 0
Labels: QuickfixJ
Environment:

Linux


Attachments: Java Source File MyThreadedSocketAcceptor.java    

 Description   

We having a productive setup where we are reuse sessions and create, start, stop ThreadedSocketAcceptor as we need them. We do not reuse them.

In Prod we saw the following problem: We were running out of file descriptors on ore 32 CPU Linux box with a max open file desriptor settings of 4096 after several days running around 20 quickfixj sessions within one JVM.

Issue:
After debugging the quickfixj and the apache mina code we found out, quickfixj is only unbinding the internal used IoAcceptors in its protected method AbstractSocketAcceptor#stopAcceptingConnections(), but not disposing them which is releasing the NIO Selectors used by Apache Mina. As a result the ExecutorServices created by Mina are not shouting down and their run() method is waiting on an internal inter thread communication lock forever.

Solution:
Just do a ioAcceptor.dispose(true); in ioAcceptor.unbind(); in quickfix.mina.acceptor.AbstractSocketAcceptor#stopAcceptingConnections() after line 248

    protected void stopAcceptingConnections() throws ConfigError {
        Iterator<IoAcceptor> ioIt = ioAcceptors.values().iterator();
        while (ioIt.hasNext()) {
            IoAcceptor ioAcceptor = ioIt.next();
            SocketAddress localAddress = ioAcceptor.getLocalAddress();
            ioAcceptor.unbind();
            ioAcceptor.dispose(true);
            log.info("No longer accepting connections on " + localAddress);
            ioIt.remove();
        }
    }


 Comments   
Comment by Uwe Guenther [ 11/Jul/16 ]

if you MyThreadedSocketAcceptor.java instead of ThreadedSocketAcceptor.java you can work around this issue.

Comment by Christoph John [ 11/Jul/16 ]

Hi Uwe, thanks for the report and suggested fix.
Cheers,
Chris.

Comment by Uwe Guenther [ 11/Jul/16 ]

Hi Chris, you are welcome! Is there a release plan for 1.6.3? Cheers Uwe





[QFJ-896] Connection to Server is closed after sending Logon message Created: 10/Jul/16  Updated: 11/Jul/16  Resolved: 11/Jul/16

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

Type: Bug Priority: Default
Reporter: Jeff Lee Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: logon
Environment:

Windows8, Java1.8, Eclipse Mars.2 Release (4.5.2)


Attachments: Zip Archive myfix.zip    

 Description   

I want to logon to dukascopy and send a market data request message. the session can be created, but when a send a logon message, the connection is closed with message "INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] Disconnecting: Encountered END_OF_STREAM"

but sometimes, it gives the message "<20160710-08:06:48, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, error> (Disconnecting: Socket exception (demo-api.dukascopy.com/194.8.15.140:9443): org.apache.mina.core.write.WriteToClosedSessionException)"



 Comments   
Comment by Jeff Lee [ 10/Jul/16 ]

attachement is my code and config file. and two possible log messages are as blow:

Jul 09, 2016 9:06:47 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] daily, 00:00:00-UTC - 00:00:00-UTC
<20160710-08:06:47, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (Session FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20160710-08:06:47, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (Created session: FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX)
onCreate:FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX
Jul 09, 2016 9:06:47 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Jul 09, 2016 9:06:47 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Jul 09, 2016 9:06:47 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Jul 09, 2016 9:06:47 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] [demo-api.dukascopy.com/194.8.15.140:9443]
Jul 09, 2016 9:06:47 PM quickfix.mina.SessionConnector startSessionTimer
INFO: SessionTimer started
Jul 09, 2016 9:06:47 PM quickfix.mina.SingleThreadedEventHandlingStrategy$1 run
INFO: Started QFJ Message Processor
toAdmin:8=FIX.4.49=13535=A34=1049=FEED_wangqilin2015_DEMOFIX52=20160710-08:06:47.68956=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=184
<20160710-08:06:47, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, outgoing> (8=FIX.4.49=13435=A34=149=FEED_wangqilin2015_DEMOFIX52=20160710-08:06:47.68956=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=135)
<20160710-08:06:47, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (No responder, not sending message: 8=FIX.4.49=13435=A34=149=FEED_wangqilin2015_DEMOFIX52=20160710-08:06:47.68956=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=135)
Logon....
Jul 09, 2016 9:06:48 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created for FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX: local=/192.168.0.108:64283, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=demo-api.dukascopy.com/194.8.15.140:9443
toAdmin:8=FIX.4.49=9335=A34=249=FEED_wangqilin2015_DEMOFIX52=20160710-08:06:48.65856=DUKASCOPYFIX98=0108=3010=027
<20160710-08:06:48, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, outgoing> (8=FIX.4.49=9335=A34=249=FEED_wangqilin2015_DEMOFIX52=20160710-08:06:48.65856=DUKASCOPYFIX98=0108=3010=027)
<20160710-08:06:48, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (Initiated logon request)
<20160710-08:06:48, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, error> (Disconnecting: Socket exception (demo-api.dukascopy.com/194.8.15.140:9443): org.apache.mina.core.write.WriteToClosedSessionException)
onLogout:FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX
Logon....
Logon....
Logon....
Logon....
Logon....
Logon....

Jul 09, 2016 9:07:39 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] daily, 00:00:00-UTC - 00:00:00-UTC
<20160710-08:07:39, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (Session FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20160710-08:07:39, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (Created session: FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX)
onCreate:FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX
Jul 09, 2016 9:07:39 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Jul 09, 2016 9:07:39 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Jul 09, 2016 9:07:39 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Jul 09, 2016 9:07:39 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] [demo-api.dukascopy.com/194.8.15.140:9443]
Jul 09, 2016 9:07:39 PM quickfix.mina.SessionConnector startSessionTimer
INFO: SessionTimer started
Jul 09, 2016 9:07:39 PM quickfix.mina.SingleThreadedEventHandlingStrategy$1 run
INFO: Started QFJ Message Processor
toAdmin:8=FIX.4.49=13435=A34=349=FEED_wangqilin2015_DEMOFIX52=20160710-08:07:39.51056=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=122
<20160710-08:07:39, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, outgoing> (8=FIX.4.49=13435=A34=149=FEED_wangqilin2015_DEMOFIX52=20160710-08:07:39.51056=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=120)
<20160710-08:07:39, FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX, event> (No responder, not sending message: 8=FIX.4.49=13435=A34=149=FEED_wangqilin2015_DEMOFIX52=20160710-08:07:39.51056=DUKASCOPYFIX98=6108=30141=Y553=wangqilin2015554=Wnswns06060610=120)
Logon....
Jul 09, 2016 9:07:39 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created for FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX: local=/192.168.0.108:64301, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=demo-api.dukascopy.com/194.8.15.140:9443
Jul 09, 2016 9:07:40 PM quickfix.Session disconnect
INFO: [FIX.4.4:FEED_wangqilin2015_DEMOFIX->DUKASCOPYFIX] Disconnecting: Encountered END_OF_STREAM
Logon....
Logon....
Logon....

Comment by Christoph John [ 11/Jul/16 ]

This is the bug tracker, please ask on the mailing list. https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-895] Reconnecting initiator does not work under some circumstances Created: 23/Jun/16  Updated: 13/Dec/16  Resolved: 11/Jul/16

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

Type: Bug Priority: Major
Reporter: Christoph John Assignee: Guido Medina
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-868 IoSessionInitiator can't reconnect th... Closed
is duplicated by QFJ-898 auto reconnect fails? Closed
Relates
relates to QFJ-866 Initiator session timer with SSL enabled Closed

 Description   

Youyu Shao provided some fixes on the mailing list.

Original mail:

On 23/06/16 02:35, Youyu Shao wrote:
> QuickFIX/J Documentation: http://www.quickfixj.org/documentation/
> QuickFIX/J Support: http://www.quickfixj.org/support/
>
>
> Recently we have been seriously looking into using QuickFixJ (code base
> 1.6.2).
> In so doing, we have discovered several problems and subsequently resolved
> in house.
>
> 1. Mina would throw org.apache.mina.core.RuntimeIoException wrapping
> java.net.SocketException at various places.
> For example, this happens at:
> org.apache.mina.core.RuntimeIoException: java.net.SocketException:
> Invalid argument: no further information
> at
> org.apache.mina.transport.socket.nio.NioSocketSession$SessionConfigImpl.setTcpNoDelay(NioSocketSession.java:208)
> at quickfix.mina.NetworkingOptions.apply(NetworkingOptions.java:155)
> at
> quickfix.mina.AbstractIoHandler.sessionCreated(AbstractIoHandler.java:93)
> at
> quickfix.mina.initiator.InitiatorIoHandler.sessionCreated(InitiatorIoHandler.java:50)
> .....
> When this happens, exceptionCaught method of AbstractIoHandler is not
> able to properly detect there was an underlying socket IOException.
> AbstractIoHandler has been modified to un-wrap the exception and see if
> along the exception chain there is an IOException.
>
> 2. org.apache.mina.core.session.IoSession internal state is problematic. On
> and off,
> IoSession.isConnected() does not return the correct value after QuickFixJ
> called IoSession.close() method(up on experiencing IOException).
> quickfix.mina.initiator.IoSessionInitiator has been refactored to replace
> the old IoConnector with a new one upon experiencing IOException.
> quickfix.mina.AbstractIoHandler is adjusted accordingly to signal the
> IoSessionInitiator to do so.
>
> 3. Modified the run() method of ConnectTask in IoSessionInitiator to be
> protected by try block. This is to prevent the scheduled Task from
> stop running in presence of exception. (see javadoc on
> scheduleWithFixedDelay(...) method of
> java.util.concurrent.ScheduledExecutorService
> which states that "...If any execution of the task encounters an
> exception, subsequent executions are suppressed...")
>
> 4. Again, org.apache.mina.core.session.IoSession internal state is
> problematic. Even after the
> normal disconnect() from IoSessionResponder, on and off the
> IoSession.isConnected() still does not return the correct value.
> quickfix.mina.IoSessionResponder is adjusted to signal the
> IoSessionInitiator to replace the IoConnector. IoSessionResponderTest is
> adjusted accordingly.
>
>
> 5. quickfix.ThreadedSocketAcceptor leaks resources when stoped.
> Instead of calling stopSessionTimer() in the stop() method, it should
> call stopInitiators().
>
> Problems identified in 1, 2, 3, and 4 ultimately manifested them in ways
> that reconnecting would stop working (forever), even absent of IOExceptions.
>
> With the fix, we have the QuickFixJ engine running for a week where
> reconnecting works with no problem. During this period the counterparty
> logged out and severed the TCP connection more than 20000 times. Our test
> also indicates that the fix works equally SSL vs non-SSL.
>
> Modified files are attached.
>
> AbstractIoHandler.java
> <http://quickfix-j.364392.n2.nabble.com/file/n7579557/AbstractIoHandler.java>
> IoSessionInitiator.java
> <http://quickfix-j.364392.n2.nabble.com/file/n7579557/IoSessionInitiator.java>
> IoSessionResponder.java
> <http://quickfix-j.364392.n2.nabble.com/file/n7579557/IoSessionResponder.java>
> IoSessionResponderTest.java
> <http://quickfix-j.364392.n2.nabble.com/file/n7579557/IoSessionResponderTest.java>
> ThreadedSocketInitiator.java
> <http://quickfix-j.364392.n2.nabble.com/file/n7579557/ThreadedSocketInitiator.java>
>



 Comments   
Comment by Guido Medina [ 23/Jun/16 ]

I'm having this issue also with QFJ 1.7.x (current master), it seems that the initiator is never able to recover from this, I was still trying to figure out what this is happening:
On a Linux system once you close the connection, netstat shows that a socket is still owned by the Java socket, to the point that I had to restart the OS in order to make the initiator connect again.

Comment by Guido Medina [ 23/Jun/16 ]

The state issue with Apache Mina might has been fixed with latest, which isn't maybe what QFJ 1.6.3 is using?

Comment by Christoph John [ 23/Jun/16 ]

Since QF/J 1.6.2 the MINA version 2.0.13 is used. You submitted a pull request for that. Do you have a link to the MINA issue which should fix this? On QFJ-868 you refer to https://issues.apache.org/jira/browse/DIRMINA-995 but this is probably another problem.

Comment by Guido Medina [ 23/Jun/16 ]

You are right, it definitely looks like another problem, will you take care of that PR?, if you can't make it before 5:30PM London time I can download the patch files and send a PR.

Comment by Christoph John [ 23/Jun/16 ]

Hi Guido, that would be great, thank you. I could not look at this earlier than next week or at the weekend.

Comment by Guido Medina [ 23/Jun/16 ]

Glad to do it, I'll send you a PR late tonight.

Comment by Christoph John [ 23/Jun/16 ]

Thanks, really appreciated.

Comment by Guido Medina [ 23/Jun/16 ]

I was able to surgically modify the other 4 which I will commit on master, but IoSessionInitiator.java I couldn't after last SSL refactored.

Comment by Guido Medina [ 23/Jun/16 ]

Check commit: https://github.com/quickfix-j/quickfixj/pull/76/commits/d82566e3d5165fb3873dc253328a3a61d3054c66

Comment by Guido Medina [ 23/Jun/16 ]

Concerning the class I couldn't patch, scratch that, I figured it out.

Comment by Guido Medina [ 23/Jun/16 ]

Simplified commit for easier code review: https://github.com/quickfix-j/quickfixj/pull/76/commits/a72d3ef5f7a9a99fd129d4430585d6591d1e2596

Comment by Guido Medina [ 23/Jun/16 ]

PRs submitted for the following branches:

Comment by Guido Medina [ 24/Jun/16 ]

The patch broke a test by moving

getNextSocketAddress()

to inside a try...catch, for this case this exception needs to be thrown: https://github.com/quickfix-j/quickfixj/pull/78





[QFJ-894] logon state is not valid for message Created: 19/May/16  Updated: 19/May/16  Resolved: 19/May/16

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

Type: Bug Priority: Default
Reporter: Ramesh Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi All,

previously when i try to logon , am getting timed out waiting for logon responce , so i set LogonTimeout=120 in setting file for fixing this issue . but now am getting other issue logon state is not valid for message , is anyone suggest me on this .

(Initiated logon request)
<20160519-11:38:26.401, FIX.4.2:MANAMARBTRPT->REDIRPT, incoming>
(8=FIX.4.29=7135=A49=REDIRPT56=MANAMARBTRPT34=1152=20160519-11:37:4498=0108=3010=014)
single reset topic = ""
<20160519-11:39:06.172, FIX.4.2:MANAMARBTRPT->REDIRPT, incoming>
(8=FIX.4.29=5935=049=REDIRPT56=MANAMARBTRPT34=1252=20160519-11:38:2310=233)
<20160519-11:39:06.172, FIX.4.2:MANAMARBTRPT->REDIRPT, event>
(Logon state is not valid for message)
<20160519-11:39:06.172, FIX.4.2:MANAMARBTRPT->REDIRPT, event>
(Disconnecting)



 Comments   
Comment by Christoph John [ 19/May/16 ]

Please use the mailing list, this is the bug tracker.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks





[QFJ-893] (Invalid message: Expected BodyLength=472, Received BodyLength=478) Created: 19/May/16  Updated: 19/May/16  Resolved: 19/May/16

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

Type: Bug Priority: Default
Reporter: Ramesh Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi All,

I am facing this issue while receiving incoming message , I wasn't have much idea on quickfix , can anyone let your suggestions on this issue , where i have to do changes , in which file i have to do . the incoming message is encapsulated message , i know the reason why we are getting this error , due to encapulation the body length is higher than expecting where i have to fix this issue .



 Comments   
Comment by Christoph John [ 19/May/16 ]

Please use the mailing list, this is the bug tracker.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks





[QFJ-892] Deadlock : quickfix.SessionState.setLastSentTime(SessionState.java:145) Created: 16/May/16  Updated: 04/Oct/17  Resolved: 03/Oct/17

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

Type: Bug Priority: Default
Reporter: Yoni Touitou Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: deadlock
Environment:

Linux



 Description   

Hi team,

We have an production issue because of deadlock in quickfixj.
I searched in your JIRA and found this ticket : QFJ-645 that is very similar issue but i did not understand the solution.
Can someone advise ?

2016-05-13 13:49:07,162 [FrequentSched-1] ERROR TaUtils detectDeadLocks - DeadLock detected "TA-CRX-JPMC-WL_trading" Id=447 WAITING on java.util.concurrent.locks.ReentrantLock$NonfairSync@366414ce owned by "TMS2InFCStoneUS_streaming" Id=364
at sun.misc.Unsafe.park(Native Method)
waiting on java.util.concurrent.locks.ReentrantLock$NonfairSync@366414ce
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
at quickfix.SessionState.lockSenderMsgSeqNum(SessionState.java:338)
...
2016-05-13 13:49:07,162 [FrequentSched-1] ERROR TaUtils detectDeadLocks - DeadLock detected "TMS2InFCStoneUS_streaming" Id=364 BLOCKED on quickfix.Session@2f7fe578 owned by "TA-CRX-JPMC-WL_trading" Id=447
at quickfix.SessionState.setLastSentTime(SessionState.java:145)
blocked on quickfix.Session@2f7fe578
at quickfix.Session.initializeHeader(Session.java:680)
at quickfix.Session.sendRaw(Session.java:2304)
at quickfix.Session.send(Session.java:2402)
at quickfix.Session.sendToTarget(Session.java:636)
at com.tradair.tnet.driver.fix.client.FixClient.sendRequest(FixClient.java:462)
at com.tradair.tnet.driver.Driver.handleMessages(Driver.java:408)
at com.tradair.tnet.driver.Driver.run(Driver.java:299)
...



 Comments   
Comment by Christoph John [ 13/Apr/17 ]

I think we cannot do anything about it without an exact description how to reproduce or a unit test. Did you try to send a message to the same Session from two different threads??

Comment by Yoni Touitou [ 01/Oct/17 ]

Hi Christoph,

Sorry for the delay.

We are disconnecting the trading session when the streaming session is disconnecting.
Is it a problem ? is it a bad practice ?

If it's a bad practive, we would like to disconnect all the sessions of a user if one of them is disconnected ? What is the correct way to do this ?

This is our current code for disconnect all the sessions of user called in the onLogout method in the Application interface

Session streaming = sessionData.getStreamingSession();
		Session trading = sessionData.getTradingSession();
		logger.info("--> logout Streaming....");
		sendLogout(streaming, reason);

		logger.info("--> logout Trading....");
		sendLogout(trading, reason);
		
		sleep(1000);
		logger.info("--> disconnect Streaming....");
		try {
			if (streaming != null) {
				streaming.disconnect(reason, true);
			}
		} catch(IOException ex) {
			logger.error("error while disconnect streaming", ex);
		}

		logger.info("--> disconnect trading....");
		try {
			if (trading != null) {
				trading.disconnect(reason, true);
			}
		} catch(IOException ex){
			logger.error("error while disconnect trading", ex);
		}
Comment by Christoph John [ 01/Oct/17 ]

The "Session" that you are getting via getStreamingSession() or getTradingSession() is a quickfix.Session, right??
What does the code of the sendLogout() method that you are calling look like?

I noticed that you are using a rather old version of QFJ (1.5.3). At least that is what you entered into the issue description. There were some concurrency fixes done since that version, e.g. QFJ-738 (which looks a little like the problem you are having) or QFJ-790. Maybe you could try a more recent version. 1.6.4 is the current version.

Apart from that I would not suggest to call Session.disconnect() from different threads and also to not send any Session-level messages by yourself (e.g. Logon, Logout).
Actually it should be enough if you called Session.logout(). That should trigger a Logout and disconnect of the FIX session. If you want to re-enable the Session then just call Session.logon().

Hope that helps,
Chris.

Comment by Yoni Touitou [ 02/Oct/17 ]

Hi Christophe,
Yes this is a QuickFix session instance.

The method sendLogout() above is called from the onLogout method from Quickfix.Application interface

@Override
	public void onLogout(SessionID arg0) {
		Thread.currentThread().setName(arg0.getTargetCompID());
		fixApi.handleUserDisconnect(arg0);
	}

the fixApi.handleUserDisconnect() disconnect the user in our system and disconnect all the sessions for the current user (Streaming and trading).
As you mentionned, i send a logout message to the streaming session via the trading thread. Is it a problem ?

Thanks for your assistance

Comment by Christoph John [ 03/Oct/17 ]

Umm, yes, as I was suggesting in my earlier comment: you shouldn't call disconnect() from a separate thread. Actually, you shouldn't call it at all and leave the whole session management / connect / disconnect stuff to QFJ. Please use Session.logon() and logout().

Chris

Comment by Yoni Touitou [ 04/Oct/17 ]

Thanks christoph,

So to clarify, if i must disconnect the streaming session via the trading thread, I need to remove the disconnect method call and using the logout method only ?
If i understand you think that the deadlock is caused by the disconnect method call from another thread ?

THanks

Comment by Christoph John [ 04/Oct/17 ]

Yes, as I was suggesting in my earlier two comments you should remove the disconnect() call and use the logout() method only. If you got an Initiator, do not forget to call logon() afterwards, otherwise it will not try to reconnect. If you got an Acceptor, the you do not need to call logon() afterwards.

The deadlock is probably caused by either the call of the disconnect() method from another thread or the call to sendLogout() while another message is still trying to be sent/received.

If you have further questions please direct them to the mailing list, since JIRA is the bug tracker. Thank you.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Regards,
Chris.





[QFJ-891] Upload release of BigDecimal versions to Maven or Sonatype central Created: 16/May/16  Updated: 15/Sep/16

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.6.2
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Igor Nemtsov Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-904 Maven central repo releases don't sup... Closed

 Description   

In repositories of Maven and Sonatype centrals missing BigDecimal versions.



 Comments   
Comment by Christoph John [ 17/May/16 ]

This is currently maintained by marketcetera: http://repo.marketcetera.org/maven/quickfixj/quickfixj-core/

If you have any questions regarding this please write to the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-890] PossDupFlag Handlying Config Created: 09/May/16  Updated: 18/May/16  Resolved: 18/May/16

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

Type: New Feature Priority: Default
Reporter: Rohit Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi

I am using QuickFixJ 1.6.1 for one of the projects as a FIX initiator.
Currently the default behavior of FIX client is to ignore any messages received with PossDupFlag(tag=43) set to "Y".
Due to which, call back method on fromApp is not invoked .

Is it possible to add a new feature to expose this property as a Config element and have clients override the behavior per their need?



 Comments   
Comment by Christoph John [ 18/May/16 ]

Why do you think that PossDup messages are ignored? We are handling PossDup messages in our application without changes to QFJ.





[QFJ-889] Leading zeros in int and float fields Created: 23/Apr/16  Updated: 28/Apr/16

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Roman Liverovskiy Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

Fedora 23 x86_64, Windows 7 64 bit SP1



 Description   

I use quickfixj-examples-executor-1.6.0.jar as FIX 5.0 server.

Server does not respond on any client messages if there are leading zeros in int or float fields in client message, for example if there are leading zeros in sequnce number in message header (in login message or in heart beat message).
Server application outputs information about client conection on socket, but there is no any response on FIX message sent from client to server (there is no even an error message).
Leading zeros are permitted by FIX 5.0 protocol specification.



 Comments   
Comment by Christoph John [ 28/Apr/16 ]

Could you please attach some logs? Thanks





[QFJ-888] DefaultMessageFactory does not support FIX5.0 SP1/2 Created: 21/Apr/16  Updated: 02/Aug/18  Resolved: 08/Feb/18

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

In DefaultMessageFactory it is assumed that FIX50 is the only version that is used with FIXT. This has historic reasons.

However, we should extend the DefaultMessageFactory to also handle other FIX50-versions out of the box, i.e. SP1 and SP2.
Since this will most probably break backward compatibility, we will do it for version 1.7 only.

Workaround:
Use a custom MessageFactory.
Or add your needed message factory for the FIX50 begin string. For example:

final DefaultMessageFactory defaultMessageFactory = new DefaultMessageFactory();
defaultMessageFactory.addFactory(FixVersions.FIX50, quickfix.fix50sp2.MessageFactory.class);



 Comments   
Comment by Christoph John [ 29/May/17 ]

Will move this ticket out of 1.7.0 since there is a workaround and no-one seems to ask for it currently.

Comment by Christoph John [ 08/Feb/18 ]

Covered by PR https://github.com/quickfix-j/quickfixj/pull/171 by https://github.com/ckolek





[QFJ-887] NoPartyIDs Tag 453 error in resend Created: 14/Apr/16  Updated: 21/Apr/16  Resolved: 21/Apr/16

Status: Closed
Project: QuickFIX/J
Component/s: Build, Message Generation, Networking
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Gilberto Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, ResendRequest,, encoding
Environment:

JVM 1.7, Centos 7



 Description   

I am developing a client using quickfix / j generally works well, but I found a problem with the resend when there is a communication error with the Acceptor.

When sending a message like the following:

FIX.4.4 8 = 9 = 228 35 = D 34 = 463 52 = 49 = INITIATOR 20160405-16: 11: 34,226 ACCEPTOR 56 = 11 = 8746340000000002 21 = 3 22 = 4 38 = 2498 40 = 1 44 = 0 48 = MX01ME050007 54 = 2 59 = 0 60 = 20160315-17: 41: 06,000 432 = 20160315 20001 = 0 453 = 2 448 = 3 447 = D 452 = 24 448 = 0000 447 = D 452 = 12 10 = 255

Where the tag 453 has a value of 2 and their associated tags are:

First group:

448 = 3
447 = D
452 = 24

Second group:

448 = 0000 (eg)
447 = D
452 = 12

When communication is restored, the Acceptor ask for resend the request by , however the resend message looks like this:
FIX.4.4 8 = 9 = 231 35 = D 34 = 428 43 = Y 49 = 52 = ARKA1 20160328-23: 16: 02,215 BMVRII 56 = 122 = 20160328-23: 15: 30 11 = 8746340000000002 21 = 3 22 = 4 38 = 2498 40 = 1 44 = 0 48 = MX01ME050007 54 = 2 59 = 0 60 = 20160315-17: 41: 06,000 432 = 20160315 20001 = 0 453 = 2 448 = 0000 447 = D 452 = 12 10 = 052

The tag 453 still has a value of 2 and the tag 43 appears with "Y" because it is a resend, but only taken considered the second group in the message body, ie 448 = 0000, 447 = D 452 = 12 which invalidates it for processing as the first group is not in the message.

Have any idea what happens in the re-transmission of the message, I appreciate very much your help.



 Comments   
Comment by Christoph John [ 15/Apr/16 ]

I see you already wrote to the quickfixj-users group (which was the right thing to do).





[QFJ-886] FIX44.xml InstrumentLeg Inconsistently Defined Created: 12/Apr/16  Updated: 13/Dec/16  Resolved: 12/Dec/16

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: None
Fix Version/s: 1.6.3

Type: Bug Priority: Default
Reporter: Mike Starkie Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
Looks like the InstrumentLeg Component block is inconsistently defined in FIX44.xml in version 1.6.0

In some places (lines 915-917, msgType=SecurityDefinition) it is defined as :
<group name="NoLegs" required="N">
<component name="InstrumentLeg" required="N"/>
</group>

In other places (lines: 3557-3558, msgType=CollateralInquiry) it is defined like:
<field name="NoLegs" required="N"/>
<component name="InstrumentLeg" required="N"/>

The impact of this is that an XML parser can not correctly parse this component block across all message types.

Regards






[QFJ-885] SocketInitiator::stop() can't send out the logout message Created: 07/Apr/16  Updated: 27/Jul/17  Resolved: 12/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.2
Fix Version/s: 1.6.4

Type: Bug Priority: Major
Reporter: Shen liang Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-920 LogOff FIX Message(35=5) is not send ... Closed

 Description   

stop() function will invoke the stop(false) to stop the connection.
In the code, the END_OF_STREAM will be put into the message queue first. So the session will believe the connection is broken. Then the intent "session.logout()" in the logoutAllSessions() will be able to get chance to executed since the session state will be not logon for that END_OF_STREAM message.

eventHandlingStrategy.stopHandlingMessages();
logoutAllSessions(forceDisconnect);
stopInitiators();






[QFJ-884] quickfixj-messages-fix44 is including quickfixj-messages-all Created: 25/Mar/16  Updated: 13/Dec/16  Resolved: 30/Apr/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.6.2
Fix Version/s: 1.6.3

Type: Bug Priority: Major
Reporter: Guido Medina Assignee: Guido Medina
Resolution: Fixed Votes: 0
Labels: QuickfixJ


 Description   

Dependency quickfixj-messages-fix44 is including quickfixj-messages-all, this wasn't like that before so I wonder if the generator was broken during latest commits.



 Comments   
Comment by Guido Medina [ 25/Mar/16 ]

I had to do this to fix it when I noticed, kind of heavy dependency to add all messages (21mb)

{{
<!-- QuickFixJ-->
<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-core</artifactId>
<version>$

{quickfixj.version}</version>
</dependency>
<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-messages-fix44</artifactId>
<version>${quickfixj.version}

</version>
<exclusions>
<exclusion>
<artifactId>quickfixj-messages-all</artifactId>
<groupId>org.quickfixj</groupId>
</exclusion>
</exclusions>
</dependency>
}}

Comment by Guido Medina [ 26/Mar/16 ]

The following commits totally went back in time with the pom composition:

  • 1018578fda5d8316f9a0480ca26348c6e2146508
  • d30acc75f873225d230220a481eeff33a8f8f240

First it changed the distribution from bundle to jar and secondly it introduced quickfixj-messages-all as a dependency of every individual quickfixj-message-fixXX dependency, I tried to fix it but so many things were changed that I honestly don't know what to do.

Comment by Guido Medina [ 26/Mar/16 ]

I'm working on a PR but it will need more attention later as I think the poms were a bit screwed up, maybe I'm wrong.

Comment by ManuReno [ 29/Mar/16 ]

Hi,

Dependancy to message-all has been introduced in QFJ-855 so that all message source files are merged and then compiled before they are JARed in order, to reproduce the packaging behavior that existed in the previous ant build.
Merging the source of all messages before compilation is required since some FIX messages type differ from one FIX spec to another : messagexx.jar are thus not inter-changeable if built independantly.

Although this dependancy is not a maven best practice, the jar themselves should be OK thanks to the following block in the messagexx/pom.xml (example for fix44):

<plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <groupId>org.apache.maven.plugins</groupId>
                <version>2.6</version>
                <configuration>
                    <classesDirectory>${project.basedir}/../quickfixj-messages-all/target/classes/</classesDirectory>
                    <includes>
                        <include>FIX44.xml</include>
                        <include>FIX44.modified.xml</include>
                        <include>quickfix/fix44/**</include>
                        <include>quickfix/field/**</include>
                    </includes>
                    <archive> 
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>

Looking again a this, a dependancy to the core module may nevertheless replace the dependancy to message-all if the <classesDirectory> of the jar plugin configuration is also changed to point to :

<classesDirectory>${project.basedir}/../../quickfixj-core/target/classes/</classesDirectory>

The code generation may then also be removed from the message-all, thus ensuring that messages are compiled only once and this would also save build time.





[QFJ-883] Reject message definition missing from FIX50 package Created: 24/Mar/16  Updated: 24/Mar/16  Resolved: 24/Mar/16

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3, 1.6.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Tamas Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

If you load only the relevant messages jar (e.g. quickfixj:quickfixj-msg-fix50:1.5.3 or quickfixj:quickfixj-msg-fix50:1.6.0) the Reject message type is not present as a class. However it is present in FIX50.XML.

Is this an oversight? We should not have to load quickfixj-msg-fix44 package or quickfixj-msg-all to get this message type.



 Comments   
Comment by Christoph John [ 24/Mar/16 ]

Reject is a session-level message and hence is included in the FIXT11 package. Starting from FIX50 the session-level messages were separated.





[QFJ-882] FIX50.xml / LegSecAltIDGrp incorrect Created: 13/Mar/16  Updated: 13/Dec/16  Resolved: 23/Aug/16

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.6.0
Fix Version/s: 1.6.3

Type: Bug Priority: Default
Reporter: Mike Starkie Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
I believe there is an error in FIX50.xml at line 4138 in the components element.

<component name="LegSecAltIDGrp">
<field name="NoLegSecurityAltID" required="N"/>
</component>

In the other xml files, as well as the FIX 4.4 spec, the component is defined as a repeating group. I believe the element should be defined as in the FIX44 xml file as follows:

<component name="LegSecAltIDGrp">
<group name="NoLegSecurityAltID" required="N">
<field name="LegSecurityAltID" required="N"/>
<field name="LegSecurityAltIDSource" required="N"/>
</group>
</component>

I checked the FixRepository.xml file from the FIX consortium and it appears to be ok in the file under FIX 5.0 components section so perhaps it's an issue with the xml generator. Just wanted to bring it to your attention in hopes that fixing this issue may fix other similar issues in the dictionaries that may have resulted from the same condition.

I also posted this to the quickfix-developers group.



 Comments   
Comment by Mike Starkie [ 29/Apr/16 ]

Hi,
I believe this is not fixed. The fix should look like this:

<component name="LegSecAltIDGrp">
<group name="NoLegSecurityAltID" required="N"/>
<field name="LegSecurityAltID" required="N"/>
<field name="LegSecurityAltIDSource" required="N"/>
</group>
</component>

Comment by Christoph John [ 29/Apr/16 ]

You are right. Sorry, I mixed something up.





[QFJ-881] FieldType.MultipleValueString are not created from FIX5+ xml files Created: 12/Mar/16  Updated: 23/Sep/16  Resolved: 17/Mar/16

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.6.1
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: exgorth Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-905 MULTIPLECHARVALUE not handled in Fiel... Closed

 Description   

Fields where 'type' attribute has value 'MULTIPLESTRINGVALUE' are referenced in all FIX5+.xml. They cannot be correctly identified when added to DataDictonary because corresponding definition quickfix.FieldType ( quickfix.FieldType#MultipleValueString) expects value 'MULTIPLEVALUESTRING'.

Quick workaround for 1.6.1 is to update values in your xml dictionary, or change type to STRING and validate within app (as suggested elsewhere https://github.com/connamara/quickfixn/issues/66).

Proper fix would probably involve correcting both xml files and quickfix.FieldType to refer to MultipleStringValue constant as defined in the the official fixmlschema doc:

<xs:simpleType name="MultipleStringValue">
      <xs:annotation>
         <xs:documentation>string field containing one or more space delimited multiple character values (e.g. |277=AV AN A| ).</xs:documentation>
      </xs:annotation>
      <xs:restriction base="xs:string">
         <xs:pattern value=".+(\s.+)*"/>
      </xs:restriction>
   </xs:simpleType>

I would also suggest an engine to generate a warning (or allow some other strategy) when a DataDictionary parser encounters some 'unexpected' value (instead of just silently assuming type was Unknown)



 Comments   
Comment by exgorth [ 12/Mar/16 ]

The benefit of fixing this: messages that carry such types, for example MarketDataIncrementalRefresh(X) holding 75=U X, could you correctly processed by the engine with dictionary validation turned on. At the moment it rejects such (valid) messages.





[QFJ-880] qfj doesn't send the next batch when ResendRequestChunkSize > 0 Created: 26/Feb/16  Updated: 10/Oct/18

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Xiaojun Zhang Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: CME, resend
Environment:

FIX4.2



 Description   

Quickfixj seems to send the 1st resend batch only after receiving a seq reset.

i.e.
ResendRequestChunkSize=10

15:28:37.142 [QFJ Message Processor] - fromAdmin PNPBBBN: 8=FIX.4.29=10735=134=44749=CME50=G52=20160225-20:28:37.22356=PNPBBBN57=DROPCOPY143=US,NY369=45621112=IDiky5miuo10=025

15:28:37.142 [QFJ Message Processor] - toAdmin PNPBBBN: 8=FIX.4.29=10735=034=4562249=PNPBBBN50=DropCopy52=20160225-20:28:37.14256=CME57=G142=US,NY143=CME112=IDiky5miuo10=004

I manually reduced the incoming seq no to 428
15:29:07.969 [Thread-30] - command: "fix PNPBBBN 428"

15:29:08.120 [QFJ Message Processor] - toAdmin PNPBBBN: 8=FIX.4.29=10535=234=4562449=PNPBBBN50=DropCopy52=20160225-20:29:08.12056=CME57=G142=US,NY143=CME7=42816=43710=188

15:29:08.148 [QFJ Message Processor] - fromAdmin PNPBBBN: 8=FIX.4.29=13635=434=42843=Y49=CME50=G52=20160225-20:29:08.25556=PNPBBBN57=DROPCOPY122=20160225-20:29:08.255143=US,NY369=4562436=449123=Y10=001

I expect quickfix to send the next batch (438-447) but it sent a normal heartbeat instead.

15:29:38.704 [QFJ Timer] - toAdmin PNPBBBN: 8=FIX.4.29=9235=034=4562549=PNPBBBN50=DropCopy52=20160225-20:29:38.70456=CME57=G142=US,NY143=CME10=069



 Comments   
Comment by Christoph John [ 26/Feb/16 ]

Sorry, this is a little hard to follow. I don't know about the command "fix PNPBBBN". Is this some custom stuff that you are executing? Actually, I would expect QFJ to send a Logout if it received too low a sequence number. The last log line is half an hour later than the log line before. What happened in between?

Actually, there are some unit tests around the chunked resend requests behaviour. But of course, this does not mean that there could be no bugs inside that portion of the code. But I cannot really follow your example. Do you have a unit test or some more concise steps which can be followed?

Comment by Xiaojun Zhang [ 26/Feb/16 ]

Sorry the log is a bit hard to read.
1. "fix PNPBBBN" is an admin command I created which calls session.setNextTargetMsgSeqNum() so I can manipulate the seq no to trigger the scenario.
2. The log started from 15:28:37 to 15:29:38. You can ignore the UTC time in the FIX message.
3. A simpler example is
1) both sides seq no started from 1.
2) for some reasons client didn't receive some messages
3) the next message client received was seq no 20
4) chunk size was set to 10. so client sent a resent request being=2 end =11
5) client received seq reset with GapFill=Y
6) client should send the next resend request begin=2 end=20 but it didn't

Hope this helps.

Comment by Xiaojun Zhang [ 26/Feb/16 ]

Sorry there was a typo in 6) client should send the next resend request begin=12 end=20 but it didn't

Comment by Christoph John [ 26/Feb/16 ]

If you look at the incoming sequence reset you see the field 36/NewSeqNo set to 449. So that is why there are no more messages resent. This should actually also be a message in your event log. Something along the lines of: "received sequence reset to 449."

Comment by Xiaojun Zhang [ 26/Feb/16 ]

Hmm i am reading the FIX doc.
The message in all situations specifies NewSeqNo <36> to reset as thevalue of the next sequence numberimmediately following the messages and/or sequence numbers being skipped.
It seems <36> just indicates the next seq no I will receive. Does it mean the whole gap has been filled? In order to send the next resend request what <36> should be?

Actually I was connecting to CME drop copy and encountered this issue.

Comment by Christoph John [ 26/Feb/16 ]

If you send a resend request and the counterparty sends SequenceReset with NewSeqNo = 449 then QFJ will continue with that incoming seqnum. That means that the gap has been filled up to that seqnum, yes. Probably there were only session messages in between, or messages that CME does not want to resend.

Comment by Christoph John [ 26/Feb/16 ]

NB: I think this belongs more onto the mailing list or with CME support than here. It's no bug after all.

Comment by Xiaojun Zhang [ 27/Feb/16 ]

Sorry I still don't quite understand the logic here.
Let's say the seq gap is 1-20 and chunk size is set to 10. Application messages are in 11-20 but NOT in 1-10. After QFJ sends the 1st resend request from 1 to 10 what NewSeqNo should be in SequenceReset?
I don't think it will be 11 because seq no shouldn't decrease.
If it is 21 QFJ will continue with 21 and lose all messages from 11 to 20.

If my understanding is not correct can you please give me an example how chunked resend should work? Appreciate your help.

Comment by Xiaojun Zhang [ 01/Mar/16 ]

If you don't think it is a bug I will add code in my Application class to override the logic. I just want to point out that current logic does NOT work for CME iLink and Drop Copy 4.0 which place a 2500 limit on resend request. QFJ would lose all messages after the first batch. It makes more sense to assume the corresponding chunk gap has been filled based on the sequence reset, not the whole gap.

Comment by Christoph John [ 01/Mar/16 ]

Sorry, I totally forgot about this one. What logic do you want to override? Actually, you do not need to override any of the session logic.

It seems <36> just indicates the next seq no I will receive. Does it mean the whole gap has been filled? In order to send the next resend request what <36> should be?

The NewSeqNo on a sequence reset is the next-to-be sequence number of the other communication side.

Let's say the seq gap is 1-20 and chunk size is set to 10. Application messages are in 11-20 but NOT in 1-10. After QFJ sends the 1st resend request from 1 to 10 what NewSeqNo should be in SequenceReset?

NewSeqNo should be 11.

I don't think it will be 11 because seq no shouldn't decrease.
If it is 21 QFJ will continue with 21 and lose all messages from 11 to 20.

Why does the seq no decrease? It is as follows: you connect to the counterparty. Your expected target seq no is 1. The other side comes in with 20. Now you send a resend request from 1-10.
You receive a SeqReset with NewSeqNo 11. Now your expected target seq no is 11. This is an increment to 1 and not a decrement.
You issue another ResendRequest for 11-20 and receive the app messages, each will increment your expected target seq no by 1.

I know that there are several users which use QFJ to connect to CME. The last issue around chunked resend requests I remember was QFJ-751 which was fixed in QF/J 1.6.0.

Please write a mail to the mailing list if you have further questions. https://lists.sourceforge.net/lists/listinfo/quickfixj-users
Or please attach a failing unit test so that I can reproduce the error.

Thanks.

Comment by John [ 07/Apr/16 ]

I can confirm that I am seeing the same behavior when connecting to the CME's Drop Copy 4.0. It appears this issue arises due to the way in which the CME increments tag 36 of SequenceReset messages and the way QuickFIX/J handles the sending of ResendRequest messages.

The following code is an excerpt from the Session class in the quickfix package which I believe is where the logic breaks down. It appears that QuickFIX/J will attempt to send chunks of ResendRequests depending upon when it receives incoming SequenceReset messages.The code below requires the value of the newSequence variable to be less than the EndSeqNo value defined in the range of messages that the client is supposed to fetch. This case fails and some ResendRequest messages will not be sent. Would it be safe to remove this logic from the if statement allowing subsequent RequestsRequests to be sent to the counterparty despite the fact that the newSequence value will be past the range of messages defined in the range variable? If so, the code would also need to be modified to not leverage the value of the newSequence variable when sending the ResendRequest to define the range of sequence numbers to send in the subsequent ResendRequest.

newSequence < range.getEndSeqNo()

private void nextSequenceReset(Message sequenceReset) throws IOException, RejectLogon,
FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
boolean isGapFill = false;
if (sequenceReset.isSetField(GapFillFlag.FIELD))

{ isGapFill = sequenceReset.getBoolean(GapFillFlag.FIELD) && validateSequenceNumbers; }

if (!verify(sequenceReset, isGapFill, isGapFill))

{ return; }

if (validateSequenceNumbers && sequenceReset.isSetField(NewSeqNo.FIELD)) {
final int newSequence = sequenceReset.getInt(NewSeqNo.FIELD);

getLog().onEvent(
"Received SequenceReset FROM: " + getExpectedTargetNum() + " TO: "
+ newSequence);
if (newSequence > getExpectedTargetNum()) {
state.setNextTargetMsgSeqNum(newSequence);
final ResendRange range = state.getResendRange();
if (range.isChunkedResendRequest()) {
if (newSequence >= range.getCurrentEndSeqNo()
&& newSequence < range.getEndSeqNo())

{ // If new seq no is beyond the range of the current chunk // and if we are not done with all resend chunks, // we send out a ResendRequest at once. // Alternatively, we could also wait for the next incoming message // which would trigger another resend. final String beginString = sequenceReset.getHeader().getString( BeginString.FIELD); sendResendRequest(beginString, range.getEndSeqNo() + 1, newSequence + 1, range.getEndSeqNo()); }

}
// QFJ-728: newSequence will be the seqnum of the next message so we
// delete all older messages from the queue since they are effectively skipped.
state.dequeueMessagesUpTo(newSequence);
} else if (newSequence < getExpectedTargetNum()) {

getLog().onErrorEvent(
"Invalid SequenceReset: newSequence=" + newSequence + " < expected="
+ getExpectedTargetNum());
if (resetOrDisconnectIfRequired(sequenceReset))

{ return; }

generateReject(sequenceReset, SessionRejectReason.VALUE_IS_INCORRECT,
NewSeqNo.FIELD);
}
}
}

Comment by Xiaojun Zhang [ 07/Apr/16 ]

John, I received your email. Do you have a non-personal email address? My corporate email doesn't allow sending to gmail, hotmail, etc.

Comment by Christoph John [ 08/Apr/16 ]

I very briefly read through http://www.cmegroup.com/confluence/display/EPICSANDBOX/Drop+Copy+Session+Layer+-+Resend+Request and I do not see anything that is contradictory to how QFJ interprets the NewSeqNo tag. However, it seems that CME is implementing something very custom. A test case would definitely help here.
One thing I noticed though, is that they mention "duplicate resend requests". Maybe you can try if the configuration SendRedundantResendRequests=Y helps in that case?

Comment by John [ 09/Apr/16 ]

Chrstoph,

What format would you prefer to see a test case in? I could provide the FIX messaging log so that it might be easier to see how the CME is increasing the sequence numbers in the SequenceReset messages they send in the middle of sending ResendRequest chunks past the end of the original ResendRequest range such that QuickFIX/J defines after logging on which causes some of the ResendRequest chunks to not be sent to the exchange.

As I mentioned in my earlier post, I believe the issue is in the code snippet I posted above where upon receiving SequenceReset messages QuickFIX/J will determine if a new ResendRequest chunk message needs to get sent out based on the following criteria in the nextSequenceReset method of the Session class by checking if newSequence < range.getEndSeqNo(). Since this fails, some ResendRequests fail to ever get sent out.

Say the defined ResendRequest range is 1-10000.
1) I send a ResendRequest for messages 1-2500. I receive these messages and then receive a SequenceReset to 2520 for example.
2) I then send a ResendRequest for messages 2501-5000. I receive these messages and then receive a SequenceReset to 5050.
3) I send a ResendRequest for messages 5001-7500. I receive these messages and then receive a SequenceReset of 11000.
At this point the newSequence < range.getEndSeqNo() test fails and QuickFIX/J never sends the final ResendRequest for messages 7501-10000. The FIX connection continues to receive real-time trades etc as per normal.

I would assume this to be custom logic that the CME is implementing on their end. I think the difference comes down to the fact that QuickFIX/J appears to rely more on the newSequence number that is received on an incoming SequenceReset message to dictate whether further ResendRequest chunks will be sent out and the CME may send out a SequenceReset message taking you past the originally defined EndSeqNo range.

I am not a FIX expert so I can't say if this solution would work but it seems that if the logic for sending chunks of ResendRequest messages is changed such that each of the ResendRequest chunk messages is defined immediately after the need for a ResendRequest arises and put into a queue (or some other object) QuickFIX/J could then pop the each ResendRequest message off the queue once it receives all of the messages for a given ResendRequest from the exchange and continue onto the next one and decouple itself in that way from the newSequenceNumber. This might ensure that any of the chunks of ResendRequest messages that need to get sent out don't get skipped. This might have negative implications as it might not be the standard logic for communicating via FIX however so it might not be a feasible solution however.

It would be really great if this functionality could be modified in QuickFIX/J as this is an extremely useful engine however for users attempting to use QuickFIX/J with CME's Drop Copy 4 this case will cause problems in a recovery scenario.

Comment by Christoph John [ 29/Apr/16 ]

Hi John,

yes, a message log would be a good starting point. From this I should hopefully be able to construct an automated test case.

Thanks, Chris.

Comment by Christoph John [ 26/Aug/16 ]

Hi John, Xiaojun Zhang: is there still the need to support this? Do you have any message logs?
Thanks, Chris.

Comment by John [ 01/Sep/16 ]

Hi Christoph John,

I can confirm that there is a need to support this functionality. To be clear, I was experiencing this issue when working with the 1.6.0 release of QuickFIX/J and have not tested with more recent releases. I don't have any message logs available currently aside from what Xiaojun posted earlier in this issue.

Thanks

Comment by Christoph John [ 01/Sep/16 ]

Hi John, OK, if this functionality was implemented could you test it against CME to verify if it works? Do they have some sort of certification test?

Comment by Dmitry Razumov [ 10/Oct/18 ]

Hey John
I know it's been two years, but did you pass the certification in the end?





[QFJ-879] SystemTime currentTimeMillis is synchronized Created: 26/Feb/16  Updated: 21/Apr/16  Resolved: 08/Mar/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0, 1.6.1
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: Guido Medina Assignee: Guido Medina
Resolution: Fixed Votes: 0
Labels: None


 Description   

The class SystemTime was created to wrap a system time source primarily for unit testing (according to its JavaDocs) but it ended up been used globally so many important classes are obtaining the current time in millis using a synchronized call for no reason.

Can you please check if such thing is needed? If so let me know so that I can send a PR via Git.



 Comments   
Comment by Guido Medina [ 26/Feb/16 ]

I'm only referring to currentTimeMillis() method which is synchronized, if you search its usages it will show some important classes that get the time from it as intended, every message sent is time stamped, if you have more than one concurrent session sending prices for example or any other high frequency message, you end up locking for no reason as System.currentTimeMillis() is just a OS global variable (most likely an atomic variable) that is constantly updated.

Comment by Christoph John [ 29/Feb/16 ]

I assume that currentTimeMillis() is synchronized because setTimeSource() is also synchronized, so that it is made sure that always the correct systemTimeSource is used. But setTimeSource() is only used for unit tests, so maybe we can ignore that.

Comment by Guido Medina [ 29/Feb/16 ]

Not necessarily, you could leave the setter synchronized to create a memory barrier, say; you want other threads to see that you actually updated the time source.
Another way is to make the time source volatile but that would be slower than having the memory barrier at the setter.
If you think about it, the time source is updated not so frequent if ever, if the time source need to block then let it block at its implementation.
If you are sending many messages like price updates it is not good to synchronize.

Comment by Christoph John [ 29/Feb/16 ]

How will the other threads see the updated timeSource variable if they do not synchronize on it? If I'm not mistaken then synchronizing only the setter could lead to the situation where other threads might read/get old states of the timeSource variable.

Comment by Guido Medina [ 29/Feb/16 ]

Is how newer Java Memory Model work, at least Java 6+; the next read in another thread will read the updated value, synchronizing in both sides is only useful if you need one thread accessing such variable at the same time.

volatile resolves both concerns but then introduce an unnecessary CAS, the atomic-ity of such variable isn't that important.

Comment by Guido Medina [ 29/Feb/16 ]

You might as well remove both synchronize, since JMM after Java 6+ will take care of it.

Comment by Guido Medina [ 29/Feb/16 ]

I'm up for volatile, I don't think is that bad after all. Let me know what you think, maybe I'm just bargaining 1ns

Comment by Guido Medina [ 29/Feb/16 ]

I just force updated the branch with a different commit, synchronization there removed completely and changed for a volatile.

Comment by Guido Medina [ 29/Feb/16 ]

I can't make up my mind, the only reason I changed it to volatile is to give you (and other developers) a sense of safety, but I know that after JDK 6+ the JMM will clear any cache with any variable been updated inside a synchronized block hence it is not that weird to see synchronized for writes and nothing for read (a faster CAS), in fact if you go to LMAX disruptor code you will find weirdness like that one everywhere abusing the JDK JMM in order to gain performance.

So I would investigate in your side to get the feeling of safety for this, as you mentioned before the time source is only updated/changed while testing and it is only done before the tests start (it wouldn't make sense to change the time source while the tests are running)

I'll redo the push again with synchronized at set only again. Sorry for the many comments and confusion.

Comment by Christoph John [ 29/Feb/16 ]

No problem. Thanks for your input.
I was only looking this up in "Java Concurrency in Practice" but it is from 2006. Here is a quote on StackOverflow: http://stackoverflow.com/a/11459616 So it might be that this has changed in the meantime.
Anyway, for me it is OK to remove the synchronization from the getter since the setter is only used for unit testing. Let's hope that the build will be stable.

Comment by Guido Medina [ 29/Feb/16 ]

Yeah, I was looking at that one too to be completely certain and other old sources, it should be OK because (you can look at usages of setTimeSource method) setTimeSource method is called at the tests setup so it is unlikely such thing will happen.

Comment by Guido Medina [ 03/Mar/16 ]

Re-pushed with volatile, screw it, volatile will keep it correct and thread safe as writes are visible as soon as done, but TBH it is still slower than no volatile at all, though without it there is a risk of not seeing the value at all if you change the time source after some other thread have started.

At least volatile won't block concurrent sessions from getting the current time.





[QFJ-878] Publish QuickFIX jars to Maven Central Created: 22/Feb/16  Updated: 22/Feb/16  Resolved: 22/Feb/16

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

Type: Improvement Priority: Minor
Reporter: Laplie Anderson Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-846 Upload release to Maven or Sonatype c... Closed

 Description   

It's industry standard that open source java projects publish their jars to "The Central Repository" (http://search.maven.org). This was brought up in http://www.quickfixj.org/jira/browse/QFJ-123 before the build was completely maven-ized and resolved using a third-party repo.

I see using marketcetera's repo as a workaround. Now that the build is fully built on maven, it should take minimal effort to publish artifacts to maven central.






[QFJ-877] Multiple sessions with same dictionary Created: 16/Feb/16  Updated: 21/Apr/20  Resolved: 21/Apr/20

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

Type: Bug Priority: Default
Reporter: Mevlüt Saim Doruklu Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: Dictionary

Issue Links:
Duplicate
duplicates QFJ-982 Using the same dictionary file with d... Open

 Description   

When multiple sessions are created with the same dictionary name, the last created session sets the value for checkUserDefinedFields in DataDictionary.java. This is because of the dictionary cache using the same object in DefaultSessionFactory. Is this a bug or is it expected behaviour?



 Comments   
Comment by Mevlüt Saim Doruklu [ 16/Feb/16 ]

Affected quickfix versions are 1.4.1 and 1.4.0.





[QFJ-876] Code Generator creates bad code for nested repeating groups Created: 17/Feb/16  Updated: 13/Dec/16  Resolved: 08/Nov/16

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.6.1
Fix Version/s: 1.6.3

Type: Bug Priority: Major
Reporter: Jeff Remillard Assignee: Scott Harrington
Resolution: Fixed Votes: 0
Labels: None

Attachments: XML File FIX50SP2.modified.xml     Text File QFJ-876.patch    

 Description   

When a component is a repeating group and the its first element is also a repeating group, the generated code is invalid. This occurred when using a custom FIX50SP2 dictionary derived from FIX 5.0 SP Expansion Pack 196.

An example is the following definition from the dictionary file:

<component name="PhysicalSettlTermGrp">
<group name="NoPhysicalSettlTerms" required="Y">
<component name="PhysicalSettlDeliverableObligationGrp" required="N"/>
<field name="PhysicalSettlCurrency" required="N"/>
<field name="PhysicalSettlBusinessDays" required="N"/>
<field name="PhysicalSettlMaximumBusinessDays" required="N"/>
<field name="PhysicalSettlTermXID" required="N"/>
</group>
</component>

Where the component PhysicalSettlDeliverableObligationGrp is defined as:

<component name="PhysicalSettlDeliverableObligationGrp">
<group name="NoPhysicalSettlDeliverableObligations" required="Y">
<field name="PhysicalSettlDeliverableObligationType" required="N"/>
<field name="PhysicalSettlDeliverableObligationValue" required="N"/>
</group>
</component>

This generates the source file PhysicalSettlTermGrp.java with the following extract:

public static class NoPhysicalSettlTerms extends Group {

static final long serialVersionUID = 20050617;

public NoPhysicalSettlTerms() {
super(40204, ,
new int[]

{40209, 40205, 40206, 40207, 40208, 0 }

);
}

Looking through the source code, it appears that there may be an issue in codegenerator/Message.xsl where the group-delimiter is generated.

I can email (or upload if possible) the entire dictionary file I'm using. To recreate, replace FIX50SP2.modified.xml file and build.



 Comments   
Comment by Christoph John [ 18/Feb/16 ]

This is a known problem with the code generator. That's why the FIX*modified.xml files were taken do generate the code.
Also see this comment:
http://www.quickfixj.org/jira/browse/QFJ-453?focusedCommentId=11685&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-11685

Comment by Scott Harrington [ 03/Nov/16 ]

I attached a patch to MessageSubclass.xsl that fixes this issue, for me it occurs with PartyRiskLimitsReport / NoPartyRiskLimits / NoRiskLimits / NoRiskLimitTypes (EP105) because the delimiter field for both NoPartyRiskLimits and for NoRiskLimits must be extracted from inside a nested group.

Christoph: I think this issue is a bit different from the repository issues that the FIX*.modified.xml dictionaries were originally designed to work around (i.e. those workarounds are still needed).

Comment by Christoph John [ 03/Nov/16 ]

Hi Scott Harrington,
thanks for the patch, I'll have a look at it.
You are right, there is at least one other problem why the modified files are needed (component names and field names must be unique).
Cheers,
Chris.





[QFJ-875] SendingTime accuracy problem Created: 16/Feb/16  Updated: 23/Aug/16  Resolved: 23/Aug/16

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

Type: Other Priority: Major
Reporter: Cedric Zeng Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: QuickfixJ
Environment:

Use Eclipse to run QuickFIX/J


Attachments: Microsoft Word Sample Code to QFJ.xlsx     Microsoft Word Sample Log to QFJ.xlsx    

 Description   

Hi,

I'm running QuickFIX/J for 8 months and still cannot solve this issue.
I run only the initiator and have synchronized time with the third party FIX server.

The problem is that sometimes machine will have a time lag to receive the message. Once the time lag is over 30 seconds, our side will report a "SendingTime accuracy problem" issue to broker and asked log-out.

After I modified the code, the frequency drops a lot. But it still happens one time per day.

Do you have any idea why this problem keeps happening?
1. internet unstable?
We save the price from broker to our server.


Here is the sample log

8=FIX.4.3|9=69|35=0|49=BrokerQuote|56=Client123|34=670|57=FX|52=20160215-07:55:34.743|369=5|10=074|
8=FIX.4.3|9=230|35=S|49=BrokerQuote|56=Client123|34=683|57=FX|52=20160215-07:55:35.369|369=5|131=3072|117=Client123-USDSEK-2016-2-15:7.55.35:72-2000000|537=1|55=USD/SEK|460=4|132=8.43613|133=8.43913|134=2000000|135=2000000|60=20160215-07:55:35.369|64=20160217|10=051|
8=FIX.4.3|9=61|35=0|34=6|49=Client123|50=FX|52=20160215-07:55:56.108|56=BrokerQuote|10=190|
8=FIX.4.3|9=229|35=S|49=BrokerQuote|56=Client123|34=684|57=FX|52=20160215-07:55:35.470|369=5|131=3072|117=Client123-GBPUSD-2016-2-15:7.55.35:80-2000000|537=1|55=GBP/USD|460=4|132=1.4515|133=1.45166|134=2000000|135=2000000|60=20160215-07:55:35.470|64=20160217|10=219|
8=FIX.4.3|9=229|35=S|49=BrokerQuote|56=Client123|34=685|57=FX|52=20160215-07:55:35.470|369=5|131=3072|117=Client123-USDRUB-2016-2-15:7.55.35:80-2000000|537=1|55=USD/RUB|460=4|132=77.8389|133=77.934|134=2000000|135=2000000|60=20160215-07:55:35.470|64=20160216|10=028|
8=FIX.4.3|9=69|35=0|49=BrokerQuote|56=Client123|34=686|57=FX|52=20160215-07:55:35.619|369=5|10=084|
8=FIX.4.3|9=229|35=S|49=BrokerQuote|56=Client123|34=687|57=FX|52=20160215-07:55:35.696|369=5|131=3072|117=Client123-USDPLN-2016-2-15:7.55.35:98-2000000|537=1|55=USD/PLN|460=4|132=3.9205|133=3.92347|134=2000000|135=2000000|60=20160215-07:55:35.696|64=20160217|10=037|
8=FIX.4.3|9=113|35=3|34=7|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|45=684|58=SendingTime accuracy problem|372=S|373=10|10=033|
8=FIX.4.3|9=61|35=5|34=8|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|10=198|
8=FIX.4.3|9=113|35=3|34=9|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|45=685|58=SendingTime accuracy problem|372=S|373=10|10=036|
8=FIX.4.3|9=62|35=5|34=10|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|10=240|
8=FIX.4.3|9=114|35=3|34=11|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|45=686|58=SendingTime accuracy problem|372=0|373=10|10=044|
8=FIX.4.3|9=62|35=5|34=12|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|10=242|
8=FIX.4.3|9=114|35=3|34=13|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|45=687|58=SendingTime accuracy problem|372=S|373=10|10=082|
8=FIX.4.3|9=62|35=5|34=14|49=Client123|50=FX|52=20160215-07:56:07.607|56=BrokerQuote|10=244|



 Comments   
Comment by Guido Medina [ 16/Feb/16 ]

30 seconds is unlikely to be the time source which is feeding your servers but just in case here is a long shot:

I have seen time offsets for networks where the time source is not reliable or even set, if you could make sure your time source in the network is being updated via internet time servers and the same for the other side if you can since the other side might be out of your hands.

If you are using Linux even better because you can set your NTP servers to the closest pool.

I would recommend you to use time sources from http://www.pool.ntp.org/en/
On the right side you can see the different pools, 1st by continent and then by country.

Hope this helps,

Guido.

Comment by Cedric Zeng [ 17/Feb/16 ]

Hi Guido,

Thanks your advice.
I don't think it is a time sync problem. We have double check the time with our broker.
Our engine runs well most of the time. It just sometimes gets jammed and can't receive message for a while. Once the time it restart to receive messages over 30 seconds, it will been logged out.

I want to investigate why the system get jammed but I don't know how to start.

Thanks.
Cedric

Comment by Guido Medina [ 17/Feb/16 ]

Again another long shot as what I'm trying to do is trying to help you with my little available time with easy fixes/suggestions, few questions:

  • What type of session do you open? Weekly? Daily? or Forever?
  • Connection stalled might be related to Mina-core, if you go to QuickFixJ GitHub you will see my countless effort to always keep the dependencies updated, specially Mina-core, you probably have 2.0.10 and between that version and latest which is 2.0.13 some weird race conditions have been fixed, specially related to SSL (Not excluding non-SSL)

Go and check Mina-core page which has the list of fixed issues: https://mina.apache.org/mina-project/index.html and see if any of these fixes your problem, but regardless I would recommend you to revised your dependencies and update them from time to time.

Hope this helps,

Guido.

Comment by Guido Medina [ 17/Feb/16 ]

Another question I forgot: Are you seeing long GC pauses at any side? And that would lead us to another different which is your JVM configuration and hence my question, what JVM are you using and what are your JVM options.

Note: I have seen crazy GC pauses of more than 30 secs but then you would have to be using a big heap size like 16g+ or so.

Comment by Christoph John [ 18/Feb/16 ]

Cedric,
my first assumption would also be a GC pause. But you can easily check that with tools like "jstat -gcutil". Other possibility would be that you do a long running processing in your fromApp() method where you process the incoming message.
Chris.

Comment by Guido Medina [ 18/Feb/16 ]

Hi Cedric,

I have to agree with Christoph there, I would check the following in the following order:

  • Make sure you are not doing processing on the QuickFixJ thread, if you have a single thread thread factory you need to forward the FIX message to another queue and then processing at another thread.
  • Check your JVM version and parameters, I strongly recommend to move to at least Java 7u80 or even Java 8u74; reason for that? GC improvement, specially if you want a near pauseless JVM, see my thread Akka forums for low-latency micro-services, my conclusion on JVM options are by the end but you are welcome to read the whole thread (12 posts): https://groups.google.com/d/msg/akka-user/9s4Yl7aEz3E/zfxmdc0cGQAJ
  • Make sure your project dependencies are updated, that's easy to do if you are using Maven with the following command which will tell you what dependencies can be updated, not all dependencies are update-able because some of them will point to an alpha or beta version but for most it helps:
  • For Windows: mvn -U versions:display-dependency-updates
  • For Linux with only the important bits: mvn U versions:display-dependency-updates | grep -e '>' -e Building
Comment by Cedric Zeng [ 19/Feb/16 ]

Hi Guido,

For your questions,

  • My session is Weekly session.
  • I'm using Java 8u66
  • Here is my JVM configuration
    -vm
    C:\Program Files\Java\jre1.8.0_66\bin\server\jvm.dll
    eclipse.home.location=file:/D:/eclipse/
    eclipse.launcher=D:\eclipse\eclipse.exe
    eclipse.launcher.name=Eclipse
    [email protected]/../p2
    eclipse.p2.profile=epp.package.java
    eclipse.product=org.eclipse.epp.package.java.product
    eclipse.startTime=1453791502283
    eclipse.stateSaveDelayInterval=30000
    eclipse.vm=C:\Program Files\Java\jre1.8.0_66\bin\server\jvm.dll
    eclipse.vmargs=-Dosgi.requiredJavaVersion=1.6
    -Xms40m
    -Xmx512m

For Christoph suggestion,
Actually I did a long running processing in my fromApp() before. After I changed that, the frequency drops a lot. "TradeAppInitiator" is the class processes the incoming message. I move other process to "TradeAppInitiatorApp" class. Does this solve the concern?

For update,
My machine runs well for 3 days and has no any problem. The frequency actually drops a lot compares to early situation. I'm going to check whether it is a GC pause.

Thanks Guido and Christoph suggestions. You are very kind and helpful.

Regards,
Cedric

Comment by Christoph John [ 23/Aug/16 ]

If there are any more problems, please write to the mailing list. Thanks





[QFJ-874] Session Qualifier for acceptor sessions Created: 07/Jan/16  Updated: 03/Apr/16

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.2.1
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Kou Jun Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello,

i think, it would be a good idear, to have a session qualifier for acceptor sessions (ConnectionType=acceptor).
If you try to configure two acceptors in separate configuration files (Same fix-version, SenderCompId, TargetCompID) and the only difference is the port number, the configuration will not work if the Message store is in the same directory. They will both use the same message and eventlog files.

Regards
Thomas Hügel



 Comments   
Comment by Kou Jun [ 07/Jan/16 ]

My case is

there are 2 fix session both are acceptor,have separate file store. but the 2 session's fix-version, SenderCompId, TargetCompID are same,only the port number is different,I didn't use property file to config the session but config the 2 sessions in code.

receive message worked well!
but if I use Session.lookupSession(sessionID).send(message);
the 2 session's sessionID is same, so Session.lookupSession(sessionID) always return the session2.

Comment by Dmytro Semenov [ 21/Mar/16 ]

Can you use session qualifier field here? "SessionQualifier Additional qualifier to disambiguate otherwise identical sessions"

Also it will solve JMX problem if you have it. Both sessions will try to expose same MBean otherwise

Comment by Kou Jun [ 03/Apr/16 ]

A SessionQualifier can only be used with an initiator.





[QFJ-873] Support processing higher resolution timestamps Created: 04/Jan/16  Updated: 22/Nov/17  Resolved: 23/May/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation, Metadata/Specs
Affects Version/s: None
Fix Version/s: 2.0.0

Type: New Feature Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-919 Upgrade to FIX 5.0.SP3 - EP206 Closed
Relates
is related to QFJ-921 Support receiving higher resolution t... Closed

 Description   

mail on quickfixj-users mailing list

-------- Forwarded Message --------
Subject: [Quickfixj-users] QuickFIX/J time precisions
Date: Mon, 4 Jan 2016 09:16:55 +0000
From: Yuval Cohen <[email protected]>
Reply-To: [email protected]
To: [email protected] <[email protected]>

QuickFIX/J Documentation: http://www.quickfixj.org/documentation/
QuickFIX/J Support: http://www.quickfixj.org/support/

FIX Standards have recently proposed changes, that require some code change in QuickFix/J.
Specifically, FIX introduced a change to the time precision to support microseconds and higher resolution timestamp.
A gap analysis made by FIX can be found by following the links in: http://www.fixtradingcommunity.org/pg/discussions/topicpost/2893609/
Please fill free to contact me directly if you need any clarifications about the new standards.

I would appreciate if anyone who is working to make the required changes will please contact me.

Kind Regards
Yuval Cohen

Etrading Software Ltd
City Tower
40 Basinghall street
London EC2V 5DE

Tel: 020 3770 5808
Mobile: 07889 176368
SkypeMe: yuval_cohen.laptop

considerations

  • Is this really required? One could argue that for normal trading applications millisecond granularity is sufficient. Probably no-one is using QFJ for high-frequency trading (which would require at least microsecond granularity).
  • To accept timestamps with higher granularity the probably easiest thing to do is to alter the fields in the data dictionary from UTCTIMESTAMP to STRING. That way the messages would get accepted and users could parse the fields by themselves.
    • However, a more sophisticated solution would be preferred.
  • Supporting timestamps up to nanosecond precision could be implemented with reasonable effort. However, it might be required to use JDK 8 for this since nanosecond support is better.
  • Picosecond granularity is totally out of scope and is also discouraged by FPL.
  • We need a configuration option to decide which precision we want to send since not all counterparties might be able to deal with it, e.g. some destinations might only be ready to receive microseconds but not nanoseconds timestamps.

Also see QFJ-921 which will merely deal with accepting messages with timestamps in microseconds or nanoseconds but not with processing them.

implementation

  • added support for sending/processing UtcTimestamps with up to nanosecond precision
  • added config TimeStampPrecision (used for (Orig)SendingTime)which can take a value of SECONDS, MILLIS, MICROS or NANOS.
  • instead of java.util.Date we will now use java.time.LocalDate/Time classes
  • extended/adapted unit tests
  • extended converters
  • added new fields UtcTimeField and UtcDateField


 Comments   
Comment by Anna Maria Cochetti [ 11/Apr/17 ]

Even when not using QFJ for trading you can still want to use it for transaction reporting and transparency pourposes.

Comment by Christoph John [ 11/Apr/17 ]

Agreed





[QFJ-872] toString() Method Breaks Repeating Groups Created: 23/Dec/15  Updated: 23/Dec/15  Resolved: 23/Dec/15

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

Type: Bug Priority: Critical
Reporter: Mike Starkie Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

OS X 10.11.2
jdk1.8.0_65


Attachments: Java Source File QuickFixGroupTest.java    

 Description   

Given a valid FIX 4.4 Execution Report FIX string containing a repeating group passed as the single argument to the constructor of the Message type, immediately calling the toString() method on the new instance results in the repeating group being mangled.

Below is the output of the sample program which demonstrates the bug. The first message has field 382[NoContraBrokers] in the correct place at the start of ContraGrp. The toString result has field 375[ContraBroker] coming before 382 which is incorrectly placed outside the group.

Fix String before creating Message instance:
8=FIX.4.4|9=173|35=8|34=3|49=BRKR|52=20121105-23:24:42|56=BANZAI|6=0|11=1352157882577|14=0|17=1|20=0|31=0|32=0|37=1|38=10000|39=0|54=1|55=MSFT|150=2|151=0|382=1|375=1|655=2|437=444|438=888|10=111|

Fix String after calling toString() on the new instance of Message:
8=FIX.4.4|9=173|35=8|34=3|49=BRKR|52=20121105-23:24:42|56=BANZAI|6=0|11=1352157882577|14=0|17=1|20=0|31=0|32=0|37=1|38=10000|39=0|54=1|55=MSFT|150=2|151=0|375=1|382=1|437=444|438=888|655=2|10=111|

----------------------- Sample Code -------------------------

package com.globalforge.infix;

import quickfix.InvalidMessage;
import quickfix.Message;

public class QuickFixGroupTest {
static String FIX_44_EXEC_REPORT =
"8=FIX.4.49=17335=834=349=BRKR52=20121105-23:24:4256=BANZAI6=011=135215788257714=017=120=031=032=037=138=1000039=054=155=MSFT150=2151=0382=1375=1655=2437=444438=88810=111";

public static String rs(String ins)

{ return ins.replaceAll("\u0001", "|"); }

public static void main(String[] args) {
System.out.println("before: " + rs(FIX_44_EXEC_REPORT));
try

{ Message quickFixMsg = new Message(FIX_44_EXEC_REPORT); System.out.println("after : " + rs(quickFixMsg.toString())); }

catch (InvalidMessage e)

{ e.printStackTrace(); }

}
}



 Comments   
Comment by Christoph John [ 23/Dec/15 ]

This is no valid FIX4.4 message for several reasons:

  • tag 20/ExecTransType is not defined in FIX4.4.
  • tag 438/ContraTradeTime should contain a timestamp but contains 888

Moreover, the position of the fields in the repeating groups should be the same as defined in the data dictionary (at least up to and including FIX4.4). But I don't remember if this is in line with the spec or a speciality of QF/J.
But apart from that you really need to specify a data dictionary when wanting to parse repeating groups from a String.

After these changes the parsing succeeds.

     System.out.println("before: " + rs(FIX_44_EXEC_REPORT));
        try {
            Message quickFixMsg = new Message();
            final DataDictionary dataDictionary = new DataDictionary("FIX44.xml");
            quickFixMsg.fromString(FIX_44_EXEC_REPORT, dataDictionary, true);
            System.out.println("after : " + rs(quickFixMsg.toString()));
        } catch (InvalidMessage e) {
            e.printStackTrace();
        }
Comment by Christoph John [ 23/Dec/15 ]

Please post to the mailing list before opening a bug. Thanks
https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-871] Print address for unsuccessful connection attempts Created: 03/Dec/15  Updated: 21/Apr/16  Resolved: 23/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.6.1
Fix Version/s: 1.6.2

Type: Improvement Priority: Default
Reporter: Kou Jun Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

If fail-over case, I config like below
SocketConnectHost=host1
SocketConnectPort=1111
SocketConnectHost1=host2
SocketConnectPort1=1111
,if the two accepter are not exist,the log will be like as below,

20151203-21:17:14.014 ERROR [QFJ Timer] errorEvent - FIX.4.2:XXX->YYY: java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 15000 milliseconds)
20151203-21:17:29.037 ERROR [QFJ Timer] errorEvent - FIX.4.2:XXX->YYY: java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 15000 milliseconds)
20151203-21:17:44.048 ERROR [QFJ Timer] errorEvent - FIX.4.2:XXX->YYY: java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 15000 milliseconds)
20151203-21:17:59.065 ERROR [QFJ Timer] errorEvent - FIX.4.2:XXX->YYY: java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 15000 milliseconds)

I could'nt know this connection is connect to which host and port is failed,
if print out the host and port,will be very useful!



 Comments   
Comment by Kou Jun [ 03/Dec/15 ]

someone could hide my SendCompID and TargetCompID?
thanks.

Comment by Christoph John [ 03/Dec/15 ]

Done





[QFJ-870] Don't Know Trade <Q> message Created: 20/Nov/15  Updated: 20/Nov/15  Resolved: 20/Nov/15

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

Type: New Feature Priority: Critical
Reporter: Anuradha Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: Message
Environment:

Windows7(OS),QFJ(FIXimulator_0.41) and Client(initiator) in C#.net
Hardware 4GB ram



 Description   

Hello,

As per my understanding, Don't Know Trade(Q) is the message which will be received to client from server end when a trade is rejected.

Can you please let me know whether my understanding is correct, if not please correct me.

I would like to know a sample Don't Know Trade(Q) generation messages.

Appreciate your response.

Thanks & Regards,
Anuradha



 Comments   
Comment by Grant Birchmeier [ 20/Nov/15 ]

The answer to your question is dependent on the counterparty. Five different counterparties could do it five different ways. You should ask your counterparty.

Please do not use JIRA to ask for help. See http://quickfixj.org/support/

Closing this issue because it's not a bug.

Comment by Anuradha [ 20/Nov/15 ]

Thank you for the response.





[QFJ-869] Getting Configuration Failed Error: Could not open body file while client (initiator) trying to logon after logout Created: 15/Nov/15  Updated: 16/Nov/15  Resolved: 16/Nov/15

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

Type: Bug Priority: Default
Reporter: parashuram Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: Reconnect, logon, session, settings
Environment:

Windows7(OS),QFJ(FIXimulator_0.41) and Client(initiator) in C#.net
Hardware 4GB ram



 Description   

Getting Configuration Failed Error: Could not open body file while client (initiator) trying to logon after logout

shows the error message as below:
Configuration failed: Could not open body file: c:\fixfiles\FIX.4.2-BANZAI-FIXIMULATOR.body

here c:\fixfiles\ path is take as FileStorePath where the FIX.4.2-BANZAI-FIXIMULATOR.body,FIX.4.2-BANZAI-FIXIMULATOR.header,FIX.4.2-BANZAI-FIXIMULATOR.seqnums,FIX.4.2-BANZAI-FIXIMULATOR.session file were stored.

But I couldn't figure out why initiator is showing this error message while trying for next logon after logout. I am thankful for any help on this issue.

Thanks & regads
Parashuram M



 Comments   
Comment by Christoph John [ 16/Nov/15 ]

Hmm, hard to tell. Are the files really there? Maybe they are corrupted?
It also seems that Fiximulator uses a pretty old QFJ version. I'd rather like to close this issue as invalid since I assume that it is not reproducible with a current QFJ version.

If you still need help please use the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-868] IoSessionInitiator can't reconnect the disconnected session Created: 13/Nov/15  Updated: 17/Aug/16  Resolved: 17/Aug/16

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.6.1
Fix Version/s: 1.6.3

Type: Bug Priority: Critical
Reporter: Shen liang Assignee: Guido Medina
Resolution: Duplicate Votes: 3
Labels: QuickfixJ, Reconnect, session

Issue Links:
Duplicate
duplicates QFJ-895 Reconnecting initiator does not work ... Closed
Relates
relates to QFJ-866 Initiator session timer with SSL enabled Closed

 Description   

The reconnection has a check shouldReconnect(). The function rely on the flag "!ioSession.isConnected()". But when the Session object disconnect its connection by

responder.disconnect();
setResponder(null);

The disconnect() itself will cause the close future set "closing = true". So there is a gap. Session object believe its connection is closed. While because of some reason the close isn't done, just be marked. So the background reconnection process will be fooled and won't be able to rebuild the connection. The Session timeout check routine will also just skip check since its responder is null by this check

// Return if we are not connected
if (!hasResponder())

{ return; }

The effect is the connection won't be back after the following exception log

Disconnecting: Socket exception : java.io.IOException: Connection reset by peer



 Comments   
Comment by Christoph John [ 20/Nov/15 ]

Hmm, I found several instances in our log files where the connection has been re-established after such an IOException. Will have to check.

Comment by Guido Medina [ 18/Dec/15 ]

Look at Github pull request #19

Comment by Guido Medina [ 18/Dec/15 ]

Sorry I meant #50

Comment by Christoph John [ 18/Dec/15 ]

Yes, you are referring to https://issues.apache.org/jira/browse/DIRMINA-995
The issue title says that it only appears with proxy, but further down the comments it seems it can also be triggered without proxy. Yeah, may very well be the problem.
Thank you.

Comment by Dan Corneanu [ 16/Aug/16 ]

Is this issue really solved in 1.6.2?
I am using

  • mina-*-2.0.13
  • quickfixj-*-1.6.2

and I can reliably reproduce this issue by enabling and disabling some firewall rules.

My session does use SSL

SocketUseSSL=Y
Comment by Christoph John [ 17/Aug/16 ]

Hi Dan,

no, it's not. But it is solved by QFJ-895. This is available in 1.6.3-SNAPSHOT and 1.7.0-SNAPSHOT.

Cheers,
Chris.





[QFJ-867] Thread handling after exiting QuickFIX Created: 06/Nov/15  Updated: 16/Nov/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Martin Vrábel Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

Apache Tomcat 8 on Windows 10, Spring 4 web application



 Description   

Hi,

I stumbling over this thing over and over. When I stop my application I always get error messages in output about spawning a new thread during execution of application but failing to remove it when application stops:

```
06-Nov-2015 12:29:26.653 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@682d21a6]) and a value of type [quickfix.field.converter.UtcTimestampConverter] (value [quickfix.field.converter.UtcTimestampConverter@7f03e077]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
06-Nov-2015 12:29:26.654 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@682d21a6]) and a value of type [quickfix.field.converter.UtcTimestampConverter] (value [quickfix.field.converter.UtcTimestampConverter@6b6c6237]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
06-Nov-2015 12:29:26.654 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@682d21a6]) and a value of type [quickfix.field.converter.UtcTimestampConverter] (value [quickfix.field.converter.UtcTimestampConverter@2aca975d]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
06-Nov-2015 12:29:26.654 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@682d21a6]) and a value of type [quickfix.field.converter.UtcTimestampConverter] (value [quickfix.field.converter.UtcTimestampConverter@2bebb3b3]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
06-Nov-2015 12:29:26.655 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [ROOT] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@682d21a6]) and a value of type [quickfix.field.converter.UtcTimestampConverter] (value [quickfix.field.converter.UtcTimestampConverter@4b8bfee1]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
```

It has something to do with `UtcTimestampConverter` but I have no idea why is it happening. I correctly shutdown all threads I manually start.



 Comments   
Comment by Christoph John [ 16/Nov/15 ]

Hmm, looks more like a false positive to me. But to be honest I never tried running QFJ in a managed environment or appserver.
http://stackoverflow.com/questions/28105803/tomcat8-memory-leak says that the ThreadLocals need to be removed but I think this is not done because it is expected that QFJ is ran in a stand-alone environment.

Comment by Martin Vrábel [ 16/Nov/15 ]

Would it be possible to call a method or something from outside of quickfix to manually shutdown all spawned threads when exiting my webapp?

Comment by Christoph John [ 16/Nov/15 ]

From what I understand from the output it does not have to do anything with threads but ThreadLocal variables that are still held. But AFAIK there is no built-in mechanism to clean them up.





[QFJ-866] Initiator session timer with SSL enabled Created: 02/Nov/15  Updated: 23/Jun/16  Resolved: 23/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0, 1.6.1
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: Guido Medina Assignee: Guido Medina
Resolution: Fixed Votes: 0
Labels: None
Environment:

Debian 7


Issue Links:
Duplicate
is duplicated by QFJ-850 QuickFix/J stop to reconnect Closed
Relates
is related to QFJ-868 IoSessionInitiator can't reconnect th... Closed
is related to QFJ-895 Reconnecting initiator does not work ... Closed

 Description   

It seems to be an issue where the weekly session for a QuickFixJ initiator is not starting properly, I have several connections as initiator with no SSL and they all start find, I disconnect my sessions every Friday at 22:00 and start them again every Sunday at 21:00, all of them show the "Session not current" message (a) in the log and all of them except the one with SSL show later the log information about the session being started (b)

Sample logs:
a) 01-11-15 21:00:00 INFO q.event - FIX.4.4:...>...: Session state is not current; resetting FIX.4.4:01-11-15 21:00:00 INFO q.event - ...>...: Session state is not current; resetting FIX.4.4:...>...>...
b) 01-11-15 21:00:00 INFO q.m.i.InitiatorIoHandler - MINA session created for ...->...: local=/...:..., class org.apache.mina.transport.socket.nio.NioSocketSession, remote=/...:...

Log B is not happening for the connection with SSL so I'm not sure what's going on with the connection, it seems that for weekly sessions the SSL connection is not closing correctly making the timer hit a sort of a lock where it cannot get out? no other error is reporting.

Usually when a connection is down for a network issue it is retried except for this particular case of weekly reconnection.



 Comments   
Comment by Christoph John [ 20/Nov/15 ]

Could you maybe take a stack dump of the process to check if there really is a lock of some kind? Does the connection come up after that (without resetting the session) or does it just hang there?

Comment by Guido Medina [ 20/Nov/15 ]

Hi Christoph,

The connection is hangs there, no other log happens, no error or anything so if you ask me I think it is either a dead lock (or unreachable condition) or some stall state within the SSL connector, I'll try to get a threads dump next week. It is not a hard lock in that once you stop and start the session it continues without any issue but now that you mention it I don't know if any other thread is stuck for ever so I'll definitely have to get a threads dump when the problem happens and then reset the session and see if such thread is still alive.

Comment by Guido Medina [ 20/Nov/15 ]

Another thing that I noticed 2 days ago is that when the connection cannot be started for SSL, it is not retried, I was adding a new connector that 1st was configured with SSL then it was changed to non-SSL and retries while network issues were present were happening only for non-SSL.

Comment by Christoph John [ 20/Nov/15 ]

Sounds a little like QFJ-868 but there is no mentioning of SSL.

Comment by Guido Medina [ 20/Nov/15 ]

Hmm, I think I have seen 868 issue now that I think about it, I wasn't paying too much attention so I automatically associated it with SSL maybe there is something with SSL that makes the issue "more" reproduce-able.

Comment by Christoph John [ 27/Nov/15 ]

Just realised there already was QFJ-850 for the same problem.

Comment by Guido Medina [ 18/Dec/15 ]

Look at pull request #50, it might fix the issue, mina core 2.0.10 released with some interesting bugs fixed and 3 of them SSL related.





[QFJ-863] In the quickfix version that we use (1.5.3b), an invalid checksum error does not result in a session reject Created: 12/Oct/15  Updated: 12/Oct/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Saurabh Desai Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The scenario:

The initiator parses the following message with quickfix.MessageUtils.parse(), and sends it to the acceptor.

8=FIX.4.4|9=238|35=AE|31=1.35|32=1000|48=EURUSD|22=6|55=EURUSD|64=20131106|194=1.35|15011=1.33|15012=1.33|461=RCSXXX|487=2|571=1105200000001234|829=0|572=M1006050412587|552=1|54=1|37=SYS1:4545556002|11=SYS2:1006050412587|526=SSP:BDID001|453=2|448=a123456|447=D|452=3|802=2|523=5730607|803=10|523=5730606|803=15|1=123456-789|

It is not a valid FIX message, as we have 453<NoPartyIDs>=2, but there is only one group in the message. We would expect the acceptor to return a validation error, but instead the following happens:

1) An error message is logged:

2013-12-07 15:47:30,919 [SocketAcceptorIoProcessor-0.0] ERROR [] q.mina.acceptor.AcceptorIoHandler - Invalid message: Expected CheckSum=29, Received CheckSum=28 in 8=FIX.4.4?9=367?35=AE?34=82?49=SIDE1?52=20131207-14:47:30.618?56=SIDE2?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?64=20131106?194=1.35?461=RCSXXX?487=2?571=1105200000001234?572=M1006050412587?829=0?15011=1.33?15012=1.33?552=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=5730607?803=10?523=5730606?803=15?1=123456-789?10=028?

2) The acceptor does not send any response and does not increase the message sequence count, either.

The suspect:

The acceptor validates the fix message with the checksum(String s) method of Message class. It calculates 29. But the checksum calculated on the initiator side is 28. The initiator calculates the checksum with a different method, which is called by the toString() method of Message class. This is the method which does the calculation (in FieldMap class) - my comments added:

int calculateTotal() {

int result = 0;
// JK: fields variable contains tags which are not group tags
for (final Field<?> field2 : fields.values()) {
final Field<?> field = field2;
if (field.getField() == CheckSum.FIELD || isGroupField(field.getField()))

{ continue; }

result += field.getTotal();
}

// JK: groups variable contains the group tags, but only the tag number (the key is Integer, not Field - why?)
final Iterator<Map.Entry<Integer, List<Group>>> iterator = groups.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<Integer, List<Group>> entry = iterator.next();
final List<Group> groupList = entry.getValue();
if (!groupList.isEmpty()) {
final IntField groupField = new IntField((entry.getKey()).intValue());
// JK: at this point we have 453=0, as this is a new field, no value yet
groupField.setValue(groupList.size());
// JK: now it is 453=1, because we have only one group
result += groupField.getTotal();
for (int i = 0; i < groupList.size(); i++)

{ final Group group = groupList.get(i); result += group.calculateTotal(); }

}
}

return result;
}

So the checksum will be the checksum of a different message actually, where 453=1.






[QFJ-862] java.lang.RuntimeException: java.io.IOException: The filename, directory name, or volume label syntax is incorrect Created: 07/Oct/15  Updated: 07/Oct/15  Resolved: 07/Oct/15

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

Type: Bug Priority: Default
Reporter: gaviya Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I am trying to import a fix message of type ExecutionReport Fix 4.2 and i get the error as "java.lang.RuntimeException: java.io.IOException: The filename, directory name, or volume label syntax is incorrect".
My session id is something like this( FIX.4.2:CXX/G->OXXXXXX/CME_NXXXXXXX)
The error is thrown at invoker.Invoke(message, sessionID); in the MessageCracker class.



 Comments   
Comment by Grant Birchmeier [ 07/Oct/15 ]

Jira is for bugs, not help requests. Please use the mailing list (see http://quickfixj.org/support/) or StackOverflow to ask for help.





[QFJ-861] OutOfMemoryError with using DefaultMessageFactory and quickfixj-all-1.6.1.jar Created: 23/Sep/15  Updated: 22/Dec/15  Resolved: 22/Dec/15

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

Type: Bug Priority: Major
Reporter: Frantisek Hradil Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-855 Change packaging strategy for quickfi... Closed

 Description   

Hi,
after upgrade from 1.5.3 to 1.6.1 I got "OutOfMemoryError". I'm using "quickfixj-all-1.6.1.jar". Problem is that "quickfix.DefaultMessageFactory" trying to add all factories (fix40,fix41,..fix50sp2). Problem is during adding "fix50sp2".

I had to use "quickfixj-all-1.6.1.jar" instead of "quickfixj-core-1.6.1.jar" + "quickfixj-messages-fix44-1.6.1.jar" because of issue "QFJ-845".

Please, could you look at it? Is there a plan for release a new quickfixj version?

Thank you.

Error replication:
MessageFactory mf = new DefaultMessageFactory();

More exception details:
java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:190)
at quickfix.DefaultMessageFactory.addFactory(DefaultMessageFactory.java:85)
at quickfix.DefaultMessageFactory.addFactory(DefaultMessageFactory.java:60)
at quickfix.DefaultMessageFactory.<init>(DefaultMessageFactory.java:54)



 Comments   
Comment by Christoph John [ 23/Sep/15 ]

Seems you'll have to increase the PermGen size then. Or use Java8 and Metaspace.

https://github.com/quickfix-j/quickfixj/wiki/QFJ-1.6.0-release-notes

Edit: QFJ-845 is solved with QFJ 1.6.1. Or did you experience problems?

Comment by Frantisek Hradil [ 23/Sep/15 ]

Hi John,
thank you for your quick answer.

I'm working in a big company, so it's not easy to upgrade to Java8 in tens of our applications. Also it is not so easy to increase memory... (Which value is enough, what do you think?)

Main problem is, that QFJ-845 was solved by the new jar "quickfixj-all-1.6.1.jar". Yes, the problem was solved. But now there is the new memory issue.
I would like to use just the jars, which I need - same as in 1.5.3.

Comment by Christoph John [ 23/Sep/15 ]

Hi, I don't know what the default PermGen setting is on your machine. But I guess somewhere around 64 or 96MB. So increasing to 128MB might already help. But this of course also depends on the classes loaded by your own application, which also go into PermGen.

I think you are referring to QFJ-855 with regard to not being able to use the single message JARs.

Another work-around: in our company we did not need the FIX5.0+ stuff either but wanted a single JAR, so we just built a new JAR only containing the needed FIX message classes for FIX4.0 - 4.4. This can be achieved with the Maven Shade plugin. But I don't know if you are using Maven.

Comment by Frantisek Hradil [ 23/Sep/15 ]

Actually I got the error also with 512MB or 1024MB - so it is really strange...
Yes, using just part of packages from "quickfixj-all-1.6.1.jar" can help - but I'm not so happy with this solution (with changing of released jar manually).

Thank you for your help. I will probably wait with upgrade untill QFJ-855 will be solved and released.

Comment by Christoph John [ 23/Sep/15 ]

Actually I got the error also with 512MB or 1024MB - so it is really strange...

I think that is impossible. I guess the setting does not get picked up by the process. You can find out the current PermGen size by doing e.g. "jmap -heap <pid>" on your process. Are you sure you are setting PermGen size, not heap size?

Comment by Frantisek Hradil [ 23/Sep/15 ]

Omg, my mistake! You are right, I increased just heap size. It works now.
Thank you.

Comment by Christoph John [ 23/Sep/15 ]

No problem





[QFJ-860] Support newest EP (expansion pack) for FIX5.0SP2 Created: 20/Aug/15  Updated: 26/Aug/15

Status: Open
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: John Khouri Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: generation
Environment:

Java



 Description   

Some new messages were added in the EPs. E.g. PartyDetailsListRequest (35=CF).



 Comments   
Comment by Christoph John [ 20/Aug/15 ]

QFJ currently only supports FIX5.0 up to SP2. The message PartyDetailsListRequest is from EP105 (extentsion pack) so it is not yet supported by QFJ.

Comment by John Khouri [ 20/Aug/15 ]

Thanks! Do you know when the EP105 will be supported by QFJ?

Comment by Christoph John [ 26/Aug/15 ]

No, sorry. It will probably wait until someone volunteers to update the data dictionary accordingly.





[QFJ-859] Performance and latency improvements Created: 17/Aug/15  Updated: 18/Sep/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: 2.1-BETA

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Charles Briquel submitted some performance related pull requests which should be integrated into the next version.

https://github.com/quickfix-j/quickfixj/pull/32
https://github.com/quickfix-j/quickfixj/pull/34
https://github.com/quickfix-j/quickfixj/pull/35
https://github.com/quickfix-j/quickfixj/pull/36
https://github.com/quickfix-j/quickfixj/pull/37
https://github.com/quickfix-j/quickfixj/pull/39
https://github.com/quickfix-j/quickfixj/pull/40
https://github.com/quickfix-j/quickfixj/pull/41
https://github.com/quickfix-j/quickfixj/pull/42






[QFJ-858] logon problem with FIX41 Created: 05/Aug/15  Updated: 10/Aug/15  Resolved: 10/Aug/15

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

Type: Bug Priority: Critical
Reporter: Praveen Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

3.0.80-0.7-default #1 SMP Tue Jun 25 18:32:49 UTC 2013 (25740f8) x86_64 x86_64 x86_64 GNU/Linux


Attachments: File FixClient.cfg    
Issue Links:
Duplicate
duplicates QFJ-845 Change packaging strategy of quickfix... Closed

 Description   

While starting engine in initator mode with FIX41 session configured , following error is received and engine fail to stablish FIX connection

Following is logs with excepiton
INFO: MINA session created for FIX.4.1:BLPFE->DSLFE: local=/10.245.150.28:56536, class org.apache.mina.transport.socket.nio.NioSocketSession, remote=tokeqappu71/10.245.150.27:10000
Aug 5, 2015 9:27:18 PM quickfix.mina.SessionConnector$SessionTimerTask run
SEVERE: Error during timer processing
java.lang.VerifyError: (class: quickfix/fix41/Logon, method: set signature: (Lquickfix/field/ResetSeqNumFlag;)V) Incompatible argument to function
at quickfix.fix41.MessageFactory.create(MessageFactory.java:35)
at quickfix.DefaultMessageFactory.create(DefaultMessageFactory.java:133)
at quickfix.Session.generateLogon(Session.java:1872)
at quickfix.Session.next(Session.java:1799)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:278)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)

Attached is config i am using



 Comments   
Comment by Grant Birchmeier [ 05/Aug/15 ]

Did you try asking on the mailing list? JIRA is not for help requests.

Comment by Christoph John [ 10/Aug/15 ]

Praveen Could you please try with QFJ 1.6.1. Looks like QFJ-845.





[QFJ-857] quickfix.FieldNotFound: 555, index=1 while using TradeCaptureReport.fromString(fixMsg, dd, true) Created: 04/Aug/15  Updated: 04/Aug/15  Resolved: 04/Aug/15

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

Type: Bug Priority: Blocker
Reporter: balakrishna Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

We are developing an utility which will take fix message string as input to the MessageUtils.parse method to create a TradeCaptureReport Object. This object intern pass it to the downstream to process further to create a Deal in our system.
Using below code, we are now able to process the fix messages for Normal Deals but the same is failing to process spread deals with the following error. while executing the
message.getGroup(i, nolegs) on TradeCaptureReport Object

quickfix.FieldNotFound: 555, index=1
but the 555 has two legs in the fix message below.

Java Code: We tried with the 2 methods the results into the same error.
1)message = (TradeCaptureReport)MessageUtils.parse(new quickfix.fix44.MessageFactory(), dd, fixMsg);
2) fixMsg is my String contains the below fix message.
TradeCaptureReport message = new TradeCaptureReport();
message.fromString(fixMsg, dd, true);

Error is coming because message.frromString()// method is not populating the group by filed map for 555 though it present in the

Fix messages:
8=FIX.4.49=94635=AE49=ICE34=352=20150804-07:38:17.86156=1574657=26571=180487=0856=0568=474be469-5eab-4207-845a-9cfa4f88f6e9828=017=500013139=2570=N55=14209048=GWM FMX0015-GWM FMZ001522=8461=FXXXXX207=IFEU9064=0916=20151101917=2015123132=531=-1.3309018=59022=3075=2015080460=20150804-07:37:10.1439413=0762=999028=666003552=154=237=500012711=707335134453=6448=tpoint_gui1447=D452=11448=Triple Point Technology, Inc.447=D452=13448=15577447=D452=56448=15577447=D452=35448=U447=D452=54448=144447=D452=55*555=2600=141989602=GWM FMX0015!603=8608=FXXXXX616=IFEU624=2637=46.570687=5654=50001329019=59023=309020=201511019021=20151130539=3524=U525=D538=54524=144525=D538=55524=15577525=D538=35600=141975602=GWM FMZ0015!603=8608=FXXXXX616=IFEU624=1637=47.900687=5654=50001339019=59023=319020=201512019021=20151231539=3524=U525=D538=54524=144525=D538=55524=15577525=D538=35*10=250



 Comments   
Comment by balakrishna [ 04/Aug/15 ]

Hi,
dd = new DataDictionary("FIX44.xml");
dd.setCheckUnorderedGroupFields(false);

After setting the above property to the Datadictionary this problem got resolved. please close this call.





[QFJ-856] Error Recieved Msg Created: 31/Jul/15  Updated: 31/Jul/15  Resolved: 31/Jul/15

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.6.0, 1.6.1
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: IJDAD Younes Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

Hello,
I have a problem with receiving messages from our server FIX,

please find below the traceability of requests sent / received.

Thanks for your help.

<20150731-16:08:27, FIXT.1.1:YOUN->IJD, outgoing> (8=FIXT.1.19=12935=D34=90849=YOUN52=20150731-16:08:27.96856=IJD11=6098538=10040=244=5154=155=ADH59=060=20150731-16:08:27.967581=110=063)
<20150731-16:08:28, FIXT.1.1:YOUN->IJD, incoming> (8=FIXT.1.19=32235=849=IJD56=YOUN34=78152=20150731-16:06:23.6541128=917=E0NpIbOJ4ohk11=60985278=O0NpIgELeV8O37=O0NpIgELeV8O442=1150=039=0151=10014=055=ADH453=3448=YOUN447=D452=53448=MCP447=D452=1448=MaroClear447=D452=8340=259=054=138=1001138=10044=51528=A60=20150731-16:06:23.6511180=130001=1581=110=224)
<20150731-16:08:28, FIXT.1.1:YOUN->IJD, error> (Rejecting invalid message: quickfix.FieldException: Tag not defined for this message type, field=278: 8=FIXT.1.19=32235=834=78149=IJD52=20150731-16:06:23.65456=YOUN1128=911=6098514=017=E0NpIbOJ4ohk37=O0NpIgELeV8O38=10039=040=244=5154=155=ADH59=060=20150731-16:06:23.651150=0151=100278=O0NpIgELeV8O442=1528=A581=11138=1001180=130001=1453=3448=YOUN447=D452=53448=MCP447=D452=1448=MaroClear447=D452=8310=224)
<20150731-16:08:28, FIXT.1.1:YOUN->IJD, error> (Reject sent for Message 781: Tag not defined for this message type:278)



 Comments   
Comment by Grant Birchmeier [ 31/Jul/15 ]

JIRA is not for help requests.

For help, join the mailing list (see http://quickfixj.org/support/) or try StackOverflow.





[QFJ-855] Change packaging strategy for quickfixj-messages-fix[40|41|42|43|44|50|50sp1|50sp2|t11] modules to prevent VerifyError Created: 17/Jul/15  Updated: 21/Apr/16  Resolved: 22/Mar/16

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

Type: Bug Priority: Default
Reporter: ManuReno Assignee: ManuReno
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Relates
relates to QFJ-832 Multi-Version support is busted in 1.6.0 Closed
relates to QFJ-845 Change packaging strategy of quickfix... Closed
relates to QFJ-861 OutOfMemoryError with using DefaultMe... Closed

 Description   

Classes generated & compiled from single FIXxx dictionaries may conflict with classes used to compile the core module resulting in VerifyError at runtime.

The aim of this ticket is to package the quickfixj-messages-fix99 jars out of the messages-all compilation result to ensure the same .class files are used between all modules.
This should allow to use these jars without facing VerifyError with the following limitations :

  • The new jar will be different from what could be obtained by generating out of a single dictionary
  • The */field/* package contain the fields from all the fix dictionaries documented in QuickFixJ

This packaging strategy is a bit unusual and has some limitations but may temporary solve the VerifyError issue for someone who doesn't want to use the messages-all jar.



 Comments   
Comment by Christoph John [ 17/Jul/15 ]

Is this a follow-up to QFJ-845? So the VerifyError does still occur when not using the messages-all.jar after QFJ-845 has been solved?

Comment by ManuReno [ 17/Jul/15 ]

This is indeed a followup as QFJ-845 fixes the issue only for the messages-all module.

Comment by ManuReno [ 27/Jul/15 ]

Pull request submitted,

Observations showed that fix50 and fixt11 specifications are required by the core module at compile time, the recommended classpath when using individual dictionaries is thus :
quickfixj-core.jar;quickfixj-messages-fix50.jar;quickfixj-messages-fixt11;[then other dictionaries]

Comment by Christoph John [ 17/Aug/15 ]

Do you mean the classpath at runtime or compile time?

Comment by Tamas [ 18/Feb/16 ]

Is there a possibility of fixing this? It is not feasible to have to use quickfixj-all which is a 20MB+ behemoth if all one needs is quickfixj-core and quickfixj-message-fix44 for example.

Additionally, the source/jar packaging is screwed up.
It looks like most fields are defined in quickfixj-core, however their source equivalents are in quickfixj-messages-fix44. Because of this you cannot get the source working automatically from maven/gradle.

See for example QuoteReqID.

  • quickfixj-core-1.6.1.jar/quickfix/field/ has QuoteReqID.class
  • quickfixj-core-1.6.1-sources.jar/quickfix/field/ is empty
  • quickfixj-messages-fix44-1.6.1.jar/quickfix/field/ is empty
  • quickfixj-messages-fix44-1.6.1-sources.jar/quickfix/field/ has QuoteReqID.java
Comment by Christoph John [ 14/Mar/16 ]

Hi Tamas,

https://github.com/quickfix-j/quickfixj/pull/31 has now been merged into trunk and 1.6.x branch. If you like you could test if this resolves your problem:
https://oss.sonatype.org/content/repositories/snapshots/org/quickfixj/quickfixj-distribution/1.6.2-SNAPSHOT/quickfixj-distribution-1.6.2-20160314.154317-15-bin.zip

I think the source packaging is another story. Please open a separate issue for this.

Thanks,
Chris.





[QFJ-854] Race discovered in SingleThreadedEventHandlingStrategyTest Created: 09/Jul/15  Updated: 21/Apr/16  Resolved: 23/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: Nathan Tippy Assignee: Marcin L
Resolution: Fixed Votes: 1
Labels: None

Attachments: Java Source File IsAliveTest.java     File start.bat    

 Description   

I have run into a problem with the unit tests on my quad core haswell i7. It looks like a race condition.

Failed tests:
SingleThreadedEventHandlingStrategyTest.testDoubleStart:55->checkThreads:94 Exactly one 'QFJ Message Processor' thread expected expected:<1> but was:<2>

Tests run: 1294, Failures: 1, Errors: 0, Skipped: 0

I can fix the problem by adding this sleep on line 54 of SingleThreadedEventHandlingStrategyTest. However this is not the right solution but it works.

ehs.blockInThread();
Thread.sleep(200); //need delay
ehs.blockInThread();
checkThreads(bean);



 Comments   
Comment by Alexey Serdyuk [ 23/Jul/15 ]

I could reproduce failing test on Intel Xeon (6 cores).

I believe that the problem is caused not by a bug in the tested class, but by an error in the unit test itself: a test method does not properly clean up, so the second test method may fail.

When the test SingleThreadedEventHandlingStrategyTest.testStartStop() is executed, it calls the method SingleThreadedEventHandlingStrategy.blockInThread() that starts a message processor thread. When the method testStartStop() finishes, the message processor thread is still running for some milliseconds. If the second test SingleThreadedEventHandlingStrategyTest.testDoubleStart() is executed quick enough, it also calls SingleThreadedEventHandlingStrategy.blockInThread() and starts the second message processor thread. After this an attempt to assert that there is only one message processor thread fails.

How to prove that this is the case: add the following main() method to SingleThreadedEventHandlingStrategyTest and run it.

    public static void main(String []args) throws Exception {
        SingleThreadedEventHandlingStrategyTest test_1 = new SingleThreadedEventHandlingStrategyTest();
        test_1.testStartStop();
        test_1.checkThreads(ManagementFactory.getThreadMXBean());
        
        SingleThreadedEventHandlingStrategyTest test_2 = new SingleThreadedEventHandlingStrategyTest();
        test_2.testDoubleStart();
    }

The method checkThreads() throws an exception if the number of message processor threads differs from 1. In my test it does not throw an exception, so the message processor thread still runs after the unit test is executed. When the second unit test is executed, it finds 2 message processor threads and fails.

Solution: in the "finally" block each unit test must somehow ensure that the message processing thread is finished. Maybe the method SingleThreadedEventHandlingStrategy.stopHandlingMessages() must be modified to wait until the message processing thread finishes, or a new method is required - I do not know QuickfixJ internals good enough to judge.

A quick workaround is to add a sleep in the "finally" block of each unit test after the method stopHandlingMessages() is called, to give the message processing thread some time to exit, but I do not consider this to be a right solution.

Comment by Christoph John [ 23/Jul/15 ]

Hi Alexey Serdyuk, thanks for the analysis!

Comment by Michael Whidden [ 11/Oct/15 ]

Also reproducible on a 4-core, JDK 8. My solution was to add this method to SingleThreadedEventHandlingStrategy.java

    /**
     * 
     * @param join if true, don't return until the thread has terminated.
     */
    public void stopHandlingMessages(boolean join) throws InterruptedException
    {
        stopHandlingMessages();
        if(join && messageProcessingThread.isAlive())
            messageProcessingThread.join();
    }

and call
ehs.stopHandlingMessages(true);
in two finally blocks in
SingleThreadedEventHandlingStrategyTest

Comment by Michael Whidden [ 11/Oct/15 ]

Sorry about the abysmal formatting of my previous comment. Hopefully you get the drift...

Comment by Christoph John [ 12/Oct/15 ]

Thanks for your comment. I have fixed the formatting.

Comment by Christoph John [ 05/Jan/16 ]

I have merged this also to the 1.6.x branch and afterwards the build failed two or three times consecutively because of this test. Now it succeeded a few times in a row. Strange indeed...
For the trunk this test did not fail at all during the last builds. Maybe there is also a relation to the JDK version being used. For trunk it is JDK7 for the branch it is JDK6.

Comment by Marcin L [ 05/Jan/16 ]

I re-run the test class multiple times on different Java versions, but I can't see it failing. I can see that you added some extra logging. Let's wait and see.

Comment by Christoph John [ 06/Jan/16 ]

For me it only occurred when running the complete build (or at least when running all tests from that module).
E.g. http://www.quickfixj.org:8085/browse/QFJ-GIT16X-22
http://www.quickfixj.org:8085/browse/QFJ-GIT16X-23
http://www.quickfixj.org:8085/browse/QFJ-GIT16X-24

Comment by Marcin L [ 06/Jan/16 ]

I found out that the problem is caused by Thread#isAlive() method. It doesn't actually guarantee to return "true" after calling Thread#start() method. It seems like there is a window of inconsistency between these two methods. I prepared a simple test class and a batch script to illustrate the problem. It runs in a loop, because it fails very occasionally and it takes some time to prove it. Same problem exists for Java 7 and Java 8, although it happens more often on Java 6 (it might not be true in practice).

I noticed that Thread#getState() method is better, because it never returns "NEW" after calling Thread#start().

Looking at QFJ-GIT16X-JOB1-32 log I can see that test case testDoubleStart() bypassed if (messageProcessingThread != null && messageProcessingThread.isAlive()) statement.
In the stack trace we can see two threads being started. We see "INFO: Started QFJ Message Processor" only once, because the second thread was executing line 123 which is this log line.

build 06-Jan-2016 13:32:05 Running quickfix.mina.SingleThreadedEventHandlingStrategyTest
error 06-Jan-2016 13:32:05 Jan 6, 2016 1:32:05 PM quickfix.mina.SingleThreadedEventHandlingStrategy$1 run
error 06-Jan-2016 13:32:05 INFO: Started QFJ Message Processor
build 06-Jan-2016 13:32:05 QFJ Message Processor RUNNABLE
build 06-Jan-2016 13:32:05 java.lang.Object.getClass(Native Method)
build 06-Jan-2016 13:32:05 java.util.logging.LogRecord.<init>(LogRecord.java:126)
build 06-Jan-2016 13:32:05 org.slf4j.impl.JDK14LoggerAdapter.log(JDK14LoggerAdapter.java:574)
build 06-Jan-2016 13:32:05 org.slf4j.impl.JDK14LoggerAdapter.info(JDK14LoggerAdapter.java:275)
build 06-Jan-2016 13:32:05 quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:123)
build 06-Jan-2016 13:32:05 java.lang.Thread.run(Thread.java:662)
build 06-Jan-2016 13:32:05 QFJ Message Processor TIMED_WAITING
build 06-Jan-2016 13:32:05 sun.misc.Unsafe.park(Native Method)
build 06-Jan-2016 13:32:05 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:196)
build 06-Jan-2016 13:32:05 java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025)
build 06-Jan-2016 13:32:05 java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:424)
build 06-Jan-2016 13:32:05 quickfix.mina.SingleThreadedEventHandlingStrategy.getMessage(SingleThreadedEventHandlingStrategy.java:99)
build 06-Jan-2016 13:32:05 quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:88)
build 06-Jan-2016 13:32:05 quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:124)
build 06-Jan-2016 13:32:05 java.lang.Thread.run(Thread.java:662)

I will provide a fix as soon as I can.

Comment by Alexey Serdyuk [ 07/Jan/16 ]

In IsAliveTest.java you start a new thread with an empty run() method, so it is possible that it is already finished at the moment when the original thread calls isAlive(). If you want to test whether the second thread reports isAlive() = true after the start, you have wait inside it's run() method to not finish to early, for example like this:

public class IsAliveTest1 {
    public static void main(final String[] args) {
        long startMillis = System.currentTimeMillis();

        while (true) {
            final java.util.concurrent.CountDownLatch latch = new java.util.concurrent.CountDownLatch(1);
            Thread thread = new Thread("FooBar") {
                @Override
                public void run() {
                    // Wait until the main thread commands this thread to finish.
                    try {
                        latch.await();
                    } catch (InterruptedException ex) {
                        // No-op.
                    }
                }
            };

            thread.setDaemon(true);
            thread.start();
            
            // in theory 'isAlive' should always return true at this point
            if (!thread.isAlive()) {
                System.out.println("BOOM!");
                System.exit(0);
            }
            
            // Command the second thread to finish.
            latch.countDown();
            
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            if (System.currentTimeMillis() - startMillis > 60000) {
                System.exit(0);
            }
        }
    }
}

With the original IsAliveTest I have observed the "BOOM!" again and again, but with the modified version I can't reproduce it.

Comment by Marcin L [ 07/Jan/16 ]

You are absolutely right Alexey. I was fiddling with the test for too long and got to ridiculous assumptions.

Comment by Marcin L [ 08/Jan/16 ]

SingleThreadedEventHandlingStrategyTest fails, because there is a stale 'QFJ Message Processor' thread left over from a different test case.
I found two test classes which do not clean up 'QFJ Message Processor' thread correctly - ResynchTest and TimerTest. The thread will be running until Java process is restarted.

Looking at the build logs I can see that ResynchTestServer (SingleThreadedEventHandlingStrategy actually) class will not clean up resources correctly if a thread
which makes a call to SocketAcceptor.stop() is in interrupted state (which is triggered in tearDown code). All failing tests have the same exception in common and there is always one log line 'INFO: Started QFJ Message Processor ' more than 'INFO: Stopped QFJ Message Processor'.

QFJ-GIT16X-JOB1-32.log:
error 06-Jan-2016 13:31:48 SEVERE: Error in TimerTestServer server:
error 06-Jan-2016 13:31:48 java.lang.RuntimeException: java.lang.InterruptedException
error 06-Jan-2016 13:31:48 at quickfix.mina.SingleThreadedEventHandlingStrategy.onMessage(SingleThreadedEventHandlingStrategy.java:56)
error 06-Jan-2016 13:31:48 at quickfix.mina.SingleThreadedEventHandlingStrategy.stopHandlingMessages(SingleThreadedEventHandlingStrategy.java:156)
error 06-Jan-2016 13:31:48 at quickfix.SocketAcceptor.stop(SocketAcceptor.java:108)
error 06-Jan-2016 13:31:48 at quickfix.SocketAcceptor.stop(SocketAcceptor.java:101)
error 06-Jan-2016 13:31:48 at quickfix.test.acceptance.resynch.ResynchTestServer.run(ResynchTestServer.java:136)
error 06-Jan-2016 13:31:48 at java.lang.Thread.run(Thread.java:662)
error 06-Jan-2016 13:31:48 Caused by: java.lang.InterruptedException
error 06-Jan-2016 13:31:48 at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1199)
error 06-Jan-2016 13:31:48 at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:312)
error 06-Jan-2016 13:31:48 at java.util.concurrent.LinkedBlockingQueue.put(LinkedBlockingQueue.java:294)
error 06-Jan-2016 13:31:48 at quickfix.mina.SingleThreadedEventHandlingStrategy.onMessage(SingleThreadedEventHandlingStrategy.java:54)
error 06-Jan-2016 13:31:48 ... 5 more

SingleThreadedEventHandlingStrategy#isStopped field is never updated when stop is called from within a thread in 'interrupted state'.

I wrote four failing test cases:
https://github.com/the-thing/quickfixj/commit/5f85381f93af17281dbcc5acbe41cf3587cb1eed

shouldCleanUpAcceptorQFJMessageProcessorThreadAfterInterrupt
shouldCleanUpInitiatorQFJMessageProcessorThreadAfterInterrupt

To fix these two we need to make a small change to SingleThreadedEventHandlingStrategy.onMethod():

@Override
public void onMessage(Session quickfixSession, Message message) {
    if (message == END_OF_STREAM && isStopped) {
        return;
    }
    try {
        eventQueue.put(new SessionMessageEvent(quickfixSession, message));
    } catch (InterruptedException e) {
        // Thread.currentThread().interrupt();
	// OR
	// isStopped = true;
	// throw new RuntimeException(e);
    }
}

shouldCleanUpAcceptorQFJMessageProcessorThreadAfterStop
shouldCleanUpInitiatorQFJMessageProcessorThreadAfterStop

I'm not sure about these two, but it looks like it might be separate issue. I seems that it's not possible to stop blocking SocketAcceptor or SocketInitiator by neither calling stop from another thread nor interrupting the thread which called block() method, unless I'm not doing it properly. Can somebody take a look at the last two?

Comment by Christoph John [ 13/Jan/16 ]

Thanks for the test. I only get failures in the test shouldCleanUpInitiatorQFJMessageProcessorThreadAfterStop. I get the same failures as you if I change the port of the acceptor on each call to createAcceptor(). Otherwise the second acceptor just reports a BindException since the port is already in use. Also see another comment here: https://github.com/the-thing/quickfixj/commit/5f85381f93af17281dbcc5acbe41cf3587cb1eed#commitcomment-15420123
I think the problem with these two tests is that the poll() call to the blocking queue can not be interrupted. I tried moving the call to

                eventHandlingStrategy.stopHandlingMessages();

out of the synchronized block in the stop() methods of SocketAcceptor/Initiator and that resolves the issue by placing the END_OF_STREAM message into the blocking queue. But I need to think about if this will cause synchronization problems of some sort when concurrently starting/stopping the same Initiator/Acceptor.

Comment by Marcin L [ 13/Jan/16 ]

I forgot to mention that the tests should be executed individually with a delay.





[QFJ-853] Add ability to modify the Proxool JDBC connection pool via session settings Created: 06/Jul/15  Updated: 13/Dec/16  Resolved: 23/Aug/16

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

Type: New Feature Priority: Minor
Reporter: Jose Elias Chavez Assignee: Jose Elias Chavez
Resolution: Fixed Votes: 0
Labels: jdbc, settings

Issue Links:
Duplicate
is duplicated by QFJ-839 Modify the proxool connection pool pr... Closed

 Description   

In file JdbcUtil.java, the proxool data source is created using hard coded settings. There is even a TODO comment for making these configurable.

It would be good if these hard coded settings could be configurable via the settings file.






[QFJ-852] Missing synchronized blocks discovered in code review. Created: 01/Jul/15  Updated: 04/Jul/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Nathan Tippy Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: sequnece

Attachments: File quickfixjQFJ-852.patch    

 Description   

In the class Session in the following method

private boolean verify(Message msg, boolean checkTooHigh, boolean checkTooLow)

we find that synchronized (state.getLock()) is used to ensure atomic updates to the multiple fields in the state object. If this is needed then we must also check to ensure partial or dirty reads are avoided. This would happen any place that we call for more than one field of the state and assume the fields remain consistent with one another until we make a second or third request for other fields.

Directly after this same block the usage of isChunkedResendRequest, getCurrentEndSeqNo and getEndSeqNo run the risk of partial (dirty) reads because they are out side the sync.

This same problem also exists here where it may be the cause of other more serious issues.
private void nextSequenceReset(Message sequenceReset)

And to a a lesser degree in
private void doTargetTooHigh(Message msg)



 Comments   
Comment by Nathan Tippy [ 02/Jul/15 ]

For immediate use I apply this patch file to be safe. However this should be re-visited with a more elegant fix.

Comment by Christoph John [ 03/Jul/15 ]

Thanks for the patch!
Edit: did you encounter dirty read problems?

Comment by Nathan Tippy [ 04/Jul/15 ]

No I have not seen any problems but after discovery in code review I was uncomfortable running it without a fix.

I have not seen any negative consequences to applying the patch. So it was a defensive move.





[QFJ-851] Include proxool-cglib in the lib/ folder of the binary (.zip) distribution Created: 30/Jun/15  Updated: 13/Dec/16  Resolved: 23/Aug/16

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

Type: Improvement Priority: Default
Reporter: Attila-Mihaly Balazs Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-846 Upload release to Maven or Sonatype c... Closed

 Description   

proxool-cglib-0.9.1.jar is needed by proxool-0.9.1.jar (which is already included) - otherwise the later throws ClassDefNotFound errors (for example when tryint to use JdbcStoreFactory).

PS. This wouldn't be a problem if QF/J would be available on Maven since the dependency would be transparently pulled in



 Comments   
Comment by Attila-Mihaly Balazs [ 30/Jun/15 ]

Forgot to mention: the aforementioned JAR can be downloaded from here: http://search.maven.org/remotecontent?filepath=com/cloudhopper/proxool/proxool-cglib/0.9.1/proxool-cglib-0.9.1.jar





[QFJ-850] QuickFix/J stop to reconnect Created: 11/Jun/15  Updated: 27/Nov/15  Resolved: 27/Nov/15

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

Type: Bug Priority: Blocker
Reporter: Andrei Marchanka Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: QuickfixJ
Environment:

Ubuntu Linux


Issue Links:
Duplicate
duplicates QFJ-866 Initiator session timer with SSL enabled Closed

 Description   

With SSL filter quickfix stop to reconect after IOException.
100% case is using tcpkill. Just kill connection and initiator won't try to reconnect.
NioSocketSession has closing == true and DefaultCloseFuture has ready == false.






[QFJ-849] SocketInitiator does not stop properly Created: 10/Jun/15  Updated: 17/Jul/17  Resolved: 22/Mar/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: 1.6.2

Type: Bug Priority: Critical
Reporter: Or Ming Chun Assignee: Christoph John
Resolution: Fixed Votes: 4
Labels: QuickfixJ, session
Environment:

Tested on Mac & Ubuntu


Attachments: Text File jstack-162-SNAPSHOT-20160312.txt     Text File quickfixJ_1.6.1_TD.txt     Text File socket.initiator.stop(false).txt     Text File socket.initiator.stop(true)-original-before-and-after.txt     Text File socket.initiator.stop(true)-original.txt     Text File socket.initiator.stop(true).txt    
Issue Links:
Duplicate
is duplicated by QFJ-907 Dead sockets are not closed when Sock... Closed

 Description   

When creating a simple Quickfixj Initiator app and after the session has successfully been created and Logon, I called initiator.stop() and exit the program. But the JVM hang and cannot exit after ~60s



 Comments   
Comment by Christoph John [ 11/Jun/15 ]

Two things:

  1. what happens if you call stop(true)
  2. could you create a stack dump when it is hanging?
    Thanks
Comment by GARY LO [ 11/Jun/15 ]

Hi Christoph John,

1. Same as stop(false), it will hangs about 60s (with no logging) before exit

2. Both stop(false) & stop(true) thread dump is attach during the hangs period

Comment by Christoph John [ 11/Jun/15 ]

Hmm, how do you exit the program? There is no trace of any QFJ-related code in the thread dump? For reference, could you create a thread dump while the program is running?

Comment by GARY LO [ 11/Jun/15 ]

Sorry that I provided wrong log that used my customized quickfixJ version that try to shun down all the executor service when I can initiator.stop()

Now, fall back to 1.6.0 original version, problem still exist

Comment by Christoph John [ 11/Jun/15 ]

Still can't see nothing QFJ-related in the dump, not even user code. Only Java classes. Could you please provide a dump while the process is running?

Comment by GARY LO [ 11/Jun/15 ]

I am using "jstack -l [pid]" to get the thread dump, is that what you want?

added thread dump of before & after initiator.stop(true)

Comment by Christoph John [ 12/Jun/15 ]

Yes, jstack is correct.
In your last dump I can still see the QFJ Timer thread being active. I don't know why it wasn't in the first dumps, though.

If your program does exit after 60 seconds it seems that it waits for the thread in the ScheduledThreadPoolExecutor to die. But actually the QFJ Timer thread is a daemon thread and should not keep the JVM from shutting down.
How do you exit your program?

Could you try with a newer / older / just another JVM version? I have not encountered this problem yet.

Comment by Or Ming Chun [ 12/Jun/15 ]

we are working or Java 1.8

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

is this information helpful?

Comment by Christoph John [ 12/Jun/15 ]

How do you exit your program?

Could you try with a newer / older / just another JVM version?

Comment by Or Ming Chun [ 12/Jun/15 ]

does it matter on what jvm version I use to build the quickfixj jar? I am using Java 1.8 too build quickfixj too

Comment by Christoph John [ 12/Jun/15 ]

I don't think that it matters. IMHO it could be dependent on the JVM that is used to run the program. It is only a guess since I never saw this error. But it could be also dependent on other things in your code/environment/etc. But I assume it is a simple program that is run on the command line and not something that is running in Spring, an app server, an OSGi environment or the like??!

Comment by Rohit [ 01/Sep/15 ]

We see the same thing after we upgraded to QuickFix 1.6.1.
The call to initiator.stop hangs. Meanwhile , we see heartbeats are still sent out from the QuickfixJ engine.
I am attaching a thread dump which I hope helps.
The java version -
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

Comment by Steve Nardone [ 03/Sep/15 ]

I was able to resolve the problem by adding this statement to IoSessionInitiator.stop():

synchronized void stop() {
if (reconnectFuture != null)

{ reconnectFuture.cancel(true); reconnectFuture = null; }

// Shutdown executor created by ioConnector (indirectly).
reconnectTask.ioConnector.dispose();
// ^^^
}

This disposes the executor created by the default constructor of NioSocketConnector (mina) instantiated in the IoConnector constructor. That executor (ExecutorService.newCachedThreadPool) has a 60s keepAliveTime. During shutdown that thread is blocked waiting until the next interval to check for more tasks.

Comment by Martin Vrábel [ 09/Sep/15 ]

Also spotted this issue both in version 1.6.1 and 1.7.0-SNAPSHOT

Comment by Rohit [ 25/Sep/15 ]

I was able to workaround this by avoiding the call to SocketInitiator.Stop()
I am logging out all the sessions manually and setting the initiator to null so it can be garbage collected

This extends to SocketAcceptors as well


 		if (socketInitiator != null) {
-			socketInitiator.stop();
+			Iterator<SessionID> sessionIds = socketInitiator.getSessions().iterator();
+			while (sessionIds.hasNext()) {
+				SessionID sessionId = sessionIds.next();
+				Session.lookupSession(sessionId).logout("user requested");
+			}
+			while (socketInitiator.isLoggedOn()) {
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException e) {
+					//Obfuscated
+				}
+			}
+			acceptor = null;
 		}
-		//Obfuscated
+		//Obfuscated
+			//Obfuscated
+		}
 		//ObfuscatedApplication = null;

Comment by Christoph John [ 25/Sep/15 ]

Hi, what about Steve Nardone 's solution a few comments above? Looks cleaner to me. Although I have not tested it yet.

Comment by Rohit [ 25/Sep/15 ]

I haven't tried that out yet. I am pulling the QuickFixJ 1.6.1 dependency straight out of the maven repository and not building my own .
I will give it a shot and see if it works. Would avoid an ugly workaround.

Comment by Christoph John [ 29/Dec/15 ]

Hi Steve Nardone,
I have integrated your suggested solution into the 1.6.x as well as the 1.7.0 branch.

Rohit, Martin Vrábel: could you test if that works for you?

Thanks,
Chris.

Comment by Colin DuPlantis [ 12/Mar/16 ]

We have encountered this issue, too, in 1.6.1, but only on machines where the "is_production_machine" flag is set to true. We have not been able to reproduce the problem outside of production. The production machine is a 16-core RedHat distro based on 2.6. Our test machines tend to be 3.x based on other distros, and no more than 8 cores, generally 2 or 4. Not sure if this is relevant in the reproduction or not.

We built and deployed the latest 1.6.2-SNAPSHOT to our (Marketcetera) repo, which has this fix included, but this did not solve the problem.

The problem seems to occur when you're trying to shutdown the initiator while it's busy receiving messages. I've uploaded a relevant jstack output that shows the problem in 1.6.2-SNAPSHOT.

Comment by Christoph John [ 14/Mar/16 ]

Hi Colin, thanks for the stack trace. It helps a lot. It seems that this is a similar issue as described in this comment: http://www.quickfixj.org/jira/browse/QFJ-854?focusedCommentId=12737&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12737
It is tried to access the EventHandlingStrategy while it is still locked. I think we can access the strategy outside of the lock and put a END_OF_STREAM message into it. That should resolve the "deadlock".

Edit: I will try to integrate this into 1.6.2-SNAPSHOT in the next days and let you know.

Comment by Colin DuPlantis [ 14/Mar/16 ]

It looks like we were able to work around the problem by manually disconnecting each session in the initiator before stopping it.

Comment by Christoph John [ 16/Mar/16 ]

I have made the promised changes. Could you please check if it resolves your problem?
Thanks, Chris.

Comment by Colin DuPlantis [ 16/Mar/16 ]

The problem wasn't 100% reproducible. With that caveat, we were unable to reproduce the problem at all with the changes.

Comment by Christoph John [ 22/Mar/16 ]

Fair enough. Please feel free to report if problem appears again.





[QFJ-848] Not able to connect to fix5.0sp2 server Created: 29/May/15  Updated: 29/May/15  Resolved: 29/May/15

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

Type: Bug Priority: Blocker
Reporter: arvind patil Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Comments   
Comment by Christoph John [ 29/May/15 ]

Wow, what an awful lot of information.
Please ask on the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users and please give some more information. Configuration, used QFJ version, error mesages, FIX messages....





[QFJ-847]  Transport Data Dict vs App Data Dict - settings not passed to App Data Dict Created: 19/May/15  Updated: 19/May/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Chris Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

N/a its in the java code



 Description   

The Quickfixj settings are not being passed to the ApplicationDataDictionary.

This seems to be because the transport dictionary is created via
DefaultSessionFactory.createDataDictionary.

Whereas the app DataDictionary is created in Default Data Dictionary
Provider, which does not seem to know about settings and so cannot pass them on.



 Comments   
Comment by Chris [ 19/May/15 ]

Not sure how best to address this - should the application DataDictionary be created when the Transport one is?

Or should the settings be made available to the DefaultDataDictionaryProvider class?





[QFJ-846] Upload release to Maven or Sonatype central Created: 15/May/15  Updated: 05/Jul/16  Resolved: 24/Mar/16

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

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Luca Burgazzoli
Resolution: Fixed Votes: 3
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-840 1.6.0 has not been uploaded to market... Closed
is duplicated by QFJ-878 Publish QuickFIX jars to Maven Central Closed
Relates
relates to QFJ-851 Include proxool-cglib in the lib/ fol... Closed

 Comments   
Comment by Or Ming Chun [ 18/May/15 ]

Yes, please upload to some public. For now, I need to checkout and build and publish to my own private repository.

Comment by Shahbaz Chaudhary [ 20/May/15 ]

It has always been a fair amount of pain working with quickfixj and its dependencies. Hope the files are uploaded to a repo with a good pom file. Not sure if the marketcetera guys are even in business anymore

Comment by Or Ming Chun [ 20/May/15 ]

Will Sonatype Central be a choose? It seems easy to use.

http://central.sonatype.org/pages/requirements.html

Comment by Christoph John [ 20/May/15 ]

Looks quite exactly like the MavenCentral requirements. I don't care actually where to upload. Are there any advantages for the one or the other?

Comment by Or Ming Chun [ 20/May/15 ]

I dont know either

Comment by Shahbaz Chaudhary [ 24/May/15 ]

I've had some success using the ServiceMix's qfj jars (pom entry below). I am not using any specific repository so maven is finding it on its own. This address shows what they have available: http://mvnrepository.com/artifact/org.apache.servicemix.bundles/org.apache.servicemix.bundles.quickfix

Note that while I'm using version 1.5, 1.6 is there as well. I had some trouble with 1.6 so I dropped down to 1.5.

<!-- QuickFIX/J dependencies from ServiceMix-->
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.quickfix</artifactId>
<version>1.5.3_1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.10</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>1.1.7</version>
</dependency>

Comment by Mark Curtis [ 01/Jun/15 ]

Why don't you just host it yourself on Github: http://kwebble.com/blog/2014/02/19/use-github-to-host-your-own-maven-repo

If you go down this route don't forget to add -DcreateChecksum=true on the install. An example of this working can be found here:

https://github.com/castramet/quickfixj

In your maven project add:

<repositories>
<repository>
<id>git-castramet</id>
<url>https://github.com/castramet/quickfixj/raw/master</url>
</repository>
</repositories>

Then pull in:

<dependency>
<groupId>quickfixj</groupId>
<artifactId>quickfixj-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>quickfixj</groupId>
<artifactId>quickfixj-messages-fix42</artifactId>
<version>1.6.0</version>
</dependency>

Hope this helps.

Comment by Luca Burgazzoli [ 15/Dec/15 ]

is there any plan to do so ?

I'd like to update dependencies of Apache Camel QuickFIX component to use the official build which is now OSGi ready and we'd love to grab it from maven central instead of Marketcetera's own repo

Comment by Christoph John [ 15/Dec/15 ]

Actually yes. But did not have the time to follow this further.
As always: volunteers welcome.

Comment by Luca Burgazzoli [ 15/Dec/15 ]

I can work on it using Sonatype OSS if ok.

Anyone who whats to do a release needs to create an account on https://issues.sonatype.org/secure/Signup!default.jspa
It is then possible to configure bamboo to publish snapshots automatically and manually run a release process.

Comment by Christoph John [ 15/Dec/15 ]

Sonatype OSS is fine with me. Thanks in advance.

Comment by Luca Burgazzoli [ 15/Dec/15 ]

https://issues.sonatype.org/browse/OSSRH-19455

Comment by Luca Burgazzoli [ 15/Dec/15 ]

First upload on Sonatype OSS snapshots I think something do not need to be there, could you advice ?

Comment by Christoph John [ 16/Dec/15 ]

Thanks. What do you mean? Do you mean that we don't need to upload all the artifacts?

Comment by Luca Burgazzoli [ 16/Dec/15 ]

Yes, i.e. does quickfixj-distribution need to be on maven central ?

Comment by Christoph John [ 17/Dec/15 ]

I think the following artifacts can be left out:

  • quickfixj-distribution
  • quickfixj-parent (has no JARs)
  • quickfixj-messages (has no JARs)
  • quickfixj-examples (has no JARs)

Thanks!

Comment by Luca Burgazzoli [ 18/Dec/15 ]

It does not seem so simple and btw, they are also in marketcetera repo.

Would it be ok if I'll look at how to remove some artifacts from delivery later on ?
Maybe you can do a 1.6.2 release on maven central and I'll work on cleaning things u if possible for 1.7.0

Comment by Laplie Anderson [ 05/Jul/16 ]

The BigDecimal (-bd) versions of 1.6.2 have not been released to Maven central. Not sure if I this belongs on this issue or if another issue should be created.

Comment by Christoph John [ 05/Jul/16 ]

The BD builds are hosted here: http://repo.marketcetera.org/maven/org/quickfixj/

Comment by Laplie Anderson [ 05/Jul/16 ]

The marketcetera repo only has snapshot builds for 1.6.2. 1.6.1 however is correct there under the old group id http://repo.marketcetera.org/maven/quickfixj/.

Regardless, isn't the point of this issue to have all the jars on Maven central?

Comment by Christoph John [ 05/Jul/16 ]

Hmm, to me the BD build is a custom one. However, there is already QFJ-891.





[QFJ-845] Change packaging strategy of quickfixj-messages-all to prevent VerifyError Created: 14/May/15  Updated: 10/Aug/15  Resolved: 20/Jul/15

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.6.0
Fix Version/s: 1.6.1

Type: Bug Priority: Major
Reporter: ManuReno Assignee: ManuReno
Resolution: Fixed Votes: 4
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-832 Multi-Version support is busted in 1.6.0 Closed
is duplicated by QFJ-858 logon problem with FIX41 Closed
Relates
is related to QFJ-855 Change packaging strategy for quickfi... Closed

 Description   

In version 1.6.0, the message-all jar is made by merging the jar each individual FIX version.
An issue arises since the type of some fields may be change between FIX versions.

For instance, the field 43 ("PossDupFlag") is a String from Fix 4.0 to Fix 4.2 and becomes a Boolean in FIX 4.3.
So classes from the jar messages-fix42 and below expect to see a StringField for field 43, whereas classes from messages-fix43 and over expect a BooleanField.
When jars are merged, only one version of the PossDupFlag is kept, resulting in a VerifyError either in fix42 and below or fix43 and over classes (depending on whioch version of PossDup has been kept).
This also happens on several other fields.

This ticket aims at changing the packaging strategy by first merging the generated source code from all FIX specs, and then compiling instead of merging classes compiled individually for each FIX spec.
The new message-all is then consistent and compatible with the quickfixj-core module which uses the same approach.

An issue remains though as only one single version of the fields that change type (field 43 for example) is compiled.
By default, the most recent version of the field is kept
It seems that this conflict was handled the same before, it thus must not be that a big issue (to be confirmed)



 Comments   
Comment by Or Ming Chun [ 18/May/15 ]

I think I have been hit by this bug. In QFJ v1.6.0, when I tried to new quickfix.fix44.NewOrderSingle(), I got:

[info] Exception encountered when attempting to run a suite with class name: com.bostontechnologies.quickfixs.messages.RichOrderSpec *** ABORTED ***
[info]   java.lang.VerifyError: Bad type on operand stack
[info] Exception Details:
[info]   Location:
[info]     quickfix/fix44/NewOrderSingle.get(Lquickfix/field/SettlType;)Lquickfix/field/SettlType; @2: invokevirtual
[info]   Reason:
[info]     Type 'quickfix/field/SettlType' (current frame, stack[1]) is not assignable to 'quickfix/CharField'
[info]   Current Frame:
[info]     bci: @2
[info]     flags: { }
[info]     locals: { 'quickfix/fix44/NewOrderSingle', 'quickfix/field/SettlType' }
[info]     stack: { 'quickfix/fix44/NewOrderSingle', 'quickfix/field/SettlType' }
[info]   Bytecode:
[info]     0x0000000: 2a2b b600 3157 2bb0

I have also tried with new quickfix.fix50.NewOrderSingle() & new quickfix.fix42.NewOrderSingle(), it works fine

Comment by dipeg [ 10/Jun/15 ]

I have the same problem, using only

Comment by dipeg [ 10/Jun/15 ]

core and messages-fix44.jar.

Comment by Or Ming Chun [ 10/Jun/15 ]

Take a look on the PR: https://github.com/quickfix-j/quickfixj/pull/29

Comment by dipeg [ 10/Jun/15 ]

Thx! Where can I take a build from?

Comment by Or Ming Chun [ 10/Jun/15 ]

if my PR merge to master soon, you can just build from the master. If not or you are in a hurry, here would help: https://github.com/mingchuno/quickfixj/tree/QFJ-845

Comment by dipeg [ 10/Jun/15 ]

Cool, I'll let you know how it goes. Thank you!

Comment by dipeg [ 10/Jun/15 ]

I built 1.7.0-SNAPSHOT from Branch QFJ-845 but the verify error is still there:

2015-06-10_20:19:45.472-ERROR-[NioProcessor-2 ]-java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
quickfix/fix44/ExecutionReport.get(Lquickfix/field/SettlType;)Lquickfix/field/SettlType; @2: invokevirtual
Reason:
Type 'quickfix/field/SettlType' (current frame, stack[1]) is not assignable to 'quickfix/CharField'
Current Frame:
bci: @2
flags: { }
locals:

{ 'quickfix/fix44/ExecutionReport', 'quickfix/field/SettlType' }
stack: { 'quickfix/fix44/ExecutionReport', 'quickfix/field/SettlType' }

Bytecode:
0000000: 2a2b b600 5657 2bb0

{quickfix.mina.initiator.InitiatorIoHandler:85}

==> java.lang.VerifyError - Bad type on operand stack
Exception Details:
Location:
quickfix/fix44/ExecutionReport.get(Lquickfix/field/SettlType;)Lquickfix/field/SettlType; @2: invokevirtual
Reason:
Type 'quickfix/field/SettlType' (current frame, stack[1]) is not assignable to 'quickfix/CharField'
Current Frame:
bci: @2
flags: { }
locals:

{ 'quickfix/fix44/ExecutionReport', 'quickfix/field/SettlType' }
stack: { 'quickfix/fix44/ExecutionReport', 'quickfix/field/SettlType' }

Bytecode:
0000000: 2a2b b600 5657 2bb0

Comment by Chris [ 10/Jun/15 ]

@dipeg did you use the core and fix44 jars or the 'all' - I suspect the former, which means there is a clash for the SettlType class. If you use the 'all' jar, its only defined once and so should not clash.

Comment by dipeg [ 10/Jun/15 ]

@Chris, Or Min Chun: it doesn't work. Maybe I miss something but I'm pretty sure all is right now

<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-all</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>

Classpath when launching the run config from intelliJ is fine, consol output confirms classpath has only quickfixj-all-1.7.0-SNAPSHOT.jar

I'd appreciate if someone could run an initiator with 1.7.0-SNAPSHOT built from https://github.com/mingchuno/quickfixj/tree/QFJ-845 receiving an ExecutionReport (I'm using FixPusher to simulate the acceptor, FIX4.4).

Thx.

Comment by Or Ming Chun [ 11/Jun/15 ]

Try to add only "org.quickfixj" % "quickfixj-core" % "1.7.0-SNAPSHOT" and "org.quickfixj" % "quickfixj-messages-all" % "1.7.0-SNAPSHOT" into your own project dependency. It should work

Comment by dipeg [ 11/Jun/15 ]

It is not working. I even deployed application to another machine to make sure that classpath is clean and only contains the jars from dependencies (see below)

  • If I change to FIX 4.2, it is OK.
  • As soon as I change to FIX 4.4: Crash with error as ==> java.lang.VerifyError - Bad type on operand stack

Could someone please confirm this behavior by sending and ExecutionReport FIX 4.4 to initiator build with QJF-854 github branch?

Thanks!

<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-core</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.quickfixj</groupId>
<artifactId>quickfixj-messages-all</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>

Comment by dipeg [ 11/Jun/15 ]

This clashes with SettlType in FIX50.xml which is STRING. Looks like SettlType class from FIX50 ends up in core and then clashes

Comment by dipeg [ 11/Jun/15 ]

because in FIX44.xml, SettlType is of CHAR.

I was able to get it working by changing SettlType in FIX44.xml to STRING. Obviously, only a workaround to get the flow working ...

Comment by Chris [ 11/Jun/15 ]

Hi dipeg. It looks like you are using the core jar and messages all jar. There is a single quickfixj all jar which includes core and all messages. Thus no clash of version types. That works for me using fix4.4

Comment by dipeg [ 11/Jun/15 ]

@Chris: which quickfix version are you using?

Comment by dipeg [ 11/Jun/15 ]

@Chris: I tried quickfixj-all-1.7.0-SNAPSHOT.jar: clash for SettlType.

If I use my own, fixed FIX44.xml (CHAR -> STRING) and build a new SNAPHOT, it works with quickfixj-all-1.7.0-SNAPSHOT.jar

FIX44.xml uses SettlType CHAR
FIX50.xml uses SettlType STRING

If the wrong field class ends up in quickfixj-all-1.7.0-SNAPSHOT.jar (or core), I results in a clash. It could be that your builder packages classes for the jar in a different order so that the "correct" SettlType class makes it (coincidentally) into the final jars (!??)

Comment by Chris [ 11/Jun/15 ]

Hi @dipeg - I am using quickfixj-all version built from the above patch - but I had to add the standard FIX44/FIX50/FIXT11 xml files to the built jar.

My understanding is that SettlType will be a STRING, which is backward compatible with the CHAR version. The quickfixj-all should include the most recent version of each such class, which should be backwards compatible.

Comment by dipeg [ 12/Jun/15 ]

Hi Chris - if I used the branch, it is not working. Only if I change the xml. What do you mean by "but I had to add the standard FIX44/FIX50/FIXT11 xml files to the built jar.".?

Comment by Chris [ 13/Jun/15 ]

When I built the branch (pr/24), amongst others, I get a jar under the quickfixj-all/target directory.

This includes core and all the messages Java code - but NOT the data dictionary xml files.

Usually they are included in this jar.

So I amended the jar (via winzip) to add them in.

Comment by Chris [ 13/Jun/15 ]

Hmm, thinking about it - maybe that's the issue - I am not using the patch above, I am using this patch - https://github.com/quickfix-j/quickfixj/pull/24 ...

Comment by Nathan Tippy [ 02/Jul/15 ]

Bump, do we have an ETA on resolving the merge issues and getting this in?

Comment by Christoph John [ 03/Jul/15 ]

Sorry, did not find time to look further into this issue yet. Reading the comments I am not even sure if it is fixed or not?!

Comment by dipeg [ 03/Jul/15 ]

As you can see, I tried several things. I had only success when changing SettlType in FIX44.xml from CHAR to STRING. Obviously a hack, nothing to be considered as a serious fix.

I'm happy to further test if someone provides me with a quickfix-all jar (at a public dropbox link or whatever) built using the branch that is supposed to be merged to master.

I'm using FixPusher to simulate acceptor, FIX44 to test ExecutionReports.

Thx.

Comment by Chris [ 04/Jul/15 ]

My built file is available here - https://www.dropbox.com/sh/nt5ayl62ocn7afq/AADfmSpfMijfdvkPhWq4Z780a?dl=0 .

I added the FIX44, FIXT11 and FIX50SP2 xml files to it to then get it working with those versions - in the same JVM.

HTH, Chris

Comment by dipeg [ 06/Jul/15 ]

yes, this seems to be working, thanks Chris. However, I also had to add the FIX44.xml when UseDataDictionary=Y. All the data dictionaries (xml) are not included in your jar.

Comment by Chris [ 06/Jul/15 ]

Hi - sorry, I think the link is for the version that comes out of the maven build. The version with the dictionaries I did afterwards.

So, that makes sense that you had to add it too.

~chris

Comment by ManuReno [ 07/Jul/15 ]

Hello,
The pull request #24 has been updated to take into account the various remarks raised since the initial proposal was made (see https://github.com/quickfix-j/quickfixj/pull/24#issuecomment-119195136)
Hope it can provide a solution to the classes incompatibility issue, any feedback welcome.
Best regards

Comment by dipeg [ 07/Jul/15 ]

Hi ManuReno, I cloned your branch, built it locally, it works fine using quickfixj-all..... Thanks a lot! No SettlType class clash anymore. Would be great if someone else could do the same and send a ExecutionReport FIX44 and confirm that no SettlType issue remains.

Comment by Chris [ 07/Jul/15 ]

Thanks ManuReno - have also built your branch. Will give it a go tomorrow to check it works for me too.

Cheers.

Comment by Nathan Tippy [ 08/Jul/15 ]

I have run into a problem with the unit tests on my quad core haswell i7. It looks like a race condition.

Failed tests:
SingleThreadedEventHandlingStrategyTest.testDoubleStart:55->checkThreads:94 Exactly one 'QFJ Message Processor' thread expected expected:<1> but was:<2>

Tests run: 1294, Failures: 1, Errors: 0, Skipped: 0

I can fix the problem by adding this sleep on line 54 of SingleThreadedEventHandlingStrategyTest. However this is not the right solution but it works.

ehs.blockInThread();
Thread.sleep(200); //need delay
ehs.blockInThread();
checkThreads(bean);

Comment by Chris [ 09/Jul/15 ]

Haven't quite got all my tests working - but thats due to my issues, the quickfix stuff is all working fine - multiple versions in same process, exec reports created ok. Thanks.

Comment by Christoph John [ 09/Jul/15 ]

Nathan Tippy: yes, this is a race condition. Could you please open a separate issue for it since it has nothing to do with QFJ-845? Thanks

Comment by Nathan Tippy [ 09/Jul/15 ]

Done, that race condition issue is now QFJ-854





[QFJ-844] Upgrade maven-compiler plugin and add more memory to the compiler Created: 11/May/15  Updated: 21/Jul/15  Resolved: 14/May/15

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

Type: Other Priority: Minor
Reporter: ManuReno Assignee: ManuReno
Resolution: Fixed Votes: 0
Labels: None
Environment:

apache-maven-3.2.2 jdk1.7.0_65 windows7



 Description   

quickfixj-core module compilation run out of memory and doesn't complete on my environment.
Adding more memory to the compiler at th pom level seems to solve the issue :

<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<fork>true</fork>
<meminitial>128m</meminitial>
<maxmem>512m</maxmem>
<source>$

{jdkLevel}</source>
<target>${jdkLevel}

</target>
</configuration>
</plugin>






[QFJ-843] Some times QuickFix Message received on Fix session is processed first by Application thread and later by socket connection Processor Thread causing sequence error by later processing Created: 04/May/15  Updated: 07/May/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: anurag jain Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: sequnece, session


 Description   

Message on Fix session received by both Application thread (ProcessQ) and socket connection Processor Thread.
In below example Our Application Thread ProcessQ got the message with 34=158757 and later quickfix thread ScoketConnectionProcessor-0.0 Thread process the same message this happen only 4 time in a whole day.
But Due to this when quickfix's socketConnectionThread thread process the message and give it to QFJMessageProcessor thread to process further it encounters sequence rest error as a result session logged out triggers. In all the other scenarios ScoketConnectionProcessor process the message first and delegate the responsibility to QFJ Message Processor thread and later to application Thread i.e. ProcessQ

Please FInd application logs as below ..
2015-04-28 14:16:03,856 [ProcessQ] INFO quickfixj.msg.incoming - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=1500^A35=X^A34=158757^A49=ANZD_SANDPIT_MD^A52=20150428-06:16:03.814^A56=MDAQ_DEV2_SANDPIT_MD^A262=9^A268=26^A279=2^A269=0^A278=7usB0^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA0^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB1^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA1^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB2^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA2^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB3^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA3^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB4^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA4^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB5^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA5^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB6^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA6^A55=USD/CHF^A15=USD^A279=0^A269=0^A278=7utB0^A55=USD/CHF^A270=0.95388^A15=USD^A271=1000000^A346=1^A279=0^A269=1^A278=7utA0^A55=USD/CHF^A270=0.95413^A15=USD^A271=1000000^A346=1^A279=0^A269=0^A278=7utB1^A55=USD/CHF^A270=0.95385^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA1^A55=USD/CHF^A270=0.95416^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB2^A55=USD/CHF^A270=0.95382^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA2^A55=USD/CHF^A270=0.95419^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB3^A55=USD/CHF^A270=0.95380^A15=USD^A271=5000000^A346=1^A279=0^A269=1^A278=7utA3^A55=USD/CHF^A270=0.95421^A15=USD^A271=5000000^A346=1^A279=0^A269=0^A278=7utB4^A55=USD/CHF^A270=0.95377^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA4^A55=USD/CHF^A270=0.95424^A15=USD^A271=10000000^A346=1^A279=0^A269=0^A278=7utB5^A55=USD/CHF^A270=0.95374^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA5^A55=USD/CHF^A270=0.95427^A15=USD^A271=10000000^A346=1^A10=041^A
2015-04-28 14:16:03,856 [SocketConnectorIoProcessor-0.0] INFO quickfixj.msg.incoming - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=1500^A35=X^A34=158757^A49=ANZD_SANDPIT_MD^A52=20150428-06:16:03.814^A56=MDAQ_DEV2_SANDPIT_MD^A262=9^A268=26^A279=2^A269=0^A278=7usB0^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA0^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB1^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA1^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB2^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA2^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB3^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA3^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB4^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA4^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB5^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA5^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB6^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA6^A55=USD/CHF^A15=USD^A279=0^A269=0^A278=7utB0^A55=USD/CHF^A270=0.95388^A15=USD^A271=1000000^A346=1^A279=0^A269=1^A278=7utA0^A55=USD/CHF^A270=0.95413^A15=USD^A271=1000000^A346=1^A279=0^A269=0^A278=7utB1^A55=USD/CHF^A270=0.95385^A15=USD^A271=2000000^A346=1^A279=0^A269=1
^A278=7utA1^A55=USD/CHF^A270=0.95416^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB2^A55=USD/CHF^A270=0.95382^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA2^A55=USD/CHF^A270=0.95419^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB3^A55=USD/CHF^A270=0.95380^A15=USD^A271=5000000^A346=1^A279=0^A269=1^A278=7utA3^A55=USD/CHF^A270=0.95421^A15=USD^A271=5000000^A346=1^A279=0^A269=0^A278=7utB4^A55=USD/CHF^A270=0.95377^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA4^A55=USD/CHF^A270=0.95424^A15=USD^A271=10000000^A346=1^A279=0^A269=0^A278=7utB5^A55=USD/CHF^A270=0.95374^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA5^A55=USD/CHF^A270=0.95427^A15=USD^A271=10000000^A346=1^A10=041^A



 Comments   
Comment by anurag jain [ 04/May/15 ]

Please note that ProcessQ Thread is application thread which read objects from application Queue and not the the Quick Fix internal queue .

Comment by Christoph John [ 04/May/15 ]

When this happens, do you have to restart your application or does the problem correct itself? Are you starting/stopping your Initiator/Acceptor at certain times? This sounds a little like QFJ-825.
Would it be possible to create a stack dump with the program "jstack" once the error appears?

Comment by anurag jain [ 04/May/15 ]

Sorry rephrasing the above JIRA:

  • We noticed 2 threads logging the string --> "quickfixj.msg.incoming" at the same time. One of the threads to log this was SocketConnectorIoProcessor-0.0, Surprisingly the second thread which logs this is the ProcesQ thread
  • The ProcessQ thread is our own application thread so we are not sure how this could happen?
  • This does not seem to be a logging issue, we are using log4j2 as our logger. I say that because of the 2 consecutive messages received one after the other, Quickfix/J complains when the second message comes in:
    2015-04-28 14:16:03,857 [QFJ Message Processor] INFO  quickfixj.msg.outgoing - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=141^A35=5^A34=11955^A49=MDAQ_DEV2_SANDPIT_MD^A52=20150428-06:16:03.857^A56=ANZD_SANDPIT_MD^A58=MsgSeqNum too low, expecting 158758 but received 158757^A10=030^A
    

All the log files below:

2015-04-28 14:16:03,856 [ProcessQ] INFO quickfixj.msg.incoming - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=1500^A35=X^A34=158757^A49=ANZD_SANDPIT_MD^A52=20150428-06:16:03.814^A56=MDAQ_DEV2_SANDPIT_MD^A262=9^A268=26^A279=2^A269=0^A278=7usB0^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA0^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB1^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA1^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB2^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA2^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB3^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA3^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB4^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA4^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB5^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA5^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB6^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA6^A55=USD/CHF^A15=USD^A279=0^A269=0^A278=7utB0^A55=USD/CHF^A270=0.95388^A15=USD^A271=1000000^A346=1^A279=0^A269=1^A278=7utA0^A55=USD/CHF^A270=0.95413^A15=USD^A271=1000000^A346=1^A279=0^A269=0^A278=7utB1^A55=USD/CHF^A270=0.95385^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA1^A55=USD/CHF^A270=0.95416^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB2^A55=USD/CHF^A270=0.95382^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA2^A55=USD/CHF^A270=0.95419^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB3^A55=USD/CHF^A270=0.95380^A15=USD^A271=5000000^A346=1^A279=0^A269=1^A278=7utA3^A55=USD/CHF^A270=0.95421^A15=USD^A271=5000000^A346=1^A279=0^A269=0^A278=7utB4^A55=USD/CHF^A270=0.95377^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA4^A55=USD/CHF^A270=0.95424^A15=USD^A271=10000000^A346=1^A279=0^A269=0^A278=7utB5^A55=USD/CHF^A270=0.95374^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA5^A55=USD/CHF^A270=0.95427^A15=USD^A271=10000000^A346=1^A10=041^A


2015-04-28 14:16:03,856 [SocketConnectorIoProcessor-0.0] INFO quickfixj.msg.incoming - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=1500^A35=X^A34=158757^A49=ANZD_SANDPIT_MD^A52=20150428-06:16:03.814^A56=MDAQ_DEV2_SANDPIT_MD^A262=9^A268=26^A279=2^A269=0^A278=7usB0^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA0^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB1^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA1^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB2^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA2^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB3^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA3^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB4^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA4^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB5^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA5^A55=USD/CHF^A15=USD^A279=2^A269=0^A278=7usB6^A55=USD/CHF^A15=USD^A279=2^A269=1^A278=7usA6^A55=USD/CHF^A15=USD^A279=0^A269=0^A278=7utB0^A55=USD/CHF^A270=0.95388^A15=USD^A271=1000000^A346=1^A279=0^A269=1^A278=7utA0^A55=USD/CHF^A270=0.95413^A15=USD^A271=1000000^A346=1^A279=0^A269=0^A278=7utB1^A55=USD/CHF^A270=0.95385^A15=USD^A271=2000000^A346=1^A279=0^A269=1
^A278=7utA1^A55=USD/CHF^A270=0.95416^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB2^A55=USD/CHF^A270=0.95382^A15=USD^A271=2000000^A346=1^A279=0^A269=1^A278=7utA2^A55=USD/CHF^A270=0.95419^A15=USD^A271=2000000^A346=1^A279=0^A269=0^A278=7utB3^A55=USD/CHF^A270=0.95380^A15=USD^A271=5000000^A346=1^A279=0^A269=1^A278=7utA3^A55=USD/CHF^A270=0.95421^A15=USD^A271=5000000^A346=1^A279=0^A269=0^A278=7utB4^A55=USD/CHF^A270=0.95377^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA4^A55=USD/CHF^A270=0.95424^A15=USD^A271=10000000^A346=1^A279=0^A269=0^A278=7utB5^A55=USD/CHF^A270=0.95374^A15=USD^A271=10000000^A346=1^A279=0^A269=1^A278=7utA5^A55=USD/CHF^A270=0.95427^A15=USD^A271=10000000^A346=1^A10=041^A

2015-04-28 14:16:03,857 [QFJ Message Processor] INFO  quickfixj.msg.outgoing - FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD: 8=FIX.4.2^A9=141^A35=5^A34=11955^A49=MDAQ_DEV2_SANDPIT_MD^A52=20150428-06:16:03.857^A56=ANZD_SANDPIT_MD^A58=MsgSeqNum too low, expecting 158758 but received 158757^A10=030^A

Could you please tell us:

  • If this is a bug in 1.5.3 version of Quickfix/J?
  • We only notice this happening 4 times a day during peak load, 2000 market data messages a second
  • We did not seem to encounter this in 1.5.2
Comment by Christoph John [ 05/May/15 ]

Could you please answer my questions from the last comment?
As already said, the only thing I could imagine is that you are hitting QFJ-825. But to be sure I would need a stack dump.
Are you able to try without log4j2? It's probably not the problem, but just to be sure... Are you using asynchronous logging?

Comment by anurag jain [ 06/May/15 ]

Please find my answer here:

  • No we are not stopping are starting Initiator/Acceptor at certain times.
  • Also When this happened, we didn't restart the application as mention above due to this we get the sequence error as a result of that log-out has sent to target session after a while it connect back again as part of login retry attempts.
  • This is not happening daily basis, we are trying to reproduce the problem at our end if succeeds we will share the JStack's stack dump with you. However No luck so far.
  • We are using synchronous logging also this is unlikely to have log4j2 issue as its result in sequence error.
Comment by Christoph John [ 06/May/15 ]

OK, without the stack dump I cannot really tell anything. Just let me know once you have it.
More questions: are you using a ThreadedSocketAcceptor/Initiator? Or the default SocketAcceptor/Initiator? is there only one session that you have configured? Could you please post your session config?

And I guess you are certain that the counterparty did not just send the same message twice?

Comment by anurag jain [ 07/May/15 ]

1) We are using default Socket Initiator.
2) Have just one session .
3) Session config is as here
DataDictionary=config/FIX42.xml
ResetOnLogon=Y
ScreenLogShowOutgoing=N
FileLogHeartbeats=N
ResetOnDisconnect=Y
ScreenLogEvents=N
ConnectionType=initiator
SocketKeyStore=config/SummitInvt.pem
TargetCompID=ANZD_SANDPIT_MD
SenderCompID=MDAQ_DEV2_SANDPIT_MD
SocketConnectHost=1.x.x.x
ReconnectInterval=10
ScreenLogShowIncoming=N
SocketConnectPort=xxxx
SocketUseSSL=Y
FileStorePath=var/fix/fxlp
PersistMessages=N
EndTime=17:00:00
SocketKeyStorePassword=*******
TimeZone=America/New_York
StartTime=17:10:00
HeartBtInt=20
UseDataDictionary=Y
ResetOnLogout=Y
Username=TODO
e-mail=
SessionID= FIX.4.2:MDAQ_DEV2_SANDPIT_MD->ANZD_SANDPIT_MD

4)and yes there is no replay of same message from counter party .

Comment by Christoph John [ 07/May/15 ]

Hmm, now that I see that you are using SSL I am asking myself if it could be the same problem as in QFJ-745. However, there is not really much information to find the problem and the issue creator did not come back with answers.





[QFJ-842] ClassCastException Created: 30/Apr/15  Updated: 10/Oct/16  Resolved: 10/Oct/16

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

Type: Bug Priority: Major
Reporter: Dotun Kola-Olaleye Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: 1.6.0, ClassCastException, QuickfixJ, Upgrade
Environment:

Windows Server 2012 64 bit



 Description   

I may be missing something, but I'm having to refactor my code that was written based on QuickFIXJJ-1.5.3. Previously, I would cast incoming quickfix.Message to specific message types e.g. quickfix.fix50.SecurityList or quickfix.fix50.ExecutionReport.

But since I switched jar files to 1.6.0, attempts to cast to message types like quickfix.fix50sp1.SecurityList or quickfix.fix50sp1.ExecutionReport results in a ClassCastException. Now, I'm having to work directly with quickfix.Message.

Any pointer is appreciated.

Dotun.



 Comments   
Comment by Christoph John [ 30/Apr/15 ]

That is not expected. Could you maybe add a simple test case?
When a text FIX message comes in, an instance of the FIX message should get created by your message factory. Are you using a custom factory?





[QFJ-841] Unable to access Bamboo server Created: 29/Apr/15  Updated: 25/Dec/15  Resolved: 25/Dec/15

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

Type: Other Priority: Default
Reporter: Sam Ratcliff Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The address http://www.quickfixj.org:8085/browse/QFJ-CORE given in the developer resources is not reachable.



 Comments   
Comment by Christoph John [ 29/Apr/15 ]

Hmm, I can reach it. Could there be a firewall issue on your end? You can even google for "quickfixj bamboo" and it shows results.
Apart from that it should now actually be "http://www.quickfixj.org:8085/browse/QFJ-GIT".

But I guess that whole "developer resources" page needs to be rewritten.

Comment by Sam Ratcliff [ 29/Apr/15 ]

Hmm okay, you may be right about a firewall issue as I can access on my phone but not via my desktop. Thanks





[QFJ-840] 1.6.0 has not been uploaded to marketcetera repository Created: 29/Apr/15  Updated: 18/May/15  Resolved: 18/May/15

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

Type: Bug Priority: Default
Reporter: Sam Ratcliff Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: None

Issue Links:
Duplicate
duplicates QFJ-846 Upload release to Maven or Sonatype c... Closed

 Description   

The installation document references the marketcetera repository for people depending on QuickFix/J through Maven but the latest (1.6.0) version has not been uploaded.



 Comments   
Comment by Or Ming Chun [ 18/May/15 ]

Yes, please upload to some public. For now, I need to checkout and build and publish to my own private repository.

Comment by Christoph John [ 18/May/15 ]

Please see QFJ-846. We should upload this to maven central. However, it could be that the marketcetera guys will also upload this to their repository.





[QFJ-839] Modify the proxool connection pool properties using the settings file Created: 21/Apr/15  Updated: 25/Dec/15  Resolved: 25/Dec/15

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

Type: Improvement Priority: Minor
Reporter: Jose Elias Chavez Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: datasource

Issue Links:
Duplicate
duplicates QFJ-853 Add ability to modify the Proxool JDB... Closed

 Description   

Currently the JdbcUtil class has the ProxoolDataSource's maximumConnectionCount hard-coded to 10.

I propose making changes so that the proxool datasource's properties can be modified via the settings file. If not specified, then the settings will default to the current values.






[QFJ-838] Tests on jdk 1.7 failed Created: 15/Apr/15  Updated: 21/Apr/16  Resolved: 23/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: 1.6.2

Type: Bug Priority: Default
Reporter: Slawomir Pawlewicz Assignee: Marcin L
Resolution: Fixed Votes: 1
Labels: session
Environment:

jdk 1.7.0_45 on Win7 x64


Issue Links:
Duplicate
is duplicated by QFJ-837 Tests on jdk1.8 fail Closed

 Description   

Tests passed on jdk 1.6. On jdk 1.7 they failed
-------------------------------------------------------------------------------
Test set: quickfix.SessionTest
-------------------------------------------------------------------------------
Tests run: 47, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 1.197 sec <<< FAILURE! - in quickfix.SessionTest
testResendRequestMsgSeqNum(quickfix.SessionTest) Time elapsed: 0.006 sec <<< FAILURE!
java.lang.AssertionError: Session should be logged out since seqnum too low!
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertFalse(Assert.java:68)
at quickfix.SessionTest.testResendRequestMsgSeqNum(SessionTest.java:1172)

testAcceptorRelogon(quickfix.SessionTest) Time elapsed: 0.002 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertFalse(Assert.java:68)
at org.junit.Assert.assertFalse(Assert.java:79)
at quickfix.SessionTest.testAcceptorRelogon(SessionTest.java:1632)

testLogoutMsgSeqNumTooHighOrLow(quickfix.SessionTest) Time elapsed: 0.001 sec <<< FAILURE!
java.lang.AssertionError: expected:<3> but was:<4>
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.failNotEquals(Assert.java:647)
at org.junit.Assert.assertEquals(Assert.java:128)
at org.junit.Assert.assertEquals(Assert.java:472)
at org.junit.Assert.assertEquals(Assert.java:456)
at quickfix.SessionTest.testLogoutMsgSeqNumTooHighOrLow(SessionTest.java:418)



 Comments   
Comment by Michael Whidden [ 11/Oct/15 ]

I'm coming across the same issue. What I observe is that the Logout messages (and most other messages generated in SessionTest.java) are dropped on the floor due to issues with the UtcTimeStamp.

Many tests call [[SystemTime.setTimeSource(systemTimeSource)]] where [[systemTimeSource]] has been set to [[new Date(1348264800000L);]]. Later tests will generate a message using [[createAdminMessage(2);]] or similar, which set the UtcTimeStamp as [[new Date();]]. These messages are never processed, because they cause [[<20120922-22:58:20, FIX.4.4:SENDER->TARGET, error> (Reject sent for Message 2: SendingTime accuracy problem)]] since the UtcTimeStamp is more that 120s different from SystemTime.

I think the fix is to reset SystemTime to use the actual system clock after each test.

Comment by Michael Whidden [ 11/Oct/15 ]

Changing{ {@AfterClass public static void cleanup()}} to @After public void cleanup() fixes the problem by restoring the SystemTime after each unit test.





[QFJ-837] Tests on jdk1.8 fail Created: 15/Apr/15  Updated: 25/Dec/15  Resolved: 25/Dec/15

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

Type: Bug Priority: Default
Reporter: Slawomir Pawlewicz Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: session
Environment:

jdk 1.8.0_40 Windows 7 x64


Issue Links:
Duplicate
duplicates QFJ-838 Tests on jdk 1.7 failed Closed

 Description   

I executed quickifix test on jdk 1.6. All went fine. On jdk 1.8 failed:

-------------------------------------------------------------------------------
Test set: quickfix.SessionTest
-------------------------------------------------------------------------------
Tests run: 47, Failures: 6, Errors: 0, Skipped: 0, Time elapsed: 1.514 sec <<< FAILURE! - in quickfix.SessionTest
testSequenceResetStackOverflow(quickfix.SessionTest) Time elapsed: 0.012 sec <<< FAILURE!
java.lang.AssertionError: expected:<51> but was:<50>
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.failNotEquals(Assert.java:647)
at org.junit.Assert.assertEquals(Assert.java:128)
at org.junit.Assert.assertEquals(Assert.java:472)
at org.junit.Assert.assertEquals(Assert.java:456)
at quickfix.SessionTest.testSequenceResetStackOverflow(SessionTest.java:1044)

testResendRequestMsgSeqNum(quickfix.SessionTest) Time elapsed: 0.011 sec <<< FAILURE!
java.lang.AssertionError: Session should be logged out since seqnum too low!
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertFalse(Assert.java:68)
at quickfix.SessionTest.testResendRequestMsgSeqNum(SessionTest.java:1172)

testSimultaneousResendRequests(quickfix.SessionTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertTrue(Assert.java:54)
at quickfix.SessionTest.testSimultaneousResendRequests(SessionTest.java:1225)

testDontCatchErrorsFromCallback(quickfix.SessionTest) Time elapsed: 0.003 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<[java.lang.Error: TEST]> but was:<[No error thrown]>
at org.junit.Assert.assertEquals(Assert.java:125)
at org.junit.Assert.assertEquals(Assert.java:147)
at quickfix.SessionTest.testDontCatchErrorsFromCallback(SessionTest.java:1462)

testAcceptorRelogon(quickfix.SessionTest) Time elapsed: 0 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertFalse(Assert.java:68)
at org.junit.Assert.assertFalse(Assert.java:79)
at quickfix.SessionTest.testAcceptorRelogon(SessionTest.java:1632)

testStateFlagsAreResetOnLogout(quickfix.SessionTest) Time elapsed: 0.001 sec <<< FAILURE!
java.lang.AssertionError: null
at org.junit.Assert.fail(Assert.java:92)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertFalse(Assert.java:68)
at org.junit.Assert.assertFalse(Assert.java:79)
at quickfix.SessionTest.testStateFlagsAreResetOnLogout(SessionTest.java:1670)



 Comments   
Comment by Kenny Tanaka [ 14/Jul/15 ]

I had exactly the same error, and found a workaround. It seems to be the order of the test methods executed. This problem has already been mentioned in QFJ-826.
http://randomallsorts.blogspot.de/2012/12/junit-411-whats-new-test-execution-order.html

  1. In quickfix-core/pom.xml, change junit version from 4.10 to 4.11.
  2. Annotate two test classes, quickfix.SessionTest and quickfix.mina.SingleThreadedEventHandlingStrategyTest, with @FixMethodOrder(MethodSorters.NAME_ASCENDING).
  3. Rename every public test methons in the two classes above. Change method name from testXxx to something like test###_Xxx, with ### a sequencial number. E.g., test001_DisposalOfFileResources() and test047_LargeQueue20000.

Now the test went through for me.





[QFJ-836] new quickfix.fix44.NewOrderSingle fail Created: 13/Apr/15  Updated: 14/Apr/15  Resolved: 14/Apr/15

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

Type: Bug Priority: Critical
Reporter: Cédric Jeanroy Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: None
Environment:

JRE 1.7 and 1.8


Issue Links:
Duplicate
duplicates QFJ-832 Multi-Version support is busted in 1.6.0 Closed

 Description   

With quickfixj 1.6.0 when I do :

quickfix.fix44.NewOrderSingle o = new quickfix.fix44.NewOrderSingle();

I get the following error :

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
quickfix/fix44/NewOrderSingle.get(Lquickfix/field/SettlType;)Lquickfix/field/SettlType; @2: invokevirtual
Reason:
Type 'quickfix/field/SettlType' (current frame, stack[1]) is not assignable to 'quickfix/CharField'
Current Frame:
bci: @2
flags: { }
locals:

Unknown macro: { 'quickfix/fix44/NewOrderSingle', 'quickfix/field/SettlType' }


stack:

Bytecode:
0000000: 2a2b b600 3057 2bb0

I foundd that there is two quickfix.field.SettlType class :
One in quickfixj-core which extends StringField
One in quickfixj-messages-fix44 which extends CharField






[QFJ-835] Required tag missing, field=447 Created: 10/Apr/15  Updated: 20/Dec/19  Resolved: 20/Dec/19

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Anevale Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

CentOS release 6.5 (Final), Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)


Issue Links:
Duplicate
duplicates QFJ-971 Intermittently we receive the "Requir... Closed

 Description   

Scenario:

The raw message received at AbstractIoHandler shows that the tag 447 is there

8=FIXT.1.1 9=X 35=8 ... 453=2 448=X 447=D 452=75 448=Y 447=D 452=1 ...10=X

However, at next step, the DataDictionary.validate() invoke from Session produces the below FieldException

Rejecting invalid message: quickfix.FieldException: Required tag missing, field=447:
8=FIXT.1.1 9=X 35=8 ... 453=2 447=D 448=X 452=75 447=D 448=Y 452=1 10=X

As shown from the exception log, the printed message still has the tag of 447, but the ordering of field 448 and 447 inside Parties(453) are reversed.

Is this a known issue of QuickFixJ 1.5.3?

we are using oracle jdk1.7.0_u51 (64bit)



 Comments   
Comment by Grant Birchmeier [ 10/Apr/15 ]

Sounds like a user configuration problem. Your engine is not using the right DataDictionary and so is failing to parse the repeating group. Make sure UseDataDictionary=Y and DataDictionary=path/to/file.xml.

"DO NOT SUBMIT HELP REQUESTS TO JIRA. INSTEAD USE THE MAILING LIST TO ASK FOR HELP."

If you need more follow up help, join the mailing list or try StackOverflow.

Comment by Anevale [ 13/Apr/15 ]

Thanks sir, a note to add to this issue

Other message with 35=8 could be parsed and processed correctly, and it is using UseDataDictionary=Y, with a correct path.

If it's a user configuration problem all message should have the same behavior.

But do you mean when the engine failed to parse the group, the message.toString() printed with the exception could still include the raw message tag in reverse order?

Comment by Grant Birchmeier [ 13/Apr/15 ]

This is not the right venue for this discussion. If you need follow-up help, there are many people (including myself) who are on the mailing list or StackOverflow.





[QFJ-834] messages.log and event.log file are not created using SLF4JLogFactory Created: 10/Apr/15  Updated: 25/Dec/15  Resolved: 25/Dec/15

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

Type: Bug Priority: Default
Reporter: garima gangwar Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I have quickfixj setup in my application and store messages.log and event.log at a location. I have configured RollingFileAppender for these logs but it is not working for quickfix logs and logs are not not rolling over.

<appender name="FIXMESSAGE" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="INFO"/>
<param name="File" value="../log/fixlog/FIX.4.2-sendercompID-targetCompID.event.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="25KB"/>
<param name="MaxBackupIndex" value="15"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d

{dd MMM yyyy HH:mm:ss,SSS}

][%t][%-5p][%c

{2}]-%m%n"/>
</layout>
</appender>
<appender name="FIXEVENT" class="org.apache.log4j.RollingFileAppender">
<param name="Threshold" value="INFO"/>
<param name="File" value="../log/fixlog/FIX.4.2-sendercompID-targetCompID.messages.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="25KB"/>
<param name="MaxBackupIndex" value="15"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{dd MMM yyyy HH:mm:ss,SSS}][%t][%-5p][%c{2}

]-%m%n"/>
</layout>
</appender>

<root>
<priority value ="INFO" />
<appender-ref ref="CONSOLE" />
<appender-ref ref="FIXMESSAGE" />
<appender-ref ref="FIXEVENT" />
</root>

Just to add, I have also defined below fix configuration as follows:

SLF4JLogEventCategory=$

{fix.connection.config.senderCompID}.${fix.connection.config.targetCompID}.events
SLF4JLogIncomingMessageCategory=${fix.connection.config.senderCompID}

.$

{fix.connection.config.targetCompID}.incoming
SLF4JLogOutgoingMessageCategory=${fix.connection.config.senderCompID}.${fix.connection.config.targetCompID}

.outgoing

Can anyone suggest something here?



 Comments   
Comment by Christoph John [ 13/Apr/15 ]

Please ask on the mailing list https://lists.sourceforge.net/lists/listinfo/quickfixj-users

This is a bug tracker.

Comment by garima gangwar [ 22/Apr/15 ]

Can you please open this issue. It can be an issue in quickfixj.





[QFJ-833] Add Slow Consumer Protection Created: 08/Apr/15  Updated: 19/Oct/17  Resolved: 28/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.6.0
Fix Version/s: 1.6.3

Type: New Feature Priority: Default
Reporter: James Olsen Assignee: James Olsen
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File SlowConsumer.patch    
Issue Links:
Relates
is related to QFJ-937 MaxScheduledWriteRequests is ineffective Resolved

 Description   

OOMs are possible where downstream consumers do not process messages fast enough. It is useful to be able to detect and prevent this, especially for MD/Quote streams.



 Comments   
Comment by James Olsen [ 08/Apr/15 ]

Attached SlowConsumer.patch adds a MaxScheduledWriteRequests Session Setting which can be used to force a disconnect if a message backlog occurs.

The MaxScheduledWriteRequests looks at the pending message queue in Mina. There will normally be additional queued messages at the TCP / OS level.

Comment by Christoph John [ 13/Apr/15 ]

Thanks for the patch. Do you happen to have a github account and are able to open a pull request? If not, it's fine this way.

Comment by James Olsen [ 13/May/15 ]

I'm afraid I'm not yet a github convert.





[QFJ-832] Multi-Version support is busted in 1.6.0 Created: 08/Apr/15  Updated: 24/Jul/15  Resolved: 24/Jul/15

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

Type: Bug Priority: Blocker
Reporter: James Olsen Assignee: ManuReno
Resolution: Duplicate Votes: 6
Labels: None

Issue Links:
Duplicate
duplicates QFJ-845 Change packaging strategy of quickfix... Closed
is duplicated by QFJ-836 new quickfix.fix44.NewOrderSingle fail Closed
Relates
is related to QFJ-855 Change packaging strategy for quickfi... Closed

 Description   

The issue discussed in http://sourceforge.net/p/quickfixj/mailman/message/32791285/ has not been resolved.

It is impossible to have a system that works with multiple FIX versions due to these VerifyErrors.

Even pre 1.6.0 systems that currently work and use only a single version may now fail depending on their classpath ordering as 'core' contains one variant of the Fields and may conflict with the desired 'messages' project.

This was not an issue in 1.5.3 and earlier where there was only one copy of the Fields.



 Comments   
Comment by Christoph John [ 13/Apr/15 ]

Thanks for the report. Regarding classpath ordering: if the desired "messages" project is listed before "core" it should be OK (at least for single FIX versions)?
Maybe I should have opened a specific JIRA issue for this problem earlier.

Comment by Chris [ 13/May/15 ]

I have to support 4.4 and 5.0SP2 for different connections - they both run in separate JVMs, so its not an issue for these per se, but I have a test harness that needs to load both.

I've tried adding the jars as follows:

  • 50sp2 messages
  • FIX11 messages
  • 44 messages
  • core

But the 4.4 related part fails with:

07:06:46:525|TH3 ERROR: NameError:cannot link Java class quickfix.fix44.NewOrderSingle, probable missing dependency: (class: quickfix/fix44/NewOrderSingle, method: set signature: (Lquickfix/field/SettlType;)V) Incompatible argument to function

If I move the 44 messages jar to be first, I get this:

07:17:37:538|TH3 ERROR: NameError:cannot link Java class quickfix.fix50sp2.Quote, probable missing dependency: (class: quickfix/fix50sp2/Quote, method: set signature: (Lquickfix/field/SettlType;)V) Incompatible argument to function

I don't suppose there is an jar ordering that will work with the current setup? Guess I need to look at spinning my tests off into separate VMs...

Comment by Christoph John [ 13/May/15 ]

I'm afraid that won't work.
Just an idea: I was asking myself if it worked when modifying the affected data dictionaries (in your case FIX44 and 50SP2) to have the same data type for the problematic fields (e.g. SettlType) and then rebuilding the message and field classes.

Comment by Christoph John [ 14/May/15 ]

Hi Chris, there is a pull request by ManuReno linked to QFJ-845. Maybe you could check if it fixes your problem.

Comment by Christoph John [ 24/Jul/15 ]

Closed in favour of QFJ-845 which fixes the problem when using the messages-all JAR file. Please note that there is still QFJ-855 which can occur when using specific message JAR files.





[QFJ-831] 35=2 after 35=4 failed because "MsgSeqNum too low" Created: 06/Apr/15  Updated: 13/Apr/15  Resolved: 13/Apr/15

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

Type: Bug Priority: Default
Reporter: Shi Lei Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

AIX



 Description   

This scenario happened in a poor network environment where some messages are missing but heartbeat still working, no logout before issue happened:

1. My app is client side using quickfixj-all-1.5.3.jar.
2. When network has problem, some messages are missing (both sides)
3. Sometimes server side send 35=4 request to increase seq_no by 1 while there's no missing seq_no from server side. E.g.
34=100, 35=8......
34=101, 35=8......
34=102, 35=4, 36=103, 123=Y...
I don't know why server side send this 35=4 asking to reset seq_no to 103 (seq_no 100 and 101 received successfully and 102 is reset request itself)
4. If next message from server side is 34=103, 35=8, it's OK
if next message from server side is 35=103, 35=2, client side FIX engine will return "MsgSeqNum too low, expecting 103 but received 102"

The question is
1) why 35=2 after 35=4 fail while 35=8 after 35=4 OK
2) the seq_no of failed 35=4 after 35=2, I double checked it's 103, why response is "MsgSeqNum too low, expecting 103 but received 102"



 Comments   
Comment by Christoph John [ 13/Apr/15 ]

Could you please send a message to the user list with the complete messages from the message log (at least the messages 100 - 103 from above)?
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks

Comment by Shi Lei [ 13/Apr/15 ]

Hi Christoph,
Please find original message from our side fix engine log below, and refer to the story how these messages generated – all messages are incoming one except the reject message and logon request after rejection:

1) some incoming 35=8 (ignore older one and keep last two 34=8120 and 34=8121. server side is 49=087003)
2) single 35=4 (34=8122 requests new seq_no set to 8124, server side says it's due to network package loss detected)
3) next message 35=8 34=8124 received no problem
4) 35=4 again, this time there's a 35=2 message after it (35=4, 34=8125 requests new seq_no set to 8126; then 35=2 use new seq_no 34=8126)
5) our side fix engine reject message, reason "MsgSeqNum too low, expecting 8126 but received 8125" – according to this reject reason I'm not sure which message got rejected – if 1st one with 35=4, 34=8125 rejected then "excepting" should be still 8125; if 2nd one with 35=2, 34=8126 rejected then rejected one has 34=8126, not too low
6) disconnected and re-connect

8=FIXT.1.1^A9=0426^A35=8^A49=087003^A56=RHBInvest^A34=8120^A50=087909^A57=99^A43=Y^A97=N^A52=20150330-02:44:52^A122=20150330-02:43:52^A37=201503300083409551^
A11=0RHB43U22408770^A453=3^A448=589^A447=C^A452=11^A448=087001-TA3979^A447=C^A452=3^A448=066^A447=C^A452=17^A880=20150330-00037299^A17=37299S^A150=F^A39=2^A1
=035450402^A55=HEVEA^A48=5095^A22=99^A762=NM^A54=2^A38=1000^A40=2^A44=2.9900^A59=0^A529=R^A32=1000^A31=2.9900^A151=0^A14=1000^A6=2.9900^A60=20150330-02:43:54
.206^A381=2990.00^A10=183^A
8=FIXT.1.1^A9=0426^A35=8^A49=087003^A56=RHBInvest^A34=8121^A50=087909^A57=99^A43=Y^A97=N^A52=20150330-02:44:52^A122=20150330-02:43:52^A37=201503300083409577^
A11=0RHB43U22408990^A453=3^A448=589^A447=C^A452=11^A448=087001-YO0391^A447=C^A452=3^A448=066^A447=C^A452=17^A880=20150330-00037300^A17=37300S^A150=F^A39=2^A1
=050626332^A55=HEVEA^A48=5095^A22=99^A762=NM^A54=2^A38=1000^A40=2^A44=2.9900^A59=0^A529=R^A32=1000^A31=2.9900^A151=0^A14=1000^A6=2.9900^A60=20150330-02:43:54
.206^A381=2990.00^A10=170^A
8=FIXT.1.1^A9=0097^A35=4^A49=087003^A56=RHBInvest^A34=8122^A50=087909^A57=99^A43=N^A97=N^A52=20150330-02:44:52^A123=Y^A36=8124^A10=116^A
8=FIXT.1.1^A9=0431^A35=8^A49=087003^A56=RHBInvest^A34=8124^A50=087909^A57=99^A43=Y^A97=N^A52=20150330-02:44:52^A122=20150330-02:44:16^A37=201503300083409631^
A11=0RHB43U22410750^A453=3^A448=667^A447=C^A452=11^A448=087001-LI1262^A447=C^A452=3^A448=098^A447=C^A452=17^A880=20150330-00037414^A17=37414S^A150=F^A39=1^A1
=048063804^A55=KTB^A48=4847^A22=99^A762=NM^A54=2^A38=50000^A40=2^A44=0.3250^A59=0^A529=R^A32=10000^A31=0.3250^A151=2300^A14=47700^A6=0.3250^A60=20150330-02:4
4:16.574^A381=15502.50^A10=095^A
8=FIXT.1.1^A9=0097^A35=4^A49=087003^A56=RHBInvest^A34=8125^A50=087909^A57=99^A43=N^A97=N^A52=20150330-02:44:52^A123=Y^A36=8126^A10=121^A
8=FIXT.1.1^A9=0098^A35=2^A49=087003^A56=RHBInvest^A34=8126^A50=087909^A57=99^A43=N^A97=N^A52=20150330-02:44:50^A7=5196^A16=5234^A10=143^A
8=FIXT.1.1^A9=116^A35=5^A34=5236^A49=RHBInvest^A52=20150330-02:44:53.299^A56=087003^A58=MsgSeqNum too low, expecting 8126 but received 8125^A10=086^A
8=FIXT.1.1^A9=109^A35=A^A34=5237^A49=RHBInvest^A52=20150330-02:44:58.810^A56=087003^A553=btx03^A554=Password321#@!^A98=0^A108=30^A1137=8^A10=186^A
8=FIXT.1.1^A9=0121^A35=A^A49=087003^A56=RHBInvest^A34=8128^A50=087909^A57=99^A43=N^A97=N^A52=20150330-02:45:01^A98=0^A108=30^A789=5196^A1137=8^A95=1^A96=0^A1
0=163^A





[QFJ-830] [QFJ Timer] ERROR quickfix.ThreadedSocketAcceptor 289 - Error during timer processing Created: 27/Mar/15  Updated: 27/Mar/15  Resolved: 27/Mar/15

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

Type: Bug Priority: Default
Reporter: wangsheng Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

2015-02-25 01:58:48,906 [QFJ Timer] ERROR quickfix.ThreadedSocketAcceptor 289 - Error during timer processing
quickfix.RuntimeError: java.io.FileNotFoundException: C:\croot\Rootnet\JavaCllientFixGateWay\store\FIX.4.2-CROOT-JETPAC.session (Access is denied)
at quickfix.SessionState.reset(SessionState.java:379)
at quickfix.Session.resetState(Session.java:2325)
at quickfix.Session.reset(Session.java:798)
at quickfix.Session.next(Session.java:1773)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:283)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.io.FileNotFoundException: C:\croot\Rootnet\JavaCllientFixGateWay\store\FIX.4.2-CROOT-JETPAC.session (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:194)
at java.io.FileOutputStream.<init>(FileOutputStream.java:116)
at quickfix.FileStore.storeSessionTimeStamp(FileStore.java:143)
at quickfix.FileStore.initializeSessionCreateTime(FileStore.java:138)
at quickfix.FileStore.initializeCache(FileStore.java:119)
at quickfix.FileStore.initialize(FileStore.java:112)
at quickfix.FileStore.reset(FileStore.java:447)
at quickfix.SessionState.reset(SessionState.java:377)
... 13 more



 Comments   
Comment by wangsheng [ 27/Mar/15 ]

Still have free space on the disk

Comment by Christoph John [ 27/Mar/15 ]

Looking at the message "Access is denied" I doubt that it has something to do with disk space but rather that the file cannot be accessed due to access restrictions. Either you do not have the correct permissions for the file or the file is open in another application.





[QFJ-829] QuickMessage: Invalid message: Expected BodyLength=454, Recieved BodyLength=469 Created: 25/Mar/15  Updated: 26/Mar/15  Resolved: 26/Mar/15

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

Type: Bug Priority: Major
Reporter: Shuaib Kaniyar Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

Windows 2008 R2 Server


Attachments: XML File FIX_42.xml    

 Description   

When receiving a ExecutionReport (35=n) i receive the below error

QuickMessage: Invalid message: Expected BodyLength=454, Recieved BodyLength=469

Sample Vendor Message

8=FIX.4.29=46935=n34=13208369=1952=20150324-08:07:58.91943=Y49=CME50=7056=UAT12357=P122=20150324-07:57:04.201212=350213=<RTRF>8=FIX.4.29=31435=834=15294369=775852=20150324-07:57:04.19949=CME50=7056=AZT000N57=DUMMY143=US,IL1=003316=011=ACP142718382415514=017=70477:206612220=037=7029490619138=1039=040=241=044=50448=806054=155=HW59=060=20150324-07:57:04.198107=HWJ5150=0151=10167=FUT432=201503241028=Y9717=ACP142718382415510=039</RTRF>10=097

Attach is DataDictionary FIX42.xml



 Comments   
Comment by Shuaib Kaniyar [ 25/Mar/15 ]

FIX2.xml attached

Comment by Christoph John [ 26/Mar/15 ]

Maybe someone on the mailing list can help you: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Where is the message "QuickMessage..." coming from? Also "Recieved" makes me suspicious. Are you using maybe another FIX library or are trying to parse the FIX messages by yourself?

Comment by Shuaib Kaniyar [ 26/Mar/15 ]

It is QuickFIX and we are using .Net wrapper

Comment by Christoph John [ 26/Mar/15 ]

OK, then you are at the wrong place here. This JIRA is for QuickFIX/J (Java implementation). Please look here http://www.quickfixengine.org/





[QFJ-828] Messages Log Contains Another Session's Messages Created: 19/Feb/15  Updated: 20/Feb/15

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Rupert Webb Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

Linux Server



 Description   

I had two quick fix sessions configured: CLIENT and CLIENT2. Our CLIENT2 session connected while no one connected to the CLIENT session. You can see this from the event logs:

::::::::::::::
FIX.4.2-LIME-CLIENT2.event.log
::::::::::::::
20150219-08:20:41: Session FIX.4.2:LIME->CLIENT schedule is daily, 05:00:00-UTC - 00:59:00-UTC
20150219-08:20:41: Created session: FIX.4.2:LIME->CLIENT

::::::::::::::
FIX.4.2-LIME-CLIENT2.event.log
::::::::::::::
20150219-08:20:41: Session FIX.4.2:LIME->CLIENT2 schedule is daily, 05:00:00-UTC - 00:59:00-UTC
20150219-08:20:41: Created session: FIX.4.2:LIME->CLIENT2
20150219-12:03:04: Accepting session FIX.4.2:LIME->CLIENT2 from /10.22.75.167:52406
20150219-12:03:04: Acceptor heartbeat set to 45 seconds
20150219-12:03:04: Received logon
20150219-12:03:04: Responding to Logon request
20150219-12:03:04: Received ResendRequest FROM: 1 TO: infinity
...

However, all the messages in CLIENT2's message log begin appearing in CLIENT's messages log:

::::::::::::::
FIX.4.2-LIME-CLIENT.messages.log
::::::::::::::
8=FIX.4.2|9=103|35=A|34=1|49=CLIENT2|52=20150219-12:03:04.175|56=LIME|98=0|108=45|553=USER2|554=DROPCOPY|10=165|
8=FIX.4.2|9=71|35=A|34=5998|49=LIME|52=20150219-12:03:04.185|56=CLIENT2|98=0|108=45|10=117|
8=FIX.4.2|9=65|35=2|34=2|49=CLIENT2|52=20150219-12:03:04.697|56=LIME|7=1|16=0|10=032|

::::::::::::::
FIX.4.2-LIME-CLIENT2.messages.log
::::::::::::::
8=FIX.4.2|9=103|35=A|34=1|49=CLIENT2|52=20150219-12:03:04.175|56=LIME|98=0|108=45|553=USER2|554=DROPCOPY|10=165|
8=FIX.4.2|9=71|35=A|34=5998|49=LIME|52=20150219-12:03:04.185|56=CLIENT2|98=0|108=45|10=117|
8=FIX.4.2|9=65|35=2|34=2|49=CLIENT2|52=20150219-12:03:04.697|56=LIME|7=1|16=0|10=032|

This only begin happening today. Here is the configuration:
[DEFAULT]
ConnectionType=acceptor
ReconnectInterval=60
SenderCompID=LIME
FileStorePath=fixstore-[4]-2015-02-19/
FileLogPath=fixlogs-[4]-2015-02-19/
ValidateFieldsOutOfOrder=N
ValidateFieldsHaveValues=N
ValidateIncomingMessage=N
AllowUnknownMsgFields=Y
UseDataDictionary=Y
StartTime=05:00:00
EndTime=00:59:00
BeginString=FIX.4.2
SocketAcceptPort=9003
SocketReuseAddress=Y
ValidateUserDefinedFields=N
PersistMessages=Y
CheckLatency= Y

[SESSION]
TargetCompID=CLIENT2
CheckPassword=Y
Password=PASS

[SESSION]
TargetCompID=CLIENT
CheckPassword=Y
Password=PASS



 Comments   
Comment by Christoph John [ 20/Feb/15 ]

Hi, some questions:

  • can you reproduce the problem or did it appear only once?
  • did you change something in the session settings before the problem appeared?
  • how do you use the FileLog? Are you creating it on your own?
Comment by Rupert Webb [ 20/Feb/15 ]

It does not appear to be reproducible. We did have exceptionally high disk load when it happened.

We did not make any changes to the session settings

We are using the default FileLog without any modifications.

As additional piece of information, this is the code that we use to send FIX messages:
public synchronized boolean sendMessage(Message message) throws SessionNotFound

{ return Session.sendToTarget(message); }

We also have multiple threads call this function.

I'll see if I try to reproduce it





[QFJ-827] quickfixj-core build failure when generating javadocs on JDK8 Created: 07/Feb/15  Updated: 02/Apr/15  Resolved: 09/Feb/15

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: kammo Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

It is throwing error while executing java-doc build. Below is trimmed snippet of the error log.

[ERROR] * @throws ConfigError
[ERROR] ^
[ERROR] C:\Users\Moliya\Documents\quickfixj-master\quickfixj-core\src\main\java\
quickfix\SessionSettings.java:564: error: block element not allowed within inlin
e element <code>: pre
[ERROR] * <code><pre>
[ERROR] ^
[ERROR]
[ERROR] Command line was: "C:\Program Files\Java\jdk1.8.0_31\jre\..\bin\javadoc.
exe" -J-Xmx1536m @options @packages
[ERROR]
[ERROR] Refer to the generated Javadoc files in 'C:\Users\Moliya\Documents\quick
fixj-master\quickfixj-distribution\target\site\apidocs' dir.
[ERROR] -> [Help 1]
[ERROR]



 Comments   
Comment by Christoph John [ 07/Feb/15 ]

Hi, I cannot reproduce this. What exactly did you do? Checked out from github?
I see you are using JDK8. Could you please check if JDK7 or 6 give the same error?
This is the build on the build server which runs fine (with JDK6, though): http://www.quickfixj.org:8085/browse/QFJ-GIT

Comment by kammo [ 07/Feb/15 ]

I felt the same that it could be jdk issue.

Comment by Christoph John [ 08/Feb/15 ]

I could reproduce this with JDK8. Seems to be caused by the DocLint feature of JDK8. http://stackoverflow.com/questions/15886209/maven-is-not-working-in-java-8-when-javadoc-tags-are-incomplete

Comment by Christoph John [ 09/Feb/15 ]

For the time being we will disable the DocLint feature for JDK8+.





[QFJ-826] Maven build is failing on test cases for quickfixj-core when compiling with JDK8 Created: 07/Feb/15  Updated: 02/Apr/15  Resolved: 11/Mar/15

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Minor
Reporter: kammo Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Below test cases are failing and hence whole build is failing.
SessionTest.testStateFlagsAreResetOnLogout
SessionTest.testAcceptorRelogon
SessionTest.testDontCatchErrorsFromCallback
SessionTest.testSimultaneousResendRequests
SessionTest.testResendRequestMsgSeqNum
SessionTest.testSequenceResetStackOverflow



 Comments   
Comment by Christoph John [ 07/Feb/15 ]

Hi, I cannot reproduce this. What exactly did you do? Checked out from github? Which java version are you using?
This is the build on the build server which runs fine: http://www.quickfixj.org:8085/browse/QFJ-GIT

Comment by kammo [ 07/Feb/15 ]

hi Chirs, thx for your comment. I'm using java 8 for compilation and build. I downloaded the code from gihub from below link and master.
https://github.com/quickfix-j/quickfixj
I went to quickfixj-master directory after download and ran "mvn clean install" and it is failing for these 6 test cases.

Comment by Christoph John [ 08/Feb/15 ]

I could reproduce this with JDK8 but currently have no idea what is causing it.

Comment by Christoph John [ 03/Mar/15 ]

Maybe related to this: http://randomallsorts.blogspot.de/2012/12/junit-411-whats-new-test-execution-order.html
(actually introduced by JDK7, but we skipped that)

Comment by Christoph John [ 10/Mar/15 ]

Hi kammo, I cannot really explain this but I cannot reproduce the errors anymore. Looking at the commits I can see nothing obvious what might have fixed it (JUnit upgrade maybe?)
Does it also work for you now with a fresh checkout?

Edit: if it does not work, could you please tell me which exact JDK and Maven version you are using.

Comment by kammo [ 11/Mar/15 ]

it looks fine now. we can close this jira.

Comment by kammo [ 11/Mar/15 ]

Thanks for your help.

Comment by Christoph John [ 11/Mar/15 ]

Strange enough that it works now, but thanks.





[QFJ-825] Restart of SessionConnector might lead to creation of additional message processor threads Created: 06/Feb/15  Updated: 02/Apr/15  Resolved: 15/Mar/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

When using a SingleThreadedEventHandlingStrategy it is expected that there is only one "QFJ Message Processor" thread. However, when starting a connector multiple times in a row or when quickly restarting it, there might be several message processor threads. This situation might lead to unforeseen effects, e.g. race conditions or sequence number issues.

The reason for this seems to be that the message processor thread is polling the event queue and does not get stopped correctly when waiting for the next message in the queue.
Workaround for the time being: make sure that you sleep at least 1000ms (polling interval on event queue) before (re)starting a connector after stopping it. This will give the message processor thread enough time to shutdown orderly.

todo

  • prevent concurrent startups of Initiator/Acceptor
  • prevent creation of multiple message processor threads
  • add some info logging that the message processor thread has been started/stopped





[QFJ-824] QuickFIXJ stops sending and processing heartbeats Created: 02/Feb/15  Updated: 12/Nov/18  Resolved: 12/Nov/18

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

Type: Bug Priority: Major
Reporter: Wongsakorn Chantrapornsyl Assignee: Unassigned
Resolution: Incomplete Votes: 1
Labels: QuickfixJ, timeout
Environment:

Microsoft Windows Server 2008



 Description   

I have a problem that QuickFIXJ stops sending the heartbeat. Please see the QuickFIXJ log below.

The heartbeat interval is set to 4.

20150127-01:01:34: 8=FIXT.1.19=7535=034=318541128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:34.78910=197
20150127-01:01:36: 8=FIXT.1.19=9535=034=3237749=TMSQ03226252=20150127-01:01:36.80256=TR MATCHING57=FXM142=TRFXMJP53776xxx10=130
20150127-01:01:38: 8=FIXT.1.19=7535=034=318551128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:38.89910=204
20150127-01:01:41: 8=FIXT.1.19=9535=034=3237849=TMSQ03226252=20150127-01:01:41.73956=TR MATCHING57=FXM142=TRFXMJP53776xxx10=136
----- After this time FIXQuickJ stops sending the heartbeart ---- only receive the heartbeat from other side. ----
20150127-01:01:42: 8=FIXT.1.19=7535=034=318561128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:42.96410=193
20150127-01:01:50: 8=FIXT.1.19=7535=034=318571128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:47.03910=192
20150127-01:01:51: 8=FIXT.1.19=9035=134=318581128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:48.063112=HBTO-3185810=242
20150127-01:01:52: 8=FIXT.1.19=7535=034=318591128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:52.12910=190
------ It seems that FIXQuickJ received heartbeat and testrequest but FIXQuickJ does not process them as QuickFIXJ send the testrequest to other side. -----
20150127-01:01:51: 8=FIXT.1.19=10435=134=3237949=TMSQ03226252=20150127-01:01:51.89656=TR MATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=200
------ The other side disconnect because it does not receive heartbeat -------

Do you have any idea why QuickFIXJ stops sending the heartbeat and also does not process the message from other side.



 Comments   
Comment by Christoph John [ 02/Feb/15 ]

Looks like a deadlock to me (at least from what can be seen from the log output). A stack trace at that time would be very useful.

Comment by Christoph John [ 02/Feb/15 ]

Do you happen to have a stack trace? Otherwise I cannot tell where the problem is.

Comment by Anupam Sinha [ 02/Feb/15 ]

I am unable to edit my comments. Can you please grant me the required permissions.

Otherwise you can delete my comment and I will post more info for the same.

Comment by Christoph John [ 02/Feb/15 ]

Deleted your previous comment.

Comment by Anupam Sinha [ 02/Feb/15 ]

Thanks Christoph!

I have added the logs from our connector as well. There is no stack trace that was generated hence unable to attach the same.

8=FIX.4.4^A9=60^A35=0^A49=<SENDER>^A56=<INITIATOR>^A34=9323^A52=20150202-05:18:58.924^A10=134^A
8=FIX.4.4^A9=60^A35=0^A34=8999^A49=<INITIATOR>^A52=20150202-05:18:59.396^A56=<SENDER>^A10=156^A
8=FIX.4.4^A9=60^A35=0^A49=<SENDER>^A56=<INITIATOR>^A34=9324^A52=20150202-05:19:03.925^A10=127^A
8=FIX.4.4^A9=82^A35=1^A49=<SENDER>^A56=<INITIATOR>^A34=9325^A52=20150202-05:19:05.405^A112=20150202-05:19:05^A10=179^A
8=FIX.4.4^A9=60^A35=0^A49=<SENDER>^A56=<INITIATOR>^A34=9326^A52=20150202-05:19:10.405^A10=120^A
8=FIX.4.4^A9=106^A35=A^A34=9000^A49=<INITIATOR>^A52=20150202-05:19:16.203^A56=<SENDER>^A98=0^A108=5^A553=<INITIATOR>@====.com^A554=<PWD>^A10=129^A
8=FIX.4.4^A9=71^A35=A^A49=<SENDER>^A56=<INITIATOR>^A34=9327^A52=20150202-05:19:16.454^A98=0^A108=5^A10=129^A

We are also on 1.5.3 and facing the same issue.

[02 Feb 2015 05:18:58,926][QFJ Message Processor][INFO ][resources.FIXMessageConnectionFactoryAgent]-session FIX.4.4:<INITIATOR>-><SENDER>, fromAdmin : 8=FIX.4.4,9=60,35=0,34=9323,49=<SENDER>,52=20150202-05:18:58.924,56=<INITIATOR>,10=134,
[02 Feb 2015 05:18:59,396][QFJ Timer][INFO ][resources.FIXMessageConnectionFactoryAgent]-toAdmin : 8=FIX.4.4,9=60,35=0,34=8999,49=<INITIATOR>,52=20150202-05:18:59.396,56=<SENDER>,10=156,
[02 Feb 2015 05:19:11,512][SocketConnectorIoProcessor-0.0][INFO ][quickfix.Session]-[FIX.4.4:<INITIATOR>-><SENDER>] Disconnecting: IO Session closed
[02 Feb 2015 05:19:11,513][SocketConnectorIoProcessor-0.0][INFO ][resources.FIXMessageConnectionFactoryAgent]-Logout of FIX session with exchangeFIX.4.4:<INITIATOR>-><SENDER>
[02 Feb 2015 05:19:11,513][SocketConnectorIoProcessor-0.0][INFO ][util.ConnectionStatusHistory]-02/02/2015 05:19:11.513 GMT     FIXMessageConnectionFactoryAgent      Disconnected
[02 Feb 2015 05:19:16,203][SocketConnectorIoProcessor-0.0][INFO ][initiator.InitiatorIoHandler]-MINA session created for FIX.4.4:<INITIATOR>-><SENDER>: local=/11.161.40.160:22770, class org.apache.mina.transport.socket.nio.SocketSessionImpl, remote=<SENDER>-hc-nat/IP.add.res.ss:port
[02 Feb 2015 05:19:16,204][QFJ Timer][INFO ][resources.FIXMessageConnectionFactoryAgent]-toAdmin : 8=FIX.4.4,9=71,35=A,34=9000,49=<INITIATOR>,52=20150202-05:19:16.203,56=<SENDER>,98=0,108=5,10=109,
[02 Feb 2015 05:19:16,529][QFJ Message Processor][INFO ][resources.FIXMessageConnectionFactoryAgent]-Logout of FIX session with exchangeFIX.4.4:<INITIATOR>-><SENDER>
Comment by Christoph John [ 02/Feb/15 ]

The stack trace is not automatically generated. If the issue appears, then you need to do a "jstack <PID>" on the java process. On Windows you could also press ctrl+break on the application's window which should send the stack trace into the log file.

What happens in "resources.FIXMessageConnectionFactoryAgent-toAdmin"??
Could you please also post your configuration?

I think this is no general issue so without a stack trace we won't get far. Unless you are able to reproduce the issue in a unit test.

Comment by Anupam Sinha [ 02/Feb/15 ]

Any suggestions on how to issue the jstack command when the issue occurs? It will be difficult to predict when the issue occurs and issue a command then.

Comment by Christoph John [ 02/Feb/15 ]

You could trigger that e.g. when a TestRequest comes in (which most of the time means that the counterparty missed heartbeats from your side).

What about my other points?

Comment by Wongsakorn Chantrapornsyl [ 03/Feb/15 ]

Unfortunately, I found this issue on the client's machine (production). I cannot run the command after the issue appears.

In this case, after disconnection, it can reconnect to the FIX server again and then work fine.

However, they do not want any disconnection.

Here is the configuration.

--------------------------------------------------
[DEFAULT]
ConnectionType=initiator
HeartBtInt=4
ReconnectInterval=30
StartDay=Sun
StartTime=13:00:00
EndDay=Sat
EndTime=00:00:00
UseDataDictionary=Y
ValidateFieldsOutOfOrder=N
ValidateFieldsHaveValues=N
EnableExpectedNextSeqNumOnLogon=Y
SocketUseSSL=N

ReLogonInterval=30000
RetryUserSessionLogonInterval=30

Comment by garima gangwar [ 03/Feb/15 ]

On Behalf of Anupam Sinha, Configurations are:

connectionType=initiator
useDataDictionary=Y
rejectInvalidMessage=N
heartBtInt=5
startDay=Sunday
startTime=16:00:00
endDay=Friday
endTime=23:00:00
resetOnLogon=N
reconnectInterval=120
checklatency=N
timeZone=GMT
socketUseSSL=N
buffersize=100

Comment by Anupam Sinha [ 03/Feb/15 ]

What happens in "resources.FIXMessageConnectionFactoryAgent-toAdmin"?

Simply logs the request when the request is NOT a logon request.

Comment by Christoph John [ 03/Feb/15 ]

Wongsakorn Chantrapornsyl : OK, so the client has a software which uses QuickFIX/J?
What are the configurations ReLogonInterval and RetryUserSessionLogonInterval? I cannot find them in the configuration page (http://quickfixj.org/quickfixj/usermanual/1.5.3/usage/configuration.html). Are you manually fiddling with the Logon or FIX session logic?

garima gangwar, Anupam Sinha: what is bufferSize config? Is it SocketSend/ReceiveBufferSize??

@all: what was the last application message that was processed prior to this problem? Is it always the same app message or is the time span after the last application message the same before the session breaks?
Does it always break at the same time? Or after same intervals?
Is there only one FIX session configured? I assume there are not much messages transmitted? So this should be no performance problem, shouldn't it?
I currently cannot say much without having a stack trace. But I assume it is no general error.
If you provide the client software you should be able to provide some mechanism to create stack trace or debug information in the log file.

Comment by Wongsakorn Chantrapornsyl [ 03/Feb/15 ]

Hi Christoph John

ReLogonInterval and RetryUserSessionLogonInterval are the internal configuration. They are not the QuickFIXJ configuration.

what was the last application message that was processed prior to this problem?
Ans: The last message was heartbeat. The client and server send/receive the heartbeat for a while and then the issue occurs.

Is it always the same app message or is the time span after the last application message the same before the session breaks?
Ans: This is the first time which I enabled the QuickFIXJ log. I cannot tell that it is the same behavior before this time. However, I think it should be the same.

Does it always break at the same time? Or after same intervals?
Ans: No, randomly.

Is there only one FIX session configured?
Ans: Yes, it is only one FIX session.

I assume there are not much messages transmitted?
Ans: Yes, there are only heartbeat between this client and the server before the issue occurred.

So this should be no performance problem, shouldn't it?
Ans: Agree. It is not performance problem.

I currently cannot say much without having a stack trace. But I assume it is no general error.
If you provide the client software you should be able to provide some mechanism to create stack trace or debug information in the log file.
Ans: Can you advise how to collect the stack trace? After the issue occurred, as the QuickFIXJ does not send the heartbeat, the server end the connection. Can we run the command to collect stack trace before the incident?

If it must be run when the issue occurs, it is quite hard to notice the problem occurs.

Thank you.

Comment by Christoph John [ 03/Feb/15 ]

Hi,

a heartbeat is no application message. An ExecutionReport/NewOrderSingle/... are application messages. However, you said that only heartbeats were received.

Regarding your initial log output in the issue description: you say that the engine does receive Heartbeats/TestRequests but does not answer them. So I would change the fromAdmin method of your application to check if the received message is a TestRequest. If yes, then create a stack trace and/or check for deadlocked threads. This can be achieved with some MBeans which are included in Java6 and up (ManagementFactory.getThreadMXBean())

Moreover, when I look at the log there seems to be a problem with the times. E.g. the first messages arrive in time (comparing the log time stamp and field 52/SendingTime). However, afterwards there is a gap of about three seconds. So this either means your network is flaky or the application/computer is heavily loaded and does not get the messages in time.

Comment by Wongsakorn Chantrapornsyl [ 03/Feb/15 ]

From the sniffer message, I can see that the ACK of the heartbeat is sent immediately after the heartbeat arrived. Then I think the QuickFIXJ process the heartbeat delayed.

The last activity from QuickFIXJ was sending the Test Request. You can see that QuickFIXJ has already received heatbeat but QuickFIXJ sent test request. Then I think QuickFIXJ does not process the heartbeat.

I do not understand why QuickFIXJ can send the test request but does not send the heartbeat.
---------------------------------------------------------------------
20150127-00:59:56: 8=FIXT.1.19=7535=034=318301128=949=TR MATCHING56=TMSQ03226252=20150127-00:59:56.96010=198
20150127-00:59:58: 8=FIXT.1.19=9535=034=3235349=TMSQ03226252=20150127-00:59:58.67356=TR MATCHING57=FXM142=TRFXMJP53776xxx10=146
20150127-01:00:00: 8=FIXT.1.19=7535=034=318311128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:01.04410=169
20150127-01:00:02: 8=FIXT.1.19=9535=034=3235449=TMSQ03226252=20150127-01:00:02.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=124
20150127-01:00:05: 8=FIXT.1.19=7535=034=318321128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:05.11910=177
20150127-01:00:06: 8=FIXT.1.19=9535=034=3235549=TMSQ03226252=20150127-01:00:06.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=129
20150127-01:00:09: 8=FIXT.1.19=7535=034=318331128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:09.21410=178
20150127-01:00:10: 8=FIXT.1.19=9535=034=3235649=TMSQ03226252=20150127-01:00:10.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=125
20150127-01:00:13: 8=FIXT.1.19=7535=034=318341128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:13.29710=185
20150127-01:00:14: 8=FIXT.1.19=9535=034=3235749=TMSQ03226252=20150127-01:00:14.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=130
20150127-01:00:17: 8=FIXT.1.19=7535=034=318351128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:17.39210=186
20150127-01:00:18: 8=FIXT.1.19=9535=034=3235849=TMSQ03226252=20150127-01:00:18.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=135
20150127-01:00:21: 8=FIXT.1.19=7535=034=318361128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:21.46610=184
20150127-01:00:22: 8=FIXT.1.19=9535=034=3235949=TMSQ03226252=20150127-01:00:22.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=131
20150127-01:00:25: 8=FIXT.1.19=7535=034=318371128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:25.54110=183
20150127-01:00:26: 8=FIXT.1.19=9535=034=3236049=TMSQ03226252=20150127-01:00:26.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=127
20150127-01:00:29: 8=FIXT.1.19=7535=034=318381128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:29.61710=192
20150127-01:00:30: 8=FIXT.1.19=9535=034=3236149=TMSQ03226252=20150127-01:00:30.67456=TR MATCHING57=FXM142=TRFXMJP53776xxx10=123
20150127-01:00:33: 8=FIXT.1.19=7535=034=318391128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:33.68210=190
20150127-01:00:34: 8=FIXT.1.19=9535=034=3236249=TMSQ03226252=20150127-01:00:34.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=129
20150127-01:00:37: 8=FIXT.1.19=7535=034=318401128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:37.74810=189
20150127-01:00:38: 8=FIXT.1.19=9535=034=3236349=TMSQ03226252=20150127-01:00:38.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=134
20150127-01:00:41: 8=FIXT.1.19=7535=034=318411128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:41.81410=179
20150127-01:00:42: 8=FIXT.1.19=9535=034=3236449=TMSQ03226252=20150127-01:00:42.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=130
20150127-01:00:45: 8=FIXT.1.19=7535=034=318421128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:45.87910=195
20150127-01:00:46: 8=FIXT.1.19=9535=034=3236549=TMSQ03226252=20150127-01:00:46.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=135
20150127-01:00:49: 8=FIXT.1.19=7535=034=318431128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:49.95310=193
20150127-01:00:50: 8=FIXT.1.19=9535=034=3236649=TMSQ03226252=20150127-01:00:50.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=131
20150127-01:00:53: 8=FIXT.1.19=7535=034=318441128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:54.01810=182
20150127-01:00:54: 8=FIXT.1.19=9535=034=3236749=TMSQ03226252=20150127-01:00:54.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=136
20150127-01:00:58: 8=FIXT.1.19=7535=034=318451128=949=TR MATCHING56=TMSQ03226252=20150127-01:00:58.09310=190
20150127-01:00:58: 8=FIXT.1.19=9535=034=3236849=TMSQ03226252=20150127-01:00:58.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=141
20150127-01:01:02: 8=FIXT.1.19=7535=034=318461128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:02.15810=183
20150127-01:01:02: 8=FIXT.1.19=9535=034=3236949=TMSQ03226252=20150127-01:01:02.67556=TR MATCHING57=FXM142=TRFXMJP53776xxx10=132
20150127-01:01:06: 8=FIXT.1.19=7535=034=318471128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:06.25310=184
20150127-01:01:06: 8=FIXT.1.19=9535=034=3237049=TMSQ03226252=20150127-01:01:06.67656=TR MATCHING57=FXM142=TRFXMJP53776xxx10=129
20150127-01:01:10: 8=FIXT.1.19=7535=034=318481128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:10.31810=182
20150127-01:01:10: 8=FIXT.1.19=9535=034=3237149=TMSQ03226252=20150127-01:01:10.67656=TR MATCHING57=FXM142=TRFXMJP53776xxx10=125
20150127-01:01:14: 8=FIXT.1.19=7535=034=318491128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:14.40210=181
20150127-01:01:14: 8=FIXT.1.19=9535=034=3237249=TMSQ03226252=20150127-01:01:14.67656=TR MATCHING57=FXM142=TRFXMJP53776xxx10=130
20150127-01:01:18: 8=FIXT.1.19=7535=034=318501128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:18.47810=190
20150127-01:01:18: 8=FIXT.1.19=9535=034=3237349=TMSQ03226252=20150127-01:01:18.84856=TR MATCHING57=FXM142=TRFXMJP53776xxx10=136
20150127-01:01:22: 8=FIXT.1.19=7535=034=318511128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:22.53310=178
20150127-01:01:23: 8=FIXT.1.19=9535=034=3237449=TMSQ03226252=20150127-01:01:23.72356=TR MATCHING57=FXM142=TRFXMJP53776xxx10=125
20150127-01:01:26: 8=FIXT.1.19=7535=034=318521128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:26.61010=179
20150127-01:01:27: 8=FIXT.1.19=9535=034=3237549=TMSQ03226252=20150127-01:01:27.81756=TR MATCHING57=FXM142=TRFXMJP53776xxx10=134
20150127-01:01:30: 8=FIXT.1.19=7535=034=318531128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:30.73410=182
20150127-01:01:32: 8=FIXT.1.19=9535=034=3237649=TMSQ03226252=20150127-01:01:32.67656=TR MATCHING57=FXM142=TRFXMJP53776xxx10=134
20150127-01:01:34: 8=FIXT.1.19=7535=034=318541128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:34.78910=197
20150127-01:01:36: 8=FIXT.1.19=9535=034=3237749=TMSQ03226252=20150127-01:01:36.80256=TR MATCHING57=FXM142=TRFXMJP53776xxx10=130
20150127-01:01:38: 8=FIXT.1.19=7535=034=318551128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:38.89910=204
20150127-01:01:41: 8=FIXT.1.19=9535=034=3237849=TMSQ03226252=20150127-01:01:41.73956=TR MATCHING57=FXM142=TRFXMJP53776xxx10=136
20150127-01:01:42: 8=FIXT.1.19=7535=034=318561128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:42.96410=193
20150127-01:01:50: 8=FIXT.1.19=7535=034=318571128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:47.03910=192
20150127-01:01:51: 8=FIXT.1.19=9035=134=318581128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:48.063112=HBTO-3185810=242
20150127-01:01:52: 8=FIXT.1.19=7535=034=318591128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:52.12910=190
20150127-01:01:51: 8=FIXT.1.19=10435=134=3237949=TMSQ03226252=20150127-01:01:51.89656=TR MATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=200
20150127-01:02:06: 8=FIXT.1.19=15435=A34=3238049=TMSQ03226252=20150127-01:01:58.11556=TR MATCHING57=FXM142=TRFXMJP53776xxx98=0108=4553=DCUA554=BTMU1234789=318581137=91407=10010=071
---------------------------------------------------------------------

Comment by Christoph John [ 03/Feb/15 ]

I do not understand why QuickFIXJ can send the test request but does not send the heartbeat.

This is triggered by two different threads. There is a separate thread which sends out heartbeats. The processing of incoming messages is in a separate thread (message processor thread). Incoming messages are also handled on the message processor thread. This will also call your application callbacks fromAdmin/fromApp. So I would start searching there.
When looking at your log it starts to "get slow" at 01:01:50:

20150127-01:01:50: 8=FIXT.1.19=7535=034=318571128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:47.03910=192
20150127-01:01:51: 8=FIXT.1.19=9035=134=318581128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:48.063112=HBTO-3185810=242

The 52/SendingTime is off by three seconds. So actually you "simply" have to find out what happens there. Maybe it is not even within your application but the machine starts to get slow.
Moreover, at the end of the log there is a message from 01:01:51 again??

20150127-01:01:52: 8=FIXT.1.19=7535=034=318591128=949=TR MATCHING56=TMSQ03226252=20150127-01:01:52.12910=190
20150127-01:01:51: 8=FIXT.1.19=10435=134=3237949=TMSQ03226252=20150127-01:01:51.89656=TR MATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=200

So the log file goes "backwards"?! In my opinion you are doing something nasty that you probably shouldn't do. I think the problem might be somewhere in your application. You are either doing something concurrently that shouldn't be done or your application is doing some time-consuming logic at some point. Are you concurrently modifying quickfix.Message objects? What are you doing anyway in your application code?

Comment by Anupam Sinha [ 04/Feb/15 ]

garima gangwar, Anupam Sinha: what is bufferSize config? Is it SocketSend/ReceiveBufferSize??

This value is now not being used anymore. What is SocketSend/ReceiveBufferSize?

@all: what was the last application message that was processed prior to this problem?
There was no application message that was received between the occurrences of the problem.

Is it always the same app message or is the time span after the last application message the same before the session breaks?

Does it always break at the same time? Or after same intervals?
No specific time. Sometimes it goes on for hours together and then sometimes it occurs within an interval of around 2 mins.

Is there only one FIX session configured? I assume there are not much messages transmitted? So this should be no performance problem, shouldn't it?
There is only one FIX session.

Comment by Christoph John [ 12/Nov/18 ]

Closing due to inactivity and old version used.





[QFJ-823] Problem with concurrent access to UtcTimestampConverter#dateCache Created: 19/Jan/15  Updated: 02/Apr/15  Resolved: 22/Jan/15

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

Type: Bug Priority: Default
Reporter: Alexander Troshanin Assignee: Alexander Troshanin
Resolution: Fixed Votes: 0
Labels: None

Attachments: PNG File image.png    

 Description   

In quickfix library there is class
UtcTimestampConverter
in last version 1.5.3 there is static varaible

private static HashMap<String, Long> dateCache

As I see, this varaible is used as cache:

    private static Long getMillisForDay(String value) {
        String dateString = value.substring(0, 8);
    	Long millis = dateCache.get(dateString);
        if (millis == null) {
            Calendar c = new GregorianCalendar(1970, 0, 1, 0, 0, 0);
            c.setTimeZone(SystemTime.UTC_TIMEZONE);
            int year = Integer.parseInt(value.substring(0, 4));
            int month = Integer.parseInt(value.substring(4, 6));
            int day = Integer.parseInt(value.substring(6, 8));
            c.set(year, month - 1, day);
            millis = c.getTimeInMillis();
            dateCache.put(dateString, c.getTimeInMillis());
        }
        return millis;
    } 

But if this code will be invoked from different threads(in my case it is so), then HashMap my become broken, => cuncurrent access and modification of hashmap.
Under high load I can reproduce this on my dev server.

I would suggest to replace HashMap with ConcurrentHashMap

private static ConcurrentHashMap<String, Long> dateCache = new ConcurrentHashMap<String, Long>(); 


 Comments   
Comment by Christoph John [ 20/Jan/15 ]

Hi, just a question: from where are you calling this concurrently? Does some of your code call UtcTimestampConverter.convert()?
What is the problem you are seeing? Does it throw ConcurrentModificationException or are you not seeing all inserts to the map?

Comment by Alexander Troshanin [ 20/Jan/15 ]

Hi,
Right now in our application we have next architecture:

  • we receive fix message
  • save it in our database as text
    public void onMessage(final quickfix.fix40.ExecutionReport executionReport, final SessionID sessionID) {
     ...
    service.save(new FixMessage(id, executionReport.toString()));
    
  • then this fix message as text is retrieved from database by another module(this is separate JVM, actually there are several instances of this module) and converted to quickfix.fix40.ExecutionReport
            ExecutionReport executionReport = new ExecutionReport();
            executionReport.fromString(messageString, dataDictionary != null ? dataDictionary : new DataDictionary("FIX40.xml"), false);
    
  • then we just call
    executionReport.getTransactTime()
    

during this call UtcTimestampConverter.convert() is invoked, we dont call UtcTimestampConverter.convert() by ourselves.

About a problems with hashmap, I did not get ConcurrentModificationException, but I got broken hashmap. It means that I cannot get elements by key from this map. When I call map.get(key), then this method never finishes it stucks in infinite loop.
In attach there is sceenshot of my debug

Comment by Christoph John [ 20/Jan/15 ]

I see, thanks for the clarification. Are you familiar with github? Would it be possible for you to open a pull request for this? Repo is here: https://github.com/quickfix-j/quickfixj

Comment by Alexander Troshanin [ 20/Jan/15 ]

Yes, I have account in github:
troshanin

Comment by Alexander Troshanin [ 21/Jan/15 ]

I've crearted pull request.
It was my first time when I made pull request, so could you check if it is ok?

Comment by Christoph John [ 21/Jan/15 ]

Changes look OK to me, but you need to open the pull request against the quickfix-j repo (not against your own). Then I can merge it into the codebase.
Could you do me a favor and make the rest of the fields final, too? (utcTimestampConverter and dateCache) So we won't have a mixture of final and non-final fields.
Thanks

Edit: here is some help https://help.github.com/articles/creating-a-pull-request/
(I'm also not that familiar with github either)





[QFJ-822] DNS change prevents reconnection Created: 08/Jan/15  Updated: 21/Apr/16  Resolved: 19/Dec/15

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.5.3
Fix Version/s: 1.6.2

Type: Improvement Priority: Default
Reporter: Dale Wilson Assignee: Dale Wilson
Resolution: Fixed Votes: 0
Labels: Reconnect
Environment:

All



 Description   

If a connection is lost and a DNS change is made before an attempt is made to reconnect, the reconnection attempt will fail, because the previous resolution information was cached by the initiator and will be re-used.

I'll be submitting a GitHub pull request for a change that invalidates the cached connection information when a connection attempt fails. This will have no impact on normal operations. The first reconnect attempt will use the cached information, but if it fails, the host name will be resolved again before the next attempt.



 Comments   
Comment by Christoph John [ 08/Jan/15 ]

Hi, just a question: isn't this a JVM specific setting?
http://docs.oracle.com/javase/6/docs/technotes/guides/net/properties.html#nct





[QFJ-821] Quickfix/J Server should validate SSL client certificates Created: 29/Dec/14  Updated: 13/Dec/16  Resolved: 26/Dec/15

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

Type: Improvement Priority: Major
Reporter: harnit Assignee: Marcin L
Resolution: Fixed Votes: 1
Labels: None
Environment:

O/S: Windows 8
Java: JDK 1.8.0_25


Issue Links:
Duplicate
is duplicated by QFJ-256 SSLContextFactory doesn't support cus... Closed

 Description   

In quickfix.mina.acceptor.AbstractSocketAcceptor we have sslFilter.setUseClientMode(false);

What we found is this means that the Quickfix/J server never validates the client certificates.

Can we please provide a configuration for this to enable needClientAuth?



 Comments   
Comment by harnit [ 29/Dec/14 ]

Sorry can not edit the above comment. Just read the SSLFilter javadoc, setUseClientMode(false) seems correct
What we are missing is a flag to enable the needClientAuth on the sslFilter to enable client certificate authentication

Is there any work planned for this?

Comment by Christoph John [ 30/Dec/14 ]

I have edited the issue description. No, currently there are no plans to implement it.

Comment by AE [ 06/Jul/15 ]

Hi Christoph, I am wondering if there have been any changes on this? I think there is value in allowing a quickfixj acceptor to authenticate the client connecting to it. Thanks.

Comment by Christoph John [ 07/Jul/15 ]

Hi, I do not doubt that this would be sensible but at the moment I have very little time to work on this and there are still some pull requests open to be merged. Best thing would be if someone submitted a pull request for this.

Comment by Marcin L [ 09/Dec/15 ]

https://github.com/quickfix-j/quickfixj/pull/49

Contains fixes for QFJ-838 and QFJ-854 as well as I wanted to execute full test suite.

Comment by Christoph John [ 19/Dec/15 ]

Great, thanks. Just merged.

Comment by Marcin [ 14/Jan/16 ]

Hello,

I can not build jar from current GITHUB source of quickfixj.

here is the "SSL" error in the output of mvn package:
====================================
Failed tests:
SSLCertificateTest.shouldFailWhenUsingEmptyServerTrustore:434 No SSL exception thrown
AcceptanceTestSuite$AcceptanceTest.run:80 message timeout: expected=

{34=2, 56=TW, 35=5, 58=Incorrect BeginString, 49=ISLD, 8=FIX.4.2, 9=74, 52=00000000-00:00:00.000, 10=0}

Tests in error:
SessionTest.testLogonIsFirstMessageOnAcceptor:490->setupFileStoreForQFJ357:814 » FileNotFound
SessionTest.testLogonLogoutOnAcceptor:536->setupFileStoreForQFJ357:814 » FileNotFound
SessionTest.testLogonOutsideSessionTimeIsRejected:767->setupFileStoreForQFJ357:814 » FileNotFound
SessionTest.testStartOfInitiatorInsideOfSessionTime:713->setupFileStoreForQFJ357:814 » FileNotFound
SessionTest.testStartOfInitiatorOutsideOfSessionTime:632->setupFileStoreForQFJ357:814 » FileNotFound
SleepycatStoreTest>AbstractMessageStoreTest.setUp:43 » Runtime java.io.IOExcep...
SleepycatStoreTest>AbstractMessageStoreTest.setUp:43 » Runtime java.io.IOExcep...
SleepycatStoreTest>AbstractMessageStoreTest.setUp:43 » Runtime java.io.IOExcep...
SleepycatStoreTest>AbstractMessageStoreTest.setUp:43 » Runtime java.io.IOExcep...
SleepycatStoreTest>AbstractMessageStoreTest.setUp:43 » Runtime java.io.IOExcep...

Tests run: 1333, Failures: 2, Errors: 10, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] QuickFIX/J Parent ................................. SUCCESS [0.493s]
[INFO] QuickFIX/J Code Generator Maven Plugin ............ SUCCESS [3:13.298s]
[INFO] QuickFIX/J Dictionary Generator ................... SUCCESS [9.434s]
[INFO] QuickFIX/J Core engine ............................ FAILURE [14:54.135s]
[INFO] QuickFIX/J Message classes for various FIX specs .. SKIPPED
[INFO] QuickFIX/J Message classes for FIX 4.0 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 4.1 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 4.2 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 4.3 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 4.4 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 5.0 ............ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 5.0 SP1 ........ SKIPPED
[INFO] QuickFIX/J Message classes for FIX 5.0 SP2 ........ SKIPPED
[INFO] QuickFIX/J Message classes for FIXT 1.1 ........... SKIPPED
[INFO] QuickFIX/J Message classes for all FIX specs ...... SKIPPED
[INFO] QuickFIX/J Examples ............................... SKIPPED
[INFO] QuickFIX/J Examples - Executor .................... SKIPPED
[INFO] QuickFIX/J Examples - Order Match ................. SKIPPED
[INFO] QuickFIX/J Examples - Banzai ...................... SKIPPED
[INFO] QuickFIX/J All runtime modules .................... SKIPPED
[INFO] QuickFIX/J Distribution ........................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20:18.896s
[INFO] Finished at: Wed Jan 13 22:55:57 GST 2016
[INFO] Final Memory: 18M/340M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.19:test (default-test) on project quickfixj-core: There are test failures.
[ERROR]

Comment by Christoph John [ 14/Jan/16 ]

From what I can see in the lines where it is failing is that it tries to create files in the temporary directory. Do you have write access there?

But actually this belongs onto the quickfixj-users group: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks





[QFJ-820] quickfixj ignores the first message on sequence reset Created: 15/Dec/14  Updated: 19/Dec/14  Resolved: 19/Dec/14

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3, 1.6.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Emma Wansbrough Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

this happens on window and linux


Attachments: Text File messages470-480.txt    

 Description   

Hi,
I am experiencing the following serious fix issue. This could be config but I am not convinced.

I have used both quickfixj 1.5.3 and the newer 1.6.0 (snapshot)

I get the following issue

I connect to the fix server periodically there is a message that comes in out of sequence

From the event log we get the following issue

20141215-00:01:02: Received logon
20141215-14:41:57: MsgSeqNum too high, expecting 473 but received 474:

Execution Report

Field Field Name Value
8 BeginString FIXT.1.1
9 BodyLength 956
35 MsgType Execution Report (8)
34 MsgSeqNum 474

20141215-14:41:57: Enqueued at pos 474: Field
Field Name Value
8 BeginString FIXT.1.1
9 BodyLength 956
35 MsgType Execution Report (8)
34 MsgSeqNum 474

20141215-14:41:57: Sent ResendRequest FROM: 473 TO: 473
20141215-14:41:57: MsgSeqNum too high, expecting 473 but received 474:
8 BeginString FIXT.1.1
9 BodyLength 956
35 MsgType Execution Report (8)
34 MsgSeqNum 474

and at this point we get a general repeat of this deadlock

From mesages log you can see that a resend request got sent
Field Field Name Value
8 BeginString FIXT.1.1
9 BodyLength 68
35 MsgType Resend Request (2)
34 MsgSeqNum 441
49 SenderCompID NOMXFIXPTM
52 SendingTime 20141215-14:41:57.405
56 TargetCompID MA
7 BeginSeqNo 473
16 EndSeqNo 0

the next message from MA is

Field Field Name Value
8 BeginString FIXT.1.1
9 BodyLength 1095
35 MsgType Execution Report (8)
34 MsgSeqNum 473
43 PossDupFlag Y
49 SenderCompID MA
52 SendingTime 20141215-14:41:57.415
56 TargetCompID NOMXFIXPTM
122 OrigSendingTime 20141215-14:41:43
37 OrderID 1240469
527 SecondaryExecID 8534860-0

And MA keep sending trades with the next sequence up but our client is having none of it.

20141215-14:41:57: Already sent ResendRequest FROM: 473 TO: 473. Not sending another.

The thing that seems to be wrong is the first message sent over after the resend request gets ignored, instead it sees the message after that.
Restarting can put this back to the correct sequencing and thus out of the deadlock

I am hoping someone might have some insight into this issue.



 Comments   
Comment by Christoph John [ 15/Dec/14 ]

You could try specifying SendRedundantResendRequests=Y in your config. But of course this is only a workaround.
Could you please post or attach a message log starting from seqnums 470 until ab out 480?

Comment by Emma Wansbrough [ 16/Dec/14 ]

I am going to look into this abit more but I scan see that the 473 was sent, but got ignored previously. It could be that this message caused an error that got swallowed and prevented a sequence number being updated.

Comment by Emma Wansbrough [ 16/Dec/14 ]

@ Christoph John, thankyou for taking a look this is much appreciated.

Comment by Emma Wansbrough [ 16/Dec/14 ]

I did specify this as suggested I found I got the same type of situation, just alot more resend requests. I will do this and show logs.

Comment by Christoph John [ 16/Dec/14 ]

Hmm, my first guess is also that there might be something wrong with the message (maybe it is failing inside fromApp)? I mean there is plenty of time in between the messages, so there most probably is no race condition.

Comment by Emma Wansbrough [ 16/Dec/14 ]

do you mean from the fix server? @fromApp

Comment by Christoph John [ 16/Dec/14 ]

When you get to process the message of your counterparty then it is passed through the fromApp callback of your application. If there are RuntimeExceptions or other unexpected behaviour inside that method, the target sequence number is not incremented which will lead to a resend on the next message.

Comment by Emma Wansbrough [ 16/Dec/14 ]

Johh,
I did abit of debugging
I am getting an invalid checksum from the message I get. I think at this point it bombs out and never increments the sequence number so I get trapped in the never ending state.

Can you verify this?
if (checkSum != checkSum(messageData))

{ // message will be ignored if checksum is wrong or missing throw new InvalidMessage("Expected CheckSum=" + checkSum(messageData) + ", Received CheckSum=" + checkSum + " in " + messageData); }

I throw this exception. I am not that familiar with the code.

Comment by Christoph John [ 17/Dec/14 ]

Yes, on an invalid checksum, the message is simply ignored and the target seqnum is not incremented. This is in line with the FIX spec and is because FIX is a rather optimistic protocol. It simply assumes that this was a transmission error and re-requests the message. Unfortunately, most of the time the error will repeat.

To get around this, your counterparty should set the correct checksum on the message. Maybe this is caused by special characters on the message?

Comment by Emma Wansbrough [ 19/Dec/14 ]

Hi Chrisoph,
The counterparty have got back and acknowledged an issue on their side with a special character.
Thanks for your input on this.

I think it can safely be closed as not a bug!

Emma.

Comment by Christoph John [ 19/Dec/14 ]

Thanks for the update.

Comment by Christoph John [ 19/Dec/14 ]

Feel free to ask on the mailing list if there are any issues:
https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-819] Create XSD Schema for FIX dictionary files Created: 19/Nov/14  Updated: 17/Oct/17

Status: Reopened
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: None
Fix Version/s: 2.1-BETA

Type: Improvement Priority: Default
Reporter: Stephen Flynn Assignee: Stephen Flynn
Resolution: Unresolved Votes: 1
Labels: None


 Description   

Fix xml dictionary documents (FIX44.xml etc) should have a defined schema (XSD).
The schema can be used for...
authoring customer fix data dictionaries.
(ii) validating documents at both build and runtime.
(iii) configuring the DataDictionary (via JAXB).

At the moment the DataDictionary.load() method pulls in an org.w3c.dom.Document instance and then iterates through it using hardwired node names doing some adhoc validation along the way. It would be much better to load a validated document as a type safe object and iterate through that.

The schema should fit the existing doc layout with as few changes as possible (probably a namespace declaration will be required).



 Comments   
Comment by praneeth thonupunoori [ 16/Oct/17 ]

Hi, any approximate ETA on this issue? it would help us a great deal if this is done. Thanks

Comment by Christoph John [ 17/Oct/17 ]

Hi praneeth thonupunoori,
no-one is working on this currently I'm afraid. So we cannot give an ETA.
Chris.





[QFJ-818] SSL3 “POODLE” Vulnerability impact QuickFIXJ (bundle Apache MINA) ? Created: 03/Nov/14  Updated: 22/Dec/15  Resolved: 22/Dec/15

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

Type: Other Priority: Critical
Reporter: surachai chatsomsiri Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: QuickfixJ, ssl
Environment:

quickfixj-all-1.5.3.jar
mina-core-1.1.7.jar
mina-filter-ssl-1.1.7.jar
JRE 6.0.2



 Description   

Hi Support.
I am developer implemented QuickFIXJ(Client side) got feed from QuickFIXJ(Feed Server side), It using SSL protocol, for my understand QuickFIXJ using Apache MINA for establish SSL protocol.

According to the links below, seems that any SSL v3 got impact from the POODLE vulnerability..
the "Poodle" vulnerability, released on October 14th, 2014, is an attack on the SSL 3.0 protocol. It is aprotocol flaw,
http://security.stackexchange.com/questions/70719/ssl3-poodle-vulnerability

Could you help me provide information please?
1. What's SSL protocol version using in Apache MINA? <= I try to find information unfortunate i not found it.

2. The “POODLE” Vulnerability will impact with QuickFIXJ (using Apache MINA) if Yes, Can you provide solution to prevent it?

Thank you very much
Surachai C.



 Comments   
Comment by Christoph John [ 03/Nov/14 ]

According to this link http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html you could try passing the https.protocols="TLSv1" property to your app. MINA should pick that up since it uses the SSLEngine from the JDK under the hood.

There is also the possibility to specify the QFJ configuration EnabledProtocols with a list of supported protocols. But I have not tested that yet.

Could you please test that and tell if it worked?
Thanks





[QFJ-817] quickfix.Message parseGroup throws NumberFormatException Created: 31/Oct/14  Updated: 12/Nov/18  Resolved: 12/Nov/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 2.1.0

Type: Bug Priority: Major
Reporter: Christian Asmussen Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I fixed it with the following snippet:

    private void parseGroup(String msgType, StringField field, DataDictionary dd, FieldMap parent)
            throws InvalidMessage {
        final DataDictionary.GroupInfo rg = dd.getGroup(msgType, field.getField());
        final DataDictionary groupDataDictionary = rg.getDataDictionary();
        final int[] fieldOrder = groupDataDictionary.getOrderedFields();
        int previousOffset = -1;
        final int groupCountTag = field.getField();
        final int declaredGroupCount;
        try {
            declaredGroupCount = Integer.parseInt(field.getValue());
        } catch(NumberFormatException nfe){
        	throw new FieldException(SessionRejectReason.INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP, "The group " + field.getTag() + " must have an integer delimiter field [value=" + field.getValue() + "]", field.getTag());
        }

This allows the parsing to continue.



 Comments   
Comment by Christoph John [ 31/Oct/14 ]

Thanks for the suggested patch.

Comment by Christoph John [ 06/Feb/15 ]

Just a question: why does the parsing continue when you throw a FieldException? Shouldn't the message get rejected?

Comment by Christoph John [ 12/Nov/18 ]

Fixed by https://github.com/quickfix-j/quickfixj/pull/150





[QFJ-816] Put milliseconds in OrigSendingTime if SendingTime has them Created: 29/Oct/14  Updated: 02/Apr/15  Resolved: 29/Oct/14

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

Type: Improvement Priority: Default
Reporter: Horia Muntean Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

OrigSendingTime is set without milliseconds even if the SendingTime has them. This seems rather trivial to implement based on the logic used for SendingTime i.e. MillisecondsInTimeStamp config and version >= 4.2.

I can do this if requested.



 Comments   
Comment by Christoph John [ 29/Oct/14 ]

Thanks, feel free to submit a pull request or patch.

Comment by Horia Muntean [ 29/Oct/14 ]

I checked the current master from github (9d6723f6cb82167b83361916417dde498299cb46) and this issue is already solved in quickfix.Session.java so please close this issue.
Sorry for any inconvenience.

Comment by Christoph John [ 29/Oct/14 ]

No problem. I forgot about that already.





[QFJ-815] Originalsending (tag 122) is getting deleted by initiator. Created: 21/Oct/14  Updated: 22/Oct/14  Resolved: 22/Oct/14

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

Type: Other Priority: Major
Reporter: raghuram potluri Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

windows



 Description   

when invoking sendtotarget, initiator removing origsendingtime field in below code snipped.

public boolean send(Message message)

{ message.getHeader().removeField(PossDupFlag.FIELD); message.getHeader().removeField(OrigSendingTime.FIELD); return sendRaw(message, 0); }

 Comments   
Comment by Christoph John [ 22/Oct/14 ]

Two things:
1. You should rather not manually set tags like PossDupFlag and OrigSendingTime. This session-level stuff is handled by the engine and it is likely that you are doing something wrong when you tamper with it.
2. If you really really want to manipulate those tags you should do it in the toApp() callback of your application.

If you have further questions please use the QF/J mailing list. https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Thanks





[QFJ-814] Sequence Reset Fails Created: 16/Oct/14  Updated: 12/Nov/18  Resolved: 16/Jul/18

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.6.0

Type: Other Priority: Default
Reporter: Rahul Gaur Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: sequence,

Attachments: PDF File fix-43_VOL-2_with_Errata_20020920.pdf    
Issue Links:
Duplicate
duplicates QFJ-673 QFJ sequence problem following inboun... Closed
is duplicated by QFJ-928 SequenceReset not processed when out ... Closed

 Description   

Hi All,

Here are the steps:

1. Our FIX engine receives an out of sequence messages with MsgSeqNum(s) => 200938 -> 200941 -> 200939 (No 200940 received).

2. It complains => "MsgSeqNum too high, expecting 200939 but received 200941" and sends a 'ResendRequest(35=2)' with 'BeginSeqNo=200939'.

3. Before receiving the reset message it receives two more messages with MsgSeqNum(s) => 200942 -> 200943.

4. It then receives the 'SequenceReset(35=4)' with:
a) NewSeqNo = 200944
b) MsgSeqNum = 200939
c) PossDupFlag = Y
d) GapFillFlag = Y

5. No trace in the logs as to whether the 'SequenceReset' is handled or not.

6. It then receives a message with MsgSeqNum = 200944 and complains => 'MsgSeqNum too high, expecting 200940 but received 200944'. This error message persists for all subsequent messages and our engine is not able to recover from it as the MsgSeqNum = 200940 is never received.

At step 6, shouldn't the engine ignore all messages from 200939-200943 and start afresh from 200944.

Thanks
Rahul



 Comments   
Comment by Christoph John [ 16/Oct/14 ]

Could you please test this with a more recent QF/J version? The current version is 1.5.3 and there was also a related bug fixed in 1.6.0 (QFJ-673) which is only available as snapshot at the moment (http://www.quickfixj.org:8085/browse/QFJ-GIT/latest/artifact/shared/qfj-zip/).

Comment by Rahul Gaur [ 26/Nov/14 ]

Hi John,

On digging more on this issue and on checking the FIX 4.3 protocol specification we find that our FIX engine behaved correctly at 'step 5' by ignoring the Sequence Reset(Gap Fill) message. Please find attached the specs and see the page 23 & 49. As per the specs:

Sequence Reset (Gap Fill)
a. Receive Sequence Reset (Gap Fill) message with NewSeqNo > MsgSeqNum and MsgSeqNum > than expect sequence number Issue Resend Request to fill gap between last expected MsgSeqNum &
received MsgSeqNum.
b. Receive Sequence Reset (Gap Fill) message with NewSeqNo > MsgSeqNum and MsgSeqNum = to expected sequence number Set next expected sequence number = NewSeqNo
c. Receive Sequence Reset (Gap Fill) message with NewSeqNo > MsgSeqNum and MsgSeqNum < than expected sequence number and PossDupFlag = "Y" Ignore message
d. Receive Sequence Reset (Gap Fill) message with NewSeqNo > MsgSeqNum and MsgSeqNum < than expected sequence number and without PossDupFlag = "Y" ....
e. Receive Sequence Reset (Gap Fill) message with NewSeqNo <= MsgSeqNum and MsgSeqNum = to expected sequence number ...

Could it be that at step 1. or step 2., the FIX engine was suppose to send one more 'ResendRequest(35=2)' with 'BeginSeqNo=200940' ?

Thanks
Rahul

Comment by Christoph John [ 27/Nov/14 ]

Hi Rahul,

you are right, the SequenceReset with a seqnum lower than the expected seqnum and PossDupFlag is (and should be) ignored. But maybe a message in the logs would be helpful though.
Was the other side also a QF/J engine? I've heard one user reporting a similar problem on the mailing list.

Cheers,
Chris.

Comment by Rahul Gaur [ 15/Jul/18 ]

Hi John,

This can be closed as this got fixed in the newer version of QuickfixJ

Thanks
Rahul

Comment by Christoph John [ 16/Jul/18 ]

Hi Rahul,
thanks for the information!
Cheers,
Chris.





[QFJ-813] SessionConnector:waitForLogout()'s InterruptedException handling. Created: 11/Oct/14  Updated: 18/Sep/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 2.1-BETA

Type: Improvement Priority: Default
Reporter: Francesco Lo Conte Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When the executing thread is interrupted the waitForLogout() method catches it and prints and error to log.

I would like to suggest that the exception is either thrown or at least re-asserted so that higher level application code can handle it. Also I would like to suggest that nothing is printed to the log file.

This would:

  • Let higher level application code realize that an interruption has occurred.
  • Stop the engine as requested (if it's thrown).
  • Let higher level application code handler the interruption properly.
  • Let higher level application code decide what to print in the log file.

Currently after the interruption is requested there is no way to know whether the engine actually stopped.
Also the log file is polluted (in my opinion) with a stack dump whereas this is not an actual error condition.

I supposed a similar behavior would be desirable in all other equivalent places in the code.

I would be interested to hearing your opinion about it.

Many thanks.
Francesco Lo Conte



 Comments   
Comment by Christoph John [ 13/Oct/14 ]

So you propose to remove the logging and call Thread.currentThread().interrupt() instead?

Comment by Francesco Lo Conte [ 13/Oct/14 ]

Yes.

Alternatively, stop catching the InterruptedException and let it be thrown by the method. The impact would be:
On the SessionConnector class:

  • "protected void waitForLogout()" would change to "protected void waitForLogout(...) InterruptedException"
  • "protected void logoutAllSessions(...)" would change to "protected void logoutAllSessions(...) InterruptedException"
  • "public void stop(...)" would change to "public void stop(...) InterruptedException"
    On the Connector interface:
  • "void stop(...)" would change to "void stop(...) InterruptedException"

This would have repercussions on the Connector interface and break backward compatibility.
Re-asserting the interrupted state on the thread as you point out might be preferable as it would still provide a way for higher level code to detect the interruption and remain backward compatible.

Comment by Christoph John [ 16/Oct/14 ]

OK, then we should change it to "Thread.currentThread().interrupt()".
What about the usages in SingleThreadedEventHandlingStrategy and ThreadPerSessionEventHandlingStrategy. Is it also feasible to change it there?

Comment by Francesco Lo Conte [ 17/Nov/14 ]

SingleThreadedEventHandlingStrategy

40: I think 'isStopped' should be volatile because it is read and set by 2 different threads

50: } catch (InterruptedException e)

{ This is called from Mina's code so it should never happen anyway. So I think it's reasonable to throw a RuntimeException. An improved handling would be for onMessage(...) not to catch it and instead throw it so not to disrupt anything inside Mina (or the Transport layer in general) that might want to know about it. But it's probably not worth it changing the interface at this time. 79: }

catch (InterruptedException e)

{ // ignore }

No change. Can be ignored as this thread is never stopped. We don't even need a handle to it as its run() method just completes.

ThreadPerSessionEventHandlingStrategy

116: } catch (final InterruptedException e)

{ quickfixSession.getLog().onErrorEvent(e.toString()); }

This is called from Mina's code so it should never happen. So I think it's reasonable to just log an error in the session's log.
Please note though that the same in SingleThreadedEventHandlingStrategy throws a RuntimeException instead. Maybe we should go with 1 alternative for both. Either log something or throw a RuntimeException.
Same as before, an improved handling would be for enqueue(...) (and onMessage(...) that calls it) not to catch it and instead throw it so not to dirupt anything inside Mina (or the Transport layer in general) that might want to know about it. But it's probably not worth it changing the interface at this time.

137:
} catch (final InterruptedException e) {
LogUtil.logThrowable(quickfixSession.getSessionID(),
"Message dispatcher interrupted", e);
stopping = true;
As far as I can tell the dispatching threads (MessageDispatchingThread) are never stopped with Thread.stop() so the catch below will never happen (as the code stands now).
One might as well leave the code as it is in case in future Thread.stop() is called on the MessageDispatchingThread object (e.g. via getDispatcher(...) that can expose it to the outside).
Still I would add Thread.currentThread().interrupt() to the code in the catch block to reassert the thread status.

One suggestion: in both SingleThreadedEventHandlingStrategy and ThreadPerSessionEventHandlingStrategy there are thread that are instantiated.
They are then notified to stop using a volatile variable. I would suggest replacing this mechanism with one more 'natural' to thread semantic.
Whereas the loop should be: while (!Thread.currentThread().isInterrupted())

{...}

Then when they need to be stopped one simply calls myThread.stop().
The while loop will exit and any clean up can be carried out before the run() method returns.
At this stage though, as the code works, it wouldn't add any benefits.

Comment by Christoph John [ 15/Dec/14 ]

Hi Francesco,

thanks for your input.
During work on QFJ-790 I already changed the isStopped flag to volatile.

If it is OK with you I would put this issue to the next major release to resolve the remaining points.

Thanks,
Chris.





[QFJ-812] Non-Logon message received before Logon should result in disconnection Created: 07/Oct/14  Updated: 02/Apr/15  Resolved: 08/Oct/14

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

Type: Bug Priority: Default
Reporter: Thom Shutt Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

According to Fix protocol, if a message is sent before Logon, an error should be logged and the user should be disconnected.

Currently, an error is logged but no disconnection happens.

Edit: this is outlined in the "Sellside-oriented (session acceptor) Logon and session initiation test case" 1S.



 Comments   
Comment by Christoph John [ 07/Oct/14 ]

Hi, could you maybe attach some log output or a test case? Thanks

Comment by Thom Shutt [ 07/Oct/14 ]

Hi, the log output we get is:

WARN | 2014-09-29 16:25:16,029 | {SocketAcceptorIoProcessor-0.0} | AcceptorIoHandler | - Ignoring non-logon message before session establishment: <FIX message content>
Comment by Christoph John [ 08/Oct/14 ]

OK, this is a one-line fix.





[QFJ-811] Tag 989 is hard coded wrongly in version 1.5.3 Created: 06/Oct/14  Updated: 17/Jun/20  Resolved: 29/Jul/19

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

Type: Bug Priority: Default
Reporter: Chaitanya N Assignee: Wojciech Zankowski
Resolution: Fixed Votes: 0
Labels: None


 Description   

Tag 989 should come after tag 81, which comes under the repeating group tag of tag 79.

public NoAllocs() {
super(78, 79,
new int[]

{ 79, 661, 573, 366, 80, 467, 81, 539, 208, 209, 161, 360, 361, 12, 13, 479, 497, 153, 154, 119, 737, 120, 736, 155, 156, 742, 741, 136, 576, 780, 172, 169, 170, 171, 85, 989, 1002, 993, 992, 1047, 635, 0 }

);
}
Check the FIX community link for more information

http://www.fixtradingcommunity.org/FIXimate/FIXimate3.0/en/FIX.5.0SP2/body_50484851.html?find=SecondaryIndividualAllocID

I know there is a work around ValidateUnorderedGroupFields='N' to ignore validation of repeating groups, But can we have a proper fix to cater to people who doesn't want to use this work around?






[QFJ-810] Messages get lost during logon process with sequence gap Created: 06/Oct/14  Updated: 16/Oct/14

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Heribert Steuer Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: condition, gap, logon, race

Issue Links:
Relates
is related to QFJ-804 Race condition between sessionClosed ... Closed

 Description   

When a sequence gap exists, all subsequent messages sent by the counterparty are lost when the logon message contains a out-of-sync sequence number.

Scenario: Counterparty A is initiating a logon, counterparty B responds to the logon and immediately sends 10 more messages. A now detects the sequence problem in the login message and closes the session. The 10 messages are lost (meaning they are logged as received but never appear in the callback)

The problem seems to be that the verify() function detects the gap in the logon messages, creates a logout and a disconnect. This leads to the fact that the ThreadPerSessionEventHandlingStrategy.run method is left and its local queue gets destroyed - still containing the messages that have been received after the logon.

Whatever the correct behaviour would be - the current one is a problem because of the messages are received but never processed. It might be better to leave ThreadPerSessionEventHandlingStrategy.run() only if the queue is empty.



 Comments   
Comment by Christoph John [ 08/Oct/14 ]

Just for clarification: the Logon of counterparty B has a sequence number which is too low? In my opinion the messages following the Logon should not be processed since their sequence number was too low. But maybe I did not understand fully.

Comment by Heribert Steuer [ 09/Oct/14 ]

In any case, just dropping messages should never happen. Probably a session level reject should be sent because business level messages appear without the session being completely established. But receiving and simply dropping does not feel good at all because none of the counterparties get a feedback on the problem.

Please share your thoughts.

Comment by Christoph John [ 10/Oct/14 ]

I see a problem with sending Reject messages if the Session is not fully established.
Let me ask again: was the sequence number too low? I guess it must have been too low if the connection has been closed immediately by A. If the sequence number is too low it is considered a serious problem and the connection has to be dropped (preferrably by sending a Logout message if possible). This would require manual intervention in any case.
Maybe the processing has to be changed in a way that the connection is closed immediately and no more messages are accepted until the session has been completely established.
What do you think?

Comment by Heribert Steuer [ 10/Oct/14 ]

Correct, the SeqNum was too low. In fact we had the issue in production where a session went out of sync and we got a periodic Logon/Logout war. This means that both "A" sent a logon, "B" accepts the logon immediately followed by a resend request. "A" then sends a logout because the sequence number of the logon "A" sent earlier did not match. The problem in total seems to be that there is no real handshake in FIX. So you never really know when a session is really established e.g. like in TCP you have SYN, SYN ACK, ACK. In FIX you would - using TCP as an example - have only SYN and SYN ACK. When the responder replies to a logon message, he never knows if the initiator will accept his logon message. Therefore he does not know when he can start to send data. This is a design flaw in FIX, it would be best the have the initiator have something like "established" returned to the acceptor after his logon.

Nevertheless, the problem remains that the acceptor sends data immediately after sending his logon without knowing if he is allowed to do so or if the logon gets rejected somehow. I do not think that closing the connection is a solution. While you are processing the logon in quickfix, Mina would probably already read data from the socket or traffic will arrive in the network stacks buffer etc., so simply closing the connection would not be a real solution. It always ends up in a race condition. In my optinion, the reject would be okay because from the perspective of the acceptor, the session is established. He received a logon and he replied to it. Therefore quickfix is able to respond to it - and it does today by sending a logout. Therefore a solution might be to check if the buffer (ThreadPerSessionEventHandlingStrategy) is empty. If so, send a logout (as it does now). If the buffer is not empty, process the messages and send a session level reject in return. As the buffer is empty, send a logout and close the socket.

Unfortunately I do not really have a better idea how to solve it, as mentioned earlier its more or less a flaw in the design of the protocol. How does the above idea sound to you?

Comment by Christoph John [ 11/Oct/14 ]

Just another question: this issue basically sounds a little like QFJ-790. Do you agree?

However, your solution sounds feasible. Will take a deeper look at it.

As a workaround for the time being: many people implement the handshake as follows: after Logon immediately send a TestRequest. As soon as you receive the Heartbeat message with your TestReqID you can be pretty sure that the session is established. Of course, this is no 100% guarantee but works quite well in most cases.





[QFJ-809] Provide sensible default for property FileStoreMaxCachedMsg Created: 29/Sep/14  Updated: 02/Apr/15  Resolved: 30/Sep/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

We should take 10000 as default and not Integer.MAX_VALUE which might lead to OutOfMemory issues.






[QFJ-808] Prevent setting illegal double values to FIX messages in order to avoid checksum errors Created: 26/Sep/14  Updated: 02/Apr/15  Resolved: 30/Sep/14

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

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-626 ResendRequest (silently) aborted when... Closed

 Description   

See discussion in comments on QFJ-626.
We should throw an Exception when trying to set a non-double value on DoubleFields.






[QFJ-807] On a NonStopSession there is no use to check the session time each second Created: 26/Sep/14  Updated: 02/Apr/15  Resolved: 26/Sep/14

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

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Comments   
Comment by Christoph John [ 26/Sep/14 ]
  • added isNonStopSession() to SessionSchedule
  • changed Session.next() to only check session time if no NonStopSession is used




[QFJ-806] Tag appears more than once Created: 11/Aug/14  Updated: 11/Aug/14  Resolved: 11/Aug/14

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

Type: Bug Priority: Default
Reporter: Victor Rosenberg Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The following exception is created when parsing the message: quickfix.FieldException: Tag appears more than once, field=279

The code:
String strMessage =
"8=FIX.4.2|9=196|35=X|49=A|56=B|34=12|52=20100318-03:21:11.364|262=A|268=2|279=0|269=0|278=BID|55=EUR/USD|270=1.37215|15=EUR|271=2500000|346=1|279=0|269=1|278=OFFER|55=EUR/USD|270=1.37224|15=EUR|271=2503200|346=1|10=171|"
.replace('|', (char)1);

Message message = MessageUtils.parse(new DefaultMessageFactory(), null, strMessage);

Also see http://stackoverflow.com/questions/24573883/quickfixj-rejecting-incoming-message-with-tag-appears-more-than-once-where-the



 Comments   
Comment by Victor Rosenberg [ 11/Aug/14 ]

Apologies, seems like the message I've attached indeed contains the tag twice.
The linked question on stack overflow should still be investigated though.

Thanks

Comment by Christoph John [ 11/Aug/14 ]

Please use the quickfixj mailing list to ask such questions.

Moreover, you cannot parse messages with repeating groups without the use of a data dictionary.





[QFJ-805] Set GBK charset will silently drop message Created: 07/Aug/14  Updated: 08/Aug/14  Resolved: 08/Aug/14

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

Type: Bug Priority: Default
Reporter: Jiang Hailong Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-38 FIX Message support double-byte charset. Closed

 Comments   
Comment by Christoph John [ 07/Aug/14 ]

Hi, I think this is due to checksum errors. This should be the same issue as QFJ-38, correct? This is fixed with 1.6.0.

Comment by Jiang Hailong [ 07/Aug/14 ]

When I set the charset as GBK, QuickFIX will log "MsgSeqNum too high, expecting 3 but received 4" into event.log and similar for each following message. But these logs will not appear when I set the charset as ISO-8859-1 or UTF-8.

So I check the message.log for more detail, and I found that the message with MsgSeqNum=3 exists, and the "fromApp" method never get called for this message. The message contains a Text field with a GBK encoded string.

Here is the MsgSeqNum=3 message:

8=FIX.4.2|9=257|35=8|34=3|49=SERVER|52=20140807-15:08:43.359|56=FIXTest140|6=0|11=1407424160744|14=0|17=290490401|20=0|37=1407424160744|38=0|39=8|54=1|55=600035|58=error_business: Broker return: Code:-420411065 Msg:-420411065[-150906020]ÊäÈëίÍÐÊýÁ¿ÓÐÎó|103=99|150=8|151=0|10=114|

So why the message is droped? And how can I set the charset as GBK?

Comment by Christoph John [ 07/Aug/14 ]

Please see my comment above. It is due to checksum error when using a non-standard encoding. Please check with current 1.6.0-SNAPSHOT version if the problem disappears. You might have to recompile your code against 1.6.0.
http://www.quickfixj.org:8085/browse/QFJ-GIT/latest/artifact/shared/qfj-zip/

Comment by Jiang Hailong [ 08/Aug/14 ]

I build from 1.6.0 and this problem is fixed. Thank you very much.





[QFJ-804] Race condition between sessionClosed and processing logout message received Created: 31/Jul/14  Updated: 27/Oct/14  Resolved: 27/Oct/14

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Glyn Walters Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: QuickfixJ

Issue Links:
Duplicate
duplicates QFJ-790 Logout message not propagated to the ... Closed
Relates
relates to QFJ-810 Messages get lost during logon proces... Open

 Description   

sessionClosed() called by AbstractIoHandler can call disconnect() on Session before a logout message has been processed by the EventHandlingSession. (This was witnessed with a SingleThreadedEventHandlingStrategy).

The disconnect() call on Session results in logonSent being set to false in SessionState. If this happens before SingleThreadedEventHandlingStrategy calls next(Message) on the Session object, the logout message will subsequently throw a SessionException in validLogonState() (as logonSent is now false). And the message will not reach the application.

This is problematic in the scenario where an ECN is informing us in a logout message of an issue with sequence numbers. The message is not received and the appropriate action can't take place,

This is an example of the occurrence from our logs with Reuters:

20140731-10:44:42.662 INFO [SocketConnectorIoProcessor-1.0] quickfix.Session - [XXX/YYY->TR MATCHING/FXM] Disconnecting: IO Session closed
20140731-10:44:42.663 ERROR [QFJ Message Processor] quickfixj.errorEvent - XXX/YYY->TR MATCHING/FXM: quickfix.SessionException Logon state is not valid for message (MsgType=5)

One possible suggestion would be to check the EventHandlingStrategy queue size and delay the sessionClosed call if there are outstanding events.

E.g. in InitiatorIoHandler

@Override
public void sessionClosed(IoSession ioSession) throws Exception {
while (eventHandlingStrategy.getQueueSize() > 0) {
log.info("Delaying sessionClosed while " + eventHandlingStrategy.getQueueSize() + " event(s) "
+ "are processed");
try

{ Thread.sleep(500); }

catch (InterruptedException e)

{ log.warn("sessionClosed dealy was interrupted"); }

}
super.sessionClosed(ioSession);
}

Perhaps there are better approaches. Is this a known race condition?



 Comments   
Comment by Christoph John [ 31/Jul/14 ]

Hi, thanks for the report. This sounds similar to QFJ-790.

Comment by Glyn Walters [ 31/Jul/14 ]

Hi, yes indeed, we're describing the same issue I believe. His proposal of having the event handler informed of the end of stream, or the approach of having the mina thread wait, to give the event handling queue to empty both would seem to be possible approaches.

Comment by Glyn Walters [ 31/Jul/14 ]

Try to phrase that a bit better: -edit "to give the event handling queue a chance to empty, would both seem possible approaches"

Comment by Christoph John [ 27/Oct/14 ]

I closed this as duplicate. Moreover, the approach from QFJ-790 will be followed. During tests it showed that waiting in the sessionClosed callback made the engine lock in some cases which got resolved after the Logout timeout. This is due to the fact that two threads want to access the ResponderSync object.





[QFJ-803] Case spelling inconsistency among FIX dictionaries Created: 26/Jul/14  Updated: 21/Jul/15  Resolved: 21/Jul/15

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

Type: Improvement Priority: Minor
Reporter: ManuReno Assignee: ManuReno
Resolution: Fixed Votes: 0
Labels: None


 Description   

Mismatch in case spelling among fix dictionaries result in duplicates in messages-all.jar :

quickfix/field/IOIID.class
quickfix/field/IOIid.class

quickfix/field/LegUnitOfMeasure.class
quickfix/field/LegUnitofMeasure.class

quickfix/field/UnderlyingUnitOfMeasure.class
quickfix/field/UnderlyingUnitofMeasure.class

quickfix/field/UnitofMeasure.java
quickfix/field/UnitOfMeasure.java






[QFJ-802] mvn message module : cut circular dependancy w/ core + merge sub-modules Created: 16/Jul/14  Updated: 12/Aug/14

Status: Open
Project: QuickFIX/J
Component/s: Build
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: ManuReno Assignee: ManuReno
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File quickfix.test.acceptance.AcceptanceTestSuite.txt     Text File quickfixj-messages-all-jar-before-after.txt     Text File quickfixj-messages-all-src-before-after.txt    

 Description   

Core module currently depends on resources located in the messages modules (hidden dependancy), while messages module depend on core module (explicit dependancy).
This prevent from importing in Eclipse IDE without manual operations.

The object of the ticket is to check if :

  • Dependancy can be declared such as core depends on messages, while cutting dependancy from messages to core
  • Make one single message mvn module


 Comments   
Comment by Christoph John [ 17/Jul/14 ]

Hi, we already have QFJ-782 but it does not have very much description.
Do you see any advantage in having one single message module?

Comment by ManuReno [ 20/Jul/14 ]

I thought about 1 single message module since :

  • the quickfix.Message class rely on generated code not present in all FIX dictionaries
    quickfix.Message class uses SessionRejectReason which is not available in FIX40 nor FIX41
    throw new FieldException(SessionRejectReason.TAG_APPEARS_MORE_THAN_ONCE, field.getTag());
    
  • While the FIX-generated classes (even FIX40 and FIX41) all depend back on this Message class.

This looks like using the jar quickfixj-msg-fix40.jar would require quickfixj-core.jar (for the Message class) and quickfixj-msg-fix42.jar or later (for the SessionRejectReason class) on its classpath.
Considering that all jars seems required everytime, why not one single jar with all messages in it ?...

When trying this I faced a compilation issue : it all the FIX-generated classes couldn't be compiled together in my environment (OOM error during compilation whatever the max heapsize, either on Java6 or Java7 JDK ) when FIX50-SPxx are present.
BTW one can see that all FIX dictionaries but FIX50-SPxx are generated and compiled in the core module so I guess that someone else has already faced the issue...

Maybe the message modules should be kept, but while ensuring that the classes used by the generated code are not using back this generated code (namely DataDictionary, DataDictionaryProvider, FieldMap, Message, MessageUtils, SessionID, SessionRejectReasonText classes).

Comment by ManuReno [ 26/Jul/14 ]

Difference in the quickfixj-messages-all artifacts before and after the build structure change

Comment by ManuReno [ 26/Jul/14 ]

A pull request is available for the change related to this ticket.

In attachement of this Jira are listed the differences in the quickfixj-messages-all artifacts that result from the build structure change.

It is not possible to use anymore standalone quickfixj-messages-[fix40|fix41|fix42|fix43|fix44].jar files.
But due to the circular dependancies described above, I guess this was a bit risky anyway (if somehow possible).
If you think this makes an issue, let me know.

The mvn artifact structure is now explicitely described in the POMs and the build is also faster.

Tests pass on my machine except 2 of them for which it looks there is a race condition (sometimes 4 are failing, sometime 2 or 3...) even after a clean checkout
The failures are attached, BTW I'm interested by a tip to make them pass.

Comment by Christoph John [ 07/Aug/14 ]

Sorry, did not find time to review the pull request yet.
I have some questions:

  • You say it is not possible to use the fix4* standalone files. What about the fix5* files?
  • Are always the 19b_PossResendMessageThatHasNotBeenSent.def tests failing or also others?
    How do the exchanged messages for these tests look like? When the tests expects a NewOrderSingle but gets only a Heartbeat it seems either like the Session did not recognize the NewOrderSingle or it has not been sent and the Session is simply heartbeating.
Comment by ManuReno [ 12/Aug/14 ]

Hi Christoph

After reviewing all, the potential issue (conflicting field classes) can be worked around if the core module is first on the classpath.
There may be other options with less impact on the build to deal with that : please don't review the pull request yet, I'll think about something else and let you know.





[QFJ-801] Validation fail on ClassCastException if using XML Created: 14/Jul/14  Updated: 14/Jul/14

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Benoit Xhenseval Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: validation
Environment:

Mac OSX


Attachments: Java Source File IOIValidation.java    

 Description   

It appears that the Message validation fails on a ClassCastException if the message contains the XmlDataLen tag.

Example:
https://gist.github.com/benoitx/e7da15dba9da133ac7b9

It seems that the validation code only expects StringField but the XmlDataLen is an IntField.

The output is:

Testing WITHOUT XML
8=FIXT.1.19=7935=649=Sender56=Target15=USD22=523=IOD-127=M28=N48=IBM.N54=255=IBM.N10=079
Testing WITH XML
8=FIXT.1.19=10335=649=Sender56=Target212=12213=<a>Hello</a>15=USD22=523=IOD-127=M28=N48=IBM.N54=255=IBM.N10=086
Exception in thread "main" java.lang.ClassCastException: quickfix.field.XmlDataLen cannot be cast to quickfix.StringField
	at quickfix.DataDictionary.iterate(DataDictionary.java:668)
	at quickfix.DataDictionary.validate(DataDictionary.java:653)
	at quickfix.DataDictionary.validate(DataDictionary.java:624)
	at quickfix.DataDictionary.validate(DataDictionary.java:606)
	at fixfun.IOIValidation.validateIoi(IOIValidation.java:45)
	at fixfun.IOIValidation.validateIoiWithXml(IOIValidation.java:37)
	at fixfun.IOIValidation.main(IOIValidation.java:78)


 Comments   
Comment by Benoit Xhenseval [ 14/Jul/14 ]

test case.

Comment by Christoph John [ 14/Jul/14 ]

It turned out that the setField( int, Field<?> ) method should rather not be used with non-String tags. Rather use setField( Field ), e.g.:
ioi.getHeader().setField(new XmlData(xml));
ioi.getHeader().setField(new XmlDataLen(xml.length()));

Of course, there should be means to prevent your original error. Either setField( int, Field<?> ) should convert the values (as setField( Field ) does) or the validate-method should not assume that all fields are Strings.





[QFJ-800] jar signing issue with quickfixj-all-1.5.3.jar Created: 10/Jul/14  Updated: 02/Apr/15  Resolved: 11/Jul/14

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

Type: Bug Priority: Default
Reporter: Hemlata Singh Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

windows and linux


Attachments: JPEG File Capture.JPG    

 Description   

getting error while signing the jar.
command used:
jarsigner -keystore calypsoJAWS.key -storepass calypso quickfixj-all-1.5.3.jar calypso

ERROR :
jarsigner: unable to sign jar: java.util.zip.ZipException: duplicate entry: FIX40.xml

Tactical fix : Resolved by removing duplicate xml files.



 Comments   
Comment by Christoph John [ 10/Jul/14 ]

I cannot see any duplicate FIX40.xml in the jar. Where did you find them?

Comment by Hemlata Singh [ 10/Jul/14 ]

multiple xml files.

Comment by Hemlata Singh [ 10/Jul/14 ]

Please find attached screenshot.

Comment by Christoph John [ 10/Jul/14 ]

That is very strange. When I look at the archive with "ark" I do not see any duplicate entries but when I list the archive entries with "jar tfv <file>" then there are multiple entries for the xml files.
But I do not know how this is even possible since the duplicates are located in the same directory?

Anyways, I was able to sign quickfixj-all-1.6.0-SNAPSHOT.jar successfully. So I'd like to close this issue.

Comment by Hemlata Singh [ 10/Jul/14 ]

Hey Christoph,

From where can i download quickfixj-all-1.6.0.jar?
Thanks in advance.

Comment by Christoph John [ 10/Jul/14 ]

Hi, you can download it here: http://www.quickfixj.org:8085/browse/QFJ-GIT/latest/artifact/shared/qfj-zip/
It is still no final release. But should hopefully be released soon

Comment by Hemlata Singh [ 10/Jul/14 ]

My google chrome is not able to connect to www.quickfixj.org:8085.
Is there any other way i can get that jar.

Comment by Christoph John [ 10/Jul/14 ]

I guess some firewall is blocking access. Maybe you could try downloading it outside of a company network? I am not aware that the access to that page is restricted.

Comment by Hemlata Singh [ 10/Jul/14 ]

How can you close the jira without giving me any solution?
I can take use quickfixj-all-1.6.0.jar unless its released.

Requesting you to provide me some solution with quickfixj-all-1.5.3.jar

Comment by Christoph John [ 10/Jul/14 ]

The solution to the issue would be to use 1.6.0 once it is released.
quickfixj-all-1.5.3 was build a long time ago and I do not see any chance or sense in altering it now. But of course you are free to unpack/repack the JAR as you desire.





[QFJ-799] SessionTest : Assertion failure as a side effect of previous sessions not being closed Created: 05/Jul/14  Updated: 02/Apr/15  Resolved: 08/Jul/14

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

Type: Other Priority: Default
Reporter: ManuReno Assignee: ManuReno
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows 7-SP1, JDK 1.6.0_45, Eclipse Luna, Maven 3.2.2



 Description   

SessionTest test cases fail in my environment (assertion failure on sequence number not being as expected)
This looks like the consequence of previous session file store not being deleted prior to running the test case. These file store can't be deleted unless the previous session used for test has been closed.
Since the session is a Closeable, I guess it should be closed at the end of each test case: by doing so tests run successfully every time.



 Comments   
Comment by ManuReno [ 05/Jul/14 ]

A pull request is available for this Jira, please let me know.

Comment by Christoph John [ 08/Jul/14 ]

I have merged the pull request. Thank you.





[QFJ-798] Refactor Session construction in test code Created: 13/Jun/14  Updated: 13/Jun/14

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Andrzej Hajderek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently to create some of the Session related test cases it is necessary to use constructs like this:

Session session = new Session(new UnitTestApplication(), new MemoryStoreFactory(),
sessionID, null, null, new ScreenLogFactory(true, true, true),
new DefaultMessageFactory(), isInitiator ? 30 : 0, false, 30, true, resetOnLogon,
false, false, false, false, false, true, false, 1.5, null, validateSequenceNumbers,
new int[]

{ 5 }

, false, disconnectOnError, false, true, false, true, false, null,
true, 0, false, false);

This kind of code turns from an asset into a liability pretty quickly, so the sooner it is rationalised the better. The Session constructor itself isn't very pretty either with its 30+ parameters.






[QFJ-797] Add a clean and safe mechanism to disconnect a session from within a call-back Created: 13/Jun/14  Updated: 13/Jun/14

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Andrzej Hajderek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi,

There is currently no clean and safe mechanism to completely stop and disconnect a session from within a call-back (e.g. when processing an incoming message inside fromApp()) with the effect that the session is immediately disconnected, no reject messages are sent back to the counter-party and no change to the session store is made.

Such a mechanism is useful for implementing failure handling scenarios, e.g. when a target database becomes suddenly unavailable, or the application needs to be shutdown in emergency. In such cases it's best to close the TCP socket immediately and keep the session state unchanged.

One could try to use something like SocketInitiatior.stop(true), but it's not generic (does not work for acceptors) and it results in a call to Session.disconnect(). Then, if Session.disconnect() is called from fromApp(), we get an immediate call to the onLogout() callback - a call is made from within the fromApp() call-back into the onLogout() call-back. This isn't a particularly safe scenario, especially when in most cases the onLogout() call is made by from QuickFIX/J threads.

Another solution is to throw a RuntimeException within the call-back method, but it's not reliable right now (QFJ-793, QFJ-795) and makes QuickFIX/J send an error message and the stack trace into the log.

I propose to add a special a subclass of RuntimeException, e.g. DisconnectSessionExcepion, which when thrown from a call-back method would notify QuickFIX/J that the session should be disconnected immediately. In such case only an informational message would be send to the log instead of error with a stack trace.

Regards,
Andrzej Hajderek






[QFJ-796] There is no mechanism to clear or update the data dictionary cache Created: 13/Jun/14  Updated: 13/Jun/14

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

A data dictionary file loaded into memory is cached without any option to reload the file after its contents has been updated. Worse - it's not even possible to clear the cache. This means that in order to use an updated data dictionary it is necessary to restart the application.

See: quickfix.DefaultSessionFactory.dictionaryCache






[QFJ-795] "MsgSeqNum too high" should not be an error Created: 13/Jun/14  Updated: 02/Apr/15  Resolved: 18/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: File SessionTest.java.qfj-795    

 Description   

Hi,

When QuickFIX/J receives a message with sequence number higher than expected it treats is as an error. For example:

<20140613-11:59:37, FIX.4.4:SENDER->TARGET, error> (MsgSeqNum too high, expecting 1 but received 101: 8=FIX.4.49=6635=B34=10149=TARGET52=20140613-11:59:3756=SENDER148=Headline10=005)

Not only an error message is logged, but also the internal logic will disconnect the counter-party, if DisconnectOnError=Y.

I believe this logic needs to be reviewed. According to the FIX protocol it is not an error to send/receive a message with too high sequence number. A too high sequence number should simply trigger a ResendRequest in order to retrieve the missing messages, which of course QuickFIX/J does.

There is a significant difference between receiving a message with too low sequence number and too high sequence number. While the first type of event is an error according to the FIX protocol, the second one isn't.

The "MsgSeqNum too high" should be an informational message, or arguably, a warning message - not an error message.

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 13/Jun/14 ]

The attached test demonstrates that reception of a message with too high sequence number disconnects the session. The session should not be disconnected because reception of a sequence number that is higher than expected is not an error. It is merely a reason to initiate the resend process.





[QFJ-794] Misleading message logged when RuntimeException thrown within a call-back: "Rejecting message: ..." Created: 12/Jun/14  Updated: 23/Aug/16

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This is in relation to QFJ-793.

When both settings RejectMessageOnUnhandledException and DisconnectOnError are set to Y and a RuntimeException is thrown within a call-back, QuickFIX/J will write to the log output messages like below:

<20140612-16:25:06, FIX.4.4:SENDER->TARGET, error> (Rejecting message: java.lang.RuntimeException: ... (with more details and the message)

2014-06-12 18:25:06 quickfix.Session disconnect

INFO: [FIX.4.4:SENDER->TARGET] Disconnecting: Auto disconnect

This is misleading because nothing is actually rejected (no reject message is sent back to the sender). The session is simply disconnected. I believe a slightly different wording should be used for this scenario, e.g "Failed to process message" instead of "Rejecting message".






[QFJ-793] When RuntimeException is thrown within a call-back and DisconnectOnError=Y the session does not get disconnected automatically Created: 12/Jun/14  Updated: 23/Aug/16

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File SessionTest.java.add     File SessionTest.java.add.fixed    

 Description   

Hi,

When a RuntimeException is thrown within a call-back and the "DisconnectOnError" parameter is set to "Y" the session does not get disconnected automatically unless the "RejectMessageOnUnhandledException" parameter is also set to "Y". This dependency is not documented, but even if it was, it wouldn’t make too much sense.

It seems to be logical to understand an occurrence of a RuntimeException within a call-back as an error condition on its own, which should be sufficient to trigger the disconnection logic dictated by the "DisconnectOnError" parameter (regardless of any other settings).

Currently, if RejectMessageOnUnhandledException=N, the engine simply ignores the message for which the exception was thrown even though DisconnectOnError=Y (although it reports the exception as an “error” in the log).

Test code attached.

Please note that probably all call-backs exhibit the same behaviour, not just the fromApp() call-back used in the TestApp class. It is also possible that the “ResetOnError” parameter is treated in a similar manner.

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 13/Jun/14 ]

Attached a fixed version of the test.





[QFJ-792] Wrong order of fields in a repeating group makes the group ignored Created: 10/Jun/14  Updated: 27/Jul/17  Resolved: 13/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.4

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: File MessageTest.java.diff     Text File MessageTest.java.patch    
Issue Links:
Relates
relates to QFJ-770 Message fromString don't report about... Closed

 Description   

Hi,

Another issue related to repeating groups in the message parsing logic. If two fields within a repeating group are in different order than expected the entire repeating group is ignored. The parsed message does not contain the ignored repeating group.

The better approach would be to process the repeating group regardless of the order of fields or to report and error in order to signal the wrong order (assuming ValidateUnorderedGroupFields=Y).

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 10/Jun/14 ]

Unit test attached.

Comment by Andrzej Hajderek [ 10/Jun/14 ]

Possibly related to QFJ-770.

Comment by Or Ming Chun [ 03/Mar/16 ]

I have the same issue too. When the incoming message contains unordered group fields, even if I set the ValidateUnorderedGroupFields=N and RejectInvalidMessage=N, the parsed message does not contain the repeating group. Here is the logs:

{{<20160303-04:55:18, FIX.4.4:HXFAKEMD->HXFAKE, incoming> (8=FIX.4.49=12135=V34=249=HXFAKE52=20160303-04:55:18.88256=HXFAKEMD262=4001263=1264=0265=0146=148=400122=8267=2269=0269=110=107)
<20160303-04:55:18, FIX.4.4:HXFAKEMD->HXFAKE, error> (Warn: incoming message with missing field: 48: Out of order repeating group members, field=48: 8=FIX.4.49=9035=V34=249=HXFAKE52=20160303-04:55:18.88256=HXFAKEMD146=1262=4001263=1264=0265=010=201)}}

You can see the group in the parsed message has been "eaten" and I can do nothing in the Application.fromApp callback. I am not really sure the issue is related to the ValidateUnorderedGroupFields setting or other issues. I have attached a patch of tests to showcase the issue.
MessageTest.java.diff

The related issue are:
QFJ-770, QFJ-647, QFJ-548, QFJ-535

Comment by Christoph John [ 07/Mar/16 ]

I think there are two sides to this: I agree with you that the parsing logic should not fail if there are group fields out of order.
However, IMHO this must not be true in case where the first field of the repeating group, a.k.a. the delimiter, is missing. Then there are no means for QFJ to find out where a new repeating group starts. If you change your test to NOT leave out the delimiter field and change some other fields of the group AND set ValidateUnorderedGroupFields to false, then the test should pass.





[QFJ-791] An unexpected field in a repeating group makes QuickFIX/J fail to detect the number of repeating groups correctly Created: 10/Jun/14  Updated: 27/Jul/17  Resolved: 05/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.4

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File MessageTest.java.patch    
Issue Links:
Duplicate
is duplicated by QFJ-909 Unexpected Behaviour for ValidateInco... Closed
Relates
relates to QFJ-169 Message parsing fails on messages wit... Closed

 Description   

Hi,

When an unexpected tag (a tag not defined in the data dictionary) is present in a repeating group QuickFIX/J fails to detect the number of repeating groups correctly. For example in the following message the unexpected tag 58 is present at the end of the first leg (600, 687, 654, 566, [58]):

8=FIX.4.4 9=233 35=AE 34=1 49=SENDER 52=20140610-15:04:53.377 56=TARGET 31=5.6789 32=1000 60=20140610-15:04:53.367 75=20140101 570=N 571=ABC1234 555=2 600=L1-XYZ 687=333 654=ABC1234-L1 566=1.2345 58=TXT1 600=L2-XYZ 687=777 654=ABC1234-L2 566=2.3456 10=017

With tag 58 in the first leg, the number of repeating groups detected by QuickFIX/J message parser will be 1 (incorrect)!
Remove tag 58 from the first leg and QuickFIX/J will sees the number of repeating groups for as 2 (correct).

This is very dangerous because it makes a QuickFIX/J applications very sensitive to changes in repeating groups. For example, when a trading platform decides to add a new tag to the repeating group, an existing application will fail completely because of the incorrect number of repeating groups detected. Instead the application should simply ignore the new tag, especially when AllowUnknownMsgFields=Y.

Of course when the new tag is added to the data dictionary this problem will not occur, however, the current behaviour of the repeating group parsing logic is inconsistent with the message body parsing logic, inconsistent with the configuration (AllowUnknownMsgFields=Y) and generally counter-intuitive.

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 10/Jun/14 ]

Unit test attached.

Comment by Christoph John [ 05/Apr/17 ]

Fixed together with QFJ-169 as there were some overlaps.





[QFJ-790] Logout message not propagated to the fromAdmin() callback Created: 09/Jun/14  Updated: 22/May/15  Resolved: 07/Dec/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Java Source File LostLogoutTest.java    
Issue Links:
Duplicate
is duplicated by QFJ-566 Incoming Logout message doesn't go to... Closed
is duplicated by QFJ-804 Race condition between sessionClosed ... Closed

 Description   

Hi,

A QuickFIX/J based application may miss a Logout request message, if the sender closes the socket shortly after sending the Logout request message. As result the application may lose important information about the reason of disconnection.

Most likely the reason of such behaviour of QuickFIX/J is such that the QFJ Message Processor stops processing queued messages as soon as it detects hasResponder() == false, which may happen even, if the input queue contains messages (or merely the Logout message). Basically the more loaded the receiver's machine is (in terms of CPU/IO) the more likely it is that it misses the Logout message.

Please note that even though the fromAdmin() callback is not called in such cases, the onLogout() is always called (because of the the closed socket). However, multiple occurrences of the same sender-side series of events (Logout + socket close) will lead to two different receiver-side behaviours on a random basis. In some cases the receiver will see the proper fromAdmin() callback and the onLogout() callback, while in some cases it will see only the onLogout() callback (triggered by socket close rather than by the incoming Logout message).

This has been an issue since 1.0.x, but only now I found some time to write a proper test.

Test code attached.

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 09/Jun/14 ]

If the delay code is removed from the Server.fromApp() method the Logout message will be received correctly in many cases, but it's not guaranteed. The test code is written in such a way that the server always misses the message, but the probability of missing the Logout message is really a function of the delay value within Server.fromApp(). In other words - the more time is spent it Server.fromApp() the more likely it is that the server misses the Logout message.

Comment by Christoph John [ 16/Oct/14 ]

Hi Andrzej, finally I found some time to look at your test. I tested this with 1.6.0-SNAPSHOT and the problem seems to be that the Logout message is received but discarded by Session.isValidLogonState() since it is a Logout message but the session is already disconnected. Fixing that method should be minimal effort but of course your test is highlighting a bigger problem (similar to QFJ-804, QFJ-810). Will take a look at those tickets.





[QFJ-789] Fully support alternate encodings (charsets) Created: 09/Jun/14  Updated: 24/Nov/18

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.6.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: amichair Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-956 Checksum validation of incoming messa... Closed
Relates
is related to QFJ-684 Support for binary data (BytesField) ... Closed
is related to QFJ-38 FIX Message support double-byte charset. Closed
is related to QFJ-382 Foreign Language Support - Multibyte ... Closed

 Description   

QuickFIX/J currently has limited support for alternate encodings (charsets). While it is 'good enough' for some cases, it still has drawbacks - it is limited to charsets that are a superset of ASCII (in particular, double-byte encodings are not supported), the encoding can only be set globally via CharsetSupport and applies to all fields (which can generate non-compliant messages), the engine still uses Strings for the most part with some awkward and inefficient handling to make it properly support encoded bytes, etc.

It would be better to have proper encoding support all around - with ASCII used for all standard fields, the MessageEncoding field used per-message to specify the encoding used in its Encoded* fields (e.g. EncodedText), using bytes array (or ByteBuffer) instead of Strings for more efficient and direct manipulation, supporting arbitrary charsets (not only ASCII supersets), etc.

Suggestions, additional related requirements and protocol-compliance corrections are welcome.






[QFJ-788] StackOverflowError still an issue when processing larger queues Created: 06/Jun/14  Updated: 02/Apr/15  Resolved: 06/Feb/15

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Major
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File SessionTest.java.patch    

 Description   

Hi,

QuickFIX/J fails regularly with the StackOverfloError when processing large queues (around 1000 messages or more - depending on Java stack size).

A typical scenario:

  • Client sends a ResendRequest to server
  • Server is slow in delivering old messages, but keeps sending real-time messages quickly
  • The queue builds up quickly
  • After the last old message is resent by server the client starts processing the queue using recursion and it fails with the StackOverflowError.

This is reproducible with trunk revision #1187. Test code attached.

Regards,
Andrzej Hajderek



 Comments   
Comment by Christoph John [ 06/Jun/14 ]

Hi Andrzej, thanks for the good test, really appreciated. Saves a lot of time.

Comment by Andrzej Hajderek [ 06/Jun/14 ]

Please note that for smaller queues the test passes correctly. Only larger queue sizes cause problems.

The same issue can be reproduced in a real-world scenario, when a large backlog of messages (say 100k messages) is present on the server. The client is in the process of retrieving the entire backlog with a relatively small chunk size (say 500) and it is not very quick at processing the responses. It takes certain amount of time to process the backlog (say 15 minutes). During that time the server keeps sending new real-time trades to the client. These new real-time trades get queued. After the processing of the backlog is completed QuickFIX/J blows up with the StackOverflowError.

The test code I attached represents the minimal scenario for reproducing the issue effectively.

Comment by Christoph John [ 25/Dec/14 ]

Hi Andrzej, I have introduced a flag into the next(Message) method whether a queue is currently processed and if that is the case, the nextQueued() method is not entered. That way, the nextQueued(Message, String) method will not recursively be called.

# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- HEAD
+++ Modified In Working Tree
@@ -875,10 +875,7 @@
         return state.getMessageStore();
     }
 
-    /**
-     * (Internal use only)
-     */
-    public void next(Message message) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
+    private void next(Message message, boolean isProcessingQueuedMessages) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
             IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage {
 
         if (message == EventHandlingStrategy.END_OF_STREAM) {
@@ -1094,12 +1091,24 @@
             }
         }
 
+        // QFJ-788: prevent StackOverflow on large queue
+        if (!isProcessingQueuedMessages) {
         nextQueued();
         if (isLoggedOn()) {
             next();
         }
     }
+    }
 
+    /**
+     * (Internal use only)
+     */
+    public void next(Message message) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
+            IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage {
+
+        next(message, false);
+    }
+
     private boolean resetOrDisconnectIfRequired(Message msg) {
         if (!resetOnError && !disconnectOnError) {
             return false;
@@ -2256,7 +2265,7 @@
     private void nextQueued(Message msg, String msgType) throws InvalidMessage, FieldNotFound, RejectLogon,
             IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType, IOException {
         try {
-            next(msg);
+            next(msg, true);
         } catch (final InvalidMessage e) {
             final String message = "Invalid message: " + e;
             if (MsgType.LOGON.equals(msgType)) {

Do you think that this solution is sufficient?
Thanks,
Chris.





[QFJ-787] OrderMassActionRequest (CA), OrderMassActionReport (BZ) Created: 05/Jun/14  Updated: 05/Jun/14  Resolved: 05/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Muhammad Rashad Irshad Khan Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-735 in quickfixj-v1.5.3, I cannot find 'O... Closed

 Description   

Do we have OrderMassActionRequest.java as I cannot use it in my FIX client for FIX5 SP1.
Please help me in this matter.



 Comments   
Comment by Muhammad Rashad Irshad Khan [ 05/Jun/14 ]

Thanks





[QFJ-786] First three fields getting truncated when converting from string to message using Message constructor Created: 03/Jun/14  Updated: 02/Apr/15  Resolved: 12/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Critical
Reporter: raghuram potluri Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

windows



 Description   

when using below code sinppet either first or second or third tag getting truncated.

scenario 1:
public class TestMessage {

public static void main(String[] args) {
String st = "35=D12=0.00000113=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.000";

quickfix.Message msg;
try

{ msg = new Message(st,false); System.out.println("original message"+st); System.out.println("quickfixj message"+msg); }

catch (InvalidMessage e)

{ // TODO Auto-generated catch block e.printStackTrace(); }



}

}
Output =
original message 35=D12=0.00000113=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.000
quickfixj message 9=13612=0.00000113=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.00010=232
First tag 35=D which was present in original string is missing after converting to message.

Scenario 2:
public class TestMessage {

public static void main(String[] args) {
String st = "8=FIX4.29=11012=0.00000113=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.000";

quickfix.Message msg;
try { msg = new Message(st,false); System.out.println("original message "+st); System.out.println("quickfixj message "+msg); } catch (InvalidMessage e) { // TODO Auto-generated catch block e.printStackTrace(); }

}

}
Output:
original message 8=FIX4.29=11012=0.00000113=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.000
quickfixj message 8=FIX4.29=12413=215=HKD21=222=538=300040=148=2318.HK54=255=2318.HK58=<AP9211WDAM><USU><CHK> namke59=060=20140507-11:10:02.00010=182

Now you can see third tag which is 12=0.000001 is truncated.



 Comments   
Comment by Christoph John [ 04/Jun/14 ]

I think it is quite hard to parse a message that is incomplete, e.g. the header is missing required fields. After adding all required header and trailer fields you could try to do the following:
new Message(st, dd, false)

Where dd is a DataDictionary which is applicable to your used FIX version.

Comment by Christoph John [ 05/Jun/14 ]

If you have further questions, please use the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Comment by raghuram potluri [ 05/Jun/14 ]

John,
definitely this is a bug coz this is not what happening when we are using quickfix for .net.
string message ="1=03100631~11=140605JWI4440~15=USD~21=1~35=D~38=6~40=1~47=A~54=1~55=UNP~59=0~60=20140605-13:58:51.016~63=0~79=03100631~336=1~377=N~581=A~6020=COMPUS~86028=JWI~86029=4440~";

message = message.Replace( '~', ( char )1 );

Console.WriteLine(message);

QuickFix.Message msg = new QuickFix.Message( message,false );

string newMessage = msg.ToString();

Console.WriteLine( newMessage );

Let us know if you would be able to resolve this ?

Comment by Christoph John [ 06/Jun/14 ]

QuickFIX/n is not QuickFIX/J. But I will take a look at it.

Comment by raghuram potluri [ 09/Jun/14 ]

Thanks John. Please let me know if you find anything.

Comment by Christoph John [ 12/Jun/14 ]

This is now fixed. When parsing the header the first three tags were checked for their correct position which meant that they were effectively skipped if they were not the expected header tags BeginString, BodyLength or MsgType.
This has now been changed to only check the first three fields if message validation is enabled.

Comment by raghuram potluri [ 16/Jun/14 ]

Thx John. Will test and let you know if I still see any issues.appreciate your quick repsonse on this issue.





[QFJ-785] Test jira jrjc issue Created: 27/May/14  Updated: 27/May/14  Resolved: 27/May/14

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

Type: Bug Priority: Minor
Reporter: Siva Tharun Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Comments   
Comment by Christoph John [ 27/May/14 ]

Hi, this JIRA is for recording bugs, not testing. Thanks.





[QFJ-784] quickfix.field package contains mix of various FIX versions Created: 26/May/14  Updated: 09/Jun/14

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: amichair Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Relates
is related to QFJ-781 Fix code generation for SP1/2 . Closed

 Description   

The FIX fields and messages classes are auto-generated from FIX spec xml files. Each FIX spec version has a corresponding jar created with its respective classes. The message package names contain the fix version (e.g. quickfix.fix44 package), so that a specific target version's messages can be used.

However, all field packages from all versions are simply named quickfix.field, so they cannot be targeted individually by code that needs them.

Worse, when all of these versioned packages are merged together into a single 'all' messages jar, the field classes overwrite each other in the quickfix.field package, which becomes a mix of classes from all versions. Seeing that the fields of newer versions are not entirely backwards-compatible with earlier versions (e.g. some field values/constants are renamed or removed), this package becomes compliant neither with the new versions or the old versions, and breaks existing client code when a new version is added (e.g. 5.0sp1/sp2) even if said code is intended to work only with and older spec version.

Worse still, the quickfix.field package is bundled not only in the quickfix-all jar but also in the quickfix-core jar, so they are not easily decoupled for users who want to select a specific target version jar to be used explicitly, or maintain a stable build unaffected by newer spec releases.

All these versions should ideally be decoupled from each other (and from core) in such a way that they can coexist in an application that must support multiple versions, and still remain compliant with each one of them independently.

These changes require additional research and have backward-compaibility implications. Currently the combined quickfix.field pakcage has the 5.0 spec classes trump all others (i.e. its classes take precedence when there are duplicates), to remain compatible with the previous release (even though new sp1/sp2 fields are added to the package as well).






[QFJ-783] Update documentation and website to reflect new project setup Created: 26/May/14  Updated: 02/Apr/15  Resolved: 02/Apr/15

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

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-597 move to github Closed
is related to QFJ-499 Modify build system to use Maven Closed

 Description   

Changes due to

  • Maven
  • github
  • update the documentation on how to run the examples (Banzai, Executor)
  • update the web site to point to the correct location for binary releases





[QFJ-782] Get rid of cyclic package dependencies Created: 15/May/14  Updated: 18/Sep/17

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 2.1-BETA

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Requires
requires QFJ-499 Modify build system to use Maven Closed




[QFJ-781] Fix code generation for SP1/2 . Created: 07/May/14  Updated: 02/Apr/15  Resolved: 09/Jun/14

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

Type: New Feature Priority: Default
Reporter: Carlos Assignee: amichair
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-735 in quickfixj-v1.5.3, I cannot find 'O... Closed
Relates
relates to QFJ-784 quickfix.field package contains mix o... Open

 Description   

Get the the generated code to have the new tags introduced by SP1 and SP2.



 Comments   
Comment by amichair [ 09/Jun/14 ]

FIX 5.0 SP1 and FIX 5.0 SP2 modules are now being built, but see also QFJ-784.





[QFJ-780] QuickFixJ behavior for Acceptance test fix42/1a_ValidLogonMsgSeqNumTooHigh.def looks incorrect Created: 01/May/14  Updated: 23/Aug/16

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Tarun Bahadur Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

QuickFixJ behavior for Acceptance test fix42/1a_ValidLogonMsgSeqNumTooHigh.def looks incorrect

After a resend request is received from server subsequent messages should be ignored unless SequenceReset is received or messages replayed. In below test case the logout message is sent with sequence number 6, this should actually be ignored by the server and the test case should fail. This would require fixing both QuickFixJ behavior and the test case(probably logout should have MsgSeqNum=1).

from fix42/1a_ValidLogonMsgSeqNumTooHigh.def
...
E8=FIX.4.29=5835=234=249=ISLD52=00000000-00:00:00.00056=TW7=116=410=0
I8=FIX.4.235=534=649=TW52=<TIME>56=ISLD
...



 Comments   
Comment by Christoph John [ 05/May/14 ]

This is related to the QF/J-specific behaviour to always accept a Logout message regardless of the sequence number. But it probably would not hurt to change this in order to be more in line with the FIX spec.





[QFJ-779] Standardize line endings Created: 01/May/14  Updated: 02/Apr/15  Resolved: 05/May/14

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

Type: Bug Priority: Default
Reporter: amichair Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Currently the source files (including xml files) have inconsistent line endings - some have LF and some CRLF. This makes it difficult to work with diffs/patches/merges/git-svn etc.

It would be best if you standardize on either LF or CRLF for everything (most source control systems standardize on LF in mixed environments, but it's up to you).

Among other solutions, you can use the 'file' utility to check the current state of files, and 'dos2unix' and 'unix2dos' to convert them.






[QFJ-778] Multi broker quickfix initiator side Created: 30/Apr/14  Updated: 05/May/14  Resolved: 30/Apr/14

Status: Closed
Project: QuickFIX/J
Component/s: Build, Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Other Priority: Major
Reporter: Cristian Manuel Vertiz Fernandez Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, session


 Description   

I need to implement a multi broker (x, y ,z) quickfix initiator side session with different dictionary specification.
The quickfix engine is built respect to xml fix dictionary and some fields are required for "x" and "y" broker an not for "z" broker, and so on.
Suggest me, what I can do?



 Comments   
Comment by Christoph John [ 30/Apr/14 ]

I think this is more a question for the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

But basically, you just need to open different sessions. Each session can have a data dictionary of its own. http://www.quickfixj.org/quickfixj/usermanual/1.5.3/usage/configuration.html#Sample%20Settings%20File

Comment by Cristian Manuel Vertiz Fernandez [ 30/Apr/14 ]

Thank you, but you mean something like:
[session]
BeginString=FIX.4.4
SocketConnectPort=10201
DataDictionary=..\config\FIX44.xml

But what about quickfixj classes definition into .jar file?, how do them behave when y create new instance.

But the problem is here :

FOR BROKER "X"
<?xml version="1.0" encoding="utf-8"?>
<fix major="4" type="FIX" servicepack="0" minor="4">
<header>
<field name="BeginString" required="Y" />
<field name="BodyLength" required="Y" />
...
<field name="OnBehalfOfCompID" required="N" />
<field name="DeliverToCompID" required="N" />

//Create Instance
quickfix.fix44.MarketDataRequest mdRequest =
new quickfix.fix44.MarketDataRequest(.... /Not required OnBehalfOfCompID and DeliverToCompID/);

FOR BROKER "Z"
<?xml version="1.0" encoding="utf-8"?>
<fix major="4" type="FIX" servicepack="0" minor="4">
<header>
<field name="BeginString" required="Y" />
<field name="BodyLength" required="Y" />
...
<field name="OnBehalfOfCompID" required="Y" />
<field name="DeliverToCompID" required="Y" />

//Create Instance
quickfix.fix44.MarketDataRequest mdRequest =
new quickfix.fix44.MarketDataRequest(.... /Required OnBehalfOfCompID and DeliverToCompID/);

Comment by Christoph John [ 05/May/14 ]

If you want to validate the message against a specific data dictionary then you should call dataDictionary.validate(Message)





[QFJ-777] Determine session's IP address Created: 15/Apr/14  Updated: 02/Apr/15  Resolved: 17/Apr/14

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

Type: Improvement Priority: Default
Reporter: Daniil S Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Really need a way of determining IP address for the session. This is especially useful for incoming sessions.



 Comments   
Comment by Christoph John [ 15/Apr/14 ]

Hi, could you please elaborate further on what you need? Do I understand correctly that you want to see the IP address of the counterparty? Is this QFJ-758?

Comment by Daniil S [ 15/Apr/14 ]

Its in similar area. We have a need to authenticate/restrict incoming sessions by source IP address. Either whole address or a regex. And its useful to have this for live debugging. I've modified (probably really badly) QFJ 1.3.3 to have method session.getRemoteIP() and will have to do similar with 1.6

Comment by Christoph John [ 15/Apr/14 ]

Hmm, but we have configuration AllowedRemoteAddresses since some versions already. Doesn't this work for you?

Comment by Daniil S [ 15/Apr/14 ]

Yes, but it won't take in regex.

Comment by Christoph John [ 16/Apr/14 ]

You could do a Session.getResponder().getRemoteIPAddress() which will return the address of the remote peer. Is this what you want.
We could also add a convenience method to the Session which returns that remote address.

Comment by Daniil S [ 17/Apr/14 ]

This does the job perfectly! I feel the need to point out how thorough this project is and that I simply don't spend enough time digging through it.

Comment by Christoph John [ 17/Apr/14 ]

Great, thanks for the feedback.
I've now added a convenience method anyway, since the indirection via Session.getResponder().getRemoteIPAddress() seemed a bit unnatural to me.

http://sourceforge.net/p/quickfixj/code/1181/

Comment by Daniil S [ 17/Apr/14 ]

Thanks, this would definitely be a great improvement. One note though, since you're using toString() method it will be a full address (/192.0.0.1:1111) not just an IP (192.0.0.1). This should be noted in a comment to avoid potential comparison problems (people may assume actual IP and not full address).

Comment by Christoph John [ 17/Apr/14 ]

Thanks for the info. Of course, you're right. I've changed the method name and comment to reflect this.





[QFJ-776] QuickFix/J Initiator fails to process messages without TargetCompID tag Created: 25/Feb/14  Updated: 02/Apr/15  Resolved: 27/Feb/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: exgorth Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File QFJ-776_-_TargetCompID_tag_checked_only_if_CheckCompID=true.patch    

 Description   

ASXTrade24 (SFE) gateways don't use TargetCompID in the messaging (they are always one-to-one connections) as described in http://www.asx.com.au/documents/trading_services/asx-trade24-developer-guide-fix-spec.pdf.
Therefore QuickFix/J initator rejects response from the gateway, even though TargetCompID was set not to be mandatory field on the message header in xml DataDictionary



 Comments   
Comment by Christoph John [ 25/Feb/14 ]

I think checking the data dictionary is a whole new topic. I guess we could check for the Sender/TargetCompID and only fail if CheckCompID=Y is set.
Would that be OK as a first step?

Comment by exgorth [ 25/Feb/14 ]

I'm adding a test case which fails on 1.5.3 if CheckCompID=M and TargetCompID isn't mandatory on dictionary. It shold pass after a fix.

I think the cleanest and less intrusive solution is to move SenderCompID/TargetCompID fields extraction from quickfix.Session#verify() to quickfix.Session#isCorrectCompID(), eg:
private boolean isCorrectCompID(Message message) throws FieldNotFound{
if (!checkCompID)

{ return true; }

Header header = message.getHeader();
final String senderCompID = header.getString(SenderCompID.FIELD);
final String targetCompID = header.getString(TargetCompID.FIELD);
return sessionID.getSenderCompID().equals(targetCompID)
&& sessionID.getTargetCompID().equals(senderCompID);
}

Thoughts?

Comment by Christoph John [ 25/Feb/14 ]

Sounds correct to me

Comment by Christoph John [ 25/Feb/14 ]

Just out of curiosity: but you do have a "dummy" TargetCompID set in your session configuration that you remove on outgoing messages?

Comment by exgorth [ 25/Feb/14 ]

I do have TargetCompID set on initiator, but receiver doesn't seem to care much (they ignore it i suppose).

Comment by Christoph John [ 27/Feb/14 ]

Committed as http://sourceforge.net/p/quickfixj/code/1137/
I have slightly simplified the unit test and proposed solution, hope that's OK for you.

Comment by exgorth [ 28/Feb/14 ]

Thanks Christoph.
1/ Test looks much neater
2/ isCorrectCompID() signature, to the extent of my familiarity with the QFJ API, would be more consistent with the rest of the checks if it accepted Message as a parameter (even though default implementation checks specifically header fields)

When are you planning 1.6.0 release? (i'm about to contribute another QFJ jira)

Comment by Christoph John [ 28/Feb/14 ]

It is a private method so I did not really care about the signature. But you are right, there are more methods which accept the general Message as parameter. So I think I will change it then.

Re 1.6.0 release: there is no real date set at the moment. There are still some things open which IMHO are needed for completion and are planned for a long time (e.g. QFJ-499). You could either build your own snapshot from trunk or check out the 1.5 branch and apply your changes there if you need it earlier. Hope that's OK for you.





[QFJ-775] FileStore: exception thrown when more than one : is used in SessionID Created: 15/Feb/14  Updated: 02/Apr/15  Resolved: 06/May/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Kosta Panousis Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: QuickfixJ, session
Environment:

Windows



 Description   

When only the SenderSubId or TargetSubId contain a : the engine starts fine. However, when both SendSubId and TargetSubId contain colons : an exception is thrown and teh engine does not start.

For example:
SenderSubID=ABC:ABC
TargetSubID=TEST

OR

SenderSubID=ABC
TargetSubID=TEST:TEST

start fine but the following fails with (The filename, directory name, or volume label syntax is incorrect):

SenderSubID=ABC:ABC
TargetSubID=TEST:TEST

It looks like a windows problem with the : in the file names but I was hoping that something could be done to the engine to replace the : internally or another work around. Unfortunately, exchanges like the CBOE require colons in both those fields.



 Comments   
Comment by Christoph John [ 17/Feb/14 ]

I guess there is no workaround. But it should be pretty simple to mask illegal characters when creating the file store.

Comment by Kosta Panousis [ 18/Feb/14 ]

It also looks as if this problem was fixed a few years ago. Maybe only the existence of a single : was fixed? In any case, this is preventing me from using QuickFIX with CBOE. If anyone knows a work around please let me know otherwise I have switch engines.

Comment by Christoph John [ 18/Feb/14 ]

Could you please post the issue number where this has been fixed?

Comment by Christoph John [ 19/Feb/14 ]

BTW, it should work if you remove the SenderSubID and TargetSubID from your session configuration and set them programatically on outgoing messages, i.e. in the callbacks toApp() and toAdmin() of your application.

Comment by Christoph John [ 06/May/14 ]

http://sourceforge.net/p/quickfixj/code/1186/





[QFJ-774] SendRedundantResendRequests seems to be ignored Created: 13/Feb/14  Updated: 14/Feb/14  Resolved: 14/Feb/14

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

Type: Bug Priority: Default
Reporter: Bill Igoe Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Linux.. Fedora 19
Testing with the CME



 Description   

Not sure if this is the right forum...but any help is appreciated as I have completed all the iLink test with the CME except for the handling if Resend Request.

below is my config

ConnectionType=initiator
ReconnectInterval=30
FileStorePath=/home/wigoe/FIX/messages
FileLogPath=/home/wigoe/FIX/logs
StartTime=00:00:00
EndTime=00:00:00
UseDataDictionary=Y
ValidateUserDefinedFields=N
ValidateFieldsHaveValues=N
ValidateIncomingMessage=N
DataDictionary=/home/wigoe/quickfixj/etc/cme/FIX42.xml

  1. standard config elements

[SESSION]

  1. inherit ConnectionType, ReconnectInterval and SenderCompID from default
    BeginString=FIX.4.2
    SenderCompID=9E8008N
    SenderLocationID=US,IL
    SenderSubID=Archi
    TargetCompID=CME
    TargetSubID=G
    SocketConnectHost****************
    SocketConnectPort=22101
    HeartBtInt=30
    SendRedundantResendRequests=N
    #PersistMessages=Y
    #SocketUseSSL=Y

Thest test proceeds as follows. I enter in one Limit order...works
I enter in a second order ....works
MY QF receives a resend request and responds with the resend the two orders....that is correct..

The CME ( being tricky) sends another Resend order
Even tho the the SendRedundantResendRequests=N

AND THE Event log say NOT sending another
QF sends a repeat...thus I fail the test.

here is the log

8=FIX.4.29=21135=D34=135149=9E8008N50=Archi52=20140213-15:05:25.94356=CME57=G142=US,IL1=TESTMA11=CME28721=138=1040=244=32157554=155=9159=060=20140213-15:05:25.898107=1NQM4167=FUT204=11028=Y1031=W9702=110=073
8=FIX.4.29=21135=D34=135249=9E8008N50=Archi52=20140213-15:05:33.96156=CME57=G142=US,IL1=TESTMA11=CME28821=138=1040=244=32157554=155=9159=060=20140213-15:05:33.960107=1NQM4167=FUT204=11028=Y1031=W9702=110=063
8=FIX.4.29=10235=234=69247369=135052=20140213-15:05:25.95949=CME50=G56=9E8008N57=ARCHI143=US,IL7=135116=010=072
8=FIX.4.29=23835=D34=135143=Y49=9E8008N50=Archi52=20140213-15:05:34.00656=CME57=G122=20140213-15:05:25142=US,IL1=TESTMA11=CME28721=138=1040=244=32157554=155=9159=060=20140213-15:05:25.898107=1NQM4167=FUT204=11028=Y1031=W9702=110=121
8=FIX.4.29=23835=D34=135243=Y49=9E8008N50=Archi52=20140213-15:05:34.00656=CME57=G122=20140213-15:05:33142=US,IL1=TESTMA11=CME28821=138=1040=244=32157554=155=9159=060=20140213-15:05:33.960107=1NQM4167=FUT204=11028=Y1031=W9702=110=111
8=FIX.4.29=10235=234=69248369=135052=20140213-15:05:33.98849=CME50=G56=9E8008N57=ARCHI143=US,IL7=135116=010=074
8=FIX.4.29=23835=D34=135143=Y49=9E8008N50=Archi52=20140213-15:05:34.10756=CME57=G122=20140213-15:05:25142=US,IL1=TESTMA11=CME28721=138=1040=244=32157554=155=9159=060=20140213-15:05:25.898107=1NQM4167=FUT204=11028=Y1031=W9702=110=123
8=FIX.4.29=23835=D34=135243=Y49=9E8008N50=Archi52=20140213-15:05:34.10756=CME57=G122=20140213-15:05:33142=US,IL1=TESTMA11=CME28821=138=1040=244=32157554=155=9159=060=20140213-15:05:33.960107=1NQM4167=FUT204=11028=Y1031=W9702=110=113
8=FIX.4.29=29535=834=69249369=135152=20140213-15:05:34.02349=CME50=G56=9E8008N57=ARCHI143=US,IL1=TESTMA6=011=CME28714=017=68279:117016620=037=6818357623338=1039=040=241=044=32157548=99816154=155=9159=060=20140213-15:05:34.022107=1NQM4150=0151=10167=FUT432=201402131028=Y1031=W10=064
8=FIX.4.29=29535=834=69250369=135252=20140213-15:05:34.03149=CME50=G56=9E8008N57=ARCHI143=US,IL1=TESTMA6=011=CME28814=017=68279:117016720=037=6818357623438=1039=040=241=044=32157548=99816154=155=9159=060=20140213-15:05:34.029107=1NQM4150=0151=10167=FUT432=201402131028=Y1031=W10=066
8=FIX.4.29=8035=034=135349=9E8008N50=Archi52=20140213-15:06:04.54856=CME57=G142=US,IL10=149
8=FIX.4.29=10535=134=69251369=135252=20140213-15:06:04.51049=CME50=G56=9E8008N57=ARCHI143=US,IL112=IDhrgedu9310=106
8=FIX.4.29=10535=134=69252369=135352=20140213-15:06:35.51449=CME50=G56=9E8008N57=ARCHI143=US,IL112=IDhrgedu9410=117

Any ideas?

Bill



 Comments   
Comment by Bill Igoe [ 13/Feb/14 ]

Forgot to mention I am using version 1.5.3

Comment by Christoph John [ 13/Feb/14 ]

This is no forum, this is the bug tracker. Please use mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-773] 'MessageStore.reset()' called extraneously outside session time window Created: 12/Feb/14  Updated: 02/Apr/15  Resolved: 16/Apr/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Tommy Hannon Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: MessageStore, Session


 Description   

The 'MessageStore.reset()' method is being called every second when beyond the session time window.

After reviewing the QF/J source code, the problem seems to be originating from the "QFJ Timer" thread calling 'Session.next()'. The following code appears at line 1748 of the 'quickfix/Session.java' class in QuickFIX/J 1.5.3 source code directory...

if (!checkSessionTime())

{ reset(); return; }

Due to the timer thread, this occurs every second for every session and can be quite resource intensive... especially if there is a substantial number of sessions defined that are not within the configured session start/end times.



 Comments   
Comment by Tommy Hannon [ 12/Feb/14 ]

It was suggested that the fix might be to check if the sequence numbers are both at 1 and suppress the reset if that is the case. Please consider how this might affect the session creation time that is saved in MessageStore.

Comment by Christoph John [ 12/Feb/14 ]

I tried to introduce the check for the sequence number and a couple of unit tests failed as a result. So need to check further how and why the session creation time is used.

Comment by Christoph John [ 21/Mar/14 ]

Hi Tommy, do you have any logic in your code which is using the creation time of the MessageStore? Or why should that be considered?
Thanks, Chris.

Comment by Tommy Hannon [ 28/Mar/14 ]

Hi, John. No, I do not have any logic referring to the creation time other than actually storing it. The reason I said to consider it is because the creation time may need to be stored even if the sequence numbers are both '1' (e.g. an acceptor session that has not connected during the configured session time). There may be other circumstances as well.

Comment by Christoph John [ 16/Apr/14 ]

Committed as http://sourceforge.net/p/quickfixj/code/1179/





[QFJ-772] NPE in DataDictionary::isTrailerField Created: 06/Feb/14  Updated: 02/Apr/15  Resolved: 19/Mar/14

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

Type: Bug Priority: Default
Reporter: Krzysztof Szalast Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: NullPointerException
Environment:

All



 Description   

In class DataDictionary: if expression "messageFields.get(TRAILER_ID)" returns null - NPE will be thrown.

I suggest to write this method just like isHeaderField method.

public boolean isTrailerField(int field) {
if (messageFields.get(TRAILER_ID) == null)

{ return false; }

return messageFields.get(TRAILER_ID).contains(field);
}



 Comments   
Comment by Christoph John [ 19/Mar/14 ]

http://sourceforge.net/p/quickfixj/code/1160/





[QFJ-771] Session and Settings JMX beans cannot be registered more than once. Created: 24/Jan/14  Updated: 23/Aug/16

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Vladimir Tsanev Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: jmx


 Description   

I need to register, unregister and then register again a Connector - but then the session and settings beans do not appear.

I looked at the source and the problem seems that the SessionJmxExporter's cache with registered sessionId's is not cleared.
ConnectorAdmin registers sessions only if they are not cached by sessionExporter - so the second time session do not show up.



 Comments   
Comment by Christoph John [ 03/Feb/14 ]

How do you register your connector? Can't you simply unregister it prior to re-registering it? Briefly looking at the code it seems there is no unregister method in class org.quickfixj.jmx.JmxExporter.
But shouldn't it work to unregister the connector by yourself by calling jmxExporter.getMBeanServer().unregisterMBean( objectName )?

Comment by Vladimir Tsanev [ 06/Feb/14 ]

I do call jmxExporter.getMBeanServer().unregisterMBean(objectName);.

I will expand on my problem. I need to be able to add and remove sessions at runtime. To achieve this a have a connector per session (there are other reasons that prevents me to use add/remove dynamic sessions, but I think the problem would still be present).
If I want a session to go away I just stop the connector and unregister the bean.
If I want a session to come back some time later I create new settings and new connector instance, but when the session id is the same the session does not show up.

It is because when I unregister the connector the sessionObjectNames map in SessionJmxExporter is still containing entry for my session id.

I think the corresponding entry in SessionJmxExporter.sessionObjectNames should be removed either in ConnectorAdmin.postDeregister or SessionAdmin.postDeregister.

What do you think?

Comment by Christoph John [ 12/Feb/14 ]

OK, I also see in ConnectorAdmin.registerSessions() that the session is only registered if it is not already contained in the sessionObjectNames map. So, yes, your proposed solution to remove the entry in one of the postDeregister() methods should be OK.

Comment by Yukun Song [ 05/Nov/14 ]

I am using a customized DynamicAcceptorSessionProvider in 1.5.3 to create dynamic session with my own session configs instead of the static SessionSettings. Even though I call sessionConnector.removeDynamicSession(sessionID) before sessionConnector.addDynamicSession(session), the previous session is not destroyed. The behaviour includes but not limited to 1) the session jmx doesn't work (i.e. any operation has no effect), 2) the new session thread doesn't own the file handlers of the session store files, so that client can't connect with ResetSeqnum on when logon.

Will the proposed solution solve this issue? Has the solution been added to version 1.6.0? Has anyone been involved in fixing this issue?

Comment by Christoph John [ 05/Nov/14 ]

This issue is currently only planned in to be fixed for 1.6.0 but has not been fixed yet. Could you possibly supply a test case?





[QFJ-770] Message fromString don't report about REPEATING_GROUP_FIELDS_OUT_OF_ORDER Created: 23/Jan/14  Updated: 27/Jul/17  Resolved: 13/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.4

Type: Improvement Priority: Minor
Reporter: Andrey Alekov Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: Message
Environment:

Windows 7.
Version: 6.1
Build: 7606 SP1

Eclipse.
Version: Juno Service Release 2
Build id: 20130225-0426


Issue Links:
Relates
is related to QFJ-792 Wrong order of fields in a repeating ... Closed

 Description   

When I tried to parse message from String I faced with not expected behavior of method Message.fromString()

Source message in Repeating group have unordered tags and values. Example are below.
SOH replaced to pipe (|)
String test = new String("8=FIX.4.4|9=16858|35=d|49=1|34=2|52=20140117-18:20:26.629|56=3|57=21|322=388721|323=4|320=1|393=42|82=1|67=1|711=1|311=780508|309=text|305=8|463=FXXXXX|307=text|542=20140716|436=10.0|9013=1.0|9014=1.0|9017=10|9022=1|9024=1.0|9025=Y|916=20140701|917=20150731|9201=23974|9200=17|9202=text|9300=727|9301=text|9302=text|9303=text|998=text|9100=text|9101=text|9085=text|9083=0|9084=0|9061=579|9062=text|9063=text|9032=10.0|9002=F|9004=780415|9005=780503|10=128|");

When call fromString I see parsed message without any error.
8=FIX.4.4|9=100|35=d|34=2|49=1|52=20140117-18:20:26.629|56=3|57=21|67=1|82=1|320=1|322=388721|323=4|393=42|711=42|10=156|

I checked Message.Exception and found next "Out of order repeating group members, field=916"

Well, I found what in Message.parse method (line Message.java:485) written exception but not raised.

} catch (final FieldException e)

{ exception = e; }

Please fix to raise InvalidMessage instead filling this.exception to case below.



 Comments   
Comment by Christoph John [ 13/Apr/17 ]

It is "normal" that the Message object tries to parse the FIX string with minimal validation. Validation is done later using dataDictionary.validate().
However, I will change the code to add the repeating group regardless of parsing errors (see QFJ-792). That way it is possible to at least have the repeating group set on the message (possibly with missing fields). You could then set some flags to have the message parsed anyway:

dictionary.setCheckUnorderedGroupFields(false);
dictionary.setCheckUserDefinedFields(false);
dictionary.setAllowUnknownMessageFields(true);

But please note that this has its limitations. If there are unknown group count fields for instance, then QFJ will never be able to parse the message since it does not know where a repeating group starts or ends.





[QFJ-769] Use both FileLogFactory and ScreenLogFactory Created: 17/Jan/14  Updated: 19/Jan/14  Resolved: 19/Jan/14

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

Type: Improvement Priority: Default
Reporter: Cristian Manuel Vertiz Fernandez Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: QuickfixJ, session


 Description   

Allow to SocketInitiator and SocketAcceptor use both log ways, FileLogFactory and ScreenLogFactory to major control.



 Comments   
Comment by Cristian Manuel Vertiz Fernandez [ 17/Jan/14 ]

For example this java code:

mdInputStream = new BufferedInputStream( new FileInputStream( new File( MD_CONFIG_FILE )));
SessionSettings mdSettings = new SessionSettings(mdInputStream);
mdInputStream.close();

LogFactory mdScreenLogFactory = new ScreenLogFactory(true, true, true, true);
LogFactory mdFilelogFactory = new FileLogFactory(mdSettings);

MessageFactory messageFactory = new DefaultMessageFactory();

mdInitiator = new SocketInitiator(mdApplication, mdMessageStoreFactory, mdSettings, mdFilelogFactory, mdScreenLogFactory, messageFactory);
mdInitiator.start();

Comment by Steve Bate [ 18/Jan/14 ]

You can create an implementation of the Log interface that does whatever you want, including logging to multiple Log implementations. You can also use the SLF4JLog with Log4J and configure Log4J to log to a file and to the console.





[QFJ-768] Improve FileLog.java so that Quickfix/j would produce different event&message log files. Created: 13/Jan/14  Updated: 13/Jan/14  Resolved: 13/Jan/14

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: macemers Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

For now Quickfix/j create event&message log files for each session, such as FIX.4.2-xxx_xxx-xxx.event.log & FIX.4.2-xxx_xxx-xxx.messages.log But it would be helpful if it create these log files on daily basis, like FIX.4.2-xxx_xxx-xxx.event-yyyyMMdd.log & FIX.4.2-xxx_xxx-xxx.messages-yyyyMMdd.log



 Comments   
Comment by Christoph John [ 13/Jan/14 ]

Isn't this something that can be configured in your used logging implementation, e.g. log4j?

Comment by Steve Bate [ 13/Jan/14 ]

I agree with Christoph. The FileLog is a basic logging component. If you want more complex logging behaviors, use the SLF4JLog which supports a variety of logging frameworks, some of which can log to files with dated file names.





[QFJ-767] StartTime/EndTime should be optional when NonStopSession=Y Created: 03/Jan/14  Updated: 02/Apr/15  Resolved: 06/Jan/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Nikitas Leogas Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File nonstopsession.patch    

 Description   

Currently, the StartTime and EndTime parameters are expected to exist even if NonStopSession is set to Y. This should not be, since in that case these two parameters do not apply.



 Comments   
Comment by Nikitas Leogas [ 04/Jan/14 ]

Proposed fix

Comment by Christoph John [ 06/Jan/14 ]

Committed as http://sourceforge.net/p/quickfixj/code/1134/.
Thanks for the patch!





[QFJ-766] FIX Resend Issue Created: 27/Dec/13  Updated: 30/Dec/13  Resolved: 30/Dec/13

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

Type: Bug Priority: Default
Reporter: Li,Wei Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: sequence,
Environment:

windows server 2008 r2 standard sp1


Issue Links:
Duplicate
duplicates QFJ-673 QFJ sequence problem following inboun... Closed

 Description   

Currently our prod env occur an issue about FIX Resend.
1) Before 03:31:16.621, our quickfixj was disconnected by upstream fix engine.
2) On 03:31:16.621, we re-connected.
3) On 03:31:16.839, we(CT) send Resend Request with tag7=23152 and tag16=0.
4) On 03:31:17.541, our customer returned from 23152 to 23974, then they send us 34=23977 and 34=23978, but SKIPPED 23975 and 23976.
5) I found our quickfix found 23974 and 23975 from its own memory queue at the same time, but not found 23976. So our sides occur 'MsgSeqNum too high, expecting 23976 but received 23977', cannot receive subsequent orders.

<fix event log>
------------------------------------------------------------------
20131120-03:25:57.913: Disconnecting: Socket exception (/14.129.28.13:35416): java.io.IOException: An existing connection was forcibly closed by the remote host
20131120-03:25:57.991: Already disconnected: Socket exception (/14.129.28.13:35416): java.io.IOException: An existing connection was forcibly closed by the remote host
20131120-03:31:16.621: Accepting session FIX.4.2:CT->S_MHK from /14.129.28.13:36040

<fix message log>
------------------------------------------------------------------
20131120-03:31:16.621: 8=FIX.4.29=011435=A49=S_MHK56=CT34=2397450=desk143=N97=N122=20131120-03:31:1752=20131120-03:31:17108=6698=010=205
20131120-03:31:16.839: 8=FIX.4.29=76 35=A34=5219849=CT52=20131120-03:31:16.83956=S_MHK98=0108=6610=000
20131120-03:31:16.839: 8=FIX.4.29=77 35=234=5219949=CT52=20131120-03:31:16.83956=S_MHK7=2315216=010=024
20131120-03:31:16.917: 8=FIX.4.29=010235=049=S_MHK56=CT34=2397550=desk143=N97=N122=20131120-03:31:1752=20131120-03:31:1710=152
20131120-03:31:16.917: 8=FIX.4.29=011535=249=S_MHK56=CT34=2397650=desk143=N97=N122=20131120-03:31:1752=20131120-03:31:177=5212916=010=236

20131120-03:31:16.980: 8=FIX.4.29=025235=D49=S_MHK56=CT34=2315250=desk143=Y97=Y122=20131120-03:25:4052=20131120-03:31:1711=00000000000276593764-00000115=CNY38=190040=244=000000003.3500000047=P54=155=60166859=060=20131120-03:25:40100=SS526=MHK0127658108421=110=070
20131120-03:31:16.980: 8=FIX.4.29=025235=D49=S_MHK56=CT34=2315350=desk143=Y97=Y122=20131120-03:25:4052=20131120-03:31:1711=00000000000276593765-00000115=CNY38=250040=244=000000004.9800000047=P54=155=60002859=060=20131120-03:25:40100=SS526=MHK0127658105921=110=070
.............................
.............................
.............................
.............................
.............................
20131120-03:31:17.541: 8=FIX.4.29=025135=D49=S_MHK56=CT34=2397150=desk143=Y97=Y122=20131120-03:29:5452=20131120-03:31:1811=00000000000276597970-00000115=CNY38=20040=244=000000005.3000000047=P54=155=60189859=060=20131120-03:29:54100=SS526=MHK0127658108921=110=051
20131120-03:31:17.541: 8=FIX.4.29=025135=D49=S_MHK56=CT34=2397250=desk143=Y97=Y122=20131120-03:29:5452=20131120-03:31:1811=00000000000276597971-00000115=CNY38=10040=244=000000004.2100000047=P54=155=60001959=060=20131120-03:29:54100=SS526=MHK0127658105821=110=031
20131120-03:31:17.541: 8=FIX.4.29=025235=D49=S_MHK56=CT34=2397350=desk143=Y97=Y122=20131120-03:29:5752=20131120-03:31:1811=00000000000276597995-00000115=CNY38=270040=244=000000004.2700000047=P54=155=60180059=060=20131120-03:29:57100=SS526=MHK0127658108521=110=106
20131120-03:31:17.541: 8=FIX.4.29=010735=449=S_MHK56=CT34=23974 43=Y97=Y122=20131120-03:31:1852=20131120-03:31:1836=23977123=Y10=111
20131120-03:31:17.541: 8=FIX.4.29=025335=D49=S_MHK56=CT34=2397750=desk243=N97=N122=20131120-03:31:1852=20131120-03:31:1811=00000000000276599095-00000115=CNY38=70040=244=000000005.7000000047=P54=255=60037759=060=20131120-03:31:17100=SS526=MHK0127647435721=110=238
20131120-03:31:17.541: 8=FIX.4.29=011135=149=S_MHK56=CT34=2397850=desk243=N97=N122=20131120-03:31:1852=20131120-03:31:18112=R110=203

20131120-03:31:17.541: 8=FIX.4.29=7735=234=5224649=CT52=20131120-03:31:17.54156=S_MHK7=2397616=010=022

<fix event log>
------------------------------------------------------------------
20131120-03:31:17.339: Received SequenceReset FROM: 23466 TO: 23467
20131120-03:31:17.417: Received SequenceReset FROM: 23665 TO: 23666
20131120-03:31:17.479: Received SequenceReset FROM: 23887 TO: 23889
20131120-03:31:17.541: ResendRequest for messages FROM 23152 TO 23973 has been satisfied.
20131120-03:31:17.541: Processing queued message: 23974
20131120-03:31:17.541: Processing queued message: 23975

20131120-03:31:17.541: MsgSeqNum too high, expecting 23976 but received 23977: 8=FIX.4.29=25335=D34=2397743=N49=S_MHK50=kerridhu52=20131120-03:31:1856=CT97=N122=20131120-03:31:1811=00000000000276599095-00000115=CNY21=138=70040=244=000000005.7000000047=P54=255=60037759=060=20131120-03:31:17100=SS526=MHK0127647435710=190
20131120-03:31:17.541: Enqueued at pos 23977: 8=FIX.4.29=25335=D34=2397743=N49=S_MHK50=desk252=20131120-03:31:1856=CT97=N122=20131120-03:31:1811=00000000000276599095-00000115=CNY21=138=70040=244=000000005.7000000047=P54=255=60037759=060=20131120-03:31:17100=SS526=MHK0127647435710=190
20131120-03:31:17.541: Sent ResendRequest FROM: 23976 TO: 23976
20131120-03:31:17.541: MsgSeqNum too high, expecting 23976 but received 23978: 8=FIX.4.29=11135=134=2397843=N49=S_MHK50=kerridhu52=20131120-03:31:1856=CT97=N122=20131120-03:31:18112=R110=155
20131120-03:31:17.541: Enqueued at pos 23978: 8=FIX.4.29=11135=134=2397843=N49=S_MHK50=desk252=20131120-03:31:1856=CT97=N122=20131120-03:31:18112=R110=155
20131120-03:31:17.541: Already sent ResendRequest FROM: 23976 TO: 23976. Not sending another.



 Comments   
Comment by Christoph John [ 30/Dec/13 ]

Should be the same as in QFJ-673.





[QFJ-765] CheckSum error if the declared number of groups does not match the actual number of groups Created: 12/Dec/13  Updated: 07/Jan/14  Resolved: 07/Jan/14

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

Type: Bug Priority: Default
Reporter: Judit Kapinya Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The scenario:

The initiator parses the following message with quickfix.MessageUtils.parse(), and sends it to the acceptor.

8=FIX.4.4|9=238|35=AE|31=1.35|32=1000|48=EURUSD|22=6|55=EURUSD|64=20131106|194=1.35|15011=1.33|15012=1.33|461=RCSXXX|487=2|571=1105200000001234|829=0|572=M1006050412587|552=1|54=1|37=SYS1:4545556002|11=SYS2:1006050412587|526=SSP:BDID001|453=2|448=a123456|447=D|452=3|802=2|523=5730607|803=10|523=5730606|803=15|1=123456-789|

It is not a valid FIX message, as we have 453<NoPartyIDs>=2, but there is only one group in the message. We would expect the acceptor to return a validation error, but instead the following happens:

1) An error message is logged:

2013-12-07 15:47:30,919 [SocketAcceptorIoProcessor-0.0] ERROR [] q.mina.acceptor.AcceptorIoHandler - Invalid message: Expected CheckSum=29, Received CheckSum=28 in 8=FIX.4.4?9=367?35=AE?34=82?49=SIDE1?52=20131207-14:47:30.618?56=SIDE2?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?64=20131106?194=1.35?461=RCSXXX?487=2?571=1105200000001234?572=M1006050412587?829=0?15011=1.33?15012=1.33?552=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=5730607?803=10?523=5730606?803=15?1=123456-789?10=028?

2) The acceptor does not send any response and does not increase the message sequence count, either.

The suspect:

The acceptor validates the fix message with the checksum(String s) method of Message class. It calculates 29. But the checksum calculated on the initiator side is 28. The initiator calculates the checksum with a different method, which is called by the toString() method of Message class. This is the method which does the calculation (in FieldMap class) - my comments added:

int calculateTotal() {

int result = 0;
// JK: fields variable contains tags which are not group tags
for (final Field<?> field2 : fields.values()) {
final Field<?> field = field2;
if (field.getField() == CheckSum.FIELD || isGroupField(field.getField()))

{ continue; }

result += field.getTotal();
}

// JK: groups variable contains the group tags, but only the tag number (the key is Integer, not Field - why?)
final Iterator<Map.Entry<Integer, List<Group>>> iterator = groups.entrySet().iterator();
while (iterator.hasNext()) {
final Map.Entry<Integer, List<Group>> entry = iterator.next();
final List<Group> groupList = entry.getValue();
if (!groupList.isEmpty()) {
final IntField groupField = new IntField((entry.getKey()).intValue());
// JK: at this point we have 453=0, as this is a new field, no value yet
groupField.setValue(groupList.size());
// JK: now it is 453=1, because we have only one group
result += groupField.getTotal();
for (int i = 0; i < groupList.size(); i++)

{ final Group group = groupList.get(i); result += group.calculateTotal(); }

}
}

return result;
}

So the checksum will be the checksum of a different message actually, where 453=1.



 Comments   
Comment by Christoph John [ 16/Dec/13 ]

It is correct that the target message seqnum is not incremented on a checksum error. Since FIX takes an optimistic approach it is expected that the checksum is incorrect due to a transient error and that the subsequent resend will transmit a correct message.

Are you able to provide the original message that went over the wire? Otherwise it is hard to create a unit test. Trying with the message from point 1) above would give me a checksum of 214. I guess you have altered it in some way.

Comment by Judit Kapinya [ 02/Jan/14 ]

First of all happy new year

Yes, I altered the message - removed sensitive information. Now I've changed my settings, and here's an unaltered message from the initiator's log:

<20140102-14:46:32, FIX.4.4:SIDE1->SIDE2, outgoing> (8=FIX.4.4?9=357?35=AE?34=11?49=SIDE1?52=20140102-14:46:32.928?56=SIDE2?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?64=20131106?194=1.35?461=RCSXXX?487=2?571=1105200000001234?572=M1006050412587?829=0?15011=1.33?15012=1.33?552=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=5730607?803=10?523=5730606?803=15?1=123456-789?10=220?)

And this is the checksum error on the acceptor side:

2014-01-02 15:46:33,009 [SocketAcceptorIoProcessor-0.0] ERROR [] q.mina.acceptor.AcceptorIoHandler - Invalid message: Expected CheckSum=221, Received CheckSum=220 in 8=FIX.4.4?9=357?35=AE?34=11?49=SIDE1?52=20140102-14:46:32.928?56=SIDE2?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?64=20131106?194=1.35?461=RCSXXX?487=2?571=1105200000001234?572=M1006050412587?829=0?15011=1.33?15012=1.33?552=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=5730607?803=10?523=5730606?803=15?1=123456-789?10=220?

I hope this helps.

Comment by Christoph John [ 03/Jan/14 ]

Happy new year to you, too.

Sorry, but I still cannot exactly reproduce the error since there are some required fields missing in the message (570/PreviouslyReported, 75/TradeDate, 60/TransactTime) plus there are two user-defined fields that are not in the default FIX4.4 data dictionary (fields 15011 and 15012). But even when altering my data dictionary to accept your message I get a different checksum (namely 214, the same as in my former test).
Would it be possible for you to transmit a message that follows the default FIX4.4 dictionary?

Comment by Christoph John [ 03/Jan/14 ]

Correction, I get 204 as checksum. But should not matter.

Comment by Judit Kapinya [ 06/Jan/14 ]

I modified the FIX message to have the mandatory fields and removed the custom ones:

Initiator:
<20140106-15:26:35, FIX.4.4:SIDE2->SIDE1, outgoing> (8=FIX.4.4?9=373?35=AE?34=8?49=SIDE2?52=20140106-15:26:35.369?56=SIDE1?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?60=20140106-23:00:00?64=20131106?75=
20140106?194=1.35?461=RCSXXX?487=2?570=Y?571=1105200000001234?572=M1006050412587?829=0?552=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=57306
07?803=10?523=5730606?803=15?1=123456-789?10=016?)

Acceptor:
2014-01-06 16:26:35,419 [SocketAcceptorIoProcessor-0.0] ERROR [] q.mina.acceptor.AcceptorIoHandler - Invalid message: Expected CheckSum=17, Received CheckSum=16 in 8=FIX.4.4?9=373?35=AE?34=8?49=SIDE2?
52=20140106-15:26:35.369?56=SIDE1?22=6?31=1.35?32=1000?48=EURUSD?55=EURUSD?60=20140106-23:00:00?64=20131106?75=20140106?194=1.35?461=RCSXXX?487=2?570=Y?571=1105200000001234?572=M1006050412587?829=0?55
2=1?54=1?37=SYS1:4545556002?11=SYS2:1006050412587?526=SSP:BDID001?453=2?448=a123456?447=D?452=3?802=2?523=5730607?803=10?523=5730606?803=15?1=123456-789?10=016?

The checksum can be different, as SendingTime/52 will be appended by the engine and will be different every time.

Comment by Christoph John [ 06/Jan/14 ]

Thanks, with that message I am able to reproduce the checksum problem. But it leaves me thinking about how the message has been constructed. If you constructed it with QFJ, e.g. message.addGroup() and so on and then the checksum calculation is wrong then that would be an error. But I actually did not manage to add repeating groups to the message in a way that would leave the group count tag in a wrong state. How did you achieve that?

Comment by Judit Kapinya [ 07/Jan/14 ]

The message was not constructed programmatically. It was created manually as part of a test harness, and in this particular scenario we would expect the engine to return a validation error message (as in case of out of order groups, for instance), but instead this checksum error occurs. This is not a typical scenario or not even highly probable to happen, but as the incoming FIX message is not a valid one, it would be nice to get a validation error. The checksum error can be quite misleading, as the calculated checksum at the client side is actually correct, but calculated for an invalid message. I hope this makes sense

Comment by Christoph John [ 07/Jan/14 ]

OK, I understand. But you will get a checksum error in this case because the validation of the checksum is done earlier (at message construction) than the group validation (when checking against the data dictionary). This can be seen at the end of method Message.parseGroup():
// For later validation that the group size matches the parsed group count
parent.setGroupCount(groupCountTag, declaredGroupCount);

QF/J just iterates over the group as often as the group delimiter is found and sets the declaredGroupCount for later validation.
If I alter the checksum on your message to the correct value I get "Incorrect NumInGroup count for repeating group", so this would be what you expect.

Comment by Judit Kapinya [ 07/Jan/14 ]

Ok, thanks for the explanation. So such a case should never happen if the message is constructed programmatically. We won't worry about such scenarios then.

Comment by Christoph John [ 07/Jan/14 ]

You're welcome. Feel free to ask at the mailing list if further questions arise. https://lists.sourceforge.net/lists/listinfo/quickfixj-users
Thank you





[QFJ-764] Create message class for XmlMessage (MsgType = 'n') Created: 11/Dec/13  Updated: 12/Dec/13

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

Type: New Feature Priority: Default
Reporter: Isaac Levin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Fix 4.4 defines XML Message (message type = 'n') that contains XmlData. There are XmlData and XmlDataLen classes in QuickFIX/J, but there is no actual class for XmlMessage. As a result calling MessageFactory.create(BEGIN_STRING, 'n') returns null



 Comments   
Comment by Christoph John [ 12/Dec/13 ]

I think the problem lies within the specification of the XmlMessage itself. In FIXimate (http://www.fixtradingcommunity.org/FIXimate/FIXimate3.0/) the MsgType n is only specified having a header and a trailer, but no body fields. When adding this information to the data dictionary and regenerating the code the MessageFactory returns a message but when adding fields and validating the message the error "No fields found" is thrown by the DataDictionary. So it seems that the XmlMessage cannot be completely supported.
Another point is that by definition of the FIXimate msgType n is an admin message but QuickFIX/J currently will not treat it as admin message (see MessageUtils.isAdminMessage()). I do not know if that will cause additional problems.





[QFJ-763] Wrong constant values in NoSides Created: 11/Dec/13  Updated: 02/Apr/15  Resolved: 12/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Isaac Levin Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

NoSides extends IntField, but constants for ONE_SIDE and BOTH_SIDES are defined as char.

public class NoSides extends IntField {
static final long serialVersionUID = 20050617;
public static final int FIELD = 552;
public static final char ONE_SIDE = '1';
public static final char BOTH_SIDES = '2';
...

When you call:
message.set(new NoSides(NoSides.ONE_SIDE));
Then the wrong value 49 (Ascii code of '1') instead of 1 is sent.



 Comments   
Comment by Christoph John [ 12/Dec/13 ]

Wow, this really is a special case. NoSides seems to be the only repeating group delimiter field which has constants specified. However, I would rather not do "message.set(new NoSides(NoSides.ONE_SIDE));" on my own but rather add the repeating group to the message which then does the necessary calculation for the NoSides field.

Comment by Christoph John [ 12/Dec/13 ]

Committed as rev1126: http://sourceforge.net/p/quickfixj/code/1126/





[QFJ-762] Message stores can become corrupted on acceptor/initiator shutdown Created: 09/Dec/13  Updated: 21/Apr/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Alexey Ermakov Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Relates
relates to QFJ-552 Message Stores expected to be thread ... Open
is related to QFJ-923 FileStore is leaking file handles Closed

 Description   

Since MessageStore implementations aren't thread safe, all operations on them should be performed from the session thread only. However, all 4 acceptor and initiator implementations perform shutdown (and thus call Session.unregisterSessions) in the calling thread. Since that calls MessageStore.close(), it can easily lead to store corruption if, for example, FileStore.close() gets called while the session thread is in the middle of persisting a Logout response.



 Comments   
Comment by Constantin Florescu [ 20/Apr/17 ]

The same issue could be reproduced when the logon request is timing out.

There are 2 threads trying to do the same thing:
16:18:28.763 [QFJ Timer] INFO quickfix.FileStore - initialize() called from.
at quickfix.FileStore.initialize(FileStore.java:111) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:465) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2503) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1968) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1808) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:278) [quickfixj-core-1.6.2.jar:1.6.2]

And from:
16:18:28.788 [QFJ Message Processor] INFO quickfix.FileStore - initialize() called from.
at quickfix.FileStore.initialize(FileStore.java:111) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:465) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2503) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1968) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:882) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1109) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:144) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:91) [quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:125) [quickfixj-core-1.6.2.jar:1.6.2]

This causes unexpected behaviour and leaks File Descriptors.
Example:
ERROR [QFJ Timer] quickfix.SocketInitiator Error during timer processing
quickfix.RuntimeError: java.io.FileNotFoundException: [/..../Session].header (Too many open files)
at quickfix.SessionState.reset(SessionState.java:384) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.resetState(Session.java:2499) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.disconnect(Session.java:1967) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.Session.next(Session.java:1808) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:278) [quickfixj-core-1.6.2.jar:1.6.2]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_74]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_74]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_74]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_74]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_74]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_74]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_74]
Caused by: java.io.FileNotFoundException: [/.../Session].header (Too many open files)
at java.io.FileOutputStream.open0(Native Method) ~[?:1.8.0_74]
at java.io.FileOutputStream.open(FileOutputStream.java:270) ~[?:1.8.0_74]
at java.io.FileOutputStream.<init>(FileOutputStream.java:213) ~[?:1.8.0_74]
at java.io.FileOutputStream.<init>(FileOutputStream.java:133) ~[?:1.8.0_74]
at quickfix.FileStore.initializeMessageIndex(FileStore.java:198) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.initializeCache(FileStore.java:121) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.initialize(FileStore.java:116) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.FileStore.reset(FileStore.java:442) ~[quickfixj-core-1.6.2.jar:1.6.2]
at quickfix.SessionState.reset(SessionState.java:382) ~[quickfixj-core-1.6.2.jar:1.6.2]
... 11 more





[QFJ-761] Remove conversion from Message to String in Session.nextQueued() Created: 09/Dec/13  Updated: 02/Apr/15  Resolved: 09/Dec/13

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

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Unnecessary conversion from Message to String in Session.nextQueued():

// TODO SESSION Is it really necessary to convert the queued message to a string?
next(msg.toString());

In method next(String msg) the message is parsed back to a Message, so the conversion is not only inefficient but also pointless.



 Comments   
Comment by Christoph John [ 09/Dec/13 ]

http://sourceforge.net/p/quickfixj/code/1125/





[QFJ-760] NullPointerException in Message.parseGroup Created: 22/Nov/13  Updated: 02/Apr/15  Resolved: 29/Nov/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

problem

java.lang.NullPointerException
at quickfix.Message.parseGroup(Message.java:600)
at quickfix.Message.parseBody(Message.java:569)
at quickfix.Message.parse(Message.java:480)
at quickfix.MessageUtils.parse(MessageUtils.java:148)

At that position in the code the result of extractField is NULL. This happens on parsing the message because the position counter is greater than the length of the message. Line 758 in Message.java:

if (position >= messageData.length())

{ return null; }

This is expected in some cases when parsing groups.
However in this current problem it happened because there were problems with the message length and checksum which went undetected by the FixMessageDecoder.
The FixMessageDecoder checks if the message ends with a checksum, i.e. tag 10=xxx. The message in question ended with that information but the SOH delimiter before tag 10 was missing.



 Comments   
Comment by Christoph John [ 29/Nov/13 ]

Committed as rev 1120 http://sourceforge.net/p/quickfixj/code/1120/





[QFJ-759] "Timed out waiting for heartbeat" after receiving and sending TestRequest message Created: 13/Nov/13  Updated: 04/Nov/16  Resolved: 13/Feb/14

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

Type: Bug Priority: Major
Reporter: Wongsakorn Chantrapornsyl Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: QuickfixJ, testRequest, timeout
Environment:

Microsoft Windows Server


Issue Links:
Duplicate
duplicates QFJ-624 Invalid "Timed out waiting for heartb... Closed
duplicates QFJ-668 Disconnecting: Timed out waiting for ... Closed

 Description   

The FIX application received the disconnection event from the FIX QuickJ after received and sent the TestRequest message so that the FIX application cannot reply the TestRequest message back to the FIX Server. Then the connection was disconnected.

From the FIX application log, it seems that FIX QuickJ received the HeartBeat message at sequence number 31934 (HeartBeat is not diaplayed in the log) but somehow FIX QuickJ does not reply the HeartBeat message back to the FIX Server.

Message log
----------------------------------------------------------------------------------------------
nformation 2013/11/12 10:04:12 Event Initiated logon request
Information 2013/11/12 10:04:11 Event Disconnecting
Warning 2013/11/12 10:04:11 Event Disconnecting: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=AE)
Warning 2013/11/12 10:04:11 Event quickfix.SessionException Logon state is not valid for message (MsgType=AE)
Information 2013/11/12 10:04:11 Event Sent test request TEST
Information 2013/11/12 10:04:11 Message <outgoing> (8=FIXT.1.19=15435=A34=3240849=TMSQ03226252=20131112-01:04:11.61456=TR MATCHING57=FXM142=TRFXMJP53776xxx98=0108=4553=DCUA554=*****789=319331137=91407=10010=055)
Information 2013/11/12 10:04:11 Event No responder, not sending message: 8=FIXT.1.19=10435=134=3240749=TMSQ03226252=20131112-01:04:11.11456=TR MATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=167
Information 2013/11/12 10:04:11 Event Disconnecting
Warning 2013/11/12 10:04:11 Event Disconnecting: Timed out waiting for heartbeat
Information 2013/11/12 10:04:11 Message <outgoing> (8=FIXT.1.19=10435=134=3240749=TMSQ03226252=20131112-01:04:11.11456=TR MATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=167)
Information 2013/11/12 10:04:10 Message <incoming> (8=FIXT.1.19=9035=134=319351128=949=TR MATCHING56=TMSQ03226252=20131112-01:04:10.409112=HBTO-3193510=223)
Information 2013/11/12 10:04:04 Message <incoming> (8=FIXT.1.19=65635=AE57=efx50=FXM34=319331128=949=TR MATCHING56=TMSQ03226252=20131112-01:04:04.6411003=267623544487=0573=0856=2325=Y828=54150=F880=29102046217=52d16b65-2909-0000-0000-0014c23f2fa5423=2075=2013111255=aud/usd167=FXSPOT60=20131112-01:04:04.51364=2013111415=AUD120=USD231=100000032=1854=131=0.9351056=9350001116=21117=BTMU TOKYO1118=C1119=131120=21121=TMSQ1122=251121=FTUA1122=21117=CITIBANK LONDON.1118=C1119=561120=11121=CITV1122=25552=154=21630=11631=01632=11633=5761634=USD1158=21164=5781=1782=SETTLEMENT THROUGH CLS783=C784=271164=4781=1782=CLS783=C784=271057=N37=10708811=1:298:1816938=110=117)
----------------------------------------------------------------------------------------------

We need to check with the FIX QuickJ why the FIX QuickJ does not response the HeartBeat message and notify the disconnection event improperly.



 Comments   
Comment by Wongsakorn Chantrapornsyl [ 13/Nov/13 ]

OS: Windows Server 2008 R2 (64-bit) SP1

Comment by Christoph John [ 15/Nov/13 ]

Is this behaviour reproducible? Looks to me like QFJ noticed the heartbeat timeout at the same time as the counterparty and dropped the connection and because of this did not reply back to the TestRequest. As you can see QFJ even did not send out its own TestRequest because the connection dropped before:

Information 2013/11/12 10:04:11 Event No responder, not sending message: 8=FIXT.1.19=10435=134=3240749=TMSQ03226252=20131112-01:04:11.11456=TRMATCHING57=FXM142=TRFXMJP53776xxx112=TEST10=167

Comment by Wongsakorn Chantrapornsyl [ 15/Nov/13 ]

We check the sniffer log. The server sent the heartbeat at 01:04:08 but there is no response from the QFJ. Then the server sent TestRequest at 01:04:10 and the disconnection is initiation by QFJ at 01:04:11.

Comment by Wongsakorn Chantrapornsyl [ 15/Nov/13 ]

It is not reproducible. It occur only once.

However, we worry that it may occur again anytime.

Comment by Christoph John [ 15/Nov/13 ]

Unfortunately, there are no milliseconds in the log. It might be that the testrequest was received at 01:04:10.999 and QFJ disconnected at 01:04.11.000. Since the disconnection is handled by a different thread than the message processing thread this might occur.

If this happened only once I would not really worry about it.





[QFJ-758] Improve log output on incoming connection Created: 07/Nov/13  Updated: 02/Apr/15  Resolved: 08/Nov/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-720 Improve log output when creating sess... Resolved

 Description   

To ease the analysis of connection problems when working with multiple sessions/ports/log files it would be handy if there was a little more information given in one log line. This is especially necessary when grepping over multiple log files.

On an incoming connection the output is currently:
MINA session created: /10.0.173.12:12345
(this is the remote address)

But should be something like:
MINA session created: local=/10.0.173.12:23456, class org.apache.mina.transport.socket.nio.SocketSessionImp, remote=/10.0.173.12:12345
(this is more similar to the InitiatorIoHandler class)



 Comments   
Comment by Christoph John [ 08/Nov/13 ]

Committed: http://sourceforge.net/p/quickfixj/code/1118/





[QFJ-757] Data dictionary file 'FIX44.xml' field number 234 'StipulationValue' should allow "other" values Created: 05/Nov/13  Updated: 05/Nov/13

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Tommy Hannon Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The provided data dictionary file 'FIX44.xml' field number 234 'StipulationValue' should allow "other" values as described in FIX 4.4 specification (p. 86 of FIX 4.4 with Errata 20030618- Volume 6).

<field number="234" name="StipulationValue" type="STRING" allowOtherValues="true">






[QFJ-756] Data dictionary file 'FIX44.xml' field number 233 'StipulationType' should allow "other" values Created: 05/Nov/13  Updated: 05/Nov/13

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Tommy Hannon Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The provided data dictionary file 'FIX44.xml' field number 233 'StipulationType' should allow "other" values as described in FIX 4.4 specification (p. 84 of FIX 4.4 with Errata 20030618- Volume 6).

<field number="233" name="StipulationType" type="STRING" allowOtherValues="true">






[QFJ-755] FIX44.xml field number 139 'MiscFeeType' should be of type 'STRING' Created: 05/Nov/13  Updated: 31/Mar/14  Resolved: 31/Mar/14

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

Type: Bug Priority: Minor
Reporter: Tommy Hannon Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-682 MiscFeeType in FIX44.xml does not mat... Closed

 Description   

FIX specification 4.4 added three values to the MiscFeeType (139) field that exceed the length of type 'CHAR'. This necessitates the type to be 'STRING' due to two-character values even though the FIX 4.4 specification still defines it as data type 'char'.

<!-field number="139" name="MiscFeeType" type="CHAR"->
<field number="139" name="MiscFeeType" type="STRING">






[QFJ-754] Session.logon() does not attempt to manually logon. Created: 04/Nov/13  Updated: 04/Nov/13

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Ming Liu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Session.logon does not attempt to manually logon. Logon message is sent only when reconnectInterval is up.






[QFJ-753] Banzai example wrong handling of replaced orders Created: 29/Aug/13  Updated: 29/Aug/13

Status: Open
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Marin Bonacci Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

After sending Cancel/Replace request with modified quantity, the target sends PENDING_REPLACE ExecutionReport, then REPLACE ExecutionReport with new quantity. The application does't update order quantity, and interprets first ExecutionReport as a fill.






[QFJ-752] Instrument component dont show the instrumentParties repeating group Created: 30/Jul/13  Updated: 12/Mar/20

Status: Open
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Christian Avalos Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ


 Description   

the noInstrumentParties(1018) component is in the componentFields int array, and not in componentGroup, so, when it added a instrumentParties ,the generated message has the field 1018, but not the other possibles fields of instrumentParties (1019, 1050, 1051, 1052)



 Comments   
Comment by Christian Avalos [ 30/Jul/13 ]

this issue is fixed adding the noIntrumentParties fields into componentGroups attribute (and removing from componentFields int[] )

public class Instrument extends quickfix.MessageComponent {
static final long serialVersionUID = 20050617;
public static final String MSGTYPE = "";
private int[] componentFields =

{ 55, 65, 48, 22, 454, 460, 461, 167, 762, 200, 541, 224, 225, 239, 226, 227, 228, 255, 543, 470, 471, 472, 240, 202, 947, 206, 231, 223, 207, 106, 348, 349, 107, 350, 351, 691, 667, 875, 876, 864, 873, 874, 965, 966, 1049, 967, 968, 969, 970, 971, 996, 997, 1079, }

;
private int[] componentGroups =

{1018, }

;

public Instrument()

{ super(); }

......
}

Comment by Jörg Thönnes [ 31/Jul/13 ]

This message and field classes are generated automatically from the data dictionary so this is most probably a code generation issue.

Comment by Christoph John [ 31/Jul/13 ]

... or in the data dictionary.

Comment by Marcin L [ 12/Mar/20 ]

I was wondering if this is really a bug. Clearly the definition in FIX5* looks like this

<component name="Instrument">
[...]
<component name="InstrumentParties" required="N"/>
</component>

<component name="InstrumentParties">
<group name="NoInstrumentParties" required="N"> // 1018
<field name="InstrumentPartyID" required="N"/> // 1019
<field name="InstrumentPartyIDSource" required="N"/> // 1050
<field name="InstrumentPartyRole" required="N"/> // 1051
<component name="InstrumentPtysSubGrp"/>
</group>
</component>

<component name="InstrumentPtysSubGrp">
<group name="NoInstrumentPartySubIDs" required="N"> // 1052
<field name="InstrumentPartySubID" required="N"/> // 1053
<field name="InstrumentPartySubIDType" required="N"/> // 1054
</group>
</component>

Component classes have their own dedicated classes generated so to access the group we need to go via component abstraction.

public class Instrument extends quickfix.MessageComponent {
private int[] componentFields =

{ [...], 1018, [...] }

;
private int[] componentGroups = { };
}

public class InstrumentParties extends quickfix.MessageComponent {
private int[] componentFields = { };
private int[] componentGroups =

{ 1018, }

;
}

public class InstrumentPtysSubGrp extends quickfix.MessageComponent {
private int[] componentFields = { };
private int[] componentGroups =

{ 1052, }

;
}

This is not a single case. This is basically a case for every component containing another component with a repeating group e.g. in FIX44 UnderlyingInstrument -> UnderlyingStipulations

What kind of errors currently generated classes could produce with this behaviour?





[QFJ-751] Incorrect handling of SequenceReset-GapFill messages when using ResendRequestChunkSize > 0 Created: 18/Jul/13  Updated: 02/Apr/15  Resolved: 28/Mar/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: ResendRequest,, sequence,
Environment:

FIX 4.4, Initiator, ResendRequestChunkSize = 100


Attachments: Text File log-file.txt     Text File SessionTest.java    

 Description   

While performing a large session-layer recovery operation (around 1 million of messages) in chunks of 100 the QuickFIX/J engine got stuck, as it ignored a valid GapFill message:

18-07-13 08:56:50.673|QFJ Message Processor|INFO|quickfix: Received SequenceReset FROM: 1000102 TO: 1000103

18-07-13 08:56:50.673|QFJ Message Processor|ERROR|quickfix: MsgSeqNum too high, expecting 1000102 but received 1000103: 8=FIX.4.29=45135=834=100010343=Y49=ABFX52=20130718-08:56:50.66356=TEST_CLIENT122=20130718-00:09:001=B2BUSER60.STP6=0.816711=B2BCLIENT60-1374106069-1000102:014=4000015=EUR17=1374106069-100010220=021=131=0.816732=4000037=B2BCLIENT60-1374106069-1000102:038=4000039=240=D54=155=EUR/GBP60=20130718-00:08:54.57564=20140221109=B2BCLIENT60150=2151=0167=FOR194=0.82195=-0.003285544=GBP5549=AcmecoFXTest6054=32668.00999999=137413781066310=200

After analysis of the Session.nextSequenceReset() method it's clear that the incoming SequenceReset-GapFill message is handled differently when using non-zero ResendRequestChunkSize. Also, it looks like in this particular scenario the target sequence number has not been set (from 1000102) to newSequence (1000103) in the Session.nextSequenceReset() method, because:

1) range[2] was > 0 (which means using non-zero ResendRequestChunkSize)

AND

2) newSequence (1000103) was NOT >= range[1] (1084290)

AND

3) newSequence (1000103) was NOT >= range[2] (1000200)

[All values in the log below.]

It looks like the following logic needs to be reviewed because in the discussed scenario the newSequence value was completely ignored:

if (range[2] > 0) {
if (newSequence >= range[1])

{ state.setNextTargetMsgSeqNum(newSequence); }

else if (newSequence >= range[2])

{ state.setNextTargetMsgSeqNum(newSequence + 1); final String beginString = sequenceReset.getHeader().getString( BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence + 1, range[1]); }

} else

{ state.setNextTargetMsgSeqNum(newSequence); }

The log is attached.



 Comments   
Comment by Andrzej Hajderek [ 18/Jul/13 ]

Attaching the actual log file, as the inline logs look awful.

Comment by Andrzej Hajderek [ 18/Jul/13 ]

BTW: Could someone please fix the incorrect tag: "sequnece" (swapped ne). It's used by a bunch of other issues as well.

Comment by Andrzej Hajderek [ 18/Jul/13 ]

The following test passes for ResendRequestChunkSize=0, but fails forResendRequestChunkSize=10:

// QFJ-751
@Test
public void testSequenceResetGapFillWithZeroChunkSize() throws Exception

{ testSequenceResetGapFillWithChunkSize(0); }

// QFJ-751
@Test
public void testSequenceResetGapFillWithNonZeroChunkSize() throws Exception

{ testSequenceResetGapFillWithChunkSize(10); }

// QFJ-751
@Ignore
private void testSequenceResetGapFillWithChunkSize(int chunkSize)
throws Exception {
final SessionID sessionID = new SessionID(
FixVersions.BEGINSTRING_FIX44, "SENDER", "TARGET");

boolean isInitiator = true, resetOnLogon = false, validateSequenceNumbers = true;

Session session = new Session(new UnitTestApplication(),
new MemoryStoreFactory(), sessionID, null, null,
new ScreenLogFactory(true, true, true),
new DefaultMessageFactory(), isInitiator ? 30 : 0, false, 30,
true, resetOnLogon, false, false, false, false, false, true,
false, 1.5, null, validateSequenceNumbers, new int[]

{ 5 }

,
false, false, false, true, false, true, false, null, true,
chunkSize, false, false);

UnitTestResponder responder = new UnitTestResponder();
session.setResponder(responder);

session.logon();
session.next();

assertEquals(1, session.getStore().getNextTargetMsgSeqNum());

Message logonRequest = new Message(responder.sentMessageData);

// Deliver Logon response with too high sequence 20 instead of 1.
session.next(createLogonResponse(sessionID, logonRequest, 20));

// The expected target sequence should still be 1.
assertEquals(1, session.getStore().getNextTargetMsgSeqNum());

// Deliver the missing message #1.
session.next(createAppMessage(1));
assertEquals(2, session.getStore().getNextTargetMsgSeqNum());

// Deliver the missing message #2.
session.next(createAppMessage(2));
assertEquals(3, session.getStore().getNextTargetMsgSeqNum());

// Deliver SequenceReset-GapFill from 3 to 5
final SequenceReset gapFill = new SequenceReset(new NewSeqNo(5));
gapFill.getHeader().setField(
new SenderCompID(sessionID.getTargetCompID()));
gapFill.getHeader().setField(
new TargetCompID(sessionID.getSenderCompID()));
gapFill.getHeader().setField(new SendingTime(new Date()));
gapFill.getHeader().setField(new MsgSeqNum(3));
gapFill.setField(new GapFillFlag(true));

session.next(gapFill);

// Deliver the missing message #5.
session.next(createAppMessage(5));
/*

  • The expected target sequence number should be 6 now.
    */
    assertEquals(6, session.getStore().getNextTargetMsgSeqNum());
    }
Comment by Andrzej Hajderek [ 19/Jul/13 ]

Please find attached the updated SessionTest.java source file, which now contains the two new test methods:

testSequenceResetGapFillWithZeroChunkSize()

and

testSequenceResetGapFillWithNonZeroChunkSize()

Comment by Andrzej Hajderek [ 19/Jul/13 ]

Not sure why the code I pasted directly got garbled. The attached file is OK.

Comment by Christoph John [ 28/Mar/14 ]

Committed as http://sourceforge.net/p/quickfixj/code/1168/





[QFJ-750] Receiving Logout with too high or too low sequence causes messages to be lost Created: 11/Jul/13  Updated: 02/Apr/15  Resolved: 18/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Niall Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File QFJ-750-Session-with-test.patch     Text File QFJ-750-Session.java.patch    

 Description   

For Loogout messages the "Too High" check is not done on the sequence number. If a Logout message with a sequence number that is too high is received, the NextTargetMsgSeqNum is still incremented anyway. This causes a message to be lost.

For example say the NextTargetMsgSeqNum=500 and a Logout message with MsgSeqNum=550 is received NextTargetMsgSeqNum gets incremented to 501. Then a Logon message is received with MsgSeqNum=551 a ResendRequest is sent for 501 to 550 and MsgSeqNum 500 is lost/never received.

In the nextLogout(Message) method I think modifying the increment statement to guard against this should avoid this situation:

int msgSeqNum = message.getInt(MsgSeqNum.FIELD);
if (!isTargetTooHigh(msgSeqNum)) {
    state.incrNextTargetMsgSeqNum();
}


 Comments   
Comment by Niall [ 12/Jul/13 ]

Attaching a patch

Comment by Christoph John [ 12/Jul/13 ]

Good catch. Are you also able to provide a unit test?

Comment by Niall [ 12/Jul/13 ]

I will try and add a test in the next day or two

Comment by Niall [ 13/Jul/13 ]

Attaching patch with unit test

Comment by Christoph John [ 18/Dec/13 ]

This also applies for Logouts with too low a sequence number. And also for Rejects.

Comment by Christoph John [ 18/Dec/13 ]

Committed as http://sourceforge.net/p/quickfixj/code/1128

Thanks to Niall for the patch. Slightly enhanced it and added same check for incoming Rejects (which are also processed regardless of seqnum, just as Logout messages).

Comment by Niall [ 23/Dec/13 ]

Great, thanks for applying this





[QFJ-749] Syntax error in SessionSettings.java/line 572 leading exception from java.util.regex Created: 17/Jun/13  Updated: 08/Jul/13

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Pavel Sagulenko Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

Eclipse 22 on Debian GNU/Linux 7.0



 Description   

There is a syntax error in SessionSettings.java class, line 572.
original line: private final Pattern variablePattern = Pattern.compile("\\$

{(.+?)}

");
Should be: private final Pattern variablePattern = Pattern.compile("\\$

{(.+?)\\}

");

(with double slash before closing parenthesis).
This causes the failure in creating a SessionSettings instance.

I tried to recompile myself the corrected version, but I got the following exception:

java.lang.NoClassDefFoundError: quickfix.SessionSettings

Probably, you can suggest the possible solution.
Thank you!



 Comments   
Comment by Christoph John [ 08/Jul/13 ]

Sorry, what do you mean by: "This causes the failure in creating a SessionSettings instance"??
Are you able to supply a test case which shows the failure?





[QFJ-748] Configuration related issue for explicit setting of " StartDay and Endday " for "ConnectionType=initiator " in the qfixsessions.config file. Created: 13/Jun/13  Updated: 13/Jun/13  Resolved: 13/Jun/13

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

Type: Other Priority: Critical
Reporter: Shree Niwas Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

I am trying to configure " StartDay" and "Endday " for "ConnectionType=initiator ". I need to configure the different setting for starting and ending Fix handler for different days of the week.
For Monday to Friday i want to have StartTime=21:35:00 and EndTime=21:32:00.
For Saturday and sunday i want to have StartTime=22:35:00 and EndTime=22:32:00..

How can i configure this explicity in the qfixsessions.config file.



 Comments   
Comment by Christoph John [ 13/Jun/13 ]

Please direct such questions to the mailing list. Thank you.
http://www.quickfixj.org/support/

Comment by Shree Niwas [ 13/Jun/13 ]

Hi Christoph,
I m still not added to the users mailing list, i have sent the mail regarding the issue to [email protected].
and the following msg:

Your mail to 'Quickfixj-users' with the subject
QFJ-748 (Configuration related issue for explicit setting of "StartDay and Endday " for "ConnectionType=initiator " in the qfixsessions.config file)
Is being held until the list moderator can review it for approval.The reason it is being held: Post by non-member to a members-only list

Either the message will get posted to the list, or you will receive
notification of the moderator's decision. If you would like to cancel
this posting, please visit the following URL:
https://lists.sourceforge.net/lists/confirm/quickfixj-users/81641ae441825bf4768faec5d13b0f85ceba673d

Comment by Christoph John [ 13/Jun/13 ]

Did you try subscribing to the list first on https://lists.sourceforge.net/lists/listinfo/quickfixj-users ?

Comment by Shree Niwas [ 13/Jun/13 ]

yes, added in the users list. thanks.

Comment by Christoph John [ 13/Jun/13 ]

Your mail came through the list now. But I cannot tell if it was the initial one of if you resent it.

Comment by Shree Niwas [ 13/Jun/13 ]

i have re sent it.anyways, it has reached to intended receipient.
Thanks.

Comment by Shree Niwas [ 13/Jun/13 ]

Hi Christoph,
The issue is related precisely to Varying session times configuration for diferent days of week.
can we have multiple session configuration for specific days .





[QFJ-747] performance issue about fromApp() and toApp() Created: 05/Jun/13  Updated: 11/Jun/13  Resolved: 11/Jun/13

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

Type: Other Priority: Critical
Reporter: Li,Wei Assignee: Unassigned
Resolution: Not a bug Votes: 2
Labels: performance
Environment:

win2008 r2 64bit, memory 32G, cpu 3.0GHz



 Description   

In our prod environment, using quick fix 1.5.2. Recently our upstream set up an algo trading system, it sends lots of DMA orders to our system. When concurrent pressures become high, we found high latency in incoming step and outgoing step.

We add some logs in fromApp() method to record callback timestamp, found between this timestamp and the timestamp of tag35=D have an average of 400ms delay, max delay is 2500ms. At outgoing step, toApp() method have same issue.

In our system, connection 9 sessions, two of them are doing algo trading by DMA, others do manual order trading.



 Comments   
Comment by Li,Wei [ 05/Jun/13 ]

So I want to know what's wrong , or what adjustments approach? Thanks.

Comment by Li,Wei [ 06/Jun/13 ]

jre 1.6.0_31

Comment by Christoph John [ 06/Jun/13 ]

You should direct your question to the mailing list which is more frequented than this bug-tracking tool.

https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Comment by Christoph John [ 11/Jun/13 ]

Suggestions by mailing list: turn off logging, use memory store, use ThreadedSocketAcceptor/Initiator.





[QFJ-746] Repeating Custom Tags Causes Parsing Error of Message Created: 31/May/13  Updated: 03/Jun/13  Resolved: 03/Jun/13

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

Type: Bug Priority: Default
Reporter: Talayeh Nili Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

software



 Description   

We are using QuicFIX J custom built functionality for parsing messages that we receive. We have custom tags with tag id in the 9000 ranges. These are allocation report messages and they can have a lot of these optional fields that we do not process, and some of them are nested and repeating. What I am seeing tis that when these tags are repeating, the QuickFIXJ is unable to read any fields after those set of tags.
Is this a known expected behaviour?

Example Message:
8=FIX.4.49=108635=AS34=183649=FCI-TNS56=CAPGROUP52=20130529-19:02:51453=2448=CPILGB2L447=B452=13802=1523=Capital Group Companies803=5448=BAMLPSWDCTM447=B452=1802=1523=Bank of America - BAMLPSWDCTM803=571=0794=3755=CPILGB2L136985417107987=09052=10137269169053=Y9057=MAGR857=054=2167=CORP6=98.86753=12460000381=12318828.2231=100.060=20130529-00:00:0075=2013052964=20130603157=166541=20180201223=1.570=27573200122=448=US828807CM76107=SIMON PROPERTY GROUP 144A LIFE SR UNSEC 1.5% 02-01-189061=49062=US828807CM769859=86181.679858=USD9874=29873=FLAT9865=EXEC9869=USD9866=09873=FLAT9865=TCOM9869=USD9866=078=379=000031467=7732620019047=2511221.880=2540000172=0169=285=1165=1781=1782=DTCYUS33783=B784=10801=0154=2528790.13742=17568.3312=013=379=000008467=7732820019047=6080320.580=6150000172=0169=285=1165=1781=1782=DTCYUS33783=B784=10801=0154=6122858742=42537.512=013=379=000078467=7732720019047=3727285.980=3770000172=0169=285=1165=1781=1782=DTCYUS33783=B784=10801=0154=3753361.73742=26075.8312=013=310=020

In this case, the allocations are not read. They start at tag 78. Right before tag 78, we see repeating tags 9865, 9869, 9866.
We have seen examples of this behaviour with other tags as well.



 Comments   
Comment by Grant Birchmeier [ 31/May/13 ]

You should ask for help on the mailing list or StackOverflow.

JIRA is for bug tracking, and this doesn't look like a bug.

Comment by Talayeh Nili [ 31/May/13 ]

Grant, my specific question is that is it the expected behavior for the parser to stop parsing the fix message once it sees a tag(not in a repeating group) multiple times?

Comment by Christoph John [ 03/Jun/13 ]

A FIX message must not contain duplicate tags, except they are in a repeating group.





[QFJ-745] "MsgSeqNum too high" error as result of "QFJ Message Processor" could parse income messages on SSL Connections Created: 23/May/13  Updated: 11/Jun/13

Status: Open
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrey Nalitkin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: sequnece, ssl, testRequest
Environment:

CentOS release 5.9 (Final)
Linux dev99 2.6.18-348.6.1.el5 #1 SMP Tue May 21 15:29:55 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux

java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.7-b02, mixed mode)



 Description   

QFJ Message Processor thread could parse income message queue and

Name: QFJ Message Processor
State: RUNNABLE
Total blocked: 1 Total waited: 8,038

Stack trace:
quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:104)
org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58)
org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:180)
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
org.apache.mina.filter.support.SSLHandler.flushScheduledEvents(SSLHandler.java:275)
org.apache.mina.filter.SSLFilter.filterWrite(SSLFilter.java:512)
org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:361)
org.apache.mina.common.support.AbstractIoFilterChain.access$1300(AbstractIoFilterChain.java:53)
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterWrite(AbstractIoFilterChain.java:659)
org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolEncoderOutputImpl.doFlush(ProtocolCodecFilter.java:369)
org.apache.mina.filter.codec.support.SimpleProtocolEncoderOutput.flush(SimpleProtocolEncoderOutput.java:97)
org.apache.mina.filter.codec.ProtocolCodecFilter.filterWrite(ProtocolCodecFilter.java:215)
org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:361)
org.apache.mina.common.support.AbstractIoFilterChain.access$1300(AbstractIoFilterChain.java:53)
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterWrite(AbstractIoFilterChain.java:659)
org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.filterWrite(AbstractIoFilterChain.java:587)
org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:361)
org.apache.mina.common.support.AbstractIoFilterChain.fireFilterWrite(AbstractIoFilterChain.java:355)
org.apache.mina.transport.socket.nio.SocketSessionImpl.write0(SocketSessionImpl.java:166)
org.apache.mina.common.support.BaseIoSession.write(BaseIoSession.java:177)
org.apache.mina.common.support.BaseIoSession.write(BaseIoSession.java:168)
quickfix.mina.IoSessionResponder.send(IoSessionResponder.java:47)
quickfix.Session.send(Session.java:2483)

  • locked java.lang.String@73013e68
    quickfix.Session.sendRaw(Session.java:2414)
    quickfix.Session.generateHeartbeat(Session.java:1827)
    quickfix.Session.next(Session.java:1800)
    quickfix.Session.next(Session.java:1101)
    quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
    quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
    quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
    java.lang.Thread.run(Thread.java:662)


 Comments   
Comment by Christoph John [ 24/May/13 ]

Please excuse me, could you please elaborate on what exactly the problem is? Thank you.

Comment by Andrey Nalitkin [ 24/May/13 ]

Problem in concurrent parsing and modification of incoming MsgSeqNum counter by 2 threads:
1. "QFJ Message Processor" thread
2. "SocketConnectorIoProcessor" thread

As result SocketConnectorIoProcessor "lose" messages, report error and request to resend

Comment by Christoph John [ 11/Jun/13 ]

Do you have some more information on this? Message logs maybe?
The stack trace only lists one thread. Do you also have a stack trace of the other involved threads?





[QFJ-744] FIX44.xml is missing fields 201 and 315 (PutOrCall and UnderlyingPutOrCall) Created: 20/May/13  Updated: 02/Apr/15  Resolved: 20/May/13

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Grant Birchmeier
Resolution: Fixed Votes: 0
Labels: None


 Description   

Originally found this in QF/n specs. QF/j also has the bug, which makes sense, since I think QF/n stole its specs from QF/j.

For needed changes, see what we did to QF/n:
https://github.com/connamara/quickfixn/commit/e3fd7aeb47709d97faa594ec57cd16567147e006

It's a pretty easy fix.



 Comments   
Comment by Grant Birchmeier [ 20/May/13 ]

Fix committed, rev 1114.





[QFJ-743] JdbcLog doesn't take into consideration the sessionID to verify if a parameter is set like JdbcMessage does Created: 13/May/13  Updated: 06/Nov/15

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Leandro Garcia Herrera Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: JdbcLog, QuickfixJ, jdbc
Environment:

Windows 7, using JBoss and camel-quickfix


Attachments: Java Source File JdbcLog.java     Java Source File TemaJdbcLog.java    

 Description   

I'm trying to configure JdbcLogFactory dynamically passing a SessionSettings object as argument to constructor. All my configurations are under an especific session ID and I have no configurations under default session.

Looking at the source code of JdbcLog I was able to confirm that only the default session configurations are taken into consideration instead of checking first in session ID configurations informed via constructor, wich I was expecting.

The JdbcStore class does this verification by session ID and I think JdbcLog should work in the same way.



 Comments   
Comment by Christoph John [ 09/Jan/14 ]

Would it be OK for you to attach the patch to this ticket? I do not have the necessary rights to grant you SVN access but could integrate the patch shortly.

Comment by Leandro Garcia Herrera [ 06/Nov/15 ]

Hi, Christoph. Look if it helps. I've attached the patch as you requested.

Best regards.

Comment by Leandro Garcia Herrera [ 06/Nov/15 ]

bug fix





[QFJ-742] If the first field of a type is a group - it will not build the group Created: 09/May/13  Updated: 02/Apr/15  Resolved: 19/Mar/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Peter Metcalf Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-732 Unable to parse messages when the fir... Closed

 Description   

in parseGroup method in Message.java - it checks if it's parsing the first field and sets it. But if this is a group groupDataDictionary.isGroup(msgType, field.getField()), the group parsing never happens. Adding the following code after "previousOffset = -1;" resolves the issue:
if (groupDataDictionary.isGroup(msgType, field.getField()))

{ parseGroup(msgType, field, groupDataDictionary, group); }

 Comments   
Comment by Christoph John [ 13/May/13 ]

This sounds like QFJ-732. Do you agree?

Comment by Peter Metcalf [ 13/May/13 ]

Yes, apologies.

Comment by Christoph John [ 13/May/13 ]

No need to apologise. Will close the other ticket since you already provided a tested solution.

Comment by Peter Metcalf [ 16/May/13 ]

Ok. I feel honoured. The type which exposes the issue RiskLimit. It has two groups and no fields.

Any idea what sort of turn around time can be expected? We are using a modified version for now, but would obviously like to got back on to released versions.

Comment by Christoph John [ 16/May/13 ]

Sorry, as far as I know there currently are no plans on when work will be started for the next release.

Comment by Christoph John [ 19/Mar/14 ]

http://sourceforge.net/p/quickfixj/code/1161/





[QFJ-741] Missing value 99 for Tag 796 in FIX44.xml Created: 08/May/13  Updated: 17/Jun/20  Resolved: 15/Jun/20

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.5.3
Fix Version/s: 2.2.0

Type: Bug Priority: Default
Reporter: Po Fong Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: QuickfixJ
Environment:

Linux



 Description   

Quickfix J will always reject a J cancel/replace messge with tag 796=99 due to missing <value enum="99" description="OTHER"/> in FIX44.xml.






[QFJ-740] Replace StringBuffer with StringBuilder Created: 24/Apr/13  Updated: 02/Apr/15  Resolved: 18/Mar/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Peter Lawrey Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-736 performance improvement: Modify the c... Closed

 Description   

In 2004 Java 5.0 was released with a note in StringBuffer's Javadoc

> As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.

Perhaps its is time to use StringBuilder as it is a drop in replacement. esp as this class is used heavily.



 Comments   
Comment by Christoph John [ 24/Apr/13 ]

As it says in the doc, we need to carefully check which places are single-threaded before replacing everything by StringBuilder.

Comment by Peter Lawrey [ 24/Apr/13 ]

Can you give me an example of when using StringBuffer in a multi-threaded context makes sense.

These methods call only be called by one thread at a time safely, so using StringBuffer doesn't buy anything.

ObjectNameFactory.addProperty(String name, String value)

SessionSessing.getToken(Reader)

In all other cases StringBuffer is used as a local variable, i.e. thread local variable.

Comment by Peter Lawrey [ 24/Apr/13 ]

The ObjectNameFactory.addProperty() method makes for an interesting puzzle.

Write a program which will generate all the possible outcomes of

[code]
// thread 1
objectNameFactory.addProperty("a", "b");
// thread 2
objectNameFactory.addProperty("c", "d");
[code]

You have the obvious

[code]
a=b,c=d
c=d,a=b
[code]

but also

[code]
ac==bd
a,c=b=d
[code]

and many more

Comment by Peter Lawrey [ 24/Apr/13 ]

I have generated the list

a=b,c=d
a=,bc=d
a=,cb=d
a=,c=bd
a,=bc=d
a,=cb=d
a,=c=bd
a,c=b=d
a,c==bd
c=d,a=b
c=,da=b
c=,ad=b
c=,a=db
c,=da=b
c,=ad=b
c,=a=db
c,a=d=b
c,a==db
a=bc=d
a=cb=d
a=c=bd
ac=b=d
ac==bd
c=da=b
c=ad=b
c=a=db
ca=d=b
ca==db

Comment by Christoph John [ 25/Apr/13 ]

Good point. To be honest I did not check the code on usages of StringBuffer yet. I was only aware of the usage referred to in QFJ-736.

Comment by Christoph John [ 18/Mar/14 ]

http://sourceforge.net/p/quickfixj/code/1152/





[QFJ-739] How can stop file logging in quickfixj?? Created: 17/Apr/13  Updated: 17/Apr/13  Resolved: 17/Apr/13

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

Type: Other Priority: Critical
Reporter: Mansoor Haider Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

Windows



 Description   

I want to stop logging to make the application more faster. Is there any way to stop logging in quickfixj??



 Comments   
Comment by Christoph John [ 17/Apr/13 ]

Please ask such general questions on the mailing list. Thank you.

http://www.quickfixj.org/support/





[QFJ-738] Deadlock on disconnect Created: 15/Apr/13  Updated: 02/Apr/15  Resolved: 13/Feb/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.1
Fix Version/s: 1.6.0

Type: Bug Priority: Major
Reporter: Alexander Kormushin Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows 7, Java SE 1.6.0_30


Attachments: Text File quickfixj-deadlock.txt     Text File stacktrace.txt    
Issue Links:
Relates
relates to QFJ-664 Upgrade MINA from 1.1.8 to 2.0.x Closed
is related to QFJ-638 SocketSynchronousWrites=Y Hangs Threa... Closed

 Description   

I'm starting quickfixj acceptor and initiator in the same thread. For test purposes only. Don't know whether it is a valid use case. Will appreciate any thoughts on this.

From time to time following deadlock occurs:

Found one Java-level deadlock:
=============================
"QFJ Message Processor":
  waiting to lock monitor 0x000000000702f0b0 (object 0x00000007c39b1230, a java.lang.Object),
  which is held by "QFJ Timer"
"QFJ Timer":
  waiting to lock monitor 0x00000000070323e0 (object 0x00000007c39f11d0, a java.lang.String),
  which is held by "QFJ Message Processor"

Java stack information for the threads listed above:
===================================================
"QFJ Message Processor":
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.doWrite(VmPipeFilterChain.java:192)
	- waiting to lock <0x00000007c39b1230> (a java.lang.Object)
	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.filterWrite(AbstractIoFilterChain.java:631)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:445)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1400(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterWrite(AbstractIoFilterChain.java:824)
	at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolEncoderOutputImpl.doFlush(ProtocolCodecFilter.java:436)
	at org.apache.mina.filter.codec.support.SimpleProtocolEncoderOutput.flush(SimpleProtocolEncoderOutput.java:112)
	at org.apache.mina.filter.codec.ProtocolCodecFilter.filterWrite(ProtocolCodecFilter.java:237)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:445)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1400(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterWrite(AbstractIoFilterChain.java:824)
	at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.filterWrite(AbstractIoFilterChain.java:727)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterWrite(AbstractIoFilterChain.java:445)
	at org.apache.mina.common.support.AbstractIoFilterChain.fireFilterWrite(AbstractIoFilterChain.java:436)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireEvent(VmPipeFilterChain.java:100)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.flushEvents(VmPipeFilterChain.java:65)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.pushEvent(VmPipeFilterChain.java:56)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireFilterWrite(VmPipeFilterChain.java:141)
	at org.apache.mina.transport.vmpipe.support.VmPipeSessionImpl.write0(VmPipeSessionImpl.java:146)
	at org.apache.mina.common.support.BaseIoSession.write(BaseIoSession.java:149)
	at org.apache.mina.common.support.BaseIoSession.write(BaseIoSession.java:135)
	at quickfix.mina.IoSessionResponder.send(IoSessionResponder.java:47)
	at quickfix.Session.send(Session.java:2322)
	- locked <0x00000007c39f11d0> (a java.lang.String)
	at quickfix.Session.sendRaw(Session.java:2253)
	at quickfix.Session.generateLogon(Session.java:2196)
	at quickfix.Session.nextLogon(Session.java:2001)
	at quickfix.Session.next(Session.java:958)
	at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
	at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
	at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
	at java.lang.Thread.run(Thread.java:662)
"QFJ Timer":
	at quickfix.Session.getResponder(Session.java:508)
	- waiting to lock <0x00000007c39f11d0> (a java.lang.String)
	at quickfix.Session.hasResponder(Session.java:518)
	at quickfix.mina.AbstractIoHandler.sessionClosed(AbstractIoHandler.java:95)
	at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.sessionClosed(AbstractIoFilterChain.java:677)
	at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$800(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
	at org.apache.mina.filter.codec.ProtocolCodecFilter.sessionClosed(ProtocolCodecFilter.java:299)
	at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$800(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
	at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
	at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireEvent(VmPipeFilterChain.java:124)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.flushEvents(VmPipeFilterChain.java:65)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.pushEvent(VmPipeFilterChain.java:56)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireSessionClosed(VmPipeFilterChain.java:159)
	at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:233)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.doClose(VmPipeFilterChain.java:240)
	- locked <0x00000007c39b1230> (a java.lang.Object)
	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.filterClose(AbstractIoFilterChain.java:644)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1500(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterClose(AbstractIoFilterChain.java:830)
	at org.apache.mina.common.IoFilterAdapter.filterClose(IoFilterAdapter.java:98)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1500(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterClose(AbstractIoFilterChain.java:830)
	at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.filterClose(AbstractIoFilterChain.java:732)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.fireFilterClose(AbstractIoFilterChain.java:456)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireEvent(VmPipeFilterChain.java:128)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.flushEvents(VmPipeFilterChain.java:65)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.pushEvent(VmPipeFilterChain.java:56)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireFilterClose(VmPipeFilterChain.java:135)
	at org.apache.mina.transport.vmpipe.support.VmPipeSessionImpl.close0(VmPipeSessionImpl.java:140)
	at org.apache.mina.common.support.BaseIoSession.close(BaseIoSession.java:119)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.doClose(VmPipeFilterChain.java:241)
	- locked <0x00000007c39b1230> (a java.lang.Object)
	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.filterClose(AbstractIoFilterChain.java:644)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1500(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterClose(AbstractIoFilterChain.java:830)
	at org.apache.mina.common.IoFilterAdapter.filterClose(IoFilterAdapter.java:98)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$1500(AbstractIoFilterChain.java:54)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.filterClose(AbstractIoFilterChain.java:830)
	at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.filterClose(AbstractIoFilterChain.java:732)
	at org.apache.mina.common.support.AbstractIoFilterChain.callPreviousFilterClose(AbstractIoFilterChain.java:464)
	at org.apache.mina.common.support.AbstractIoFilterChain.fireFilterClose(AbstractIoFilterChain.java:456)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireEvent(VmPipeFilterChain.java:128)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.flushEvents(VmPipeFilterChain.java:65)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.pushEvent(VmPipeFilterChain.java:56)
	at org.apache.mina.transport.vmpipe.support.VmPipeFilterChain.fireFilterClose(VmPipeFilterChain.java:135)
	at org.apache.mina.transport.vmpipe.support.VmPipeSessionImpl.close0(VmPipeSessionImpl.java:140)
	at org.apache.mina.common.support.BaseIoSession.close(BaseIoSession.java:119)
	at quickfix.mina.IoSessionResponder.disconnect(IoSessionResponder.java:69)
	at quickfix.Session.disconnect(Session.java:1918)
	- locked <0x00000007c39a3358> (a java.lang.String)
	at quickfix.Session.next(Session.java:1790)
	at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:283)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
	at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
	at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:180)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:204)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

Found 1 deadlock.


 Comments   
Comment by Alexander Kormushin [ 15/Apr/13 ]

Full stack trace attached.

Comment by Alexander Kormushin [ 16/Apr/13 ]

It seems the issue is only reproducible with VM_PIPE transport.

Comment by Christoph John [ 17/Apr/13 ]

Could you please check if the problem exists with a newer version? E.g. there was QFJ-645. The stack trace looks different but the problem also appeared on disconnection.

Comment by Attila-Mihaly Balazs [ 10/Sep/13 ]

This is still happening with 1.5.3, see the attached stacktrace.

The sequence of events is the following (from the attached stacktrace):

  • T1 (FixMessageHandler-ExecThread) obtains responderSync in quickfix.Session.send
  • T2 (main) obtains session.getLock() (this isn't shown in the thread dump - apparently jstack still doesn't have very good suppport for explicit locks - it happens in VmPipeFilterChain$VmPipeIoProcessor.remove at line 253)
  • T1 tries to obtain the same lock (sssion.getLock()) at VmPipeFilterChain$VmPipeIoProcessor.flush (line 184)
  • T2 tries to obtain responderSync at Session.disconnect (line 1892).

This only happens with the VmPipe transport (used by me for fast integration testing) and is solved by the following patch (which calls responder.send outside of the lock). The patch is against trunk and all the unit tests pass with it.

Index: core/src/main/java/quickfix/Session.java
===================================================================
— core/src/main/java/quickfix/Session.java (revision 1114)
+++ core/src/main/java/quickfix/Session.java (working copy)
@@ -2475,13 +2475,15 @@

private boolean send(String messageString) {
getLog().onOutgoing(messageString);
+ Responder responder;
synchronized (responderSync) {
if (!hasResponder())

{ getLog().onEvent("No responder, not sending message: " + messageString); return false; }
  • return getResponder().send(messageString);
    + responder = getResponder();
    }
    + return responder.send(messageString);
    }

private boolean isCorrectCompID(String senderCompID, String targetCompID) {

Comment by Christoph John [ 10/Sep/13 ]

Thanks for the patch. Could you please attach it since the code formatting in comments is not very optimal. Thank you.

Comment by Christoph John [ 17/Dec/13 ]

Did some more tests with unit test MultiAcceptorTest and could reproduce this almost always. However, the suggested patch does not solve this issue at all times. One more problem is that on a disconnection the AbstractIoHandler gets notified by MINA via callback sessionClosed and also tries to get hands on the responderSync lock (via Session.hasResponder() and disconnect()).

I guess we need to analyse if it is always feasible to check the hasResponder() from outside or just call the necessary Session method and do the responder check inside the Session.
Moreover, since almost all deadlocks I saw (also from other QFJ issues) were based around the disconnect() method, maybe it would be better to switch on a initiateDisconnect-flag of some sort from outside and handle the disconnection from inside the next() method or similar. Don't know if this will solve all problems, though.





[QFJ-737] Use current JDK for compilation of QuickFIX/J and discontinue JDK 1.4 compatibility Created: 21/Mar/13  Updated: 02/Apr/15  Resolved: 02/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Build, Engine
Affects Version/s: None
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Requires
is required by QFJ-664 Upgrade MINA from 1.1.8 to 2.0.x Closed

 Description   

We need to discuss which JDK to use. Either JDK6 or JDK7 with JDK6-compatibility switch (since JDK7 compiled code is not backwards binary-compatible). Since we are not using any JDK7 language features yet, the JDK6 compilation should be sufficient.

steps

  • removed retrotranslator usage from build
  • removed Java4 libs from source tree
  • re-enabled tests which were ignored due to JDK1.4 usage on release build


 Comments   
Comment by Jörg Thönnes [ 21/Mar/13 ]

I would start with JDK 6 in the first step. Switching to JDK 7 at a later point should not be a big issue then.

Comment by Dennys Fredericci [ 08/May/13 ]

I agree with JDK 6 in the first step

Comment by Christoph John [ 02/Dec/13 ]

Committed: http://sourceforge.net/p/quickfixj/code/1122/





[QFJ-736] performance improvement: Modify the code to use StringBuilder instead of StringBuffer in calculateString method of FieldMap Created: 18/Mar/13  Updated: 02/Apr/15  Resolved: 14/Mar/14

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

Type: Improvement Priority: Default
Reporter: Srinivas Kirti Teja Rao Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-740 Replace StringBuffer with StringBuilder Closed

 Description   

The calculate string method expects a StringBuffer and does all the concatenation on this object. This can be changed to StringBuilder to improve performance. All most of the applications want to log an incoming or outgoing messages and improvement in this calculate string can help them.

protected void calculateString(StringBuffer buffer, int[] preFields, int[] postFields)



 Comments   
Comment by Ryan Lea [ 21/Mar/13 ]

I actually think it might be even more performant to use cached CharBuffer's as they don't need resizing (once they're at their desired size) and can be easily reused.

Comment by Christoph John [ 21/Mar/13 ]

Speaking of cached objects, we also need to take the concurrent access to the FieldMap/Message classes into account. So we either need to make the using methods thread-safe or clearly document that they are not.

Comment by Peter Lawrey [ 25/Apr/13 ]

A pre-allocated StringBuilder doesn't need resizing any more than CharBuffer does, except it will resize if it needs to.

Instead of using StringBuffer or StringBuilder, I suggest using the interface Appendable. This supports either, or a wrapper for CharBuffer or ByteBuffer (Given most FIX messages are ISO-8859-1 compliant i.e. don't need char anyway)

I agree the documentation should state whether it is thread safe or not, but as suggested in QFJ-740 it is not thread safe now which might be confusing given it is using StringBuffer.

Comment by Jörg Thönnes [ 25/Apr/13 ]

Peter, as you write "most FIX messages are ISO-8859-1 compliant"...

There have been requests in the past to allow international characters, so we should not block this route.
But yes, at the bottom encoding level we talk about ISO-8859-1 encoded chars which are bitwise identical to the raw bytes the FIX checksum algorithm is working on.

Comment by Christoph John [ 03/May/13 ]

@Peter: nice article. http://java.dzone.com/articles/why-synchronized-stringbuffer

Comment by Christoph John [ 14/Mar/14 ]

http://sourceforge.net/p/quickfixj/code/1147/





[QFJ-735] in quickfixj-v1.5.3, I cannot find 'Order Mass Action Request' with MsgType="CA" Created: 14/Mar/13  Updated: 05/Jun/14  Resolved: 05/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Roger Deng Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: QuickfixJ
Environment:

Windows/Linux


Issue Links:
Duplicate
duplicates QFJ-781 Fix code generation for SP1/2 . Closed
is duplicated by QFJ-787 OrderMassActionRequest (CA), OrderMas... Closed

 Description   

in quickfixj-v1.5.3, I cannot find 'Order Mass Action Request' with MsgType="CA" :
Do we have OrderMassActionRequest.java file?
FIX.5.0SP1 Message
OrderMassActionRequest [type 'CA']
<OrdMassActReq>



 Comments   
Comment by Christoph John [ 14/Mar/13 ]

You are right, the message class is missing. Seems this is a problem with the code generation.

Comment by Muhammad Rashad Irshad Khan [ 05/Jun/14 ]

Please provide the solution for it or suggest to resolve it ASAP.
thanks,

Comment by Muhammad Rashad Irshad Khan [ 05/Jun/14 ]

Did you get the solution ?

Comment by Christoph John [ 05/Jun/14 ]

This will be solved by QFJ-781.

Workaround for the time being: recompile QFJ 1.5.3 with the added messages inside the FIX50.xml data dictionary (FIX50SP1/SP2 dictionary is not used for code generation in QFJ 1.5.3). Check http://www.quickfixj.org/confluence/display/qfj/User+FAQ on how to recompile.

Other option: use QFJ 1.6.0. But this is still in testing phase and not finished. Snapshot can be downloaded here: http://www.quickfixj.org:8085/browse/QFJ-GIT/latest/artifact/shared/qfj-zip/

If you have further questions please use the mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users





[QFJ-734] Properties for configuring Proxool vs. not incremented outgoing sequence number Created: 13/Mar/13  Updated: 13/Mar/13

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Krzysztof Szalast Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

All



 Description   

I want to remind about comment in quickfix.JdbcUtil in method "static synchronized DataSource getDataSource(String jdbcDriver, String connectionURL, String user, String password, boolean cache)":
// TODO JDBC Make these configurable
setMaximumActiveTime(ds, 5000);
ds.setMaximumConnectionLifetime(28800000);
ds.setMaximumConnectionCount(10);
ds.setSimultaneousBuildThrottle(10);

If "messages" table are locked longer than 5 seconds, connection is aborted by Proxool:
[13.03.2013|12:42:07:875] [HouseKeeper] [DEBUG] [proxool.quickfixj-1] [org.logicalcobwebs.proxool.ConnectionPool] [removeProxyConnection] [441] : 000026 (01/02/00) - #0001 removed because it has been active for too long.
[13.03.2013|12:42:07:875] [HouseKeeper] [WARN ] [proxool.quickfixj-1] [org.logicalcobwebs.proxool.HouseKeeper] [sweep] [149] : #0001 was active for 98688 milliseconds and has been removed automaticaly. The Thread responsible was named 'QFJ Timer', but the last SQL it performed is unknown because the trace property is not enabled.
[13.03.2013|12:42:07:906] [QFJ Timer] [ERROR] [quickfixj.errorEvent] [quickfix.SLF4JLog] [logError] [147] : Error Reading/Writing in MessageStore
java.io.IOException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see logs).
at quickfix.JdbcStore.set(JdbcStore.java:252)
at quickfix.SessionState.set(SessionState.java:308)
at quickfix.Session.sendRaw(Session.java:2313)
at quickfix.Session.generateHeartbeat(Session.java:1861)
at quickfix.Session.next(Session.java:1834)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:283)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.sql.SQLException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection. It has been automatically closed by Proxool for some reason (see logs).
at org.logicalcobwebs.proxool.WrappedConnection.invoke(WrappedConnection.java:207)
at org.logicalcobwebs.proxool.WrappedConnection.intercept(WrappedConnection.java:87)
at $java.sql.Wrapper$$EnhancerByProxool$$a5ac9e8b.prepareStatement(<generated>)
at quickfix.JdbcStore.set(JdbcStore.java:245)
... 14 more

and outgoing sequence number is not incremented! Next outgoing message has the same sequence number (sic!).

Scenario:
1. Send NOS message.
2. Lock "messages" table (on Postgres: LOCK TABLE messages IN ACCESS EXCLUSIVE MODE)
3. Send NOS message - message will be sent, but stacktrace from above will be happen. For example message has t34=666
4. Send NOS message - message will be sent with t34=666



 Comments   
Comment by Jörg Thönnes [ 13/Mar/13 ]

Good find! I think in that case the message should not be sent.





[QFJ-733] Provide customisable hooks into the core QuickFIX/J workflow Created: 11/Mar/13  Updated: 21/Mar/13

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Ryan Lea Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, modules, performance


 Description   

Background:
I have been using QuickFIX for some time and found it a great library. As my usage has increased, I have become more aware that it's not necessarily GC-friendly. As such I'm in the process of extending the Message object to become more GC-friendly, but really a step away from the message type-safety that is currently present within QuickFIX/J.

In order to achieve my goal, I have made (what I consider) minor modifications to the core codebase to provide locatable service lookups where need be,

Improvement:
It would be great if QuickFIX/J was more customisable in the services that were able to be overriden/extended or generally customised. I've currently created a (very simple - based on http://martinfowler.com/articles/injection.html) ServiceLocator that prepares services with defaults (current 1.5.3 behaviour) that can be overriden with custom services on startup (if required).

The services that I have currently customised are:

  1. Message validation with the Data Dictionary
  2. Message creation from String (the FIXMessageDecoderFactory)
  3. Handling of FIX Messages within the abstract IoHandler (as it depends upon MINA passing it a String)

This approach seemed less intrusive than a DI framework, and perhaps a simpler fit into QuickFIX core. It provides the benefits of maintaining a library that can be used out of the box, whilst providing the capability of customisation where required or necessary.

I'd be mostly interested to know whether this (or something like it) would be considered as part of the roadmap with QuickFIX/J and how or whether I would be able to contribute.



 Comments   
Comment by Jörg Thönnes [ 15/Mar/13 ]

Dear Ryan,

we appreciate your idea and would like to consider it.
It is true the QF/J is quite monolithic and would greatly benefit from being split into more components.
E.g.

  • separate IO layer in order to allow to replace MINA by Netty, etc (QFJ-598)

But currently there is no roadmap what should be done.

But it would be good if you could start a page in QF/J Confluence to outline your thoughts
and perhaps attached some code.

Thanks, Jörg

Comment by Ryan Lea [ 21/Mar/13 ]

Hi Jorg,

Thanks for your feedback. I will certainly attach a patch once I've extracted out the pieces I need to.

Following that, I will look at creating a Confluence page as well (quite a few of the Confluence pages seem quite old as well I've noticed). Do you have a preference of which hierarchy you would like it placed in?

Ryan





[QFJ-732] Unable to parse messages when the first tag inside the group is another group Created: 05/Mar/13  Updated: 13/May/13  Resolved: 13/May/13

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

Type: Bug Priority: Critical
Reporter: Srinivas Kirti Teja Rao Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

java 6, windows


Issue Links:
Duplicate
duplicates QFJ-742 If the first field of a type is a gro... Closed

 Description   

The function parseGroup(String msgType, StringField field, DataDictionary dd, FieldMap parent) in quickfix.Message.java does not consider a case where the first tag in the group is another group.
The code to parse the inner group is in else for a condition to check is that is a first field. Becuase the inner group is the first element, it does not prase the inner group anymore.

if (field.getTag() == firstField) {
if (group != null)

{ parent.addGroupRef(group); }

group = new Group(groupCountTag, firstField, groupDataDictionary.getOrderedFields());
group.setField(field);
firstFieldFound = true;
previousOffset = -1;
} else

{ //there is code here to handle prasing the inner group. }

I looked at the fix specification to see if that is a valid message, having a group as first tag in another group, I think it is allowed. I am using FIX 4.2 spec for this.

The simple but not the best fix is to pull the code out of the else and let is execute for the first field as well.



 Comments   
Comment by Srinivas Kirti Teja Rao [ 05/Mar/13 ]

by "pull the code out of else" i mean the code to parse the inner group out of the else condition.

Comment by Grant Birchmeier [ 05/Mar/13 ]

What is the message that you are trying to parse? Is it a custom message?

I'm not sure if the spec forbids it, but I also don't think the default message/field set has any messages where this occurs.

Comment by Srinivas Kirti Teja Rao [ 05/Mar/13 ]

It is QuoteAcknowledgement message but our customer does not send any other field in NoQuoteSets except for NoQuoteEntries.
Attached is the spec i have to parse the message.

<message name="QuoteAcknowledgement" msgcat="app" msgtype="b">
<field name="QuoteReqID" required="N" />
<field name="QuoteID" required="N" />
<field name="QuoteAckStatus" required="Y" />
<field name="QuoteRejectReason" required="N" />
<field name="QuoteResponseLevel" required="N" />
<field name="TradingSessionID" required="N" />
<field name="Text" required="N" />
<group name="NoQuoteSets" required="N">
<group name="NoQuoteEntries" required="N">
<field name="Symbol" required="N" />
<field name="QuoteEntryID" required="N" />
<field name="SymbolSfx" required="N" />
<field name="SecurityID" required="N" />
<field name="IDSource" required="N" />
<field name="SecurityType" required="N" />
<field name="MaturityMonthYear" required="N" />
<field name="MaturityDay" required="N" />
<field name="PutOrCall" required="N" />
<field name="StrikePrice" required="N" />
<field name="OptAttribute" required="N" />
<field name="ContractMultiplier" required="N" />
<field name="CouponRate" required="N" />
<field name="SecurityExchange" required="N" />
<field name="Issuer" required="N" />
<field name="EncodedIssuerLen" required="N" />
<field name="EncodedIssuer" required="N" />
<field name="SecurityDesc" required="N" />
<field name="EncodedSecurityDescLen" required="N" />
<field name="EncodedSecurityDesc" required="N" />
<field name="QuoteEntryRejectReason" required="N" />
</group>
</group>
</message>

Comment by Srinivas Kirti Teja Rao [ 05/Mar/13 ]

I think you are right, i didnt find with any default message where this occurs but the spec does not forbid it. So it is still a valid message I believe.

Comment by Christoph John [ 05/Mar/13 ]

I think the problem is that the first field of a repeating group is always required to be set since it acts as delimeter. Could be difficult in your case.
And you say that the FIX4.2 spec does not forbid it? There are some version-unspecific cases that are clarified in later FIX specs as well. So it might be worth taking a look at the current FIX spec.
Here are some general points about the NumInGroup field: http://fixwiki.org/fixwiki/NumInGroupDataType
There is also a linked discussion. Maybe it's worth asking there, if your message is a valid one with regard to the spec.

Comment by Srinivas Kirti Teja Rao [ 05/Mar/13 ]

FIX 4.2 spec mandates the first field to be present always. But the first field in my case turned out to be group and it is present always in the message. I didnt find anything that says FIX42 spec forbids this and the above code in parseGroup assumes the first field is not a group.

But yeah, i will try and refer the current fix spec and see if i find any clarifications regarding this.
Thanks for the quick response.

Comment by Srinivas Kirti Teja Rao [ 07/Mar/13 ]

I referred to the FIX spec 5 and found nothing that forbids a group being a first field in another group.
Can you please take a look and confirm if this is a bug in QuickFixJ and the approach i suggested would solve it without any other repercussions?

Comment by Srinivas Kirti Teja Rao [ 07/Mar/13 ]

I have also posted the question on validity of message on FIX general discussion forum (http://fixprotocol.org/discuss/read/0cd64db1)

Comment by Srinivas Kirti Teja Rao [ 08/Mar/13 ]

The response the thread says is it is allowed to have a repeating group as first field in another repeating group. PartyRiskLimitsGrp is an example for this construct. There are also concerns of how 35=b message is modeled in my case but then that is the message structure decided by one of our makers and because FIX does not forbid that message structure I do not have enough justification to go back and tell them it is invalid structure .

Quickfixj as a fix engine i believe should be able to parse these messages. Can we please look at the fixing the problem?

Comment by Christoph John [ 13/May/13 ]

Closed in favour of QFJ-742 which included a tested solution.





[QFJ-731] QuickFIXJ 1.5.3 does NOT support 5.0SP1 Created: 21/Feb/13  Updated: 16/Dec/13  Resolved: 16/Dec/13

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

Type: Bug Priority: Major
Reporter: Roger Deng Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: QuickfixJ
Environment:

Windows



 Description   

I used QuickFix/J examples:
(1) executor as the server;
[default]
FileStorePath=examples/target/data/executor
ConnectionType=acceptor
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SenderCompID=EXEC
TargetCompID=BANZAI
UseDataDictionary=Y
DefaultMarketPrice=12.30

[session]
BeginString=FIXT.1.1
DefaultApplVerID=FIX.5.0SP1
SocketAcceptPort=9881

(2) banzai as the client;
[default]
FileStorePath=examples/target/data/banzai
ConnectionType=initiator
SenderCompID=BANZAI
TargetCompID=EXEC
SocketConnectHost=localhost
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ReconnectInterval=5

[session]
BeginString=FIXT.1.1
DefaultApplVerID=FIX.5.0SP1
SocketConnectPort=9881



 Comments   
Comment by Jörg Thönnes [ 21/Feb/13 ]

Roger, according to your description I cannot see any issue.

So please describe your issue according to the usual bug reporting scheme:

1. Steps to reproduce the issue
2. Actual (observer) behaviour
3. Expected (wanted) behaviour

In the description, you started with point 1, but completely missing 2 and 3.

Comment by Christoph John [ 21/Feb/13 ]

As Jörg said, an exact error message would be helpful. What happens if you pass DefaultApplVerID=8? Same error message?





[QFJ-730] Wrong SeqNum in the last Sequence Reset message after a Resend Request Created: 18/Feb/13  Updated: 21/Apr/16  Resolved: 04/Jan/16

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

Type: Bug Priority: Major
Reporter: Damien Vidal Assignee: Flakron Vranovci
Resolution: Fixed Votes: 0
Labels: ResendRequest,
Environment:

Eclipse, Windows



 Description   

In the function nextResendRequest(Message resendRequest) you have this code at the end of the loop

if (begin != 0)

{ generateSequenceReset(begin, msgSeqNum + 1); }

if (endSeqNo > msgSeqNum) {
endSeqNo = endSeqNo + 1;
final int next = state.getNextSenderMsgSeqNum();
if (endSeqNo > next)

{ endSeqNo = next; }

generateSequenceReset(beginSeqNo, endSeqNo);
}

=> when you are on the case generating two Sequence Reset at the end of resend request you have an issue of FIX(34) in the last Sequence Reset:

Sequence Reset Message 1 begin != 0 => FIX(34)=begin => OK
Sequence Reset Message 2 endSeqNo > msgSeqNum => FIX(34)=beginSeqNo but beginSeqNo < begin => critical error in protocol it have to be FIX(34)=msgSeqNum+1 ( value sent in the message 1 with NewNoSeq=msgSeqNum+1)



 Comments   
Comment by Damien Vidal [ 19/Feb/13 ]

More details about this issue :

In the default implementation of QFJ you don't have this case but if you change the store implementation removing the persistance of the administrative messages you will have this issue. The loop done with the stored messages supports this case detecting a gap between each FIX(34). Only the last 2 messages are wrong when the last messages ( not stored ) were one or more admin messages at the end.

Here the fix I did and tested :

if (begin != 0)

{ generateSequenceReset(begin, endSeqNo + 1); }

else if (current != endSeqNo + 1) {
if (endSeqNo > msgSeqNum) {
endSeqNo = endSeqNo + 1;
final int next = state.getNextSenderMsgSeqNum();
if (endSeqNo > next)

{ endSeqNo = next; }

generateSequenceReset(beginSeqNo, endSeqNo);
}
}

}

Comment by Damien Vidal [ 19/Feb/13 ]

Sorry an error in the fix of my previous comment :

if (begin != 0)

{ generateSequenceReset(begin, endSeqNo + 1); // update the next SeqNum to support a gap }

else if (current != endSeqNo+1) // do it only if needed
{
if (endSeqNo > msgSeqNum)
{
endSeqNo = endSeqNo + 1;
final int next = state.getNextSenderMsgSeqNum();
if (endSeqNo > next)

{ endSeqNo = next; }

generateSequenceReset(current, endSeqNo); // update the SeqNum to support a gap
}
}

Comment by Flakron Vranovci [ 26/Nov/15 ]

Encountered this independently and have submitted a pull request

https://github.com/quickfix-j/quickfixj/pull/48

Comment by Christoph John [ 04/Jan/16 ]

Merged, thanks.





[QFJ-729] Allow MessageCrackers to handle polymorphic Message types Created: 07/Feb/13  Updated: 07/Feb/13

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: S Raf Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The MessageCracker expects an invoker to be registered for the specific actual Message type being processed. If an invoker exists for a supertype of the received Message, the invoker won't be called.

For those extending MessageCracker, the onMessage(quickfix.Message message, SessionID sessionID) method can be overridden to allow implementers to handle the most general quickfix.Message type (but not, for example, only quickfix.fix44.Message messages).

However, for those providing a delegate object to the MessageCracker, there is no option to provide a handler for a more general Message type to provide custom fallback logic.

The crack(..) method should look for invokers registered for the received Message's superclass(es), as well as its actual type, before resorting to the fallback onMessage call in MessageCracker.






[QFJ-728] SessionState is leaking memory when dealing with resends and sequence numbers are skipped due to a SequenceReset Created: 05/Feb/13  Updated: 02/Apr/15  Resolved: 19/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.1, 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Critical
Reporter: Thilo-Alexander Ginkel Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: None
Environment:

JDK 1.7



 Description   

When QuickFIX/J has to deal with ResendRequests (e.g., due to sequence number gaps or exceptions thrown by the client), the SessionState.messageQueue will grow and fill up with entries until the ResendRequest has been fulfilled, but will never clean up these queue entries later. Eventually this will consume all available heap (if no disconnect happen in between, which would clear the queue) and cause an OOM.

To reproduce this issue, subscribe to market data and raise an exception with a certain probability (e.g., every 100th message). Depending on the incoming message volume the messageQueue will fill up pretty quickly and won't release its content after the ResendRequest has been satisfied.



 Comments   
Comment by Thilo-Alexander Ginkel [ 05/Feb/13 ]

Another user also blogged about this issue at: http://www.natesimpson.com/blog/archives/2011/06/15/quickfixj-and-odd-memory-leaks/

While making sure to never throw an exception solved this issue for the referenced case, it also happens for regular resends caused by a server-side issue or temporary network issues.

Comment by Thilo-Alexander Ginkel [ 05/Feb/13 ]

Just some further results of our investigation: This seems to be related to nextSequenceReset calling SessionState.setNextTargetMsgSeqNum, which causes the messages skipped by the SequenceReset to remain in the SessionState.messageQueue forever.

Comment by Christoph John [ 05/Feb/13 ]

Is this the same problem as described in QFJ-271 or QFJ-409?

Comment by Thilo-Alexander Ginkel [ 05/Feb/13 ]

No, we are not seeing any StackOverflowErrors. It's just the SessionState.messageQueue that fills up which messages that will never be processed or garbage-collected.

Comment by Christoph John [ 05/Feb/13 ]

OK, I assume that QFJ-678 describes the messageQueue in question? Of course, having a bounded queue does not rectify the problem that the queue is not cleared after the ResendRequest has been satisfied.

Comment by Thilo-Alexander Ginkel [ 05/Feb/13 ]

The messageQueue described in QFJ-678 is indeed a different one. The messageQueue I refer to is not a LinkedBlockingQueue, but the LinkedHashMap referenced in quickfix.SessionState:

private final Map<Integer, Message> messageQueue = new LinkedHashMap<Integer, Message>();

At the moment I am no longer sure whether the SequenceReset handling implemented by QuickFIX/J is actually correct for GapFill mode. When a SequenceReset w/ GapFillFlag=Y and NewSeqNo is received, QuickFix/J will just set a new target msg sequence number (via setNextTargetMsgSeqNum), but completely ignores any messages it may have received with a lower sequence number. I'm not exactly sure whether those should be discarded or processed, but something needs to be done about them.

Comment by Christoph John [ 19/Dec/13 ]

Committed as http://sourceforge.net/p/quickfixj/code/1129/

In Session.nextSequenceReset(): make sure that all messages lower than the new seqnum are deleted from the message queue.





[QFJ-727] build failure due to invalid character in source files Created: 21/Jan/13  Updated: 02/Apr/15  Resolved: 06/May/14

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: amichair Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: QuickfixJ, ant
Environment:

Kubuntu 12.10, Oracle JDK 1.7.0_11


Attachments: File fixed-compilation-error-by-changing-source-file-encoding-trunk.patch     File fixed-compilation-error-by-changing-source-file-encoding.patch    

 Description   

A Fresh checkout of the QFJ_RELEASE_1_5_3 tag fails to compile (using 'ant jar' following installation instructions on website), with the error:

[javac] /home/user/dev/quickfixj-src/core/src/main/java/quickfix/CachedFileStore.java:408: error: unmappable character for encoding UTF8
[javac] * @author mratsimbazafy 29 ao�t 2008

The platform encoding on most Linux systems (and probably others too nowadays) is UTF-8, whereas the source files seem to be in ISO-8859-1 (or ISO-8859-15, whatever the devs happen to be using). A search for non-ascii characters in all source files reveals:

$ find -name "*.java" | xargs grep -P -n "[\x80-\xFF]"
./core/src/test/java/quickfix/FileLogTest.java:65: // �bcf�d��
./core/src/test/java/quickfix/AbstractMessageStoreTest.java:102: // message 111 == �bcf�d��
./core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java:119: // �bcf�d��
./core/src/test/java/quickfix/mina/message/FIXMessageEncoderTest.java:64: // �bcf�d��
./core/src/main/java/quickfix/CachedFileStore.java:408: * @author mratsimbazafy 29 ao�t 2008

The workaround would be to just delete these strings (they are all in comments), but the proper future-proof/cross-platform fix would be to convert these source files to UTF-8 encoding (e.g. using iconv) and update the build.xml files to add an encoding="UTF-8" attribute to all javac and jalopy tasks.



 Comments   
Comment by amichair [ 21/Jan/13 ]

the full fix to sources and build scripts

Comment by amichair [ 01/May/14 ]

Rebased the previous patch (which was against release 1.5.3) on top of current trunk.

Comment by amichair [ 01/May/14 ]

Any chance this will make it into trunk for the next release (or at least snapshot) sometime soon? It's pretty straightforward.

btw for the upcoming mavenization (+1!) you would use

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

(but you should still apply this patch first in order to fix the mis-encoded source files.)

Comment by Christoph John [ 02/May/14 ]

Thanks for your patch. Will integrate this into the next release.

Comment by Christoph John [ 05/May/14 ]

I have now committed the updated files. Could you please check if there are still compile errors? I could not use your patch since I am not using git so I converted the files using iconv.
Just curious: from which git repository did you get the source code?

Comment by amichair [ 05/May/14 ]

It compiles ok now as far as encoding is concerned - there is another unrelated error, but I'll open a separate issue for it.

The patch was created with 'git format-patch' from the commit in my custom branch. It's in standard diff format, so you should to be able to apply it normally with the patch utility (with the -p1 parameter, iirc) - that's how I tested it before I attached it to this issue.

I used svn2git to clone (and later rebase) the svn repository into a local mirror git repository - it uses git-svn internally with additional cleanup added. I then worked on my own local branches with fixes such as this one. I'd actually recommend migrating the project to git if you're considering it - svn2git makes it simple, and in my opinion git makes collaboration easier than svn.

Comment by Christoph John [ 06/May/14 ]

OK, thanks for testing.
Regarding git: we already have QFJ-597 and I'm planning to look at that, too.





[QFJ-726] Missing fields in generated classes Created: 29/Dec/12  Updated: 29/Dec/12  Resolved: 29/Dec/12

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Maarten Boekhold Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The following fields are not present in the generated Java class for TradeCaptureReport (FIX44 standard), but they are listed in the FIX44.xml message file:

<field name="SettlCurrAmt" required="N"/>
<field name="SettlCurrency" required="N"/>
<field name="SettlCurrFxRate" required="N"/>
<field name="SettlCurrFxRateCalc" required="N"/>



 Comments   
Comment by Maarten Boekhold [ 29/Dec/12 ]

Sorry, I was wrong. These fields are part of the NoSides repeating groups. The vendor document I'm working off was unclear about this and said they were part of the top-level TradeCaptureReport message.

Please close this issue as invalid or whatever





[QFJ-725] Note that sequence numbers will be reset at 'StartTime' even if ResetOnLogon=N Created: 27/Dec/12  Updated: 12/Apr/13

Status: Open
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: Jim Mulcahey Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ


 Description   

When a new session is started based on the QF/J 'StartTime' configuration setting, the sequence numbers will be reset even if ResetOnLogon=N. The Configuration section in the User Manual does not make this clear, as 'StartTime' is only defined as..

"Time of day that this FIX session becomes activated"

It would help to have a note added in the Configuration section that the sequence numbers will be reset even if ResetOnLogon=N.



 Comments   
Comment by Jörg Thönnes [ 12/Apr/13 ]

A new FIX session is defined by resetting the numbers to 1. Or in other words: You cannot start a new session
without setting numbers back to 1.

The ResetOnLogon forces to reset the sequence numbers even if we are in the normal [StartTime, EndTime] frame.

So "Time of day that this FIX session becomes activated" should get "Time of day when the new FIX session starts".

Actually, the new FIX session starts some where in between the previous days EndTime and the todays StartTime.
And the engine really resets the sequence numbers if it detects that it is out of session time (e.g. after last days EndTime).

Comment by Jim Mulcahey [ 12/Apr/13 ]

Thanks for the clarification, Jörg. You can go ahead and close this ticket.





[QFJ-724] quickfix.field.NoLegSecurityAltID extends quickfix.StringField instead of quickfix.IntField Created: 24/Dec/12  Updated: 21/Apr/16  Resolved: 04/Jan/16

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.3
Fix Version/s: 1.6.2

Type: Bug Priority: Major
Reporter: Maarten Boekhold Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

quickfix.field.NoLegSecurityAltID extends quickfix.StringField instead of quickfix.IntField like all the other "No*" fields...



 Comments   
Comment by Laurent Danesi [ 24/Dec/12 ]

Committed in r1114

Comment by Maarten Boekhold [ 09/Sep/15 ]

Hi,

No, this issue is not fixed, see https://github.com/quickfix-j/quickfixj/search?utf8=%E2%9C%93&q=NoLegSecurityAltID

Comment by Christoph John [ 04/Jan/16 ]

Hi Maarten Boekhold,

the referenced commit does indeed point to another issue. Will reopen this.

Comment by Christoph John [ 04/Jan/16 ]

Corrected with https://github.com/quickfix-j/quickfixj/commit/bbf8de58a336d5812802044190efbb7ce98f4ce2





[QFJ-723] need complete validation in DataDictionary rather than just first failure Created: 20/Dec/12  Updated: 20/Dec/12

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

Type: New Feature Priority: Default
Reporter: Vishal Arora Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently when DataDictionary.validate method is called over a FIX Message, it throws exception on first failure. We need to fail it last, listing all failures during validation. This is required for testing of our application, where we can't expect developers to fix one FIX validation failure to find next one.






[QFJ-722] Unnecessary Trailer and Header object allocation for every Message instance Created: 04/Dec/12  Updated: 17/Jun/20  Resolved: 12/Aug/19

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

Type: Improvement Priority: Default
Reporter: Drew Noakes Assignee: Wojciech Zankowski
Resolution: Fixed Votes: 0
Labels: garbage-collection, memory, performance
Environment:

N/A



 Description   

In quickfix.Message, the field initialisers for 'header' and 'trailer' each new up an object.

Generated Message classes then replace these. This creates unnecessary work for the GC.

I see no reason that subclasses need to re-assign the trailer.

The Header can vary with each FIX version, so perhaps the API could be modified such that the header is created by a protected method which is overridden in generated subclasses.






[QFJ-721] non-FIXT sessions: NPE accessing ApplVerID if previous Logon was not completely processed Created: 29/Nov/12  Updated: 30/Nov/12  Resolved: 30/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Jörg Thönnes Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-592 (FIXT .1.1) Application version id ca... Resolved

 Description   

In some cases the thread processing incoming FIX messages can get a NullPointerException accessing the ApplVerID
if the Logon process is not complete, e.g. because the counter party did not answer with a Logon response but continues
to send application messages.

In real ife, this issue was observed as a counter party sent many FIX messages without noticing a FIX re-login:

  1. counter party sends many messages
  2. QF/J sends logout
  3. counter party continues to send many messages
  4. QF/J forces disconnect due to Logout time-out (no 35=5 received so far)
  5. process restarts
  6. QF/J creates a new session
  7. QF/J sends Logon
  8. counter party continues to send many messages (but no Logon)
  9. QF/J receives a NPE for every message from the counter party:
    [2012-11-08 14:44:26,644] [QFJ Timer] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: outgoing: 8=FIX.4.4|9=68|35=A|34=1079|49=XXXAT|52=20121108-13:44:26.640|56=XXXFL|98=0|108=30|10=124|
    [2012-11-08 14:44:26,699] [SocketConnectorIoProcessor-0.0] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: incoming: 8=FIX.4.4|9=375|35=8|34=65834|43=Y|49=XXXFL|50=BU/XXXFL|52=20121108-13:44:26.675|56=XXXAT|122=20121108-12:45:47|6=0|...
    [2012-11-08 14:44:26,712] [QFJ Timer] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: event   : Initiated logon request
    [2012-11-08 14:44:26,801] [QFJ Message Processor] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: event   : null
    java.lang.NullPointerException
            at quickfix.MessageUtils.toBeginString(MessageUtils.java:256)
            at quickfix.DefaultDataDictionaryProvider.getApplicationDataDictionary(DefaultDataDictionaryProvider.java:62)
            at quickfix.Session.next(Session.java:913)
            at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
            at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
            at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
            at java.lang.Thread.run(Thread.java:722)
    [2012-11-08 14:44:26,802] [SocketConnectorIoProcessor-0.0] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: incoming: 8=FIX.4.4|9=353|35=8|34=65835|43=Y|49=XXXFL|50=BU/XXXFL|52=20121108-13:44:26.676|56=XXXAT|122=20121108-12:45:47|6=0|...
    [2012-11-08 14:44:26,811] [QFJ Message Processor] FIX.4.4:XXXAT->XXXFL:TEST-XXX-XXXFL-YYY: event   : null
    java.lang.NullPointerException
            at quickfix.MessageUtils.toBeginString(MessageUtils.java:256)
            at quickfix.DefaultDataDictionaryProvider.getApplicationDataDictionary(DefaultDataDictionaryProvider.java:62)
            at quickfix.Session.next(Session.java:913)
            at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
            at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
            at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
            at java.lang.Thread.run(Thread.java:722)
    


 Comments   
Comment by Jörg Thönnes [ 29/Nov/12 ]

This issue is most probably related.

Comment by Jörg Thönnes [ 29/Nov/12 ]

For non-FIXT.1.1 session this is not a race condition.

Comment by Christoph John [ 30/Nov/12 ]

The code change will be to set the targetDefaultApplVerID already on construction of the Session. Until now it was only set when a Logon message has been processed. This is OK for FIXT-sessions but for non-FIXT sessions the targetDefaultApplVerID needs not to be set on every Logon since it can be constructed from the BeginString of the SessionID.





[QFJ-720] Improve log output when creating sessions and on unknown session ID during Logon Created: 28/Nov/12  Updated: 07/Nov/13  Resolved: 29/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-758 Improve log output on incoming connec... Closed

 Description   

To ease the analysis of connection problems when working with multiple sessions/ports/log files it would be handy if there was a little more information given in one log line. This is especially necessary when grepping over multiple log files.

When starting a session the output is currently:
Listening for connections at <local address>

But should be something like:
Listening for connections at <local address> for sessions [<list of sessions>]

When there is an unknown session id encountered during logon, the output is currently:
Unknown session ID during logon: <session ID>

But to quickly identify the session which is concerned, the following output is better:
Unknown session ID during logon: <session ID> connecting from <remote address> to <local address> cannot be found in session list: [<list of sessions>]






[QFJ-719] Document all FIX Session settings Created: 27/Nov/12  Updated: 30/Nov/12  Resolved: 30/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None

Attachments: Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip    

 Description   

Answering a question posted on the mailing list I found at least one undocumented setting:

  • The TestRequestDelayMultiplier is not documented.

So we should document it and at the same time check for other undocumented features.
Here is the list of all session setttings (defined as constant with the prefix "SETTING_" in the Session class) which are
not mentioned in the "configuration.html":

  • TestRequestDelayMultiplier
  • NonStopSession
  • DisableHeartBeatCheck
  • ForceResendWhenCorruptedStore
  • AllowedRemoteAddresses

Steps

  • Added documentation for missing items.
  • Corrected formatting:
  • Some settings are not in italics.
  • Always "Y<BR>N".


 Comments   
Comment by Jörg Thönnes [ 30/Nov/12 ]

Extracted the text strings of all SETTINGS_* constants from the Session class and did a grep on the configuration.html:

for s in $(< QFJ-Settings-List.txt ); do echo -n "$s:"; grep -c "$s" configuration.html ; done|grep :0
TestRequestDelayMultiplier:0
NonStopSession:0
DisableHeartBeatCheck:0
ForceResendWhenCorruptedStore:0
AllowedRemoteAddresses:0
Comment by Jörg Thönnes [ 30/Nov/12 ]

Documented TestRequestDelayMultiplier.

Comment by Jörg Thönnes [ 30/Nov/12 ]

Finished documentation of all listed options and improved formatting.





[QFJ-718] Logout message sent after event "resetting sequence numbers to 1" with msgSeqNum too low error Created: 22/Nov/12  Updated: 16/Dec/13  Resolved: 16/Dec/13

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

Type: Bug Priority: Default
Reporter: Ashish Goswami Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: QuickfixJ, logon
Environment:

Windows7


Issue Links:
Relates
relates to QFJ-444 Logout logic problem Resolved

 Description   

Acceptor program sometimes send logout message with msgSeqNum too low error after receving logon message with reset Seq num flag<TAG 141>=Y.

Expected Behavior: Acceptor program should reset the seq and send the log on message

Config file settings:

ResetOnDisconnect=Y
ResetOnLogout=Y
ResetOnLogon=Y

Entries from Log file When this error happens:

2012-11-10 18:59:13,045 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=61|35=0|34=182|49=CD|52=20121110-23:59:13.045|56=DLR1|10=068|
2012-11-10 18:59:33,325 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=61|35=0|34=189|49=DLR1|52=20121110-23:59:54.923|56=CD|10=085|
2012-11-10 18:59:33,325 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=61|35=0|34=183|49=CD|52=20121110-23:59:33.325|56=DLR1|10=072|
2012-11-10 18:59:37,599 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=61|35=5|34=190|49=DLR1|52=20121110-23:59:59.199|56=CD|10=092|
2012-11-10 18:59:37,599 INFO event - FIX.4.4:CD->DLR1: Received logout request
2012-11-10 18:59:37,599 INFO Session - [FIX.4.4:CD->DLR1] Disconnecting: IO Session closed
2012-11-10 18:59:37,599 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=61|35=5|34=184|49=CD|52=20121110-23:59:37.599|56=DLR1|10=095|
2012-11-10 18:59:37,599 INFO event - FIX.4.4:CD->DLR1: No responder, not sending message: 8=FIX.4.4|9=61|35=5|34=184|49=CD|52=20121110-23:59:37.599|56=DLR1|10=095|
2012-11-10 18:59:37,599 INFO event - FIX.4.4:CD->DLR1: Sent logout response
2012-11-10 18:59:37,599 INFO event - FIX.4.4:CD->DLR1: Already disconnected: Received logout request
2012-11-10 19:00:12,700 INFO AcceptorIoHandler - MINA session created: /124.30.187.33:35167
2012-11-10 19:00:12,980 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=77|35=A|34=1|49=DLR1|52=20121111-00:00:34.573|56=CD|98=0|108=20|141=Y|10=046|
2012-11-10 19:00:12,980 INFO event - FIX.4.4:CD->DLR1: Accepting session FIX.4.4:CD->DLR1 from /124.30.187.33:35167
2012-11-10 19:00:12,980 INFO event - FIX.4.4:CD->DLR1: Acceptor heartbeat set to 20 seconds
2012-11-10 19:00:12,980 INFO event - FIX.4.4:CD->DLR1: Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
2012-11-10 19:00:12,980 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=112|35=5|34=185|49=CD|52=20121111-00:00:12.980|56=DLR1|58=MsgSeqNum too low, expecting 191 but received 1|10=110|
2012-11-10 19:00:12,980 ERROR errorEvent - FIX.4.4:CD->DLR1: quickfix.SessionException MsgSeqNum too low, expecting 191 but received 1
2012-11-10 19:00:12,980 ERROR errorEvent - FIX.4.4:CD->DLR1: Disconnecting: Verifying message failed: quickfix.SessionException: MsgSeqNum too low, expecting 191 but received 1

Entries from log file when it works fine

2012-11-21 00:19:36,335 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=60|35=0|34=12|49=CD|52=20121121-05:19:36.335|56=DLR1|10=016|
2012-11-21 00:19:48,597 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=60|35=0|34=13|49=DLR1|52=20121121-05:19:58.465|56=CD|10=025|
2012-11-21 00:19:56,335 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=60|35=0|34=13|49=CD|52=20121121-05:19:56.335|56=DLR1|10=019|
2012-11-21 00:19:57,598 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=60|35=5|34=14|49=DLR1|52=20121121-05:20:07.458|56=CD|10=019|
2012-11-21 00:19:57,598 INFO event - FIX.4.4:CD->DLR1: Received logout request
2012-11-21 00:19:57,598 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=60|35=5|34=14|49=CD|52=20121121-05:19:57.598|56=DLR1|10=037|
2012-11-21 00:19:57,598 INFO event - FIX.4.4:CD->DLR1: Sent logout response
2012-11-21 00:19:57,598 INFO Session - [FIX.4.4:CD->DLR1] Disconnecting: Received logout request
2012-11-21 00:20:34,274 INFO AcceptorIoHandler - MINA session created: /124.30.187.33:4995
2012-11-21 00:20:55,162 INFO incoming - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=77|35=A|34=1|49=DLR1|52=20121121-05:21:05.042|56=CD|98=0|108=20|141=Y|10=044|
2012-11-21 00:20:55,162 INFO event - FIX.4.4:CD->DLR1: Accepting session FIX.4.4:CD->DLR1 from /124.30.187.33:4995
2012-11-21 00:20:55,162 INFO event - FIX.4.4:CD->DLR1: Acceptor heartbeat set to 20 seconds
2012-11-21 00:20:55,162 INFO event - FIX.4.4:CD->DLR1: Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
2012-11-21 00:20:55,162 INFO event - FIX.4.4:CD->DLR1: Received logon
2012-11-21 00:20:55,162 INFO outgoing - FIX.4.4:CD->DLR1: 8=FIX.4.4|9=77|35=A|34=1|49=CD|52=20121121-05:20:55.162|56=DLR1|98=0|108=20|141=Y|10=051|
2012-11-21 00:20:55,162 INFO event - FIX.4.4:CD->DLR1: Responding to logon request



 Comments   
Comment by Christoph John [ 22/Nov/12 ]

At first sight this looks a lot like QFJ-444 where some state flags were not reset. Could you please check if the behaviour can still be observed with QF/J 1.5.3 (should be out in the next few weeks)?

Comment by Ashish Goswami [ 22/Nov/12 ]

Thanks for the update, It looks like i have similar issue, Will wait for QF/J 1.5.3





[QFJ-717] Use the same session for initiator and acceptor Created: 15/Nov/12  Updated: 15/Nov/12  Resolved: 15/Nov/12

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

Type: Other Priority: Default
Reporter: Eugene Lin Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: sequnece
Environment:

QFJ engine under Linux



 Description   

trying to use the same session for both initiator and acceptor, using the same port. How to set up connection Type if it is doable ?

thanks



 Comments   
Comment by Grant Birchmeier [ 15/Nov/12 ]

Please send help requests to the mailing list.
http://quickfixj.org/support/

Closing this issue because it's not a bug.





[QFJ-716] Logout message is still sent before Logon on Initiators Created: 08/Nov/12  Updated: 13/Nov/12  Resolved: 13/Nov/12

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Relates
relates to QFJ-357 Logout message is sent before Logon o... Closed

 Description   

Follow-up to QFJ-357.

The problem still exists on Initiators in some cases. If an initiator is started before its StartTime is reached it can happen that a Logout message is sent as first message.



 Comments   
Comment by Christoph John [ 13/Nov/12 ]

Committed as rev #1100.





[QFJ-715] CLONE - To handle 880 tag in FIX4.4 protocol using quickfixj1.3.3 jar Created: 08/Nov/12  Updated: 08/Nov/12  Resolved: 08/Nov/12

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Lailesh Jawale Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Production



 Description   

Hi,

I am trying to populate some extra fields as part of my ongoing requirment in project for clearing fields.
The extra tags need to be populated are:

Repeating group is:
453 =2 (448=CME447=D452=21448=CCP447=D452=16)
1003 and 880 tags

To process the repeating group we require to use DataDictionay internally so we are using it as below:

1) The call for quickfix message is:
quickfix.Message(msb.toString(), new DataDictionary("FIX44.xml"), true);

2) UseDataDictionary=Y as configuration part for FIX level.

We are able to genearte the repeating group (453 =2 (448=CME447=D452=21448=CCP447=D452=16)) and 1003 tag successfully, however when we tray to pass 880 field the quickfixj 1.3.3 throws an error as:

********************************************************************************
Exception stack is:
1. Header fields out of order (quickfix.InvalidMessage)
quickfix.Message:386 (null)
2. Component that caused exception is: SedaService

{PreprocessServiceComponent}

. Message payload is of type: String (org.mule.api.service.ServiceException)
org.mule.component.DefaultLifecycleAdapter:216 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/service/ServiceException.html)
********************************************************************************
Root Exception stack trace:
quickfix.InvalidMessage: Header fields out of order

**********************************************************************************

Please guide us to handle 880 tag along with repeating group and 1003 tag in fix4.4 protocol and using quickfixk1.3.3 jar.



 Comments   
Comment by Lailesh Jawale [ 08/Nov/12 ]

I have updated the quickfix jar to 1.5.2 version, still I am getting problems as :

Message : Component that caused exception is: SedaService

{PreprocessServiceComponent}. Message payload is of type: String
Type : org.mule.api.service.ServiceException
Code : MULE_ERROR--2
Payload : 35=8|116=AUTOMAT01|115=AUTOMAT|1=CMECC@AUTOMAT|6=53.880000000|11=74121601|14=100000.000000000|15=USD|17=1675136|30=TRA|31=53.880000000|32=100000.000000000|37=TRAIANA_354877064|38=100000.000000000|39=2|54=1|55=USDINR|60=20121029-19:25:55|64=20121108|75=20121029|120=INR|150=F|119=5388000.000000000|194=53.880000000|195=.000000000|461=Forward|1003=1675136|453=2|448=CME|447=D|452=21|448=CCP|447=D|452=16|541=20121106|880=123|
JavaDoc : http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/service/ServiceException.html
********************************************************************************
Exception stack is:
1. Field [35] was not found in message. (quickfix.InvalidMessage)
quickfix.Message:426 (null)
2. Component that caused exception is: SedaService{PreprocessServiceComponent}

. Message payload is of type: String (org.mule.api.service.ServiceException)
org.mule.component.DefaultLifecycleAdapter:216 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/service/ServiceException.html)
********************************************************************************
Root Exception stack trace:
quickfix.InvalidMessage: Field [35] was not found in message.
at quickfix.Message.getMsgType(Message.java:426)
at quickfix.Message.parseBody(Message.java:448)
at quickfix.Message.fromString(Message.java:358)

The input sample is :
35=8|116=AUTOMAT01|115=AUTOMAT|1=CMECC@AUTOMAT|6=53.880000000|11=74121601|14=100000.000000000|15=USD|17=1675136|30=TRA|31=53.880000000|32=100000.000000000|37=TRAIANA_354877064|38=100000.000000000|39=2|54=1|55=USDINR|60=20121029-19:25:55|64=20121108|75=20121029|120=INR|150=F|119=5388000.000000000|194=53.880000000|195=.000000000|461=Forward|1003=1675136|453=2|448=CME|447=D|452=21|448=CCP|447=D|452=16|541=20121106|880=123|

We are using java methods to call the quickfixj.message method as:

new quickfix.Message(msb.toString(), new DataDictionary("FIX44.xml"), false);

Please guide us we are getting issues only when we add 880 tag in input, otherwise rest tags work properly with repeting group and 1003 tag.

Comment by Christoph John [ 08/Nov/12 ]

As stated on QFJ-714:

You should join the mailing list and send your question there. The JIRA system is for tracking engine bugs and is not monitored by many people.

http://quickfixj.org/support/

Thank you!!!





[QFJ-714] To handle 880 tag in FIX4.4 protocol using quickfixj1.3.3 jar Created: 07/Nov/12  Updated: 07/Nov/12  Resolved: 07/Nov/12

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Lailesh Jawale Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Production



 Description   

Hi,

I am trying to populate some extra fields as part of my ongoing requirment in project for clearing fields.
The extra tags need to be populated are:

Repeating group is:
453 =2 (448=CME447=D452=21448=CCP447=D452=16)
1003 and 880 tags

To process the repeating group we require to use DataDictionay internally so we are using it as below:

1) The call for quickfix message is:
quickfix.Message(msb.toString(), new DataDictionary("FIX44.xml"), true);

2) UseDataDictionary=Y as configuration part for FIX level.

We are able to genearte the repeating group (453 =2 (448=CME447=D452=21448=CCP447=D452=16)) and 1003 tag successfully, however when we tray to pass 880 field the quickfixj 1.3.3 throws an error as:

********************************************************************************
Exception stack is:
1. Header fields out of order (quickfix.InvalidMessage)
quickfix.Message:386 (null)
2. Component that caused exception is: SedaService

{PreprocessServiceComponent}

. Message payload is of type: String (org.mule.api.service.ServiceException)
org.mule.component.DefaultLifecycleAdapter:216 (http://www.mulesource.org/docs/site/current2/apidocs/org/mule/api/service/ServiceException.html)
********************************************************************************
Root Exception stack trace:
quickfix.InvalidMessage: Header fields out of order

**********************************************************************************

Please guide us to handle 880 tag along with repeating group and 1003 tag in fix4.4 protocol and using quickfixk1.3.3 jar.



 Comments   
Comment by Grant Birchmeier [ 07/Nov/12 ]

You should join the mailing list and send your question there. The JIRA system is for tracking engine bugs and is not monitored by many people.

http://quickfixj.org/support/

Comment by Christoph John [ 07/Nov/12 ]

Please do not forget to add the code excerpt which shows how you add the fields to the message/header.





[QFJ-713] On JDK 7 unexpectedly find a registerd MBean for the ObjectName("org.quickfixj:type=Connector,role=Acceptor,*") by the camel-quickfix component of Apache Camel Created: 05/Nov/12  Updated: 19/Nov/12  Resolved: 19/Nov/12

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

Type: Bug Priority: Default
Reporter: Babak Vahdat Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: jmx


 Description   

Using QuickFixJ version 1.5.2-bd by camel-quickfix we're observing some odd test failures on JDK 7 profile of Apache Camel however the behaviour is nondeterministic as we see the failed tests only from time to time where all the tests of QuickfixjEngineTest do fail because of the same assert, but as already said only on the JDK 7 and just from time to time. Also we cann't reproduce the issue locally. As you see on the trunk currently we've disabled the assert on JDK7.

The stacktrace of the failed assert looks as the following:

java.lang.AssertionError: QFJ mbean should not have been registered
	at org.junit.Assert.fail(Assert.java:93)
	at org.junit.Assert.assertTrue(Assert.java:43)
	at org.apache.camel.component.quickfixj.QuickfixjEngineTest.assertDefaultConfiguration(QuickfixjEngineTest.java:569)
	at org.apache.camel.component.quickfixj.QuickfixjEngineTest.defaultAcceptor(QuickfixjEngineTest.java:161)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:119)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:101)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103)
	at $Proxy0.invoke(Unknown Source)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69)

Which corresponds to this revision of QuickfixjEngineTest.

Currently we've disabled this assert as you can see by the revision history of this class.

Please also note that QuickfixjEngine does properly register/unregister the MBean, see it's doStart & doStop methods. This component's documentation is here. Any hint or idea would be much appreciated. Please let us know if there's any more details you may need.



 Comments   
Comment by Babak Vahdat [ 05/Nov/12 ]

For more details also see https://issues.apache.org/jira/browse/CAMEL-5751

Comment by Christoph John [ 05/Nov/12 ]

Just out of curiosity (I'm pretty sure it does not solve the problem since it would be too obvious ):
Why don't you unregister the MBean for acceptors in the same way as you do for initiators?

Comment by Babak Vahdat [ 05/Nov/12 ]

Ah thanks, yeah indeed it was too obvious to be the cause of the problem and I must have been blind not to see it. Indeed I overlooked this as I committed the fix for https://issues.apache.org/jira/browse/CAMEL-5686
Anyway I've applied a patch into the trunk and reenabled the test again on JDK 7 as well, so let's see how the things will go. Already keeping my fingers crossed!

Comment by Christoph John [ 10/Nov/12 ]

And you say that the same tests always passed on JDK6? Although the beans were not correctly deregistered?

Comment by Babak Vahdat [ 10/Nov/12 ]

Exactly! And this was exactly what baffling me. The same tests never failed on JDK 6.

Comment by Babak Vahdat [ 11/Nov/12 ]

There has been no single test failure on the CI-Server since the fix, following the last run from yesterday:

https://builds.apache.org/job/Camel.trunk.fulltest.java7/356/org.apache.camel$camel-quickfix/testReport/org.apache.camel.component.quickfixj/QuickfixjEngineTest/

Still keeping my fingers crossed

Comment by Christoph John [ 12/Nov/12 ]

Sounds good. I think we should define a reasonable time after which this ticket can be closed.

Comment by Babak Vahdat [ 19/Nov/12 ]

O.K. I think it's time to close this ticket as the issue has not popped up anymore. @Christoph would you please close this ticket as apparently I don't have enough JIRA permission to do that. At least I don't see any "Resolve Issue" button.

Once again thanks for your help.





[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.





[QFJ-711] Lost Order Requests Created: 24/Oct/12  Updated: 24/Oct/12  Resolved: 24/Oct/12

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

Type: Bug Priority: Critical
Reporter: Robert Shalonov Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Linux x86_64



 Description   

When we get two order requests at the same time, the quickFixJ does not notify us of the second order. The fromApp method only notifies us of the first order and the second order gets lost. In the order requests bellow that came almost at the same time, only the first order got processed. Please, advise.

8=FIX.4.4 9=166 35=D 34=1904 49=CLIENT 52=20121024-12:37:39.100 56=SERVER-ORD 1=CLIENT_FIX 11=19_0_3_6_1_45459 21=1 38=250000 40=1 44=0.98956 54=1 55=USD/CAD 59=1 6 0=20121024-12:37:39.100 10=048
8=FIX.4.4 9=166 35=D 34=1905 49=CLIENT 52=20121024-12:37:39.101 56=SERVER-ORD 1=CLIENT_FIX 11=19_0_2_6_1_45459 21=1 38=800000 40=1 44=0.98956 54=1 55=USD/CAD 59=1 6 0=20121024-12:37:39.101 10=051



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

You should join the mailing list and send your question there. The JIRA system is for tracking engine bugs and is not monitored by many people.

http://quickfixj.org/support/

When you send your message, you should attach the part of your message logs that contains these messages. That will be helpful.

Comment by Robert Shalonov [ 24/Oct/12 ]

Why it's not a bug? Can you explain yourself before closing the issue?

Comment by Christoph John [ 24/Oct/12 ]

Explanation in comment above. Sorry, but the mailing list is a better fit for exchanging information before opening issue tickets.
When writing to the mailing list please include some more lines of message and event log. Thanks.

Comment by Grant Birchmeier [ 24/Oct/12 ]

Looks like it might be legitimate. Please send to the mailing list. We can reopen this bug if it turns out to be legit.

(Forgive us, we get a lot of people opening lame tickets which are little more than requests for help.)

Comment by Robert Shalonov [ 24/Oct/12 ]

how can I truck the issue on the mailing list? url perhaps?





[QFJ-710] Lost Subscription Requests Created: 23/Oct/12  Updated: 24/Oct/12  Resolved: 24/Oct/12

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

Type: Bug Priority: Critical
Reporter: Robert Shalonov Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Linux x86_64 GNU/Linux



 Description   

We are using QuickFIX/J 1.5.2 . Our application runs as an Acceptor for our client. The client sends us a subscription requests for different symbols. However, out of 10 subscription requests send by the client our application gets only 8 requests. The 10 requests do show up on our fix messages logs. However, fromApp(quickfix.Message message, quickfix.SessionID sessionID) call back method only notifies us of 8 requests and not 10. Why fromApp() method notifies us only of 8 requests and not 10 despite of ten requests showing up in fix messages log? It happens sporadically. Our client is very unhappy about it and our reputation is on the line. Please, advise ASAP. Thanks.



 Comments   
Comment by Grant Birchmeier [ 23/Oct/12 ]

You should join the mailing list and send your question there. The JIRA system is for tracking engine bugs and is not monitored by many people.

http://quickfixj.org/support/

When you send your message, you should attach the part of your message logs that contains these messages. That will be helpful.





[QFJ-709] expose field order constructor for message header and trailer Created: 15/Oct/12  Updated: 15/Oct/12  Resolved: 15/Oct/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
is required by QFJ-416 Support Header/Trailer field ordering... Open

 Description   

As a first step towards header/trailer field ordering in code generation, we need to make the field order constructors for header and trailer visible.






[QFJ-708] SocketTcpNoDelay does not seem to work Created: 04/Oct/12  Updated: 09/Oct/12  Resolved: 09/Oct/12

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

Type: Other Priority: Default
Reporter: Paul Mason Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: QuickfixJ
Environment:

Linux Redhat 4.1.2-44



 Description   

Hi.

I'm using QuickFIX/J version 1.3.1. And in my config file I have SocketTcpNoDelay=Y under the [default] section. However, using TCP Dump and Wireshark, it looks like Nagle is not disabled.
Couple of questions.

1. Was this a known issue in version 1.3.1.?
2. Do I have the setting in the wrong place?
3. Is it possible for Linux to overide this setting?

Thanks.



 Comments   
Comment by Grant Birchmeier [ 04/Oct/12 ]

Send your question to the mailing list. Jira is for bugs, and few people will be notified.

Comment by Paul Mason [ 04/Oct/12 ]

OK. sorry.
Thanks.

Comment by Christoph John [ 09/Oct/12 ]

There was QFJ-344 which was fixed in QF/J 1.3.3. That issue deals with the setting of SocketTcpNoDelay and might fix your problem. Could you work with that (or a current) version of QF/J?

Comment by Paul Mason [ 09/Oct/12 ]

Thanks for the response.

I found that if I set the SocketTcpNoDelay in the [session] section, it did take effect.
The plan obviously is to upgrade to the latest version, but these things move very slowly where I work.

Regards,

Comment by Christoph John [ 09/Oct/12 ]

OK, thanks for the update.

Cheers





[QFJ-707] DefaultMessageFactory class docs should not advise users to make subclasses Created: 21/Sep/12  Updated: 09/Oct/12  Resolved: 09/Oct/12

Status: Resolved
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: None
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Grant Birchmeier
Resolution: Fixed Votes: 0
Labels: None


 Description   

DefaultMessageFactory's docs say:

"The default factory for creating FIX message instances. Create subclasses of this factory for generating custom messages using nonstandard message types."

Looking at the source, this has to be wrong. There's no way a subclass of this can be useful, unless it entirely re-implements one or both of the create() methods, which are the only public methods anyway.

Users should instead subclass MessageFactory, and pass that to the Socket/Session constructors.

Suggested fix: Strike the second sentence from the above-quoted doc comment.



 Comments   
Comment by Grant Birchmeier [ 09/Oct/12 ]

fixed in 1091

Comment by Christoph John [ 09/Oct/12 ]

Changed assignee to Grant.





[QFJ-706] we create a order cancel request when testing FIX4.4 and do not send tag55(Symbol),QuickFIX Engine promotes 'Required tag missing' Created: 18/Sep/12  Updated: 19/Sep/12  Resolved: 18/Sep/12

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

Type: Other Priority: Default
Reporter: 杨吉光 Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: FIX4.4, Instrument, QuickfixJ, Symbol
Environment:

operating system : Windos XP



 Description   

In FIX4.4,tag55(Symbol) is not required necessarily when ceating a order cancel request(msgType='F'),but as the summary said,QuickFIX Engine promotes 'Required tag missing'.



 Comments   
Comment by Christoph John [ 18/Sep/12 ]

This depends on your counterparty's data dictionary.

Please ask such general questions on the mailing list: http://quickfixj.org/support/

Thank you.

Comment by 杨吉光 [ 18/Sep/12 ]

Hi Christoph,

our counterparty's data dictionary for FIX4.4 doesn't contains Symbol in MsgType='F'.

<message name="OrderCancelRequest" msgtype="F" msgcat="app">
<field name="OrigClOrdID" required="Y"/>
<field name="OrderID" required="N"/>
<field name="ClOrdID" required="Y"/>
<field name="SecondaryClOrdID" required="N"/>
<field name="ClOrdLinkID" required="N"/>
<field name="ListID" required="N"/>
<field name="OrigOrdModTime" required="N"/>
<field name="Account" required="N"/>
<field name="AcctIDSource" required="N"/>
<field name="AccountType" required="N"/>
<component name="Parties" required="N"/>
<component name="Instrument" required="Y"/>
<component name="FinancingDetails" required="N"/>
<group name="NoUnderlyings" required="N">
<component name="UnderlyingInstrument" required="N"/>
</group>
<field name="Side" required="Y"/>
<field name="TransactTime" required="Y"/>
<component name="OrderQtyData" required="Y"/>
<field name="ComplianceID" required="N"/>
<field name="Text" required="N"/>
<field name="EncodedTextLen" required="N"/>
<field name="EncodedText" required="N"/>
</message>

Comment by Christoph John [ 18/Sep/12 ]

Hi,
the Symbol is specified in the Instrument component.

Comment by 杨吉光 [ 19/Sep/12 ]

Hi Christoph,

although the Symbol is specified in the Instrument component,but it's not required necessarily as below.

FIX 4.4 : <Instrument> component block
Tag Field Name Req'd
55 Symbol N





[QFJ-705] Redundant ResendRequest is sent after logon when tag 789 based recovery is supposed to be used Created: 17/Sep/12  Updated: 18/Sep/12  Resolved: 18/Sep/12

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1, 1.5.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Andrzej Hajderek Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-704 New parameter "EnableResendRequest" t... Closed
Relates
relates to QFJ-567 Would like QuickFix/J to natively sup... Resolved

 Description   

Hi,

It looks like more and more people are experiencing the same issue - tag 789 support is incomplete. Please see:
http://www.quickfixj.org/jira/browse/QFJ-567
http://www.quickfixj.org/jira/browse/QFJ-704

Below I propose a partial fix for the problem. Since it requires only two lines of code it should be easier to accept, assuming it does not break anything else.

I propose to make the call to doTargetTooHigh(logon) in in nextLogon(Message logon) conditional:

private void nextLogon(Message logon) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage

{ ... boolean useTag789 = enableNextExpectedMsgSeqNum && logon.isSetField(NextExpectedMsgSeqNum.FIELD); if (!useTag789) doTargetTooHigh(logon); ... }

The above condition ensures that when tag 789 mode recovery is enabled the ResendRequest will not be sent.

In fact some trading platforms do not allow a redundant ResendRequest. I tested this fix with an initiator application connecting to Reuters MAPI FIX (Drop Copy).

Regards,
Andrzej Hajderek



 Comments   
Comment by Andrzej Hajderek [ 17/Sep/12 ]

Sorry, the first link should have been:

http://www.quickfixj.org/jira/browse/QFJ-567

Comment by Christoph John [ 18/Sep/12 ]

Corrected link.





[QFJ-704] New parameter "EnableResendRequest" to disable sending ResedRequest message Created: 14/Sep/12  Updated: 18/Sep/12  Resolved: 18/Sep/12

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

Type: New Feature Priority: Default
Reporter: Krzysztof Szalast Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

ALL


Issue Links:
Duplicate
duplicates QFJ-705 Redundant ResendRequest is sent after... Closed

 Description   

WSE in new system requires to not send ResendRequest Message. Gaps is filled by data from 789 tag. I propose to add new parameter:
EnableResendRequest=Y|N (default Y)
If "EnableResendRequest==N" then QuickFix/J don't send ResendRequests.

Affects methods:
quickfix.Session::nextSequenceReset(Message sequenceReset):
(...)
} else if (newSequence >= range[2]) {
state.setNextTargetMsgSeqNum(newSequence + 1);
final String beginString = sequenceReset.getHeader().getString(BeginString.FIELD);
if (this.enableResendRequest)

{ sendResendRequest(beginString, range[1] + 1, newSequence + 1, range[1]); }

}
(...)

and:

quickfix.Session::verify(Message msg, boolean checkTooHigh, boolean checkTooLow)
(...)
if (msgSeqNum < range[1] && range[2] > 0 && msgSeqNum >= range[2]) {
final String beginString = header.getString(BeginString.FIELD);
if (this.enableResendRequest)

{ sendResendRequest(beginString, range[1] + 1, msgSeqNum + 1, range[1]); }

}
(...)

and:

quickfix.Session::doTargetTooHigh(Message msg)
(...)
Last line:
if (this.enableResendRequest)

{ generateResendRequest(beginString, msgSeqNum); }

(...)



 Comments   
Comment by Andrzej Hajderek [ 17/Sep/12 ]

Having the same problem I proposed a smaller change (2 lines) that seems to work:

http://www.quickfixj.org/jira/browse/QFJ-705

Krzysztof,

If you tested it in your project and confirmed, it could help this case.

Comment by Christoph John [ 18/Sep/12 ]

Hi Krzysztof,

we will track the needed changes on QFJ-705 now. Hope that is OK for you.

Cheers,
Chris.





[QFJ-703] Do not reject PossDup message which does not have OrigSendingTime tag set Created: 10/Sep/12  Updated: 11/Sep/12  Resolved: 11/Sep/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: session

Issue Links:
Relates
relates to QFJ-654 Rejecting due to OrigSendingTime not ... Closed
is related to QFJ-403 Rejecting due to OrigSendingTime not ... Closed

 Description   

I think we should just check if tag 122/OrigSendingTime is present and if it isn't we shouldn't do the SendingTime vs. OrigSendingTime check.

QF/J should rather try to synchronize correctly instead of throwing validation errors. So we will introduce a configuration "RequiresOrigSendingTime" which defaults to true to keep the original behaviour.



 Comments   
Comment by Grant Birchmeier [ 10/Sep/12 ]

Someone on the QF/n list is having a similar problem, e.g. an exchange is not including OrigSendingTime.

Thus he is working on a patch that will allow config RequiresOrigSendingTime=N to disable checking of this field. (Default =Y). Maybe QF/j could use this as well.

Comment by Christoph John [ 11/Sep/12 ]

Hi Grant, thanks for the pointer. Sounds reasonable to have the same naming.





[QFJ-702] ERROR QFJ Timer errorEvent:logError:147 - FIX.4.2:DBSWMT->ATR: java.io.IOException: java.io.IOException: Permission denied Created: 10/Sep/12  Updated: 10/Sep/12  Resolved: 10/Sep/12

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

Type: Other Priority: Default
Reporter: Oliver Capalad Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

Sun Solaris



 Description   

Hi,

We are getting the below when we started fix bridge after we have switch server.

ERROR QFJ Timer errorEvent:logError:147 - FIX.4.2:DBSWMT->ATR: java.io.IOException: java.io.IOException: Permission denied



 Comments   
Comment by Christoph John [ 10/Sep/12 ]

Given the little amount of information you have submitted, I assume this is no bug but rather an issue of the correct file permissions on the new server (different user name maybe?). You could either correct the file permissions or delete the filestore and have it newly created on the new sever.

However, please ask such general questions on the mailing list: http://quickfixj.org/support/

Thank you.





[QFJ-701] Restart FIX engine occur I/O exception Created: 04/Sep/12  Updated: 04/Sep/12  Resolved: 04/Sep/12

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

Type: Other Priority: Default
Reporter: Li,Wei Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: logon
Environment:

Windows 2003 Server


Issue Links:
Relates
is related to QFJ-653 IOException if sessionTimestamp file ... Closed

 Description   

Recently when our system was restarted, occasionally occur I/O exception, the following:

quickfix.ConfigError: error during session initialization
at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:135)
at quickfix.mina.initiator.AbstractSocketInitiator.createSessionInitiators(AbstractSocketInitiator.java:84)
at quickfix.SocketInitiator.initialize(SocketInitiator.java:84)
at quickfix.SocketInitiator.start(SocketInitiator.java:64)
at com.rootnet.fix.framework.FixModule.startup(FixModule.java:142)
at com.rootnet.fix.algo.FixAlgoGateway.main(FixAlgoGateway.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.tanukisoftware.wrapper.WrapperSimpleApp.run(WrapperSimpleApp.java:238)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.RuntimeException: java.io.IOException
at quickfix.FileStoreFactory.create(FileStoreFactory.java:80)
at quickfix.Session.<init>(Session.java:338)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:156)
at quickfix.mina.SessionConnector.createSession(SessionConnector.java:114)
at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:129)
... 11 more
Caused by: java.io.IOException
at quickfix.FileStore.initializeSessionCreateTime(FileStore.java:133)
at quickfix.FileStore.initializeCache(FileStore.java:120)
at quickfix.FileStore.initialize(FileStore.java:113)
at quickfix.FileStore.<init>(FileStore.java:100)
at quickfix.FileStoreFactory.create(FileStoreFactory.java:78)
... 15 more

I check .session file in store directory, find that it is an empty file. And as long as this file is empty, start FIX engine must occur this I/O exception.

I compare quickfixj1.4.0 and quickfixj1.5.2, find the code was strengthened, increased 'sessionTimeFile.length() > 0', by this way when .session file is an empty file, will execute storeSessionTimeStamp(), program will be correctly executed. This handle whether it is in order to avoid .session empty file lead to I/O exception. So what science would generate a empty .session file?

--quickfixj1.5.2
private void initializeSessionCreateTime() throws IOException {
final File sessionTimeFile = new File(sessionFileName);
if (sessionTimeFile.exists() && sessionTimeFile.length() > 0) {
final DataInputStream sessionTimeInput = new DataInputStream(new BufferedInputStream(
new FileInputStream(sessionTimeFile)));
try

{ final Calendar c = SystemTime.getUtcCalendar(UtcTimestampConverter .convert(sessionTimeInput.readUTF())); cache.setCreationTime(c); }

catch (final Exception e)

{ throw new IOException(e.getMessage()); }

finally

{ sessionTimeInput.close(); }

} else

{ storeSessionTimeStamp(); }

}



 Comments   
Comment by Christoph John [ 04/Sep/12 ]

I don't really understand the intention of this issue.

Is it just the question under which circumstances an empty session file would be generated? I don't know exactly but we also faced this issue when one of our process crashed on startup. I guess this is due to the method FileStore.storeSessionTimeStamp() which creates the file and closes it (regardless of whether a timestamp could be stored or not).

Comment by Christoph John [ 04/Sep/12 ]

If you still have questions, please ask on the mailing list: http://quickfixj.org/support/

Thank you.





[QFJ-700] QFJ Timer and QFJ message processor try to execute generateLogout() at the same time, resulting in QFJ Timer to stop Created: 16/Aug/12  Updated: 08/Apr/14  Resolved: 10/Oct/12

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

Type: Bug Priority: Critical
Reporter: Martijn Stokhof Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: QFJ, SessionSchedule, Timer, session
Environment:

Microsoft Windows [Version 6.1.7601]

java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)


Attachments: Text File thread_dump_QFJ-700-1-after.mdd.txt     Text File thread_dump_QFJ-700-2-after.sfx.txt    
Issue Links:
Duplicate
duplicates QFJ-645 Deadlock between message sending and ... Resolved
is duplicated by QFJ-571 QFJ Timer - JDBCStore reset issues Closed

 Description   

Our application runs 24/7. We have started using a weekly SessionSchedule (Sunday 17:02 - Friday 16:59:50). In the out-of-schedule period, several clients try to connect, every 2 seconds, sending Logon messages to our application. As far as I know, the QFJ Timer regularly checks if the Session is already within schedule and if not, resets the Session.

In this out-of-schedule period, it happens that both QFJ Timer and QFJ message processor try to execute Session.generateLogout(...) at the same time (within the same millisecond). QFJ timer does that as result from the regular Session-check, QFJ MessageProcessor as a result from the received Logon message. None of the two is able to generate the logout and QFJ Timer stops checking the Session(s) regularly. At the SessionSchedule start, the Session(s) is not valid because it has not been reset since the unsuccesful Session.generateLogout(...). No client can Logon because "Logon rejected: quickfix.RejectLogon: Logon attempt not within session time". This is a critical problem: we have to stop and restart our application to reset all Sessions.

To investigate and pinpoint this, I have added several debug-statements to get to this conclusion. I would like to stress that we experience this every out-of-schedule-period where clients try to logon continously and the Session.generateLogout(...) is called within the same millisecond. It is reproducable, but you might have to wait for several hours to see this happening.

I cannot oversee the whole issue yet, but it seems that some sort of synchronisation is lacking the generateLogout in this case. I am able to provide log files and help you investigating this.



 Comments   
Comment by Steve Bate [ 17/Aug/12 ]

Are there any exceptions in the log?

Comment by Martijn Stokhof [ 17/Aug/12 ]

Hi Steve,

No, I forgot to mention that, no exceptions in any of the log files.

Comment by Christoph John [ 17/Aug/12 ]

Hi Martijn,
I think a thread dump before and after the problem appears might also be helpful.
thanks, Chris

Comment by Martijn Stokhof [ 17/Aug/12 ]

Hi Chris,

I will do my best. As said, it takes some time to reproduce the problem, but eventually it will occur. When I have more information I will attach it here. Thank you.

Martijn.

Comment by Martijn Stokhof [ 17/Aug/12 ]

Thread-dump 1 and 2, both from after the problem has occured. MDD and SFX are acronyms for two of our applications.

Comment by Martijn Stokhof [ 17/Aug/12 ]

I see a deadlock in both Thread-dumps. These follow (well, kind of ) what I described in the problem description at a first glance.

Comment by Christoph John [ 17/Aug/12 ]

thanks, looks promising. I wonder if this is the same issue as in QFJ-645. The stack trace of the QFJ timer thread looks very similar.

Comment by Christoph John [ 11/Sep/12 ]

Did you have a chance to reproduce this with a trunk build?

Comment by Martijn Stokhof [ 11/Sep/12 ]

Hi Chris,

I have not tried. I am not connected to the Quickfix repository for a trunk build. Can you tell me where to download the latest trunk build or send it to me by email, preferrably with source code included so I can add some extra debug statements? I will then use that build for some extra tests. Thank you.

Kind regards, Martijn Stokhof.

Comment by Martijn Stokhof [ 17/Sep/12 ]

Hi Chris,

Good news: this does not happen anymore with quickfix-trunk build.

I have used a quickfix-trunk build the last couple of days. The SessionSchedule ended on Friday and restarted on Sunday (48 hours later). As described in the original text of this issue, a client continuously tried to logon. Previously we have seen that this caused the QFJ Timer to stop. The latest test turned out to be successful: the QFJ Timer has not stopped and at the start of the SessionSchedule, the client logged on immediately, as where previously the client was refused to logon because the time was not in the SessionSchedule.

We will continue to monitor this, using the Quickfix-trunk build. So far so good! Thank you for your help and suggestions so far.

Kind regards, Martijn Stokhof.

Comment by Christoph John [ 17/Sep/12 ]

hi Martijn,
sounds good. thanks for the update.
cheers





[QFJ-699] Configuring some sessions with SSL and some other sessions with nonSSL is not working as expected Created: 11/Aug/12  Updated: 24/Aug/12  Resolved: 14/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Viswanath Palutla Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: QuickfixJ, SocketUseSSL, logon, nonssl, ssl

Attachments: Java Source File SSLAndNonSSLTest.java    

 Description   

I have a session configured with SocketUseSSL=Y at port 9887 and another session configured with SocketUseSSL=N at port 9888.
When client for second session (with SocketUseSSL=N at 9888) is trying to connect, a SSL handshake exception is coming.
If same client is connecting with SocketUseSSL=Y at 9888, connection is successful



 Comments   
Comment by Christoph John [ 14/Aug/12 ]

Committed as rev1081.
It turned out that the acceptors were stored in a map in which the transportType was the key. Since for both SSL and non-SSL acceptors the transport type was the same, the same acceptor was used for SSL and non-SSL.
I have added the useSSL-flag to the key to treat SSL and non-SSL acceptors differently.

Comment by Viswanath Palutla [ 14/Aug/12 ]

thanks much





[QFJ-698] Not possible to restart a stopped SocketInitiator using FileLog Created: 09/Aug/12  Updated: 11/Sep/12  Resolved: 11/Sep/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Mate Varga Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   
  • An initiator creates the sessions in start() -> initialize() -> createSessionInitiators()
  • if an initiator is stopped, then the sessions will be unregistered
  • if an initialized initiator is started, then it only re-registers the sessions, and does not recreate them (see initialize())
  • a Session closes it's Log if it's closeable (see Session -> unregisterSessions() -> close() -> closeIfCloseable(getLog())
    a FileLog only opens it's streams in clear() and in it's constructor
  • therefore, if SocketInitiator using a FileLog is stopped, then next time it gets started it will throw exceptions as the underlying file descriptor is closed.

This bug is NOT present in the case of Acceptors as they recreate sessions when they start up.



 Comments   
Comment by Mate Varga [ 09/Aug/12 ]

A simple solution would be to recreate the sessions in SocketInitiator instead of re-registering them. I.e. in SocketInitiator.java:

[Sorry for not giving you a diff, this is probably easier to understand for people and also this is not a patch as I haven't verified that it works properly, but should be more or less correct.]

// Replace this:

private synchronized void initialize() throws ConfigError {
if (!isInitialized)

{ createSessionInitiators(); isInitialized = true; } else {
for (Session session : getSessionMap().values()) { Session.registerSession(session); }
}
startInitiators();
}

// with this:

private synchronized void initialize() throws ConfigError {
if (!isInitialized) { createSessionInitiators(); isInitialized = true; }

else

{ createSessions(); }

}
startInitiators();
}

Comment by Mate Varga [ 24/Aug/12 ]
  • Hi,

I've seen your patch, and in SocketInitiator.java

77 finally {
78 Session.unregisterSessions(getSessions()); Session.unregisterSessions(getSessions());
79 synchronized (lock)

{ 80 isStarted = Boolean.FALSE; 81 }

... I don't really understand
a) why are you using a Boolean instead of a boolean (that's not an issue really, just differs from the QFJ coding style and the accepted Java coding style in general – I'd understand the decision if you synchronised on the object but you create another one to synch on)
b) what is the synchronisation model in general and why are you entering the monitor in stop(). The following can happen: thread 1 is in stop(), and thread 2 is in initialize(). Thread 2 acquires the lock. Thread 1 stops the initiators, etc. and arrives to synchronized block. Thread 2 starts the initiators. Thread 2 sets isStarted=TRUE and releases the lock. Thread 1 acquires the lock and sets isStarted=FALSE. At this point, the initiators are started but isStarted=FALSE.
So it'd make sense to either remove the synchronized block from stop() at least (as it makes no sense in this form) and possibly from initialize() as welll and declare SocketInitiator to be non-thread safe, or move the whole stop() method inside the synchronized block (which still does not guarantee that the whole thing is thread safe).

Comment by Christoph John [ 24/Aug/12 ]

Hi,

Regarding a): this evolved from another patch which was done on SocketAcceptor. There, a Boolean was used as lock variable which was wrong (QFJ-563).

b): You are right about the scenario you described.
But we should try to avoid that an initiator can be stopped and started at the same time. So I think the whole stuff in stop() should also be synchronized.

What do you think?

Comment by Mate Varga [ 24/Aug/12 ]

a):
yes, static globals should not be used for synchronisation but why have you replaced a Boolean with a boolean?

b)
I don't know. That really depends on whether QFJ tries to be thread-safe in general. If yes, then it worths doing this, but if not, then just serialising access to two random methods is misleading because it suggests that the class is thread safe.
It's probably safe to synchronise inside stop(), but so far this has not been the case and I don't know QFJ so well that I could see all possible consequences.

Comment by Christoph John [ 24/Aug/12 ]

a) To have it at least look a little bit like the SocketAcceptor which used Boolean for quite some time.

b) I'll think a little about it and change it. Probably it is OK if the Initiator is just not initialized twice at the same time.

Comment by Christoph John [ 11/Sep/12 ]

Removed synchronization inside stop() method. We just want to make sure that initialization is not done twice/concurrently so we only synchronize access to start() method.





[QFJ-697] Unable to restart a stopped acceptor (SocketAcceptor) -- still exists Created: 08/Aug/12  Updated: 08/Aug/12  Resolved: 08/Aug/12

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Mate Varga Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: None


 Description   

This is a similar issue as in QFJ-348 but for acceptors.

When I do acceptor.start() QF/J says:

Listening for connections at 0.0.0.0/0.0.0.0:10040

netstat output:

tcp6       0      0 :::10040                :::*                    LISTEN

After a stop() and another start(), the acceptor does not print the usual "Listening... at" information and also the netstat output is not listing the port.

A workaround could be to re-create the acceptor. But this is somewhat unexpected since we have start() and stop() methods.

If I interpret the code in the SocketAcceptor.class correctly, all that is needed is to set the "isStarted" flag to FALSE again on a stop(). This would trigger the call of the method "startAcceptingConnections()" on the next start() call. Could someone with more insight into the code please comment on this?

Thanks in advance,
Chris.



 Comments   
Comment by Mate Varga [ 08/Aug/12 ]

The problem still exists.

AbstractSocketAcceptor creates the sessions in it's constructor:

[...]
protected AbstractSocketAcceptor(SessionSettings settings, SessionFactory sessionFactory)
throws ConfigError {
super(settings, sessionFactory);
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
ByteBuffer.setUseDirectBuffers(false);
this.sessionFactory = sessionFactory;
try {
createSessions(settings); // !!!!!
[...]

... but SocketAcceptors unregister them in their stop() method:

public void stop(boolean forceDisconnect) {
eventHandlingStrategy.stopHandlingMessages();
stopAcceptingConnections();
logoutAllSessions(forceDisconnect);
stopSessionTimer();
Session.unregisterSessions(getSessions()); // !!!!

... and do not re-register them in their 'start' method.

The most probable solution is to re-register sessions in 'start', if they have been unregistered.

Comment by Mate Varga [ 08/Aug/12 ]

Hm, this seems to be fixed in 1.5.2. Apologies for reopening, I was probably looking at the wrong source – please close the issue.

Comment by Christoph John [ 08/Aug/12 ]

OK, thanks.
Yes, this was fixed for 1.5.2.





[QFJ-696] Possibility to set SessionStatus on Logout Created: 03/Aug/12  Updated: 24/Aug/12  Resolved: 07/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
requires QFJ-453 FIX 5.0 SP1 and SP2 Support Resolved

 Description   

Currently there is only the possibility to supply a text which gets set to the Text field of the Logout message.

Additionaly we should have the possibility to submit a value for the field SessionStatus (introduced with FIX5.0 EP56).






[QFJ-695] Remove logging on invocation of ApplicationExtended.canLogon(sessionID) Created: 30/Jul/12  Updated: 24/Aug/12  Resolved: 30/Jul/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

problem

Inside the Session.next() method, the callback ApplicationExtended.canLogon(sessionID) is invoked. However, each time the next() method gets called (i.e. each second) and canLogon is FALSE a log line is created:

"Do not initiate logon, Application can not logon on <sessionID>"

This logging should be removed as that log output could be implemented in the specific application. There is no logging output for the other callbacks (onLogon, onLogout, ...) either.






[QFJ-694] I am getting the following message IOException when I initiate logout request. 20120724-21:49:36: Initiated logout request 20120724-21:49:36: Received logout response 20120724-21:49:36: Already disconnected: Socket (/208.89.234.196:563): java.io.IOExcep Created: 25/Jul/12  Updated: 25/Jul/12  Resolved: 25/Jul/12

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

Type: Bug Priority: Default
Reporter: Robert Shalonov Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I am getting the following message IOException when I initiate logout request. Please, advise the fix

20120724-21:49:36: Initiated logout request
20120724-21:49:36: Received logout response
20120724-21:49:36: Already disconnected: Socket (/208.89.234.196:563): java.io.IOException: Connection reset by peer



 Comments   
Comment by Grant Birchmeier [ 25/Jul/12 ]

Send your help request to the mailing list.
http://quickfixj.org/ -> Support





[QFJ-693] SessionStateListener onMissedHeartBeat(), onHeartBeatTimeout() is called once network connection reestablishes after a disconnect Created: 23/Jul/12  Updated: 25/Jul/12  Resolved: 25/Jul/12

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

Type: Bug Priority: Default
Reporter: Saneesh Kumar Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: QuickfixJ, SessionStateListener, onHeartBeatTimeOut, onMissedHeartbeat, onTimeOut
Environment:

Open Suse 12.1 Asparagus


Issue Links:
Duplicate
is duplicated by QFJ-692 QuickfixJ Session not disconnecting w... Closed

 Description   

I need to implement the SessionStateListener in the Initiator to understand when there is a network disconnect event.

Firstly, I defined my Initiator to Implement SessionStateListener, Then I added the listener by:

Session.lookupSession(quickfixSessionID).addStateListener(fixInitiator);

and now trying to receive following callbacks to check if the network is down:
@Override
public void onMissedHeartBeat()

{ System.out.println("######onMissedHeartBeat"); }

@Override
public void onHeartBeatTimeout()

{ System.out.println("######Heartbeat time out"); }

But the onMissedHeartBeat() and OnHeartbeatTimeout() methods are called only once the network connection is reestablished. I need to understand when the network went down and when it came back.

Please send me if you have any solution for the above to [email protected]



 Comments   
Comment by Grant Birchmeier [ 23/Jul/12 ]

This looks like a help request, not a bug.

Send your question to the mailing list, and you will probably get an answer.
http://quickfixj.org/support/

Comment by Christoph John [ 25/Jul/12 ]

Works for me:

code:
@Override
public void onHeartBeatTimeout()

{ System.out.println( "XXXXXX onHeartBeatTimeout"); }

@Override
public void onMissedHeartBeat()

{ System.out.println( "XXXXXX onMissedHeartBeat"); }

log:

[2012-07-25 09:02:24,884] [DEBUG] FIX.4.2:FixGateway->FixClient: outgoing: 8=FIX.4.2|9=62|35=0|34=5|49=FixGateway|52=20120725-07:02:24.884|56=FixClient|10=091|
[2012-07-25 09:02:27,883] [DEBUG] FIX.4.2:FixGateway->FixClient: outgoing: 8=FIX.4.2|9=71|35=1|34=6|49=FixGateway|52=20120725-07:02:27.883|56=FixClient|112=TEST|10=113|
[2012-07-25 09:02:27,883] [INFO ] FIX.4.2:FixGateway->FixClient: event : Sent test request TEST
XXXXXX onMissedHeartBeat
...
[2012-07-25 09:02:36,882] [ERROR] FIX.4.2:FixGateway->FixClient: error : Disconnecting: Timed out waiting for heartbeat
XXXXXX onHeartBeatTimeout





[QFJ-692] QuickfixJ Session not disconnecting when Network unavailable/unplugged Created: 22/Jul/12  Updated: 25/Jul/12  Resolved: 25/Jul/12

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

Type: Bug Priority: Critical
Reporter: Saneesh Kumar Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-693 SessionStateListener onMissedHeartBea... Closed

 Description   

QuickfixJ session never disconnects or throws any exception when there is a network related issue (network unavailable/unplugged) is there any kind of time out which can be defined after which could be used to make out a network issue?

Is there any solution to handle the above problem?



 Comments   
Comment by Saneesh Kumar [ 23/Jul/12 ]

I was trying to use the SessionStateListener, but the onMissedHeartBeat() or onHeartBeatTimeout() are not called even though I tried unplugging the network cable.

Comment by Jörg Thönnes [ 25/Jul/12 ]

Please provide more details about your environment and test setup. Basically, this should work.





[QFJ-691] But when handling garbled messages and processing the pending queue Created: 12/Jul/12  Updated: 19/Dec/13  Resolved: 19/Dec/13

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

Type: Bug Priority: Critical
Reporter: rohit qfj Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None
Environment:

prod



 Description   

For the below use case, QFJ is not working correctly.

Client doesn't send HB messages to server and server always sends TestRequest.

1) Client sends a garbled message. Example 34=35. QFJ just logs the message "invalid checksum or body length"
2) Client sends next message with 34=36. QFJ sends ResendRequest to replay 35 (correct) and puts into the queue
3) Client sends next message with 34=37. QFJ logs Resend already sent(correct) and puts into the queue
4) Client is NOT sending any messages to server and due to no processed incoming messages, it fires TestRequest
5) Client respond to TestReqeust with HB
6) QFJ code hande the HB in the nextHeartbeat message, where it will verify for Seq too high and just return (correct)

private void nextHeartBeat(Message heartBeat) throws FieldNotFound, RejectLogon,
IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType, IOException,
InvalidMessage {
if (!verify(heartBeat))

{ return; }

state.incrNextTargetMsgSeqNum();
nextQueued();
}

7) But, the public void next(Message message) method after calling nextHeartBeat method, it just continue and process the nextQueued(); method as nextHeartBeat just returns and no further checks.

Ideally nextHeartbeat should return a boolean flag and action accordingly.

This happens due to combination of events.
1) Client is not sending any incoming messages(not even HB)
2) Client session gets into seq too high
3) Then engine fire TestRequest and client responding with HB



 Comments   
Comment by rohit qfj [ 12/Jul/12 ]

This bug is present in the latest 1.5.2 and all other previous branches

Comment by Christoph John [ 10/Oct/12 ]

Sorry, could you please be more specific on what you expect? What should happen after the verify method returns and why?

Thanks





[QFJ-690] ConfigError Exception, Component Not Found -- doesn't say which component! Created: 11/Jul/12  Updated: 24/Aug/12  Resolved: 21/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Evan Ross Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

Win7, Eclipse



 Description   

During initialization I'm getting:
quickfix.ConfigError: FXI-FIX43.xml: Component not found, quickfix.ConfigError: Component not found
but it doesn't tell me which component is missing



 Comments   
Comment by Christoph John [ 21/Aug/12 ]

Committed as rev 1086.





[QFJ-689] Initiator Sessions Created: 14/Jun/12  Updated: 18/Jul/12  Resolved: 18/Jul/12

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

Type: Bug Priority: Default
Reporter: Michael Blout Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I have an initiator running with two sessions. While it was running, I noticed some crosstalk that should not have been happening, Session1 received a message that was intended for Session2. Is there any way to prevent this from happening?



 Comments   
Comment by Grant Birchmeier [ 14/Jun/12 ]

This looks like a help request, not a bug.

Please join the mailing list and send your question there. You will be much more likely to get a response. Only a few people are notified about new bug reports.

Comment by Jörg Thönnes [ 18/Jul/12 ]

This crosstalk should of course not happen, but depends heavily on your code.
Closing as not a bug. Please talk on the mailing list as Grant suggested.





[QFJ-688] not getting response to logon message Created: 14/Jun/12  Updated: 15/Nov/12  Resolved: 18/Jul/12

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

Type: Bug Priority: Critical
Reporter: sagar narasgonde Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: logon
Environment:

windows 7,my eclipse



 Description   

USING FIX 5.0

I am trying to send logon message from initiator but not able to see any response in acceptor.

In initiator i setField for logon type(35) and i send message by session.sendToTarget(message);

but i am not getting any response in acceptor side and logon is not successfully done.

*********Acceptor side code**********

---AlertAcceptor.java
class AlertAcceptor

{ Application application = new AlertServer(); //All setting is done socketAcceptor acceptor=socketAcceptor(application ,,,); acceptor.start(); //sleep acceptor.stop(); }

---AlertServer.java

class AlertServer implements Application

{ OnLogon() { //expecting logon from initiator but not getting } OnLogout { }

fromApp() { }

toApp() { }

fromAdmin()
{ }

toAdmin()

{ } }

*********Initiator Side code***************

--AlertInitiator.java

class AlertInitiator

{ Application application = new AlertProcess(); //All setting is done socketInitiator initiator=socketInitiator(application ,,,); initiator.start(); //sleep initiator.stop(); } --AlertProcess.java class AlertProcess implements Application { OnLogon() { Message msg=new Message(); msg.getHeader.setField(new String(35,"A"));//header //additionally two more fields from body session.sendTotarget(msg); } OnLogout() { } fromApp() { } and so on.. }

 Comments   
Comment by Grant Birchmeier [ 14/Jun/12 ]

This looks like a help request, not a bug.

Please join the mailing list and send your question there. You will be much more likely to get a response. Only a few people watch new bugs.

Comment by Jörg Thönnes [ 18/Jul/12 ]

Closing as not a bug. This is the wrong way to use QF/J. Please look at the examples provided. Thanks.





[QFJ-687] Lost message on package fragmentation at 12 bytes in a FIXT.1.1 message Created: 12/Jun/12  Updated: 04/Sep/12  Resolved: 04/Sep/12

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

Type: Bug Priority: Default
Reporter: Jonas Fügedi Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: encoding

Issue Links:
Relates
relates to QFJ-544 Header with BeginString=FIXT.1.1 inco... Resolved

 Description   

The begin string header will be incorrectly detected if a FIXT.1.1 message is fragmented at 12 bytes and a message will be lost with a message regarding bad message length.

    /**
     * Checks to see if the byte_buffer[buffer_offset] starts with data[]. The
     * character ? is a one byte wildcard, lowercase letters are optional.
     *
     * @param pBuffer
     * @param pBufferOffset
     * @param pData
     * @return
     */
    public static int startsWith(ByteBuffer pBuffer, int pBufferOffset, byte[] pData) {
        if (pBufferOffset + minMaskLength(pData) > pBuffer.limit()) {
            return -1;
        }
        final int tInitOffset = pBufferOffset;
        int tDataOffset = 0;
        for (int tBufferLimit = pBuffer.limit();
            (tDataOffset < pData.length) && (pBufferOffset < tBufferLimit);
            tDataOffset++, pBufferOffset++)
        {
            if (pBuffer.get(pBufferOffset) != pData[tDataOffset] && pData[tDataOffset] != '?') {
                // Now check for optional characters, at this point we know we didn't
                // match, so we can just check to see if we failed a match on an optional character,
                // and if so then just rewind the buffer one byte and keep going.
                if (Character.toUpperCase(pData[tDataOffset]) == pBuffer.get(pBufferOffset)) {
                    continue;
                }
                // Didn't match the optional character, so act like it was not included and keep going
                if (Character.isLetter(pData[tDataOffset]) && Character.isLowerCase(pData[tDataOffset])) {
                    --pBufferOffset;
                    continue;
                }
                return -1;
            }
        }
        if (tDataOffset < pData.length) {
            // the buffer was consumed but not the whole mask
            return -1;
        }
        return pBufferOffset - tInitOffset;
    }


 Comments   
Comment by Jonas Fügedi [ 12/Jun/12 ]

The code provided shows my fix where if the whole mask is not consumed then -1 is returned

Comment by Jonas Fügedi [ 12/Jun/12 ]

Oops, copy paste bug... the variable names are wrong, won't compile

        if (dataOffset < data.length) {
            // the buffer was consumed but not the whole mask
            return -1;
        }
Comment by Christoph John [ 15/Aug/12 ]

This looks like QFJ-544. Can you confirm that the issue is fixed by that ticket?

Comment by Jonas Fügedi [ 20/Aug/12 ]

Yes, QFJ-544 seems to cover the same issue. This fix only covered part of the fragmentation issues though, so further issues remain in the same problem area.

Comment by Christoph John [ 20/Aug/12 ]

Sorry, I do not understand fully. Do you mean that the fix you posted covered only part of the problem or the fix in QFJ-544? Are there still open problems or can this (QFJ-687) ticket be closed?

Thanks

Comment by Jonas Fügedi [ 03/Sep/12 ]

This can be closed, the QFJ-544 patch seems to resolve all the issues (I have not run thorough garbled message testing and verified that parser recovery is correct, but valid messages are correct in all my fragmentation scenarios).





[QFJ-686] ThreadPerSessionEventHandlingStrategy still leaks threads after client disconnect Created: 07/Jun/12  Updated: 24/Aug/12  Resolved: 14/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Critical
Reporter: Andre Mermegas Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File ThreadPerSessionEventHandlingStrategy.java    

 Description   

MessageDispatchingThread is not correctly GC'd or released because it is not stopped and removed from dispatcher map after client disconnects.



 Comments   
Comment by Andre Mermegas [ 07/Jun/12 ]

attached fixes.





[QFJ-685] Extend QuicFIX for custom FIX messages Created: 05/Jun/12  Updated: 06/Jun/12  Resolved: 05/Jun/12

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: Future Releases
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Arunkumar Krishnamoorthy Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: generation
Environment:

All environment



 Description   

I have a need where QuickFIX can generate the code for custom FIX messages say Goldman-Sachs or Barclayes or citi, etc. I went through the code. I found that we can extend QuickFIX to support this with very minimal change. I am briefly listing them here. Let me know if it is a meaningfull change then I can upload a patch for you to incorporate.

All changes are localized to code gen module
1. Currently versions are hardcoded in a single array within MessageCodeGenerator. These versions are used for most of the tasks in code generation like accessing Data dictionary (XML files containing FIX messages, fields and components), generating FIX packages, etc. We need to move these versions to program arguments (say comma separated)
2. All fields are generated within single package (fields package). Though it is fine for standard FIX messages, it might not be sufficient for custom FIX as GS and BCX can use the same tag (user defined field) for different purpose. So, there should be a rule based on which we can decide if the fields should be generated in single package or separate ones (as simple as the version if it stars with FIX then standard else custom)
3. XSL files assume that fields are in same package and hardcodes the "import quickfix.fields.*". It has to be changed to a dynamic one based on parameter.

Above are most of the major changes. Once we do that, we can create a custom version by changing on top of the base version. If GS' FIX message is an extension of FIX 4.2, then we can create a copy of FIX 4,2 .xml (data dictionary) and name it as "GSFIX 4.2" and do changes within it. Once we include GSFIX 4.2 as part of version, we will get all messages generated.

I understand that the core engine is specifically built for FIX standard spec. As FIX standards allows firms to customize the FIX messages, my thought is on the same lines with QuickFIX as perspective. Let me know if this approach is right. I am open for other better approaches too to achieve this.



 Comments   
Comment by Grant Birchmeier [ 05/Jun/12 ]

You already can regenerate the QF/J source and recompile to accomodate any DataDictionary modifications you make. Any FIX engine that didn't allow you to use custom DDs would be pretty worthless.

Please join the mailing list and ask about it. Or search the mail list archives, as I know I've written a short how-to more than once. Pretty sure I did it within the last month.

I'm going to close this because it doesn't look like a bug. If I'm mistaken in this, we can reopen it.

Comment by Arunkumar Krishnamoorthy [ 06/Jun/12 ]

Thanks. My only concern was version numbers being hard coded in the code generator and the fixed logic of generating / assuming all fields in the same package. If it can be configurable from outside the source code, I thought it would help.

thanks for your response.

  • K. Arun




[QFJ-684] Support for binary data (BytesField) does not (and cannot) work on full range of bytes Created: 01/Jun/12  Updated: 04/May/21  Resolved: 04/May/21

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

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-789 Fully support alternate encodings (ch... Open

 Description   

The BytesField support for putting raw bytes into a message does not work unless the bytes are compatible with the charset. e.g., the test below will fail. If QF/J is to support raw data fields (and encoded fields), some areas that currently work on/as Strings will need to change to work on byte[]s or ByteBuffers. In the mean time, if BytesField can't work, best to remove it.

public void testBytesFieldForReal()
throws Exception

{ byte[] data = new byte[256]; for(int i = 0; i < 256; ++i) data[i] = (byte)i; BytesField field = new BytesField(RawData.FIELD); field.setValue(data); StringBuilder sb = new StringBuilder(); field.toString(sb); byte[] tagBytes = sb.toString().getBytes(CharsetSupport.getCharset()); assertEquals(256 + 3, tagBytes.length); for(int i = 0; i < data.length; ++i) assertEquals(data[i], tagBytes[i + 3]); }

 Comments   
Comment by Christoph John [ 04/May/21 ]

https://github.com/quickfix-j/quickfixj/pull/289





[QFJ-683] Tag 43=Y is not being sent when I set the value in getHeader() Created: 25/May/12  Updated: 15/Nov/12  Resolved: 31/May/12

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

Type: Bug Priority: Default
Reporter: Andrew Niland Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

When I set the tag in the body the tag is sent in the message:
executionReport.setField(new BooleanField(43, true));

But not when I set it in the header:
executionReport.getHeader().setField(new BooleanField(43, true));

Is there a way to force header tags to be sent?



 Comments   
Comment by Jörg Thönnes [ 26/May/12 ]

Hi Andrew,

first of all you should not be able to set the header field 43/PossDup in the body of a FIX message. This is an error.

And if you set this flag in the header you are basically asking for trouble. This field is controlled by the FIX engine
which implements the FIX protocol. The field 43/PossDup is only set if a message is resent, i.e. been sent more than
one time.

What is your reason you wanto to set this field?

Cheers, Jörg

Comment by Jörg Thönnes [ 31/May/12 ]

You could manipulate the outgoing messages in this callback:

    /**
     * This is a callback for application messages that you are sending to a
     * counterparty. If you throw a DoNotSend exception in this function, the
     * application will not send the message. This is mostly useful if the
     * application has been asked to resend a message such as an order that is
     * no longer relevant for the current market. Messages that are being resent
     * are marked with the PossDupFlag in the header set to true; If a DoNotSend
     * exception is thrown and the flag is set to true, a sequence reset will be
     * sent in place of the message. If it is set to false, the message will
     * simply not be sent. You may add fields before an application message
     * before it is sent out.
     * 
     * @param message
     *            QuickFIX message
     * @param sessionId
     *            QuickFIX session ID
     * @throws DoNotSend --
     *             This exception aborts message transmission
     */
    void toApp(Message message, SessionID sessionId) throws DoNotSend;




[QFJ-682] MiscFeeType in FIX44.xml does not match FIX Protocol Created: 24/May/12  Updated: 01/Apr/14  Resolved: 01/Apr/14

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

Type: Bug Priority: Default
Reporter: Jose Elias Chavez Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: Field, Message, QuickfixJ
Environment:

Linux, CentOS, Java 1.6.0b22 64-bit JVM


Issue Links:
Duplicate
is duplicated by QFJ-755 FIX44.xml field number 139 'MiscFeeTy... Closed

 Description   

I was comparing what is in the default FIX44.xml data dictionary with what is defined for Tag 139 MiscFeeType. It's defined as follows in the FIX44.xml:

<!-- Changed to string in FIX5.0, overrides this field type -->
<field number="139" name="MiscFeeType" type="CHAR">
<value enum="1" description="REGULATORY"/>
<value enum="2" description="TAX"/>
<value enum="3" description="LOCAL_COMMISSION"/>
<value enum="4" description="EXCHANGE_FEES"/>
<value enum="5" description="STAMP"/>
<value enum="6" description="LEVY"/>
<value enum="7" description="OTHER"/>
<value enum="8" description="MARKUP"/>
<value enum="9" description="CONSUMPTION_TAX"/>
</field>

However, in the FIXimate, I see that an additional 3 values are defined:

10 = Per transaction [PerTransaction]
11 = Conversion [Conversion]
12 = Agent [Agent]

I was using a version of FIX44.xml that I modified in order to communicate with NSCC's new UTC system. They are adhering to the 4.4 spec, but I would need to pick up 10 (Per Transaction) field from their TradeCaptureReport message.

Any reason why these 3 fields are not included in the data dictionary?

Also, data dictionary is defined as char. Since the addition of the 3 fields, is this the reason why it is now defined as String in FIX 5.0?



 Comments   
Comment by Christoph John [ 01/Apr/14 ]

Yes, MiscFeeType is defined as String from FIX 5.0 onwards. Strangely it is defined as char in FIX 4.4 although values 10-14 were added.
So you need to modify your data dictionary in order to accept those values. Since in the end the MiscFeeType class will be generated from the FIX5.0 data dictionary it will be of type StringField and will have the additional values.





[QFJ-681] During load test, some clients are able to connect only after repeated attempts Created: 22/May/12  Updated: 22/May/12

Status: Open
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: 1.5.2
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Viswanath Palutla Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, logon
Environment:

1. on my PC, i am running 'Executor' from quickfixj examples
PC config: windows7, i7, 2.7 GHz, 32-bit, 4GB RAM

2. one linux box, where i am starting 25-30 clients to put load on the 'Executor'
linux config: Intel(R) Xeon(TM) CPU 3.20GHz, 2GB RAM


Attachments: Zip Archive load-test-executor.zip    

 Description   

I am using Executor service in the example, because it is similar to my FIX Gateway, in terms of using AcceptorTemplate

1. I have a simple client that connects to Executor service and puts a MarketDataRequest for every 10 milliseconds, total 100 market data requests.
note: 'UnsupportedMessageType' errors are expected for all MarketDataRequests

2. two clients are started for every second. total 30 clients are started

Issues:
-> connection is not established for some clients for some period
From client logs:
(Pending connection not established after 2146 ms.)
(Pending connection not established after 2850 ms.)
(Pending connection not established after 9795 ms.)

-> server is not responding to logon requests promptly for some clients
From client logs:
(Initiated logon request)
(Disconnecting: Timed out waiting for logon response)
(Pending connection not established after 4648 ms.)
(Pending connection not established after 21948 ms.)
(Initiated logon request)
(Received logon)



 Comments   
Comment by Viswanath Palutla [ 22/May/12 ]

attaching batch scripts and class files to load Executor





[QFJ-680] UtcTimestampConverter.convert() threading issue Created: 21/May/12  Updated: 24/Aug/12  Resolved: 15/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: N Byrne Assignee: Christoph John
Resolution: Fixed Votes: 1
Labels: None
Environment:

n/a


Attachments: Text File QFJ-680.patch    

 Description   

The root cause is actually very simple.

1) Multiple threads call convert(String) for a new day [new = wasn't already in dateCache]
2) Multiple threads get a handle to the same new GregorianCalendar instance for the new day
3) Multiple threads concurrently call getTimeInMillis() for the same instance from step #2
4) ArrayIndexOutOfBoundsException due to concurrent modification of internal GregorianCalendar state

Example stack trace

Caused by: java.lang.ArrayIndexOutOfBoundsException: 101
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2333)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2753)
at java.util.Calendar.updateTime(Calendar.java:2606)
at java.util.Calendar.getTimeInMillis(Calendar.java:1118)
at quickfix.field.converter.UtcTimestampConverter.convert(UtcTimestampConverter.java:82)
at quickfix.FieldMap.getField(FieldMap.java:432)
at quickfix.fix44.MarketDataIncrementalRefresh$NoMDEntries.getExpireTime(MarketDataIncrementalRefresh.java:2001)

There are many easy ways to fix this. I would even suggest just storing the millis in the dateCache



 Comments   
Comment by N Byrne [ 25/Jun/12 ]

Suggested solution

Comment by AE [ 20/Aug/12 ]

Hi, while we haven't seen the exception above, we have twice seen 'SendingTime accuracy' issues between 2 quickfixj engines at exactly midnight, even though the clock on both machines are in sync, which I imagine is related to the above thread safety issues. We have seen this in both 1.3 and 1.5. When will the patch above make it into the next version of qfj? Thanks

Comment by Christoph John [ 20/Aug/12 ]

Currently it is not yet defined when the next patched version will be released. Hopefully soon.

Comment by AE [ 20/Aug/12 ]

Thanks, do you know if the 'SendingTime accuracy' I see can be related to the thread safety issue above? Thanks.

Comment by Christoph John [ 21/Aug/12 ]

This looks related. When doing the SendingTime check, the field is retrieved from the message and converted using the UtcTimestampConverter.convert() method.





[QFJ-679] TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE because of wrong order of tags Created: 03/May/12  Updated: 01/Aug/12  Resolved: 01/Aug/12

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

Type: Other Priority: Critical
Reporter: Sujit Jaju Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The message I am creating is:
8=FIX.4.49=20135=R34=249=abcd52=20120503-04:25:30.61456=pqrs146=155=EUR/USD167=FOR38=10000063=664=2012052815=USD1=mnop40=C453=1131=1448=wxyz452=310=071
But I want to create it in the order:
8=FIX.4.49=20135=R34=249=abcd52=20120503-04:25:30.61456=pqrs131=1 146=155=EUR/USD167=FOR38=10000063=664=2012052815=USD1=mnop40=C453=1448=wxyz452=310=071

(Tag 131 at start of body and not between tag 453 and tag 458)

I have written following code:
QuoteRequest message = new QuoteRequest();
QuoteRequest.NoRelatedSym group = new QuoteRequest.NoRelatedSym();
group.setString(131, quoteRequestBean.getQuoteReqID().getValue());
group.setString(55, quoteRequestBean.getSymbol().getValue());
group.setString(167, quoteRequestBean.getSecurityType().getValue());
group.setDouble(38, quoteRequestBean.getOrderQty().getValue());
group.setChar(63, quoteRequestBean.getSettlType().getValue());
group.setString(64, quoteRequestBean.getSettlDate().getValue());
group.setString(15, quoteRequestBean.getCurrency().getValue());
group.setString(1, quoteRequestBean.getAccount().getValue());
group.setChar(40, quoteRequestBean.getOrdType().getValue());
group.setInt(453, quoteRequestBean.getNoPartyIDs().getValue());
group.setString(448, quoteRequestBean.getPartyID().getValue());
group.setInt(452, quoteRequestBean.getPartyRole().getValue());
message.addGroup(group);

But still it pushes the tag 131 between tag 453 and tag 448.
Since tag 448 is part of tag 453 group, i believe the error is coming as:

8=FIX.4.49=14435=334=249=abcd52=20120503-04:45:53.62756=pqrs45=258=Tag not defined for this message type371=448372=R373=210=005

Please help me solve this problem asap. Also let me know if any other input is needed from my side and if I am writing any step wrongly.



 Comments   
Comment by Grant Birchmeier [ 04/May/12 ]

You should try the mailing list. (Only a few eyes are alerted to bug submissions.)

Please note this bug number in your mail. If someone helps you solve it, please come back and close this bug.

Comment by Grant Birchmeier [ 04/May/12 ]

Um, if you don't want 131 in your group, why did you set it in the group?

This line sets it in the group.
group.setString(131, quoteRequestBean.getQuoteReqID().getValue());

I think you want this:
message.setString(131, quoteRequestBean.getQuoteReqID().getValue());

Also, you should consider using typesafe methods, instead of setString() and setInt().
http://quickfixj.org/quickfixj/usermanual/1.5.1/usage/sending_messages.html





[QFJ-678] EventHandlingStrategy BlockingQueues are unbounded Created: 02/May/12  Updated: 02/Apr/15  Resolved: 20/Oct/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.2
Fix Version/s: 1.6.0

Type: Improvement Priority: Minor
Reporter: Greg Chabala Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

In reference to a question on the quickfixj-users list from 2012-04-25:
"1. Why are all the LinkedBlockingQueues unbounded in the EventHandlingStrategies?

We've found that if you have to go back to the beginning of a session and have a large amount of traffic to process you can end up with memory issues without using a bounded queue."

Both quickfix.mina.EventHandlingStrategy implementations contain a BlockingQueue of Messages, or a wrapper of Messages in the case of SingleThreadedEventHandlingStrategy, and both of these queues are unbounded. We had an issue where while trying to recover from a period of downtime, the resent traffic would fill this queue faster than it could be processed, leading the app to run out of memory. We solved this by overriding the classes locally and giving the queues a capacity of 5000.

I'd like to see this improvement made into the vanilla library. While hard coding to some large value less than Integer.MAX_VALUE would probably be an improvement, ideally this could become a configuration option or an optional parameter to the constructors of Initiators and Acceptors.



 Comments   
Comment by Christoph John [ 20/Oct/14 ]
  • changed Acceptor/Initiator/EventHandlingStrategy to use a default of 10000 as queue size in order to avoid OutOfMemory issues
  • queue size can be specified using the respective (Threaded)SocketAcceptor/Initiator constructors




[QFJ-677] The fix for QFJ-318 was reverted (inadvertently?) in r928 Created: 30/Apr/12  Updated: 27/Jul/17  Resolved: 12/Jul/17

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

Type: Bug Priority: Default
Reporter: Ryan Caudy Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-318 FileLog for Messages Sometimes Omits ... Closed

 Description   

We've found that the components (timestamp, message, newline) of log lines are occasionally interleaved in multi-threaded applications that concurrently send and receive FIX messages via QuickFIX/J 1.5.2. This issue wasn't present in QuickFIX/J 1.3.2.
It looks to me like the removal of "synchronized" from FileLog.writeMessage() in r928 was an error. None of the JIRA tickets cited in the commit log seem to explain the change.






[QFJ-676] Invalid MsgType n Created: 30/Apr/12  Updated: 10/Oct/12  Resolved: 10/Oct/12

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

Type: Other Priority: Major
Reporter: James Beattie Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ


 Description   

When sending/receiving a FIX 4.4 message with field 35=n, the message is rejected with the following error:

58=Invalid MsgType
372=n
373=11

Is this a bug, or does anyone know what can be done to resolve this issue?

Many thanks.



 Comments   
Comment by Grant Birchmeier [ 04/May/12 ]

I assume you get it only on reception, since you obviously can't reject a message you're sending.

I'm going to guess that your MessageCracker did not implement an OnMessage() handler for "n" message type.

Also, this question should probably have gone on the mailing list. It doesn't look like a bug.





[QFJ-675] Message.clear() should reset position field to zero to enable Message to be reused Created: 25/Apr/12  Updated: 24/Aug/12  Resolved: 02/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Ming Fang Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

Since the clear() does not currently reset the position field, the next call to parse() will not work.






[QFJ-674] acceptor.getSessions() returning empty ArrayList Created: 25/Apr/12  Updated: 02/Aug/12  Resolved: 02/Aug/12

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

Type: Bug Priority: Major
Reporter: Dan Marques Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Java 7, Windows 7 - x64



 Description   

In QFJ 1.5.2 acceptor.getSessions() is returning an empty array list when previous version (at least 1.4.0, but I'm pretty sure this was working in 1.5.1 as well) are returning non-empty lists.

For example, the following little code segment (as part of an application)

Acceptor acceptor = null;
String configFileName = null;
try

{ configFileName = args[0]; final SessionSettings sessionSettings = new SessionSettings(new FileInputStream(configFileName)); final MessageStoreFactory storeFactory = new FileStoreFactory(sessionSettings); final LogFactory logFactory = new FileLogFactory(sessionSettings); final MessageFactory messageFactory = new DefaultMessageFactory(); acceptor = new SocketAcceptor(app, storeFactory, sessionSettings, logFactory, messageFactory); log.info("version " + org.quickfixj.Version.getVersion() + ", size " + acceptor.getSessions().size()); }

given the same config file (describing two acceptor sessions), produces different output with 1.5.2 than with 1.4.0

DropCopy 20:06:55,087 INFO [main] (DropCopy.java:285) - version Version: 1.5.2, size 0
DropCopy 20:07:39,103 INFO [main] (DropCopy.java:285) - version Version: 1.4.0, size 2



 Comments   
Comment by Christoph John [ 25/Apr/12 ]

The call to createSessions() has been moved into the method startAcceptingConnections() of the AbstractSocketAcceptor to ensure that the acceptor can be restarted after a call to stop() (QFJ-643).

I.e. after call to SocketAcceptor.start() you should be able to get the sessions.





[QFJ-673] QFJ sequence problem following inbound SequenceReset - a previously received ResendRequest not "queued"? Created: 30/Mar/12  Updated: 16/Jul/18  Resolved: 18/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: John Peng Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: Reconnect, ResendRequest,, SequnceReset,, queued, sequence,

Attachments: Text File QFJ_bug_report.log    
Issue Links:
Duplicate
is duplicated by QFJ-658 Sequence numbers not checked for inco... Closed
is duplicated by QFJ-766 FIX Resend Issue Closed
is duplicated by QFJ-814 Sequence Reset Fails Closed

 Description   

Sequence of events - from the perspective of an Acceptor:

0. Acceptor is restarted with inbound sequence number reset to 0 - all missed messages were session messages.
1. Incoming Logon@sequence=6; responded with Logon response.
2. Outgoing ResendRequest for sequence gap 1-5.
3. Incoming ResendRequest@sequence=7 for sequence range 1005 to infinity.
4. Incoming SequenceReset from 1 to 6 – i.e. gap 1-5 now filled. "Processing queued message: 6".
5. Outgoing SequenceReset - requested gap starting 1005 filled.
6. Incoming Heartbeat@sequence=8. --> At this point Acceptor complains "MsgSeqNum too high, expecting 7 but received 9". WRONG!
7. Acceptor claims that "Already sent ResendRequest FROM: 1 TO: 5. Not sending another." --> and hence all subsequent inbound messages are considered out of sequence. PROBLEM!

This problem seems to be due to that QFJ failed to "queue" the received ResendRequest at step 3 above, and hence treated sequence 7 as never received.

Log excerpt below:
--------------------------------------------------------------
2012-03-29 18:56:43,999 INFO [SocketAcceptorIoProcessor-0.0] AbstractIoHandler.messageReceived(AbstractIoHandler.java:106): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=6535=A34=649=TRS52=20120329-22:56:43.62056=TRS_OUT98=0108=3010=078
2012-03-29 18:56:44,037 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] Session.send(Session.java:2217): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=6835=A34=100649=TRS_OUT52=20120329-22:56:44.03756=TRS98=0108=3010=229
2012-03-29 18:56:44,047 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] Session.send(Session.java:2217): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=6535=234=100749=TRS_OUT52=20120329-22:56:44.04656=TRS7=116=510=059
2012-03-29 18:56:44,047 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Sent ResendRequest FROM: 1 TO: 5
2012-03-29 18:56:44,050 INFO [SocketAcceptorIoProcessor-0.0] AbstractIoHandler.messageReceived(AbstractIoHandler.java:106): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=6535=234=749=TRS52=20120329-22:56:44.04956=TRS_OUT7=100516=010=061
2012-03-29 18:56:44,052 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Received ResendRequest FROM: 1005 TO: infinity
2012-03-29 18:56:44,054 INFO [SocketAcceptorIoProcessor-0.0] AbstractIoHandler.messageReceived(AbstractIoHandler.java:106): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=9135=434=143=Y49=TRS52=20120329-22:56:44.05256=TRS_OUT122=20120329-22:56:4436=6123=Y10=104
2012-03-29 18:56:44,055 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] Session.send(Session.java:2217): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=9735=434=100543=Y49=TRS_OUT52=20120329-22:56:44.05456=TRS122=20120329-22:56:4436=1008123=Y10=152
2012-03-29 18:56:44,055 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Sent SequenceReset TO: 1008
2012-03-29 18:56:44,056 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Received SequenceReset FROM: 1 TO: 6
2012-03-29 18:56:44,056 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Processing queued message: 6
2012-03-29 18:57:14,623 INFO [SocketAcceptorIoProcessor-0.0] AbstractIoHandler.messageReceived(AbstractIoHandler.java:106): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=5335=034=849=TRS52=20120329-22:57:14.62156=TRS_OUT10=035
2012-03-29 18:57:14,626 ERROR [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] SLF4JLog.logError(SLF4JLog.java:133): FIX.4.2:TRS_OUT->TRS: MsgSeqNum too high, expecting 7 but received 8
2012-03-29 18:57:14,626 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Already sent ResendRequest FROM: 1 TO: 5. Not sending another.
2012-03-29 18:57:14,627 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] Session.send(Session.java:2217): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=5635=034=100849=TRS_OUT52=20120329-22:57:14.62756=TRS10=189
2012-03-29 18:57:45,623 INFO [SocketAcceptorIoProcessor-0.0] AbstractIoHandler.messageReceived(AbstractIoHandler.java:106): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=5335=034=949=TRS52=20120329-22:57:45.62156=TRS_OUT10=040
2012-03-29 18:57:45,625 ERROR [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] SLF4JLog.logError(SLF4JLog.java:133): FIX.4.2:TRS_OUT->TRS: MsgSeqNum too high, expecting 7 but received 9
2012-03-29 18:57:45,625 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] ?.?(?:?): FIX.4.2:TRS_OUT->TRS: Already sent ResendRequest FROM: 1 TO: 5. Not sending another.
2012-03-29 18:57:45,626 INFO [QF/J Session dispatcher: FIX.4.2:TRS_OUT->TRS] Session.send(Session.java:2217): FIX.4.2:TRS_OUT->TRS: 8=FIX.4.29=5635=034=100949=TRS_OUT52=20120329-22:57:45.62656=TRS10=193
-------------------------------------------------------------------



 Comments   
Comment by John Peng [ 30/Mar/12 ]

Log excerpt attached as file.

Comment by John Peng [ 30/Mar/12 ]

After doing a quick trace-through into the 1.6 code – I now have a better idea as to why this was happening:

1. Session.State.enqueue() is only called via Session.doTargetTooHigh();
2. Session.doTargetTooHigh() in turn is only called in Session.nextLogon() or Session.verify(msg, checkTooHigh, checkTooLow) - when checkTooHigh=true;
3. When Session.verify(msg, checkTooHigh, checkTooLow) is applied to ResendRequest in Session.nextResendRequest(), the "checkTooHigh" parameter is always false!

Therefore, a ResendRequest that comes after an outstanding sequence gap is NEVER enqueued!

I believe the following code in Session.java should be improved in order to fix the bug:
-----------------------------------------------------------------------------------------
private void nextResendRequest(Message resendRequest) throws IOException, RejectLogon,
FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType,
InvalidMessage {
if (!verify(resendRequest, false, false))

{ return; }

..........
}
-----------------------------------------------------------------------------------------

In particular, verify() shouldn't always be called with "false, false". More conditional check on the Session state should be carried out to determine the right value for the parameters.

Comment by John Peng [ 30/Mar/12 ]

Given the above, this issue would affect version 1.6 as well. Can someone help modify "Affects Version/s" to also include 1.6? Thanks.

Comment by Heribert Steuer [ 13/Dec/13 ]

Being still an open bug, can someone confirm that Johns patch addresses this problem correctly? Its pretty annoying as we have a couple of FIX sessions using VPN, broken network connections regularily bring up this problems and
leave failed sessions. Thanks!

Comment by Christoph John [ 13/Dec/13 ]

Calling verify with "true", "true" is likely to correct the problem and will adhere to the spec (see QFJ-658), however then there are some acceptance tests that fail. Will have to check further.

Comment by Christoph John [ 16/Dec/13 ]

There are two problems here:
1. verify is called without checking for too high seqnums
2. when point 1 has been corrected the queued ResendRequest is not processed

Problem 2 can be corrected by changing method Session.nextQueued(int num) to also process queued ResendRequests and not just increment the target seqnum.

Proposed fix is:
1. to check sequence numbers also on ResendRequests based on configuration ValidateSequenceNumbers as this is also done for other messages as well.
2. to process queued ResendRequest if ValidateSequenceNumbers=Y. Otherwise discard ResendRequest and just increment target seqnum since ResendRequest processing already took place (former behaviour).

Comment by Christoph John [ 18/Dec/13 ]

Committed as rev1127: http://sourceforge.net/p/quickfixj/code/1127/

Just enabling the "tooHigh"-check in verify() would have solved the original problem. However, this could have lead to kind of a deadlock in which the counterparty waited for our messages to be resent and we were also waiting for our ResendRequest to be satisfied in order to process the queued ResendRequest of the counterparty (and only then send the missing messages to the counterparty).
So the former behaviour has been kept and another condition has been introduced outside of the verify() method in nextResendRequest() which will simply enqueue the ResendRequest and method nextQueued(int) will later just increase the target seqnum (this was already present in nextQueued(int) so the new behaviour was probably intended from the beginning but it was forgotten to enqueue the ResendRequest).





[QFJ-672] Using stunnel with banzai and executor Created: 19/Mar/12  Updated: 10/Oct/12  Resolved: 10/Oct/12

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

Type: Other Priority: Major
Reporter: Andreea Ion Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

Windows 64, eclipse,jdk 7



 Description   

Can you tell me if I can use stunnel to make the connection between banzai-executor (banzai is on one computer and executor on another computer)?

------------here is my stunnel.conf for acceptor:

cert = stunnel.pem
key = stunnel.pem
output =stunnel.log

; Socket parameters tuning
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
socket = l:SO_KEEPALIVE=1
socket = r:SO_KEEPALIVE=1

[FIX]
accept = 24800
connect = 192.168.2.213:25800

----------stunnel.conf for initiator:
cert = stunnel.pem
key = stunnel.pem

output = stunnel.log

; Socket parameters tuning
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
socket = l:SO_KEEPALIVE=1
socket = r:SO_KEEPALIVE=1

[FIX]
client = yes
accept = 25800
connect = 24800



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

Please discuss this on the mailing list.
http://www.quickfixj.org/support/

Thank you!





[QFJ-671] Connection exec-banzai Created: 19/Mar/12  Updated: 15/Nov/12  Resolved: 18/Jul/12

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Examples, Networking
Affects Version/s: 1.5.2
Fix Version/s: None

Type: Other Priority: Major
Reporter: Andreea Ion Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

Windows 64, Eclipse,jdk7



 Description   

What I'm trying to do is basicly. I whan to establish a connection between 2 machines. On one of them I have Executor, and on the other machine Banzai.
Machine 1:- executor
------executor.cfg------------
[default]
FileStorePath=examples/target/data/executor
ConnectionType=acceptor
SenderCompID=EXEC
UseDataDictionary=Y

[session]
BeginString=FIX.4.0
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SocketAcceptPort=9876
SocketAcceptHost=192.168.2.213
DataDictionary=/etc/FIX40.xml

[session]
BeginString=FIX.4.1
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SocketAcceptPort=9877
SocketAcceptHost=192.168.2.213
DataDictionary=etc/FIX41.xml

[session]
BeginString=FIX.4.2
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SocketAcceptPort=9878
SocketAcceptHost=192.168.2.213
DataDictionary=etc/FIX42.xml

[session]
BeginString=FIX.4.3
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SocketAcceptPort=9879
SocketAcceptHost=192.168.2.213
DataDictionary=etc/FIX43.xml

[session]
BeginString=FIX.4.4
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SocketAcceptPort=9880
SocketAcceptHost=192.168.2.213
DataDictionary=etc/FIX44.xml

[session]
BeginString=FIXT.1.1
TargetCompID=BANZAI
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
DefaultApplVerID=FIX.5.0
SocketAcceptPort=9881
SocketAcceptHost=192.168.2.213
DataDictionary=etc/FIXT50.xml

Machine 2:
-----------banzai.cfg---------------------
[default]
FileStorePath=examples/target/data/banzai
ConnectionType=initiator
SenderCompID=BANZAI
ReconnectInterval=5
UseDataDictionary=Y

[session]
BeginString=FIX.4.0
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9876
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIX40.xml

[session]
BeginString=FIX.4.1
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9877
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIX41.xml

[session]
BeginString=FIX.4.2
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9878
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIX42.xml

[session]
BeginString=FIX.4.3
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9879
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIX43.xml

[session]
BeginString=FIX.4.4
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9880
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIX44.xml

[session]
BeginString=FIXT.1.1
TargetCompID=EXEC
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
DefaultApplVerID=FIX.5.0
SocketConnectPort=9881
SocketConnectHost=192.168.2.184
DataDictionary=etc/FIXT11.xml

When I run banzai.cfg this is the output:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/Beta1/Desktop/quickfix%20test1/quickfixj/lib/slf4j-jdk14-1.6.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/Beta1/Desktop/quickfix%20test1/quickfixj/lib/optional/slf4j-log4j12-1.6.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
Mar 19, 2012 5:13:05 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.2:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
<20120319-15:13:05, FIX.4.2:BANZAI->EXEC, event> (Session FIX.4.2:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:05, FIX.4.2:BANZAI->EXEC, event> (Created session: FIX.4.2:BANZAI->EXEC)
Mar 19, 2012 5:13:06 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.3:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:13:06 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.1:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
<20120319-15:13:06, FIX.4.3:BANZAI->EXEC, event> (Session FIX.4.3:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:06, FIX.4.3:BANZAI->EXEC, event> (Created session: FIX.4.3:BANZAI->EXEC)
<20120319-15:13:06, FIX.4.1:BANZAI->EXEC, event> (Session FIX.4.1:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:06, FIX.4.1:BANZAI->EXEC, event> (Created session: FIX.4.1:BANZAI->EXEC)
<20120319-15:13:06, FIX.4.0:BANZAI->EXEC, event> (Session FIX.4.0:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:06, FIX.4.0:BANZAI->EXEC, event> (Created session: FIX.4.0:BANZAI->EXEC)
<20120319-15:13:06, FIX.4.4:BANZAI->EXEC, event> (Session FIX.4.4:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:06, FIX.4.4:BANZAI->EXEC, event> (Created session: FIX.4.4:BANZAI->EXEC)
<20120319-15:13:06, FIXT.1.1:BANZAI->EXEC, event> (Session FIXT.1.1:BANZAI->EXEC schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:13:06, FIXT.1.1:BANZAI->EXEC, event> (Created session: FIXT.1.1:BANZAI->EXEC)
Mar 19, 2012 5:13:06 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.0:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:13:06 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.4:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:13:06 PM quickfix.SessionSchedule <init>
INFO: [FIXT.1.1:BANZAI->EXEC] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:13:06 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:06 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:06 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.3:BANZAI->EXEC] [localhost/127.0.0.1:9879]
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.2:BANZAI->EXEC] [localhost/127.0.0.1:9878]
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.1:BANZAI->EXEC] [localhost/127.0.0.1:9877]
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.4:BANZAI->EXEC] [localhost/127.0.0.1:9880]
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIX.4.0:BANZAI->EXEC] [localhost/127.0.0.1:9876]
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:13:07 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:13:07 PM quickfix.mina.initiator.IoSessionInitiator <init>
INFO: [FIXT.1.1:BANZAI->EXEC] [localhost/127.0.0.1:9881]
Mar 19, 2012 5:13:07 PM quickfix.mina.SessionConnector startSessionTimer
INFO: SessionTimer started
<20120319-15:13:08, FIX.4.1:BANZAI->EXEC, error> (java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 5000 milliseconds))
<20120319-15:13:09, FIX.4.4:BANZAI->EXEC, error> (java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 5000 milliseconds))
<20120319-15:13:10, FIXT.1.1:BANZAI->EXEC, error> (java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 5000 milliseconds))

When I run executor.cfg this is the output:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/matlabopt1/Desktop/quickfix%20test1/quickfixj/lib/slf4j-jdk14-1.6.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/matlabopt1/Desktop/quickfix%20test1/quickfixj/lib/optional/slf4j-log4j12-1.6.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
Mar 19, 2012 5:08:47 PM quickfix.examples.executor.Executor <init>
INFO: Acceptor registered with JMX, name=org.quickfixj:type=Connector,role=Acceptor,id=1
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.2:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
<20120319-15:08:48, FIX.4.2:EXEC->BANZAI, event> (Session FIX.4.2:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIX.4.2:EXEC->BANZAI, event> (Created session: FIX.4.2:EXEC->BANZAI)
<20120319-15:08:48, FIX.4.2:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
<20120319-15:08:48, FIX.4.0:EXEC->BANZAI, event> (Session FIX.4.0:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIX.4.0:EXEC->BANZAI, event> (Created session: FIX.4.0:EXEC->BANZAI)
<20120319-15:08:48, FIX.4.0:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
<20120319-15:08:48, FIX.4.3:EXEC->BANZAI, event> (Session FIX.4.3:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIX.4.3:EXEC->BANZAI, event> (Created session: FIX.4.3:EXEC->BANZAI)
<20120319-15:08:48, FIX.4.3:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.0:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.3:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.4:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIXT.1.1:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
Mar 19, 2012 5:08:48 PM quickfix.SessionSchedule <init>
INFO: [FIX.4.1:EXEC->BANZAI] daily, 00:00:00-UTC - 00:00:00-UTC
<20120319-15:08:48, FIX.4.4:EXEC->BANZAI, event> (Session FIX.4.4:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIX.4.4:EXEC->BANZAI, event> (Created session: FIX.4.4:EXEC->BANZAI)
<20120319-15:08:48, FIX.4.4:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
<20120319-15:08:48, FIXT.1.1:EXEC->BANZAI, event> (Session FIXT.1.1:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIXT.1.1:EXEC->BANZAI, event> (Created session: FIXT.1.1:EXEC->BANZAI)
<20120319-15:08:48, FIXT.1.1:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
<20120319-15:08:48, FIX.4.1:EXEC->BANZAI, event> (Session FIX.4.1:EXEC->BANZAI schedule is daily, 00:00:00-UTC - 00:00:00-UTC)
<20120319-15:08:48, FIX.4.1:EXEC->BANZAI, event> (Created session: FIX.4.1:EXEC->BANZAI)
<20120319-15:08:48, FIX.4.1:EXEC->BANZAI, event> (Valid order types: [2, F, 1])
Mar 19, 2012 5:08:49 PM quickfix.mina.SessionConnector startSessionTimer
INFO: SessionTimer started
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9878
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9879
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9876
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9877
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9880
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Mar 19, 2012 5:08:49 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
Mar 19, 2012 5:08:49 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9881
press <enter> to quit

Can you tell me where I am wrong?



 Comments   
Comment by Grant Birchmeier [ 19/Mar/12 ]

Have you tried sending your questions to the mailing list? That is the preferred avenue for help.

Most people will not see this bug report. (And bug reports aren't supposed to be used for help requests.)

Comment by sagar narasgonde [ 14/Jun/12 ]

there are many mistakes

like

instead of SocketAcceptHost=192.168.2.213 SocketAcceptAddress=192.168.2.213

Comment by Jörg Thönnes [ 18/Jul/12 ]

This is more about debugging network connections. Please ask in the mailing list.





[QFJ-670] CLONE - Session Qualifier or some other field Created: 05/Mar/12  Updated: 05/Mar/12

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

Type: Other Priority: Default
Reporter: Howard Andresier Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I want to identify each session uniquely through my own Id (not version, sender or target_comp_id combination)

I mean onCreate gives a callback with SessionId, which gives a combination of version, sender_comp_id and target_compid. sessionQualifier helped in giving my own Id, but SessionQualifier is not supported with acceptor sessions, Is there some easy way I can identify the sessions with the my own id?



 Comments   
Comment by Howard Andresier [ 05/Mar/12 ]

Clone of QFJ-392, since I appear unable to re-open it.
Could someone give me the fix version where this was resolved? I too would like a qualifier for Acceptors.

Comment by Howard Andresier [ 05/Mar/12 ]

I see now also QFJ-207, which is closed with a 'Wont Fix'. Please disregard if that is still the case.





[QFJ-669] Initiator interprets logout response as logout request. Created: 02/Mar/12  Updated: 24/Jan/13

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.2, 1.5.3
Fix Version/s: Future Releases

Type: Bug Priority: Default
Reporter: Bogdan Dornean Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Steps:
1.INITIATOR sends logout request.
2.ACCEPTOR sends logout response.
3.INITIATOR interprets received logout message as logout REQUEST
4.INITIATOR sends logout response.

INFO: Logging out all sessions
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, event> (Initiated logout request)
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, outgoing> (8=FIX.4.29=5535=534=5549=INITIATOR52=20120302-14:43:55.80556=ACCEPTOR10=100)
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, incoming> (8=FIX.4.29=8135=552=20120302-14:43:55.80849=ACCEPTOR34=17156=INITIATOR58=At the opposite wish.10=242)
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, event> (Received logout request)
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, outgoing> (8=FIX.4.29=5535=534=5649=INITIATOR52=20120302-14:43:55.81356=ACCEPTOR10=100)
Mar 2, 2012 11:43:55 PM quickfix.Session disconnect
INFO: [FIX.4.2:INITIATOR->ACCEPTOR] Disconnecting: IO Session closed

<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, error> (Error Reading/Writing in MessageStore
java.io.IOException: Bad file descriptor
at java.io.RandomAccessFile.writeBytes(Native Method)
Mar 2, 2012 11:43:55 PM quickfix.mina.SessionConnector stopSessionTimer
at java.io.RandomAccessFile.write(RandomAccessFile.java:453)
INFO: SessionTimer canceled
at quickfix.FileStore.set(FileStore.java:409)
at quickfix.SessionState.set(SessionState.java:308)
at quickfix.Session.sendRaw(Session.java:2307)
at quickfix.Session.generateLogout(Session.java:1350)
at quickfix.Session.generateLogout(Session.java:1323)
at quickfix.Session.nextLogout(Session.java:1301)
at quickfix.Session.next(Session.java:965)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
at java.lang.Thread.run(Thread.java:619)

<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, event> (Sent logout response)
<20120302-14:43:55, FIX.4.2:INITIATOR->ACCEPTOR, error> (Error processing message: 8=FIX.4.29=8135=534=17149=ACCEPTOR52=20120302-14:43:55.80856=INITIATOR58=At the opposite wish.10=242
ava.io.IOException: Bad file descriptor
at java.io.RandomAccessFile.seek(Native Method)
at quickfix.FileStore.storeSequenceNumbers(FileStore.java:414)
at quickfix.FileStore.incrNextTargetMsgSeqNum(FileStore.java:307)
at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:368)
at quickfix.Session.nextLogout(Session.java:1310)
at quickfix.Session.next(Session.java:965)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:114)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:77)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:94)
at java.lang.Thread.run(Thread.java:619)



 Comments   
Comment by Krzysztof Szalast [ 14/Sep/12 ]

I also have this error. After second unnecessary LogOut, when I am sending LogOn, in field 34 is bad value (to high).

Scenario:
Me (initiator): Logout t34=204
Counterparty (acceptor): Logout t34=315
Me: Logout* t34=205 (counterparty don't receive this message, but my outgoing_seqnum is incremented)
Me: Logon t34=206, t789=316
Counterparty: t34=316, t789=205 (205 was second Logout*)
Me: SequenceReset t34=205, 36=207 <-- this message sould not be sent. This is side effect of Logout* (t34=205)

Very sorry for my English

Comment by Krzysztof Szalast [ 14/Sep/12 ]

I've resolved problem by add "synchronized" modifier to methods:
quickfix.Session::next()
quickfix.Session::next(Message)
ugly, but looks work properly.

Comment by Jörg Thönnes [ 24/Jan/13 ]

I could reproduce this issue. It seems to happen if there is a very low latency in the network connection between client and server (e.g. on the same host).

Two things happen very quickly:

  • Incoming Logout is processed before the sentLogout flag in the session state is set / published.
  • Shortly after that the socket is closed: "Disconnecting: IO Session closed"

QFJ tries to answer the Logout it considers as request and fails:

  • event : No responder, not sending message: 8=FIX.4.4|9=53|35=5|34=...

But this message is kept in the message store and leads to a ResendRequest at the next logon.

IHMO, syncing on next() is too brute-force. On the other hand, correcting the already complicated state handling is tricky.

Comment by Jörg Thönnes [ 24/Jan/13 ]

Lowering priority since this is a race condition in a very specific situation and does not affect general functionality.





[QFJ-668] Disconnecting: Timed out waiting for heartbeat, after exchanging the Test messages. Created: 15/Feb/12  Updated: 04/Nov/16  Resolved: 09/Aug/12

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

Type: Bug Priority: Major
Reporter: Abcedf12345 Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: QuickfixJ
Environment:

Linux and Windows


Issue Links:
Duplicate
duplicates QFJ-624 Invalid "Timed out waiting for heartb... Closed
is duplicated by QFJ-759 "Timed out waiting for heartbeat" aft... Closed

 Description   

Looks like many blogs are around this, but no resolution. Here is log.

<20120214-20:00:09, FIX.4.4:COMP1_OUT->COMP2_IN, outgoing> (8=FIX.4.4^A9=84^A35=1^A34=1154^A49=COMP1_OUT^A52=20120214-20:00:09.303^A56=COMP2_IN^A112=TEST^A10=098^A)
<20120214-20:00:09, FIX.4.4:COMP1_OUT->COMP2_IN, event> (Sent test request TEST)
<20120214-20:00:09, FIX.4.4:COMP1_OUT->COMP2_IN, incoming> (8=FIX.4.4^A9=83^A35=0^A34=998^A49=COMP2_IN^A52=20120214-20:00:08.908^A56=COMP1_OUT^A112=TEST^A10=073^A)
<20120214-20:00:10, FIX.4.4:COMP1_IN->COMP2_OUT, outgoing> (8=FIX.4.4^A9=74^A35=0^A34=942^A49=COMP1_IN^A52=20120214-20:00:10.303^A56=COMP2_OUT^A10=026^A)
<20120214-20:00:14, FIX.4.4:COMP1_IN->COMP2_OUT, incoming> (8=FIX.4.4^A9=74^A35=0^A34=976^A49=COMP2_OUT^A52=20120214-20:00:13.776^A56=COMP1_IN^A10=050^A)
<20120214-20:00:29, FIX.4.4:COMP1_IN->COMP2_OUT, outgoing> (8=FIX.4.4^A9=83^A35=1^A34=943^A49=COMP1_IN^A52=20120214-20:00:29.302^A56=COMP2_OUT^A112=TEST^A10=055^A)
<20120214-20:00:29, FIX.4.4:COMP1_IN->COMP2_OUT, event> (Sent test request TEST)
<20120214-20:00:29, FIX.4.4:COMP1_IN->COMP2_OUT, incoming> (8=FIX.4.4^A9=83^A35=0^A34=977^A49=COMP2_OUT^A52=20120214-20:00:28.906^A56=COMP1_IN^A112=TEST^A10=070^A)
<20120214-20:00:36, FIX.4.4:COMP1_OUT->COMP2_IN, error> (Disconnecting: Timed out waiting for heartbeat)



 Comments   
Comment by Christoph John [ 15/Feb/12 ]

Can you reproduce this issue reliably? If yes, also with the current version (1.5.2)? Can you supply a test case?

Moreover, I noticed there is already QFJ-624 with a similar issue so I will close this ticket as a duplicate.

Comment by Abcedf12345 [ 15/Feb/12 ]

Looks like QFJ-624 related to version 1.3.0.
However I don't think it is reproduciable, happens occasionally, following the exchange of "Test" messageses as depcited in log.

Comment by Christoph John [ 15/Feb/12 ]

Yes, QFJ-624 relates to version 1.3.0. But since the issue is still open I would guess that the problem was inherited since then.
Are you able to provide a little more context (e.g. the full log file)? What is your QFJ configuration? Does the problem go away after the Logout?

Comment by Abcedf12345 [ 15/Feb/12 ]

Correct, problem goes away in subsequent login.

QFJ configuration is:
[default]
ConnectionType=acceptor
StartTime=00:00:00
EndTime=00:00:00

[session]
BeginString=FIX.4.4
SenderCompID=COMP1_IN
TargetCompID=COMP2_OUT
SocketAcceptPort=XXXXXX
RefreshOnLogon=Y
UseDataDictionary=Y
DataDictionary=/apps/fix/fg/fix44.xml
FileStorePath=/apps/fix/msg_store/COMP1_COMP2

[session]
BeginString=FIX.4.4
SenderCompID=COMP2_IN
TargetCompID=COMP1_OUT
SocketAcceptPort=XXXXXX
RefreshOnLogon=Y
UseDataDictionary=Y
DataDictionary=/apps/fix/fg/fix44.xml
FileStorePath=/apps/fix/msg_store/COMP2_COMP1

Comment by Christoph John [ 16/Feb/12 ]

OK, again. Can you test if the problem also occurs with the most current QF/J version 1.5.2? Can you provide the full log file? Or at least all non-business messages?

Comment by Abcedf12345 [ 16/Feb/12 ]

Log trail after the above one:

===========================
15:00:36.715 [SocketAcceptorIoProcessor-0.0] INFO q.mina.acceptor.AcceptorIoHandler - MINA session created: /10.163.40.238:53725
<20120214-20:00:40, FIX.4.4:COMP1_OUT->COMP2_IN, incoming> (8=FIX.4.4^A9=86^A35=A^A34=999^A49=COMP2_IN^A52=20120214-20:00:40.231^A56=COMP1_OUT^A98=0^A108=30^A10=086^A)
<20120214-20:00:40, FIX.4.4:COMP1_OUT->COMP2_IN, event> (Accepting session FIX.4.4:COMP1_OUT->COMP2_IN from /10.163.40.238:53725)
<20120214-20:00:40, FIX.4.4:COMP1_OUT->COMP2_IN, event> (Acceptor heartbeat set to 30 seconds)
<20120214-20:00:41, FIX.4.4:COMP1_OUT->COMP2_IN, error> (quickfix.SessionException Logon state is not valid for message (MsgType=0))
<20120214-20:00:41, FIX.4.4:COMP1_OUT->COMP2_IN, error> (Disconnecting: Verifying message failed: quickfix.SessionException: Logon state is not valid for message (MsgType=0))
================

Comment by Abcedf12345 [ 17/Feb/12 ]

Unfortunately it is not reproduciable to try with new version

Comment by another day [ 21/Aug/12 ]

Hi, I am also looking for a solution on this. I consider using ThreadedSocketInitiator instead of SocketInitiator.
Any opinions on this ?

Any other ideas ? I have no clue how to reproduce this behaviour, it occurs with the latest version of QuickFix/J, albeit rarely.

Thanks!

Comment by Enrico Petracchi [ 07/May/13 ]

I have the same issue on one environment with about 10 fix session.
A few days ago all sessions detected an heartbeat missing condition while they were receiving about 10 messages/sec.
I added some logs to the code related to heartbeat missing detection and I found all sessions detecting a lastReceivedTime= 90 seconds plus some milliseconds. All log timestamps are correct (no drift observed); it seems the lastReceivedTime variable has been modified adding 90 seconds or the time read from System.currentTimeMillis was wrong. But the strange things is it happened on all session
Still investigating....

Comment by Andy Tai [ 04/Nov/16 ]

May I know if you have found any solution to this issue? We just encountered it again.
Why did QFJ send a test request in the first place?
It seemed that QFJ will not be able to accept reconnection request, after test request is sent out.
If QFJ cannot handle test request properly, can we disable it or delay it?

Thanks.

Comment by Christoph John [ 04/Nov/16 ]

Hi Andy Tai,
which version of QFJ are you using? How many FIX sessions are handled in your application? How often does this occur? Do you have log files that you could attach?

You could set DisableHeartBeatCheck=Y to completely disable heartbeat/test request checking. You could also set TestRequestDelayMultiplier=1 (default is 0.5) which means that the TestRequest will be sent some seconds later.

Chris.





[QFJ-667] for a custom data dictionary, some fields are generated twice, and so compilation fails with XY.java: get(quickfix.field.Currency) is already defined in quickfix.fix44.XY Created: 03/Feb/12  Updated: 03/Feb/12  Resolved: 03/Feb/12

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

Type: Bug Priority: Default
Reporter: Heiko Seebach Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: generation
Environment:

I tried it under Linux (Ubuntu 11.10) AND Windows 7 with Sun-JDK6,and only under Linux with OpenJDK6 and OpenJDK7



 Description   

Steps to reproduce:
1. Take the - probably relatively often used - datadictionary from http://www.fxprogrammers.com/apisupport/FXCM_FIX.zip (wich is officially published in http://forexforums.dailyfx.com/fix-api-support/453300-fix-documentation-subscribe-updates-2.html)
2. copy the file FIXFXCM10.xml from this zip and to core/src/main/resource/FIX44.xml
3. run "ant clean jar"
Then you (at least I) get 100 errors like this:

[javac] Compiling 1924 source files to /home/hk/ws/e/quickfix-1.5.2/core/target/classes/main
[javac] Advertisement.java:1886: set(quickfix.field.Currency) is already defined in quickfix.fix44.Advertisement
[javac] public void set(quickfix.field.Currency value) {
[javac] ^
[javac] Advertisement.java:1890: get(quickfix.field.Currency) is already defined in quickfix.fix44.Advertisement
[javac] public quickfix.field.Currency get(quickfix.field.Currency value)
[javac] ^
[javac] Advertisement.java:1897: getCurrency() is already defined in quickfix.fix44.Advertisement
[javac] public quickfix.field.Currency getCurrency() throws FieldNotFound {
[javac] ^
[javac] Advertisement.java:1904: isSet(quickfix.field.Currency) is already defined in quickfix.fix44.Advertisement
[javac] public boolean isSet(quickfix.field.Currency field) {
[javac] ^
[javac] Advertisement.java:1908: isSetCurrency() is already defined in quickfix.fix44.Advertisement
[javac] public boolean isSetCurrency() {
[javac] ^
[javac] AllocationInstruction.java:2997: set(quickfix.field.Currency) is already defined in quickfix.fix44.AllocationInstruction
[javac] public void set(quickfix.field.Currency value) {
[javac] ^
[javac] AllocationInstruction.java:3001: get(quickfix.field.Currency) is already defined in quickfix.fix44.AllocationInstruction
[javac] public quickfix.field.Currency get(quickfix.field.Currency value)
[javac] ^

The problem is, that these methods are really generated twice. I've no idea how this might happen.

Any ideas?
Thank you very much,
Heiko Seebach



 Comments   
Comment by Christoph John [ 03/Feb/12 ]

Hi Heiko,

actually, this could only be an issue with the custom data dictionary since it is working with the original one. Fields can get created multiple times for a message if they are listed multiple times on the same message.

This applies to the custom data dictionary. E.g. the Currency is defined on Advertisement (standard) and then also on the Instrument component (custom usage). Since the Instrument component is used on the Advertisement, the Currency field will appear twice which is not allowed. Please bear in mind that components are not the same as repeating groups (in which a field could appear multiple times).

The fields which are defined multiple times are: Currency, RoundLot, FXCMPegFluctuatePts and PrevClosePx. They have been added to the components Instrument or PegInstructions. PrevClosePx was defined multiple times on the NewOrderSingle itself.

Just as a note for the future: maybe first ask the people who have created the data dictionary.

Cheers,
Chris.

Comment by Heiko Seebach [ 03/Feb/12 ]

Hi Christoph,

thank you very much for this analysis.
> maybe first ask the people who have created the data dictionary
well yes, normally I would have done that, but I couldn't image, that they didn't found out that themselves, and I'm not so much into the topic, that I found out these double definitions myself.

Thank you very much, I'll contact FXCM then,

Heiko Seebach

Comment by Christoph John [ 03/Feb/12 ]

Hi Heiko,
you're welcome.
Cheers

Comment by Christoph John [ 03/Feb/12 ]

BTW, it is a different topic if you just use the data dictionary for incoming message validation or if you really create the message classes from the data dictionary. For the first case, the error will probably go undetected for a longer time.





[QFJ-666] FIXMessageEncoder got BufferOverflowException when encoding fix mesage Created: 02/Feb/12  Updated: 09/Jun/14  Resolved: 02/Feb/12

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

Type: Improvement Priority: Default
Reporter: Zhao Mingyu Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: QuickfixJ, encoding
Environment:

windows server 2003
Java Hotspot VM build 1.6.0_29-b11


Issue Links:
Duplicate
duplicates QFJ-38 FIX Message support double-byte charset. Closed
duplicates QFJ-382 Foreign Language Support - Multibyte ... Closed
is duplicated by QFJ-282 FIXMessageEncoder#encode() may throws... Closed

 Description   

Hi All, I add the code below into my quickfix app, hoping that it could send fix message with multibytes character, such as Chinese.
CharsetSupport.setCharset("GBK");

But I found it failed to send out the fix execution report and throws a BufferOverflowException in method encode of quickfix.mina.message.FIXMessageEncoder.
Below is the code fragment in method encode:

ByteBuffer buffer = ByteBuffer.allocate(fixMessageString.length());
try

{ buffer.put(fixMessageString.getBytes(charsetEncoding)); }

catch (UnsupportedEncodingException e)

{ throw new ProtocolCodecException(e); }

BufferOverflowException is thrown by the code "buffer.put".
The reason is String.length() only return the count of character. For multibytes char, String.length() is half smaller than String.getBytes().length, so the capacity of ByteBuffer is not sufficient for the encoded bytes of the fixMessageString.
Although there is rarely multibytes char in fix message, it can be improved like the below:
ByteBuffer buffer = null;
try { byte[] encodedBytes = fixMessageString.getBytes(charsetEncoding) buffer = ByteBuffer.allocate(encodedBytes.length); buffer.put(encodedBytes); } catch (UnsupportedEncodingException e) { throw new ProtocolCodecException(e); }

 Comments   
Comment by Christoph John [ 02/Feb/12 ]

Hi,
could you please check if one of the tickets QFJ-382 or QFJ-38 fits for you? Maybe you can add a comment there.
Thanks, Chris.

Comment by Zhao Mingyu [ 02/Feb/12 ]

Hi Chris,
I got it. Thanks for your help

Comment by Christoph John [ 02/Feb/12 ]

Great, will close this evil ticket as duplicate then.





[QFJ-665] "Dangling meta character '*' near index 0" Exception when trying to use new ReconnectInterval syntax from QFJ-419 Created: 30/Jan/12  Updated: 24/Aug/12  Resolved: 25/Jul/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Andy Faibishenko Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

Solaris x86


Issue Links:
Relates
is related to QFJ-419 Reconnect Interval: set different int... Closed

 Description   

I set ReconnectInterval in the DEFAULT section to the same string as the example in QFJ-419
ReconnectInterval=6*5;5*15;60

When I run the program I get the following stack trace

quickfix.ConfigError: java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*
^
at quickfix.DefaultSessionFactory.getLogonIntervalsInSeconds(DefaultSessionFactory.java:339)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:176)
at quickfix.mina.SessionConnector.createSession(SessionConnector.java:140)
at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:160)
at quickfix.mina.initiator.AbstractSocketInitiator.createSessionInitiators(AbstractSocketInitiator.java:81)
at quickfix.SocketInitiator.initialize(SocketInitiator.java:85)
at quickfix.SocketInitiator.start(SocketInitiator.java:65)
at com.cboe.driver.LogonDOSApplication.main(LogonDOSApplication.java:104)
Caused by: java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*
^
at java.util.regex.Pattern.error(Pattern.java:1713)
at java.util.regex.Pattern.sequence(Pattern.java:1878)
at java.util.regex.Pattern.expr(Pattern.java:1752)
at java.util.regex.Pattern.compile(Pattern.java:1460)
at java.util.regex.Pattern.<init>(Pattern.java:1133)
at java.util.regex.Pattern.compile(Pattern.java:823)
at java.lang.String.split(String.java:2292)
at java.lang.String.split(String.java:2334)
at quickfix.SessionSettings.parseSettingReconnectInterval(SessionSettings.java:742)
at quickfix.DefaultSessionFactory.getLogonIntervalsInSeconds(DefaultSessionFactory.java:336)
... 7 more



 Comments   
Comment by Christoph John [ 31/Jan/12 ]

Could you try if it works when specifying "x" as the multiplier character?
Anyway, there seems to be a bug when using "*" as multiplier.

Comment by Christoph John [ 31/Jan/12 ]
Index: core/src/main/java/quickfix/SessionSettings.java
===================================================================
--- core/src/main/java/quickfix/SessionSettings.java	(revision 1061)
+++ core/src/main/java/quickfix/SessionSettings.java	(working copy)
@@ -735,7 +735,7 @@
         if (raw == null || raw.length() == 0) {
             return null;
         }
-        final String multiplierCharacter = raw.contains("*") ? "*" : "x";
+        final String multiplierCharacter = raw.contains("*") ? "\\*" : "x";
         final String[] data = raw.split(";");
         final List<Integer> result = new ArrayList<Integer>();
         for (final String multi : data) {

Seems it was forgotten to escape the asterisk when parsing the parameters. But as said, it should also work with "x" as separator.





[QFJ-664] Upgrade MINA from 1.1.8 to 2.0.x Created: 25/Jan/12  Updated: 02/Apr/15  Resolved: 03/Jan/14

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.5.2, 1.5.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: oliver jehle Assignee: Christoph John
Resolution: Fixed Votes: 6
Labels: None

Attachments: Text File actual_patch_v02.txt     File quickfix-1.5.3-mina2.path    
Issue Links:
Relates
is related to QFJ-738 Deadlock on disconnect Closed
Requires
requires QFJ-737 Use current JDK for compilation of Qu... Closed
is required by QFJ-285 Proxy Support for Initiator connections Closed

 Description   

Upgrade quickfix/j to the mina 2.x release

NB: In the meantime MINA version is now 2.0.9 (https://github.com/quickfix-j/quickfixj/commit/93f263a2096d9f3a102cfb04b78a76515810927d)



 Comments   
Comment by Attila-Mihaly Balazs [ 27/Feb/12 ]

The patch from QFJ-285 by Oliver seems to solve this issue (I also applied it and successfully ran all the unittests). We'll be using the patched version in a UAT environment and I'll follow up with any observed problems.

Comment by Jörg Thönnes [ 28/Feb/12 ]

In reply to comment #1:
> The patch from QFJ-285 by Oliver seems to solve this issue (I also applied it
> and successfully ran all the unittests). We'll be using the patched version in a
> UAT environment and I'll follow up with any observed problems.

Sounds good. Please provide feedback as soon as you have some.

Comment by oliver jehle [ 05/Mar/12 ]

sorry, late delay... i will rediff on the latest tree and post the patch with all cleanups. the problem is, that i have to split out the proxy hack stuff und the mina stuff. i hope i can work tomorrow in train on the diff, so i can repost the patch tomorrow or on wednesday.

Comment by Jörg Thönnes [ 06/Mar/12 ]

In reply to comment #3:
> sorry, late delay... i will rediff on the latest tree and post the patch with
> all cleanups. the problem is, that i have to split out the proxy hack stuff und
> the mina stuff. i hope i can work tomorrow in train on the diff, so i can repost
> the patch tomorrow or on wednesday.

That's fine, Oliver. I am also short of time due to my work.

Comment by oliver jehle [ 13/Mar/12 ]

latest patch and last one.... please test this patch in your UAT environment. there is only a small diff to the v01 patch. only some System.out and System.err and Log.info are removed. rest ist stable and the ant test was successfull. don't forget to replace the mina-1.1.7 with the mina-2.0.4 or higher libs...

Comment by Christoph John [ 01/Aug/12 ]

Unfortunately it seems that we will have to wait until at least 1.6.0 to incorporate this change since we need to discontinue the JDK1.4 support of QF/J when we want to use MINA2. MINA2 is only available for JDK5+ and the QFJ code needs to be changed to work with MINA2.

Comment by Attila-Mihaly Balazs [ 19/Mar/13 ]

This is an updated version of the previous patch, done against quickfix/j 1.5.3.

I would like to mention that at this point Java 1.4 is ancient history and not even Java 1.6 is publicly supported anymore. Along this line of reasoning you should run java 1.7 because (other than common sense - which is not all that common):

  • you get patches for free
  • you avoid possibly violating regulations like PCI for example by not running unsupported software
Comment by Christoph John [ 20/Mar/13 ]

Thanks for the patch. I agree that we should definitely use a recent JDK. I will send a message to the quickfixj-users group.

Comment by Attila-Mihaly Balazs [ 17/Jun/13 ]

One more reason to remove 1.5 and lower: the JDK itself will remove support for them: http://openjdk.java.net/jeps/182

Comment by Aaron Li [ 11/Jul/13 ]

Applied patch quickfix-1.5.3-mina2.path and built without issues. Can someone point me how to make a change to quickfix/j and let it pick up proxy settings and establish connection via socks v4 proxy server?

Tried returning a ProxyConnector with ProxyIoSession set from ProtocolFactory.createIoConnector() but got no luck. Can't even pass through jSocks tests. Very frustrated.

Any help is highly appreciated.

Aaron

[email protected]

Comment by oliver jehle [ 11/Jul/13 ]

i did only tests with http proxies. socks i dont know

if mina support it, perhaps passing socks option
to mina would work

but as you can see, the patch is old and never
accepted to mainstream, because jdk discussions.

Comment by Niall [ 18/Jul/13 ]

We have a dependency on both quickfixj & apache qpid - but qpid uses mina 2.0 which clashes with quickfixj's dependency on mina 1.0. So would be really good if quickfixj could move to mina 2.0

Comment by Christoph John [ 03/Jan/14 ]

Committed as http://sourceforge.net/p/quickfixj/code/1131/ and http://sourceforge.net/p/quickfixj/code/1132/.
Thanks to Oliver Jehle and Attila-Mihaly Balazs for the submitted patches.

Comment by Christoph John [ 03/Jan/14 ]

With the new MINA libraries some deadlock situations on disconnect are now more prominent than before. This will be handled in QFJ-738.





[QFJ-663] FieldMap's "getGroup()", "replaceGroup()", and possibly others... should start with 0 (not 1) Created: 23/Jan/12  Updated: 23/Jan/12

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: John Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The first index for anything in the IT world is "0", not "1". Most certainly any programmer in this world expects the index "0" to be the first one.
An implementation must add 1 to each index, and the FIX engine then decrements it (will not kill the CPU but it is at least some work that could be avoided).

My solution would be to deprecate the methods and have new replacing methods (remove the deprecated methods and rename the new ones in a later version).






[QFJ-662] FIX4.4.xml - TradeReportRejectReason/751 missing value of Other/99 Created: 19/Jan/12  Updated: 20/Jan/12  Resolved: 20/Jan/12

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

Type: Bug Priority: Default
Reporter: Akron Lefact Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-661 missing value '99' for tag '751' in F... Resolved

 Description   

As per FIXimate, TradeReportRejectReason/751 should have a value of Other/99 as one of the valid values. FIX4.4.xml doesn't have this (only 0-4)



 Comments   
Comment by Christoph John [ 20/Jan/12 ]

Closing as duplicate of QFJ-661.





[QFJ-661] missing value '99' for tag '751' in FIX44.xml Created: 13/Jan/12  Updated: 24/Aug/12  Resolved: 01/Aug/12

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

Type: Bug Priority: Trivial
Reporter: Christophe Domas Assignee: Christoph John
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-662 FIX4.4.xml - TradeReportRejectReason/... Closed

 Description   

The '99' value for tag '751' exists in specs but not in the FIX44.xml.



 Comments   
Comment by Christophe Domas [ 13/Jan/12 ]

I've check in quickfix c++ 4.4 dictionary and the value also exists.

By the way, how do you generate the dictionary files? In the FIX repository, the xml format is very different (lots of xml distinct files)?

Comment by Jari Junikka [ 24/Feb/12 ]

This is trivial to fix, but priority is high, not trivial. This leads rejection messages not being delivered correctly to applications and incorrect rejections of the rejection messages delivered to the other party.

In other words, it causes a mess.

Comment by Christoph John [ 24/Feb/12 ]

I guess the priority was set to trivial because there is an easy workaround: just add the tag to the data dictionary yourself.





[QFJ-660] Sequence number file can become corrupted. Created: 11/Jan/12  Updated: 24/Aug/12  Resolved: 24/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Christopher Hurst Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows, QFJ under heavy load (performance test)



 Description   

I keep meaning to investigate this ...

I've seen this a few times and reported it on the forum with no response, basically it appears possible to end up with two sets of sequence numbers in the seqnum file (I assume that's not intentional).

I suspect if the engine were to fail at the exact time the bug occurs the current sequence numbers could be wrong ?, this should be very, very unlikely though potentially serious.

So Expected seqnum file :
<length><Seq 1>:<Seq2>

corrupted file ..
<length1><Seq 1>:<Seq 2><length2><Another Seq 1>:<Another Seq 2>

The session does not fail with such a corrupted file or show ill effect, I suspect possible session recovery would be the only issue and as the file can still be read only at the exact point the corruption occurred.

The only explanation I can think of is ..
I was wondering if this was a multithreading issue with FileStore.storeSequenceNumbers ? I keep meaning to check if this can be called by multiple threads for a single session as that would fit, ie two threads try to move to the start of the file and write at the same time ?



 Comments   
Comment by Christoph John [ 12/Jan/12 ]

Do you use the SingleThreadedEventHandlingStrategy or ThreadPerSessionEventHandlingStrategy?
From what I know, the FileStore is not thread-safe and concurrent calls to e.g. storeSequenceNumbers() could lead to strange results. The sequence numbers can be incremented by various next...() methods in the Session class. However, normally the session should only process one message at once. There is either one thread for all sessions, or a thread per session.

But one possible cause for this might be a concurrent call to one of the next...() methods and sendRaw(), i.e. messages are sent and received at the same time so that there are concurrent calls to storeSequenceNumbers(). But this is only speculation, I have not checked thoroughly if this is possible at all or if this is prevented by some means.

Comment by Christopher Hurst [ 12/Jan/12 ]

SingleThreadedEventHandlingStrategy .. I believe but I don't think that's relevant as the issue is in the engine threading ??

I think I have got to the bottom of the issue and it looks a lot more serious (unless I'm missing something ), I'm not sure the memory cache is consistent with the filestore, I would have thought changes to persistence numbers should be atomic (one complete change AND values published across threads 'visibility') but that doesn't appear to be the case. I think we may have a 'race' here also ...

I've trapped the two threads in memory (I vaguely guessed what they would be but wanted to check my facts), on is essentially the timer thread e.g. heart beats the other effectively business messages.

The following is the stack traces from two threads trying to manipulate sequence numbers at the same time
(to reproduce this just put a break point in the filestore though be careful as obviously this code is time sensitive)

If some one else can't fault my logic the priority of this might need raising, should be a very easy fix i.e. synchronization

Daemon Thread [QFJ Timer] (Suspended (breakpoint at line 403 in FileStore))
FileStore.storeSequenceNumbers() line: 403
FileStore.incrNextSenderMsgSeqNum() line: 288
SessionState.incrNextSenderMsgSeqNum() line: 359
Session.sendRaw(Message, int) line: 2382
Session.generateHeartbeat() line: 1806
Session.next() line: 1779
SessionConnector$SessionTimerTask.run() line: 251
Executors$RunnableAdapter<T>.call() line: 441
FutureTask$Sync.innerRunAndReset() line: 317
ScheduledThreadPoolExecutor$ScheduledFutureTask<V>(FutureTask<V>).runAndReset() line: 150

Daemon Thread [QFJ Message Processor] (Suspended (breakpoint at line 403 in FileStore))
FileStore.storeSequenceNumbers() line: 403
FileStore.setNextTargetMsgSeqNum(int) line: 280
SessionState.setNextTargetMsgSeqNum(int) line: 355
Session.nextSequenceReset(Message) line: 1338
Session.next(Message) line: 943
SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage() line: 112
SingleThreadedEventHandlingStrategy.block() line: 75
SingleThreadedEventHandlingStrategy$1.run() line: 92
Thread.run() line: 662

ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.access$101(ScheduledThreadPoolExecutor$ScheduledFutureTask) line: 98
ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.runPeriodic() line: 180
ScheduledThreadPoolExecutor$ScheduledFutureTask<V>.run() line: 204
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908
Thread.run() line: 662

Comment by Christoph John [ 12/Jan/12 ]

Thanks. This supports my assumption from my previous comment: "concurrent call to one of the next...() methods and sendRaw()".

Comment by Christoph John [ 16/Jan/12 ]

As a workaround, maybe QFJ-552 helps for the time being.
Another workaround would be a custom file store which stores incoming and outgoing seq nums in separate files.

Comment by Christoph John [ 24/Aug/12 ]

The implementation will now be changed to use separate files for sender and target seqnums to avoid concurrent writes of SessionState.set/incrNextTargetMsgSeqNum and SessionState.set/incrNextSenderMsgSeqNum to the same file.

Of course this means that anyone accessing the sequence number files directly (NOT via MessageStore methods) will have a problem now.

Comment by Christoph John [ 24/Aug/12 ]

NB: The change means that sequence number files from an older version cannot be read with this version. So you shouldn't switch the QF/J version during the day and it's safest to delete the message store beforehand.





[QFJ-659] Sequence number issues when acceptor sends a message immediately following logon response Created: 09/Jan/12  Updated: 09/Jan/12

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0, 1.5.2
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Andrew Richards Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: logon, sequnece


 Description   

I have an initiator connection to a foreign acceptor which has sequence number confusion on logon as the foreign acceptor sends a TestRequest immediately after the logon response.

It looks like the following is happening: Quickfix/J accepts both (Logon & TestRequest) messages. The and proceeds to check the sequence number of the Logon to make sure the session is valid. It does this via Session.isTargetTooHigh() which looks at the last message in the message store which is now 1 higher than is should be because the TestRequest has been received and stored. The "MsgSeqNum too high" is issued and the engine tries to recover. In some most circumstances, but not all it (with the engine in question) it can recover however it's not ideal.

The effect can be simulated (QuickFIX/J -> QuickFIX/J) by using and acceptor with the toAdmin below.

public void toAdmin(Message message, SessionID sessionID)
{
print("toAdmin", message, sessionID);

try {
Header header = message.getHeader();
if ( header.getField( new MsgType() ).valueEquals( MsgType.LOGON ) )

{ quickfix.fix44.TestRequest tst = new quickfix.fix44.TestRequest(new TestReqID("TEST")); Session.sendToTarget(tst, sessionID); }

}
catch (Exception e) {}
}

09-Jan-2012 08:49:19 INFO : Initialize
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: 8=FIX.4.49=5535=034=349=SERVER52=20120109-08:49:50.01356=CLIENT10=107
09-Jan-2012 08:49:50 SEVERE : FIX.4.4:CLIENT->SERVER: MsgSeqNum too high, expecting 2 but received 3: 8=FIX.4.49=5535=034=349=SERVER52=20120109-08:49:50.01356=CLIENT10=107
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: Enqueued at pos 3: 8=FIX.4.49=5535=034=349=SERVER52=20120109-08:49:50.01356=CLIENT10=107
09-Jan-2012 08:49:50 INFO : [toAdmin](FIX.4.4:CLIENT->SERVER)[2](MsgType:ResendRequest (2))
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: 8=FIX.4.49=6435=234=249=CLIENT52=20120109-08:49:50.01956=SERVER7=216=010=238
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: Sent ResendRequest FROM: 2 TO: 2
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: 8=FIX.4.49=9335=434=243=Y49=SERVER52=20120109-08:49:50.02556=CLIENT122=20120109-08:49:5036=4123=Y10=182
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: ResendRequest for messages FROM 2 TO 2 has been satisfied.
09-Jan-2012 08:49:50 INFO : [fromAdmin](FIX.4.4:CLIENT->SERVER)[2](MsgType:SequenceReset (4))
09-Jan-2012 08:49:50 INFO : FIX.4.4:CLIENT->SERVER: Received SequenceReset FROM: 2 TO: 4
09-Jan-2012 08:50:20 INFO : [toAdmin](FIX.4.4:CLIENT->SERVER)[3](MsgType:Heartbeat (0))
09-Jan-2012 08:50:20 INFO : FIX.4.4:CLIENT->SERVER: 8=FIX.4.49=5535=034=349=CLIENT52=20120109-08:50:20.21556=SERVER10=100
09-Jan-2012 08:50:20 INFO : FIX.4.4:CLIENT->SERVER: 8=FIX.4.49=5535=034=449=SERVER52=20120109-08:50:20.21856=CLIENT10=104
09-Jan-2012 08:50:20 INFO : [fromAdmin](FIX.4.4:CLIENT->SERVER)[4](MsgType:Heartbeat (0))






[QFJ-658] Sequence numbers not checked for incoming ResendRequest Created: 08/Dec/11  Updated: 02/Apr/15  Resolved: 16/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.1
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Duplicate Votes: 1
Labels: session

Issue Links:
Duplicate
duplicates QFJ-673 QFJ sequence problem following inboun... Closed

 Description   

When QF/J receives a ResendRequest it does not check for the MsgSeqNum of the ResendRequest. Depending on the MsgSeqNum on the ResendRequest it does the following (no PossDup flag was set):

  • MsgSeqNum on ResendRequest too low: QF/J performs the normal resending or SequenceReset, incoming sequence number is not altered
  • MsgSeqNum on ResendRequest correct: QF/J performs the normal resending or SequenceReset, incoming sequence number is incremented
  • MsgSeqNum on ResendRequest too high: QF/J performs the normal resending or SequenceReset, incoming sequence number is not altered

According to the spec (e.g. http://fixprotocol.org/documents/3070/FIX_Transport_1.1.pdf on pages 12 and 13) the behaviour should be as follows:

  • MsgSeqNum too low: terminate the connection
  • MsgSeqNum too high: perform the normal resending or SequenceReset, afterwards send a ResendRequest of your own to fill the gap


 Comments   
Comment by Christoph John [ 16/Dec/13 ]

Closing as duplicate since this is part of a bigger problem which is handled in QFJ-673.





[QFJ-657] TestRequest should be sent before a Logout is sent. (Initiator) Created: 05/Dec/11  Updated: 06/Dec/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Ken Douglas Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: Logout, testRequest
Environment:

Windows 7 Ultimate, Java 6 u29
QuickFix J 1.5.1



 Description   

TestRequest should be sent before a Logout is sent (Initiator).
You may not agree this is a bug by the way but perhaps a feature not currently supported but the FIX Protocol recommends the following:-

[1] a TestRequest is sent and a hearbeat is expected to be sent in return
[2] NB No logout is sent until a heartbeat (with the TestRequest ID) is received.
[3] Once receive a logout is sent and waitfor Logout is carried out.
[4] then disconnect is done.

I have seen a question relating to this on the forum but this goes way back
http://quickfix-j.364392.n2.nabble.com/Log-file-rotation-td665743.html

Currently the way the reset() on the Session is done it does not allow you to fire a TestRequest off and wait for the hearbeat.

Any idea guys?

Thanks



 Comments   
Comment by Christoph John [ 06/Dec/11 ]

I think this would be a good improvement. BTW, the link to the forum thread is wrong. It leads to a discussion about log rotation.





[QFJ-656] allowUnknownMsgFields has no effect if the field is not defined in the dictionary Created: 28/Nov/11  Updated: 21/Apr/16  Resolved: 08/Jan/16

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0, 1.5.0, 1.5.1
Fix Version/s: 1.6.2

Type: Bug Priority: Major
Reporter: test Assignee: Marcin L
Resolution: Fixed Votes: 2
Labels: None

Attachments: Text File suggested_fix.txt    

 Description   

The documentation of allowUnknownMsgFields is a bit misleading, it has no effect if the field is not defined in the dictionary. allowUnknownMsgFields is not checked in void checkValidTagNumber(Field<?> field) .



 Comments   
Comment by Greg Chabala [ 25/Jun/12 ]

This is still an issue in version 1.5.2

Comment by Marcin L [ 30/Dec/15 ]

I wanted to produce a fix for this issue, but I have trouble understanding what the correct logic should be. I believe the question is if the behaviour should be respectively the same, regardless if a field exists in <fields> section or not. I did some analysis on the topic, but I need a second opinion if this is desired solution, before I submit a patch. Please see attachment.

Comment by Christoph John [ 31/Dec/15 ]

Hi Marcin L,

you forgot to mention if the fields are required. I was wondering why test case 2 with field 6000 (AllowUnknownMessageFields=false and CheckUserDefinedFields=true) failed. But this is because the field 6000 is required I assume?
Why should the case with field 6000 and AllowUnknownMessageFields and CheckUserDefinedFields both set to true be fixed?
IMHO you are right about the FIXMEs for case 3. If AllowUnknownMessageFields is set to true then it should not matter if the field is inside the dictionary or not.

Thanks,
Chris.

Comment by Marcin L [ 31/Dec/15 ]

Hello Christoph,

1) Actually none of the fields are required, because all them are missing in the message fields section:

<messages>
<message name="TestMessage" msgtype="T" msgcat="app">
<!-- no fields defined -->
</message>
</messages>

Field 6000, test case (2, 2) fails currently, because field 6000 is not defined in message + AllowUnknownMessageFields == false:

private void checkIsInMessage(Field<?> field, String msgType) {
if (!isMsgField(msgType, field.getField()) && !allowUnknownMessageFields)

{ throw new FieldException(SessionRejectReason.TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE, field.getField()); // line: 779 }

}

The above check is triggered, because of CheckUserDefinedFields == true.

2) I'm not sure about test case (2,4). It would make sense to FAIL according to documentation, because

  • 6000 is a user defined field
  • CheckUserDefinedFields == true
  • it's not defined in the message

In general I think that checks dependent on flags AllowUnknownMessageFields and CheckUserDefinedFields should be executed independently, although this is not the case at the moment.

From docoumentation. ValidateUserDefinedFields: If set to N, user defined fields will not be rejected if they are not defined in the data dictionary, or are present in messages they do not belong to.

This basically means that if value is true, then all fields >= 5000 should fail if not in message field section or global field section, which would imply that test case (2, 4) should result in FAILURE.

Additionally in my understanding of these flags:

AllowUnknownMessageFields == !CheckUserDefinedFields (however the first flag applies to fields < 5000 only, second to fields >=5000 only)

Comment by Christoph John [ 04/Jan/16 ]

Hi Marcin L and happy new year,

you are of course right about points 1) and 2). Sorry, it was late.
As you said, according to the documentation ValidateUserDefinedFields applies to fields >= 5000 and AllowUnknownMsgFields to tags < 5000. Currently the behaviour is not as expected, as your analysis has shown.

It would be great if you could provide a patch and unit test for this.
Thanks in advance.

Comment by Marcin L [ 04/Jan/16 ]

https://github.com/quickfix-j/quickfixj/pull/57





[QFJ-655] How to run examples? Created: 28/Nov/11  Updated: 02/Aug/12  Resolved: 02/Aug/12

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

Type: Other Priority: Default
Reporter: caowei Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: QuickfixJ
Environment:

win32/java5/eclipse3.4.2



 Description   

I run Banzai.java, no sessionID in combox and show "FIX.4.2:BANZAI->EXEC, error> (java.net.ConnectException: java.net.ConnectException: Connection refused: no further information (Next retry in 30000 milliseconds))" message in console.

[default]
FileStorePath=examples/target/data/banzai
ConnectionType=initiator
SenderCompID=BANZAI
TargetCompID=EXEC
SocketConnectHost=localhost
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ReconnectInterval=30

[session]
BeginString=FIX.4.2
SocketConnectPort=9876

How to run these examples? anywhere need to change?



 Comments   
Comment by Christoph John [ 28/Nov/11 ]

The Banzai program only initiates a connection (FIX initiator). You also need to have another FIX process that listens for connections (FIX acceptor). The example program "Executor" could serve for this purpose.





[QFJ-654] Rejecting due to OrigSendingTime not being in Tag without Data Dictionary Created: 24/Nov/11  Updated: 15/Nov/12  Resolved: 12/Dec/11

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

Type: Improvement Priority: Default
Reporter: Christophe Domas Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: session

Issue Links:
Duplicate
is duplicated by QFJ-403 Rejecting due to OrigSendingTime not ... Closed
Relates
is related to QFJ-703 Do not reject PossDup message which d... Resolved

 Description   

Hi,

I'm using quickfix/J and for some reason I keep rejecting messages with reject:

20090210-16:13:01: Message 641 Rejected: Required tag missing:122

I have the following configuration options set in configuration:

UseDataDictionary=N
ValidateFieldsOutOfOrder=N
ValidateFieldsHaveValues=N
VaidateUserDefinedFields=N
CheckLatency=N

And I have also attempted to rip out OrigSendingTime from my Data Dictionary as a precautionary measure. I don't ever explicitly call this tag in code. Any help on this issue would be appreciated.

Regards,
Herman



 Comments   
Comment by Christophe Domas [ 24/Nov/11 ]

Hi,

I've cloned the issue QFJ-403 cause I'm in the same case. My counterpart does not set the OrigSendingTime for dup message.
I don't see any solution, except they correct their soft or hacking quickfix/j.

Comment by Grant Birchmeier [ 24/Nov/11 ]

QFJ-403 was marked fixed, so presumably this shouldn't be happening. Are you using an old version of QF/J?

Comment by Christophe Domas [ 24/Nov/11 ]

Yes, the problem is marked fixed and I use the last 1.5.1 version (that include the patch).
But as I say, my counterpart does not set the OrigSendingTime for dup message (FIX 4.2) and I'm looking for a workaround (correct answer should be "they have to respect the protocol" but it seems to be difficult - big company, lots of customers).

Comment by Christophe Domas [ 28/Nov/11 ]

The only way I found to intercept the message to add missing tag 122 is to set an IoFilterChainBuilder on SocketInitiator.
But the problem is the message received in interceptor method messageReceived() is a String, so I have to parse it.

Is there a better way to intercept FIX message before session handles it?

Comment by Christophe Domas [ 28/Nov/11 ]

Maybe I should create a new ticket: "How can I intercept quickfix message before session handles it", no?

Comment by Christoph John [ 29/Nov/11 ]

Hi guys,

indeed, QFJ-403 is marked as fixed. But the proposed solution was not incorporated into QF/J. At least the code in validatePossDup(Message) still looks like this (on 1.5.1 and on trunk):

if (!header.isSetField(OrigSendingTime.FIELD)) {
    generateReject(msg, SessionRejectReason.REQUIRED_TAG_MISSING, OrigSendingTime.FIELD);
    return false;
}
Comment by Christoph John [ 30/Nov/11 ]

Hi Christophe,
I will take care of this. It seems the fix was not applied or got reverted.
Cheers,
Chris.

Comment by Krzysztof Szalast [ 06/Sep/12 ]

Hi,
Setting "RejectInvalidMessage" flag to "Y" is too risky when I want ignore ONLY 122 field but I want to validate rest of fields. I propose reopen this bug.

Maybe should be added property something like:
IgnoredFieldsDueValitation=<field1>,<field2>...
and errors in field1, field2 will be ignored, but not in the other fields?

P.S. Sorry for my english

Comment by Christoph John [ 10/Sep/12 ]

Cześć Krzysztof,
I think we should just check if tag 122/OrigSendingTime is present and if it isn't we shouldn't do the SendingTime vs. OrigSendingTime check. In my opinion QF/J should rather try to synchronize correctly instead of throwing validation errors. -> QFJ-703

Comment by Krzysztof Szalast [ 14/Sep/12 ]

I agree. So I am waiting for new version. Thanks





[QFJ-653] IOException if sessionTimestamp file exists but is empty Created: 17/Nov/11  Updated: 15/Nov/12  Resolved: 17/Nov/11

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

Type: Bug Priority: Default
Reporter: Laurent Danesi Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: FileStore

Issue Links:
Relates
relates to QFJ-701 Restart FIX engine occur I/O exception Closed

 Description   

In case of full disk or file corruption, it is impossible to restart QFJ that throws IOException while reading the file






[QFJ-652] Reject is missing RefTagID when answering SequenceReset with invalid NewSeqNo Created: 15/Nov/11  Updated: 01/Dec/11  Resolved: 01/Dec/11

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

Type: Improvement Priority: Minor
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: session


 Description   

When sending a SequenceReset message with invalid (i.e. too low) tag 36/NewSeqNo, QFJ answers with a Reject. This is correct, but the Reject is missing the tag 371/RefTagID.

sending message: 8=FIX.4.49=6735=434=252=20111115-14:33:51.65449=FixClient56=FixGateway36=110=049
received message: 8=FIX.4.49=12935=334=349=FixGateway52=20111115-13:33:58.18056=FixClient45=258=Value is incorrect (out of range) for this tag372=4373=510=146

Looking at the code in Session.nextSequenceReset() the method generateReject(sequenceReset, SessionRejectReason.VALUE_IS_INCORRECT, 0) is called. Here we should supply NewSeqNo.FIELD instead of 0. Further down the chain, the method setRejectReason will prevent the 371/RefTagID field to be set for FIX versions lower than FIX4.2.






[QFJ-651] To stop unsuccessful connection attempts after few retries Created: 14/Nov/11  Updated: 29/Nov/11  Resolved: 29/Nov/11

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

Type: Other Priority: Default
Reporter: Mansoor Haider Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: QuickfixJ
Environment:

Java,windows 7



 Description   

How to stop unsuccessful connection attempts after few retries???



 Comments   
Comment by Grant Birchmeier [ 14/Nov/11 ]

This is not a good idea. Traditionally, you want your initiator to keep trying to connect. If the counterparty goes down for some unexpected reason, you want your initiator to keep re-attempting so that it will reconnect as soon as the counterparty comes back up.

If you wish to do this anyway, you can implement logic in your toAdmin or fromAdmin callbacks to shut your program down after however-many retries. I suggest that a better idea is to have it send a notification to a human (via email or whatnot) so that a human can decide whether to shut down the app and whether some fixes are needed.

Comment by Mansoor Haider [ 14/Nov/11 ]

Thanks for your suggestion,but do we have any quickfixj api support to do the same.

Comment by Mansoor Haider [ 15/Nov/11 ]

Hi,

Could please tell me as it is urgent for me..

Comment by Laurent Danesi [ 15/Nov/11 ]

Hi Mansoor,

If you want to prevent a Session to try to connect, you can call session.setEnabled(false). This will disconnect the Session if connected and avoid IoSessionInitiator to try to reconnect to the server.
As Grant said, you can count the attempts by adding a counter in toApp method of your Application implementation.

Regards,

Laurent DANESI

Comment by Mansoor Haider [ 15/Nov/11 ]

Hi,

Thanks for your suggestion,I will implement as you suggested and see whether it fulfils my requirement or not.

But I think quickfixj should implement a parameter in config file where we can state number of retries i.e. 0 could be value for retries till connected and any number should tell the number of retries.

Thanks,
Mansoor

Comment by Mansoor Haider [ 15/Nov/11 ]

Hi,

I tried but I unable to count the number of reconnection because my scenario is slightly different.
In my scenario the connection is refused and java.net.ConnectionException is thrown in the event log i.e. any of the method of application will not be called accept onCreate.Any other way or api support for such kind of scenario.

Thanks,
Mansoor

Comment by Christoph John [ 16/Nov/11 ]

Maybe you could use another approach and simply define a time after which the connection should be established and if not generate an alert. E.g. create a ScheduledExecutor which gets invoked say 5 minutes after onCreate() and which checks if the session is logged on and reacts accordingly.

Comment by Mansoor Haider [ 16/Nov/11 ]

Hi,

This seems to be a good and feasible for my scenario.I would implement you and reach back soon.However we can have similar functionality (suggested by me in my third comment) in coming versions of quickfixj because I have seen that quickfixj keeps a track of number of failed attempts in nested member private class of IoSessionInitiator.

Thanks
Mansoor

Comment by Mansoor Haider [ 16/Nov/11 ]

Hi,

I tried the new approach, I was able to count the number of retries but when I tried implementing session.setEnabled(false) I found that it is a private function of Session class.Any other suggestion to stop the connection attempts.

Thanks,
Mansoor

Comment by Laurent Danesi [ 16/Nov/11 ]

You can use logout method on Session

Comment by Mansoor Haider [ 16/Nov/11 ]

Hi,

I already have disconnect button implementing logout method but even clicking the disconnect button quickfixj does not stop reconnection attempts in this scenario.Here in my scenario it has not yet created connection over tcp/ip network i.e. due internet connection problem on side of acceptor or firewall and quickfixj still keeps on retring connection (remember it has not logged in yet).I could not stop the application because in the meanwhile it has already connected with one or more different acceptors so I have to stop the reconnection attempts for the one which is still retring because it is creating issues with other acceptors..

Thanks
Mansoor

Comment by Mansoor Haider [ 16/Nov/11 ]

Hi,

Is there any configuration through which I can set timeout??

Thanks
Mansoor

Comment by Mansoor Haider [ 18/Nov/11 ]

Hi,

I am still waiting for some solution.Please help.

Thanks
Mansoor

Comment by Christoph John [ 18/Nov/11 ]

Hi,

I have tested the suggested approach with Session.logout() and it works for me:

waiting for stop... time is 18 Nov 2011 08:41:33 GMT
<20111118-08:41:33, FIX.4.4:FixGateway->FixClient:dummy, error> (java.net.ConnectException: java.net.ConnectException: Connection refused (Next retry in 30000 milliseconds))
<20111118-08:42:03, FIX.4.4:FixGateway->FixClient:dummy, error> (java.net.ConnectException: java.net.ConnectException: Connection refused (Next retry in 30000 milliseconds))
calling Session.logout()... time is 18 Nov 2011 08:42:08 GMT
shutting down... time is 18 Nov 2011 08:43:08 GMT

You can see that he tries to connect every 30 seconds. After the second attempt I am calling logout() which prevents the connection attempts. You can see that there is no further attempt for a minute.

Comment by Mansoor Haider [ 18/Nov/11 ]

Hi,

I will try again the same thing because your error in the log same as mine so might help...

Thanks,
Mansoor

Comment by Christoph John [ 29/Nov/11 ]

Hi, can this ticket be closed now? As Grant pointed out, the normal behaviour would be to keep reconnecting. Did the suggested custom approach work for you?

Thanks,
Chris.

Comment by Mansoor Haider [ 29/Nov/11 ]

ya sure





[QFJ-650] Wrong handling of messages without sequence number (MsgSeqNum) - leads to wrong Reject message and increase of target sequence number Created: 09/Nov/11  Updated: 01/Dec/11  Resolved: 01/Dec/11

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

Type: Bug Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: session


 Description   

If QF/J receives a message which is missing tag 34 it rejects the message by the means of a session-level Reject (MsgType=3). This is not according to the spec which suggests to send a Logout message in that case (e.g. FIXT1.1 spec, p.40, "What constitutes a garbled message").

But the really troubling point IMHO is that QF/J increases the sender sequence number anyway. This is done in method generateReject( Message, int, int ) and so the sequence numbers are out of sync starting from that point. The generateReject method even checks if the MsgSeqNum field is set and if not assumes '0' as default. (which can be seen as error output: (Reject sent for Message 0: Required tag missing:34). Moreover, the resulting Reject message is missing the 45/RefSeqNum field, which is a required one!

QFJ-557 is addressing a similar topic with regard to the increase of the target sequence number in the generateReject() method. However, the missing MsgSeqNum is a special case and should be answered by a Logout and not a Reject.

Probably there should be a check for the MsgSeqNum in Session.next( Message ) which triggers a call of disconnect() and prints out a message to the error log. Would the Session.next(Message) method be the correct point for such a check?

Thanks,
Chris.






[QFJ-649] Tag not defined for this message type, field=55 Created: 09/Nov/11  Updated: 15/Nov/11  Resolved: 15/Nov/11

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

Type: Other Priority: Default
Reporter: Avidnyat Chiddarwar Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

<20111109-15:57:37, FIX.4.4:360T_SEP_TEST->FX Trade Financial.TEST, incoming> (8=FIX.4.49=14935=V34=249=FX Trade Financial.TEST50=FXTRADE.AutoDealer252=20111109-15:57:36.67056=360T_SEP_TEST55=EUR/USD146=1262=1263=0264=1267=2269=210=185)
<20111109-15:57:37, FIX.4.4:360T_SEP_TEST->FX Trade Financial.TEST, error> (Rejecting invalid message: quickfix.FieldException: Tag not defined for this message type, field=55: 8=FIX.4.49=14935=V34=249=FX Trade Financial.TEST50=FXTRADE.AutoDealer252=20111109-15:57:36.67056=360T_SEP_TEST55=EUR/USD146=1262=1263=0264=1267=1269=210=184)
<20111109-15:57:37, FIX.4.4:360T_SEP_TEST->FX Trade Financial.TEST, error> (Reject sent for Message 2: Tag not defined for this message type:55)
<20111109-15:57:37, FIX.4.4:360T_SEP_TEST->FX Trade Financial.TEST, outgoing> (8=FIX.4.49=16735=334=249=360T_SEP_TEST52=20111109-15:57:37.12956=FX Trade Financial.TEST57=FXTRADE.AutoDealer245=258=Tag not defined for this message type371=55372=V373=210=077)



 Comments   
Comment by Christoph John [ 09/Nov/11 ]

I think you should ask such questions (I am guessing that you want to ask a question) on the quickfixj mailing list: https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Looking at the FIX spec (e.g. via http://www.fixprotocol.org/FIXimate3.0/) it seems you should put the 55/Symbol into the 146/NoRelatedSym repeating group.

Comment by Laurent Danesi [ 15/Nov/11 ]

Please reopen if needed





[QFJ-648] Logon with negative heartbeat interval (HeartBtInt) should be rejected Created: 08/Nov/11  Updated: 01/Dec/11  Resolved: 01/Dec/11

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

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: session, timeout


 Description   

When logging on with a negative heartbeat interval, the Logon is accepted but then the connection is terminated immediately due to a Heartbeat timeout ("Disconnecting: Timed out waiting for heartbeat").

I would propose to reject the Logon in case of a negative HeartBtInt setting.

Maybe the check for the negative interval should be done somewhere at the beginning inside Session.nextLogon(). Is this a valid place for this check? Any comments?



 Comments   
Comment by Grant Birchmeier [ 08/Nov/11 ]

I can't resist asking: Who is sending you a negative heartbeat interval?

Comment by Christoph John [ 08/Nov/11 ]

This is an issue that came up when one of our customers was doing internal tests.

In my opinion this issue should be handled more clearly by QF/J since the current handling is not very optimal: The acceptor receives the Logon message and even replies with a Logon message. The initiator receives the Logon message and immediately afterwards the connection is dropped by the counterparty.

According to the spec: "In general a Logout message should always be sent prior to shutting down a connection. If the Logout is being sent due to an error condition, the Text field of the Logout should provide a descriptive reason, so that operational support of the remote FIX system can diagnosis the problem."

I agree that a lot of people would spot this problem once they look at the Logon messages. But most of the support staff does not have such a low level view. So for the support staff it can be very time-consuming to tackle problems that do not look like a problem at first sight (since the Logon is accepted).





[QFJ-647] Out of Order Repeating Group Members Created: 27/Oct/11  Updated: 20/Dec/13  Resolved: 20/Dec/13

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

Type: Bug Priority: Default
Reporter: Jodev Devassy Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 1
Labels: None


 Description   

I am trying to validate an incoming market data.

This is the piece of code that attempts to validate the message :

try

{ System.out.println("Validating MarketData"); DataDictionary dd = new DataDictionary("FIX50.xml"); dd.setCheckUnorderedGroupFields(false); dd.validate(message); System.out.println("Market data validated"); }

catch (Exception e)

{ e.printStackTrace(); }

This is the FIX message :
20111027-14:48:39: 8=FIXT.1.19=22335=Server56=Connection34=2452=20111027-14:10:04.8171021=220203=1268=2279=0269=055=EUR/USD461=RCSXXX63=0270=1.41193271=3000000279=2269=155=EUR/USD461=RCSXXX63=0270=1.41211271=10000000010=209

This is the contents from FIX50.xml :

<message name="MarketDataIncrementalRefresh" msgtype="X" msgcat="app">
<field name="MDReqID" required="N"/>
<field name="MDBookType" required="N"/>
<field name="MDLastIncrementalRefresh" required="N"/>
<component name="MDIncGrp1" required="Y"/>
</message>

<component name="MDIncGrp1">
<group name="NoMDEntries" required="Y">
<field name="MDUpdateAction" required="Y"/>
<field name="MDEntryType" required="N"/>
<field name="Symbol" required="N"/>
<field name="CFICode" required="N"/>
<field name="SettlType" required="N"/>
<field name="MDEntryPx" required="N"/>
<field name="MDEntrySize" required="N"/>
</group>
</component>

This is the part of output :

Validating MarketData
quickfix.FieldException: Out of order repeating group members, field=270
at quickfix.Message.parseGroup(Message.java:617)
at quickfix.Message.parseBody(Message.java:556)
at quickfix.Message.parse(Message.java:467)

Please advise how to process the message.



 Comments   
Comment by Jodev Devassy [ 27/Oct/11 ]

Sorry. I deleted some tags from the FIX message unknowingly. This is a better version of the same :

20111027-14:48:39: 8=FIXT.1.19=22335=X49=Server56=Connection34=2452=20111027-14:10:04.8171021=220203=1268=2279=0269=055=EUR/USD461=RCSXXX63=0270=1.41193271=3000000279=2269=155=EUR/USD461=RCSXXX63=0270=1.41211271=10000000010=209

Comment by James Olsen [ 14/Mar/12 ]

I'm having the same issue via the ValidateUnorderedGroupFields='N' setting. It does not seem to work in 1.5.1. I've read the many related issues and their duplicates that claim this is fixed and that the correct setting to use to turn off out of order group validation is ValidateUnorderedGroupFields='N', however it definitely does not work.

Comment by Christoph John [ 15/Mar/12 ]

@Jodev:
The following code works with QF/J 1.5.2 without problems. The message is validated successfuly. Please note that I have removed the tag 20203 from the original message since it is not part of the FIX5.0 data dictionary.

    public static void main( String[] args )
        throws Exception {

        DataDictionary dd = new DataDictionary( "FIX50.xml" );
        dd.setCheckUnorderedGroupFields( false );
        String messageString = "8=FIXT.1.19=22335=X49=Server56=Connection34=2452=20111027-14:10:04.8171021=2268=2279=0269=055=EUR/USD461=RCSXXX63=0270=1.41193271=3000000279=2269=155=EUR/USD461=RCSXXX63=0270=1.41211271=10000000010=107";
        Message message = new Message();
        message.fromString( messageString, dd, true );
        // double check
        dd.validate( message );
        System.out.println( "validated successfully!");


    }

@James:
Have you tried with QF/J 1.5.2? Do you have a test case that shows the incorrect behaviour?

Comment by Don Rizzo [ 14/Sep/13 ]

messageString does not contain the FIX delimiters, so validation will always fail.





[QFJ-646] MiscFeeType field is handled incorrectly Created: 27/Oct/11  Updated: 17/Nov/11

Status: Open
Project: QuickFIX/J
Component/s: Engine, Metadata/Specs
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: John Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ


 Description   

The "MiscFeeType" extends StringField and the constants into it are "String"s. The specification however (and the dictionary) indicates that this field is a "char".
One of our clients sends this as a "String" (value "12"), but we reject the message because it is more than one "char" long. If he sent it as a "char", we would not reject, but it would not match the constants in the Class file.

Workarround, either:

  • Change the dictionary to have this field be a "STRING" (used this one since our client sends it as a String).
  • Have the "MiscFeeType" class extends "CharField" and change the constants in the Class file, and embed it into your own code to replace the one from the library (haven't tested that though).


 Comments   
Comment by Laurent Danesi [ 15/Nov/11 ]

Hi John,

Which FIX version are you using?

In fact, in the spec, this field was ever a char and recently changed to String with FIX5.0.
So the FIX4X.xml dictionaries are declaring it as a CharField and FIX50.xml is specifying it as a StringField accordingly with the spec.

Now, of course, if you need to downgrade FIX5 feature code to a FIX4X session, you need a custom dictionary but it is not a bug, isnt it?
What do you think?

Regards,

Laurent

Comment by John [ 15/Nov/11 ]

Hi,
I'm using the 4.x version. The problem is not to have "String" or "char", I do not care.
The problem is that if we receive a client's message as a char (which is the standard), it would not match the constants in the java source file

Comment by Laurent Danesi [ 15/Nov/11 ]

Hi,

In fact, we generate fields for each dictionary but only once for a field (no override) and we generate FIX50 before FIX4X so MiscFeeType is a StringField.

But I understand that if a client sends a String and MiscFeeType is a CharField, QFJ will reject but the current code should work as the parser will set the char as a String.anyway and we can match constants with equals method or I'm missing something perhaps?

Can you provide me a simple test to well understand and fix it please?

Laurent

Comment by John [ 17/Nov/11 ]
  • If the user sends as a String, he will send "12" => error on our side because it is more than two characters.
  • If the user sends as a character (character \0x000C), then it will be OK, BUT it will not match the constants declared in the java file "12" (this is a guess, maybe your code changes character '\0x000C' in String "12").




[QFJ-645] Deadlock between message sending and reset due to message reception on Session and senderMsgSeqNumLock Created: 27/Oct/11  Updated: 08/Apr/14  Resolved: 31/Jul/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: 1.5.3

Type: Bug Priority: Critical
Reporter: marc sperisen Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: deadlock

Attachments: Java Source File SessionResetTest.java    
Issue Links:
Duplicate
is duplicated by QFJ-700 QFJ Timer and QFJ message processor t... Closed
is duplicated by QFJ-571 QFJ Timer - JDBCStore reset issues Closed

 Description   

Deadlock arises between the following threads:

Thread1:
"GatewayStateTimer" daemon prio=3 tid=0x04d65388 nid=0x2bef waiting for monitor entry [0x790ff000..0x790ff9f0]
at quickfix.SessionState.isLogonSent(SessionState.java:162)

  • waiting to lock <0x9d12c020> (a quickfix.Session)
    at quickfix.Session.sentLogon(Session.java:690)
    at quickfix.Session.isLoggedOn(Session.java:731)
    at quickfix.Session.sendRaw(Session.java:2151)
    at quickfix.Session.send(Session.java:2213)
    at quickfix.Session.sendToTarget(Session.java:590)
    at com.greatBank.application.fix.Engine.sendMessage(Engine.java:54)
    at com.greatBank.application.fix.Engine.pingFIX(Engine.java:191)
    at com.greatBank.application.fix.Engine.access$0(Engine.java:186)
    at com.greatBank.application.fix.Engine$PingTimerTask.run(Engine.java:176)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)

-> Thread1 is sending a message: it first acquires the lock senderMsgSeqNumLock and then tries to acquire a lock on the session instance

Thread2:
"QF/J Session dispatcher: FIX.4.2:SENDER1->TARGET1" daemon prio=3 tid=0x014e5ac8 nid=0x2bfc waiting on condition [0x794ff000..0x794ff970]
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
at quickfix.SessionState.lockSenderMsgSeqNum(SessionState.java:322)
at quickfix.Session.sendRaw(Session.java:2117)
at quickfix.Session.generateLogout(Session.java:1293)
at quickfix.Session.generateLogout(Session.java:1284)
at quickfix.Session.reset(Session.java:756)

  • locked <0x9d12c020> (a quickfix.Session)
    at quickfix.Session.next(Session.java:836)
    at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)

-> Thread2: while processing an incoming message, the engine notices that it is in a new session time interval (StartTime/EndTime) and therefore a MsqSeqNum reset is started.
The reset method acquires a lock on the session and, when generating a Logout, tries to acquire the lock senderMsgSeqNumLock, and then deadlocks with Thread1



 Comments   
Comment by Peter Clarke [ 12/Jan/12 ]

Hi
I've also seen this issue with our application.

My solution to this was to remove the synchronized keyword from the Session.reset function.

I've also attached a unit test we have to check for the issue.

Pete

Comment by John [ 17/Jan/12 ]

had this one too, but I haven't changed the library so I synchronized on the "Session" (=> so locks are taken in the same order).

Comment by John [ 02/Feb/12 ]

Erratum on the preceding comment.
Synchronizing "send" on the session created a huge performance hit when having heavy load.

Peter's was solution was the best one from the beggining and my workarround is not that good ;o)

I just put the code I used for the "reset" method :

quickfix.Session
public void reset() throws IOException {
  if (!resetting.compareAndSet(false, true)) {
    return;
  }
  try {
    if (hasResponder()) {
      if (application != null && application instanceof ApplicationExtended) {
        ((ApplicationExtended) application).onBeforeSessionReset(sessionID);
      }
      generateLogout();
      disconnect("Session reset", false);
    }
    resetState();
  }
  finally {
    resetting.set(false);
  }
}
Comment by Christoph John [ 31/Jul/12 ]

Peter and John,
thanks for your contributions. I have changed the reset() method accordingly and have added the UnitTest (I changed it slightly to work with a pausable Executor and made it detect the deadlock programmatically).





[QFJ-644] keep getting quickfix.FieldNotFound: 268, eventhough it's set in the message Created: 21/Oct/11  Updated: 15/Nov/12  Resolved: 02/Dec/11

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

Type: Bug Priority: Critical
Reporter: Robert Shalonov Assignee: Christoph John
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

quickfix.fix50


Attachments: Text File QFJ644.java    

 Description   

I keep getting quickfix.FieldNotFound: 268, index=1.
As you can see from the message bellow 268 is set. Bellow is the sample code that is used to read the message. Please, advise

Message:

8=FIXT.1.19=36935=W49=ICAPServer56=FXDD34=452=20111021-15:09:16.535262=131920975731621021=255=EUR/USD461=RCSXX=0268=8269=0270=1.38898271=2000000269=0270=1.38897271=8000000269=0270=1.38854271=2000000269=1270=1.38855271=6000000269=1270=1.38856271=7000000269=1270=1.38857271=3000000269=1270=1.38858271=9000000269=1270=1.38859271=10000000010=128

Sample Code:

MarketDataSnapshotFullRefresh message= (MarketDataSnapshotFullRefresh) message;
MarketDataSnapshotFullRefresh.NoMDEntries group= new MarketDataSnapshotFullRefresh.NoMDEntries();
message.getGroup(1, group); // Throws the error above, quickfix.FieldNotFound: 268, index=1.



 Comments   
Comment by Laurent Danesi [ 15/Nov/11 ]

Hi,

I tried to reproduce your problem but I was able to.
Can you provide me a TestCase showing the problem or modify the attached test, please?

Regards,

Laurent

Comment by Christoph John [ 02/Dec/11 ]

Robert,

you need to use a valid data dictionary if you want to correctly parse messages with repeating groups. The attached test case by Laurent also works for me. But if I do not pass the data dictionary into the Message(String, DataDictionary, boolean) I keep getting the same error as you: "quickfix.FieldNotFound: 268, index=1".

Regards,
Chris.





[QFJ-643] Unable to restart a stopped acceptor (SocketAcceptor) Created: 18/Oct/11  Updated: 02/Dec/11  Resolved: 02/Dec/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: 1.5.2

Type: Bug Priority: Major
Reporter: Christoph John Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

This is a similar issue as in QFJ-348 but for acceptors.

When I do acceptor.start() QF/J says:

Listening for connections at 0.0.0.0/0.0.0.0:10040

netstat output:

tcp6       0      0 :::10040                :::*                    LISTEN

After a stop() and another start(), the acceptor does not print the usual "Listening... at" information and also the netstat output is not listing the port.

A workaround could be to re-create the acceptor. But this is somewhat unexpected since we have start() and stop() methods.

If I interpret the code in the SocketAcceptor.class correctly, all that is needed is to set the "isStarted" flag to FALSE again on a stop(). This would trigger the call of the method "startAcceptingConnections()" on the next start() call. Could someone with more insight into the code please comment on this?

Thanks in advance,
Chris.



 Comments   
Comment by Christoph John [ 18/Oct/11 ]

I expect the issue to exist for longer than 1.5.0 and 1.5.1. But these are the versions I have tested with.

Comment by Laurent Danesi [ 19/Oct/11 ]

Hi Christoph,

You are right for the boolean "isStarted" but this is not enough since in the stop(boolean forceDisconnect) method, we call Session.unregisterSessions(getSessions()) that will remove all sessions.
Indeed, if we call start() again, we will listen to the socket but no session will be there.

So, the actual stop() method is more a "destroy" method if can say that. A good solution, could be to move the sessions creation in the start or split the stop() method.

Regards,
Laurent

Comment by Christoph John [ 08/Nov/11 ]

Hi Laurent,

could you please elaborate further on where to move the sessions creation? I have not had very much insight into the QF/J code until now.

Thanks,
Chris.





[QFJ-642] SessionSettings getSessionProperties(Foo, true) merges the actual settings into the defaults Created: 17/Oct/11  Updated: 15/Nov/12  Resolved: 19/Oct/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: 1.5.2

Type: Bug Priority: Major
Reporter: Mate Varga Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

If you do the following in your code:

Properties sessionProperties = sessionSettings.getSessionProperties(sessionID, true);

Then after executing the previous statement, sessionSettings.getDefaultProperties() will return the original default properties MERGED WITH the session properties specified under the sessionID, which is completely wrong. The reason lies in SessionSettings.java (comments inlined):

public Properties getSessionProperties(SessionID sessionID, boolean includeDefaults) throws ConfigError {
final Properties p = sections.get(sessionID);
if (p == null)

{ throw new ConfigError("Session not found"); }

if (includeDefaults)

{ final Properties mergedProperties = sections.get(DEFAULT_SESSION_ID); // THIS RETURNS A REFERENCE, NOT A COPY!! mergedProperties.putAll(p); /// THAT IS COMPLETELY WRONG, AS THIS MODIFIES THE ORIGINAL MAP CONTENTS return mergedProperties; }

else

{ return p; }

}

The proper solution would be to create a new Properties object and initialise it using the Properties object returned by sections.get().



 Comments   
Comment by Mate Varga [ 18/Oct/11 ]

// Fix:

public Properties getSessionProperties(SessionID sessionID, boolean includeDefaults) throws ConfigError {
final Properties p = sections.get(sessionID);
if (p == null)

{ throw new ConfigError("Session not found"); }


if (includeDefaults)

{ final Properties mergedProperties = new Properties(); mergedProperties.putAll(sessionSettings.getDefaultProperties()); mergedProperties.putAll(p); return mergedProperties; }


else

{ return p; }


}

Comment by Laurent Danesi [ 19/Oct/11 ]

committed rev #1054





[QFJ-641] Invalid fields order in InstrmtLegExecGrp component for FIX50 Created: 12/Oct/11  Updated: 15/Nov/12  Resolved: 19/Oct/11

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.5.0
Fix Version/s: 1.5.2

Type: Bug Priority: Default
Reporter: Sergey Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

FIX50 spec specifies order:
687 LegQty
685 LegOrderQty
...
637 LegLastPx

But FIX50.xml and generated InstrmtLegExecGrp.java has:
687 LegQty
...
637 LegLastPx
685 LegOrderQty



 Comments   
Comment by Laurent Danesi [ 19/Oct/11 ]

committed rev #1055

Comment by Sergey [ 19/Oct/11 ]

Thanks Laurent!





[QFJ-640] Ability to run unit tests behind a proxy in fork mode Created: 06/Oct/11  Updated: 06/Oct/11

Status: Open
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Improvement Priority: Trivial
Reporter: Val Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Yes, there is ability to run tests in the same JVM so the "http.proxyHost" and "http.ProxyPort" properties will affect the tests phase, but I think people behind a proxy would appreciate for following additional parameters in JUnit Ant task:

<jvmarg line="-Dhttp.proxyHost=$

{http.proxyHost}

-Dhttp.proxyPort=$

{http.proxyPort}

"/>

(For trunk there is not so much sense, but I think this way is more convenient than assumption check)






[QFJ-639] QFJ-609 (JMX Registration) Fails For Dynamic Sessions Using ThreadPerSessionEventHandlingStrategy Created: 03/Oct/11  Updated: 15/Nov/12  Resolved: 19/Oct/11

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

Type: Improvement Priority: Default
Reporter: James Olsen Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File QFJ-639.patch    

 Description   

The ThreadPerSessionEventHandlingStrategy does not need a SessionConnector reference internally however QFJ-609 and a few other things only work if it has one available.



 Comments   
Comment by James Olsen [ 03/Oct/11 ]

Patch attached.

Comment by Laurent Danesi [ 19/Oct/11 ]

committed rev #1057





[QFJ-638] SocketSynchronousWrites=Y Hangs Threads on Session responderSync Created: 03/Oct/11  Updated: 02/Apr/15  Resolved: 13/Feb/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.1
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: James Olsen Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File QFJ-638.patch    
Issue Links:
Relates
relates to QFJ-738 Deadlock on disconnect Closed

 Description   

As first noted by Parwinder Sekhon in QFJ-433 and further elaborated (perhaps confusingly) in QFJ-484, the locking used in the following Session method causes threads to hang when SocketSynchronousWrites is enabled.

private boolean send(String messageString) {
getLog().onOutgoing(messageString);
synchronized (responderSync) {
if (!hasResponder())

{ getLog().onEvent("No responder, not sending message: " + messageString); return false; }

return getResponder().send(messageString);
}
}

Slow consumers do exist in the real world. We therefore sometimes have to use SocketSynchronousWrites=Y in order to avoid memory leaks due to all the WriteFuture objects that are generated. The problem with the current locking is that the background thread that handles heartbeats and forces logouts etc can get stuck waiting for one of these slow consumers. This means that the Session will not be logged out even if it has missed many heartbeats. Even worse, the same background thread is used for other Sessions on the same Connector so they are also impacted even if they are not synchronous.

Changing the code as follows resolves these issues.

private boolean send(String messageString) {
getLog().onOutgoing(messageString);
Responder responder;
synchronized (responderSync)

{ responder = this.responder; }

if (responder == null)

{ getLog().onEvent("No responder, not sending message: " + messageString); return false; }

return responder.send(messageString);
}

The message sequence number locking used in the sendRaw method seems sufficient to coordinate any multi-threaded message senders given that the above change otherwise opens a hole.

The use of a ReentrantLock as discussed in QFJ-484 is not required for this issue. As shown above, the existing responderSync String object is sufficient.



 Comments   
Comment by James Olsen [ 03/Oct/11 ]

Patch attached.





[QFJ-637] QuickFixJ appears to modify headers of a message after delivery; iteration over the Header's fields on another thread produces a ConcurrentModificationException Created: 29/Sep/11  Updated: 15/Nov/11  Resolved: 15/Nov/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Michael Guyver Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: Concurrency, ConcurrentModificationException, QuickfixJ
Environment:

RHEL kernel 2.6.18; Sun/Oracle Java 1.6.20; QuickFixJ 1.5.1



 Description   

We have created a client to the QuickFixJ engine which implements the Application interface; in order to manage our threading we have put a thread barrier between our client Application and QuickFixJ, where its invocations of the Application API are converted into Runnable commands which are executed on the client thread. Other parts of the system interact with the client across the thread barrier in the same way and it enables the client to run in a single-threaded manner.

We log the messages we get from QuickFixJ and fairly frequently see a ConcurrentModificationException being raised when we iterate over the fields in a message's header:

Iterator<Field> iter = message.getHeader().iterator();
while (iter.hasNext())

{ // log out the values - CME is raised here }

I would have thought that a message and its header should be immutable after it has been delivered to the client Application, but it seems it is being changed on a different thread. Is this expected behaviour? Does QuickFixJ implement some sort of Message pooling?

Thanks

Michael



 Comments   
Comment by Michael Guyver [ 05/Oct/11 ]

It seems that this was being caused by the presentation of messages by QuickFixJ to the toAdmin(Message,SessionID) and toApp(Message,SessionID) methods prior to sending: in these two cases the subsequent modification of the message header is expected due to the addition of a sending-time field.

Since the thread boundary was implemented ascynchronously, it's likely that the CME was being produced by QuickFixJ adding the header while the message was being inspected. IOW, expected behaviour.

Comment by Michael Guyver [ 10/Oct/11 ]

Handling the message on the QuickFixJ server thread in the .toAdmin method would appear not to have solved the problem. We have just seen this exception while attempting to .clone() the message in order to provide an immutable message to pass to the client application:
java.util.ConcurrentModificationException
at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1100)
at java.util.TreeMap$EntryIterator.next(TreeMap.java:1136)
at java.util.TreeMap$EntryIterator.next(TreeMap.java:1131)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2372)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2364)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2322)
at java.util.TreeMap.putAll(TreeMap.java:296)
at quickfix.FieldMap.initializeFrom(FieldMap.java:488)
at quickfix.Message.cloneTo(Message.java:126)
at quickfix.Message.clone(Message.java:116)
[...]

Could someone suggest how QuickFixJ can realistically expect to modifiy the fields of a message while it is being processed by application code?

Comment by Michael Guyver [ 10/Oct/11 ]

Please ignore the above - the issue was caused elsewhere and not by QuickFixJ. Apologies.





[QFJ-636] Custom fields in component blocks are not added to parent Created: 26/Sep/11  Updated: 17/Jun/20  Resolved: 03/Jun/20

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

Type: Bug Priority: Major
Reporter: Mate Varga Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm creating an Instrument repeating group and I want to add a custom field to it – this works fine so far.

Instrument instrument = new Instrument(new Symbol("VOD.L"));
instrument.set(new SecurityID("GB012345689"));
instrument.set(new SecurityIDSource(SecurityIDSource.ISIN_NUMBER));
instrument.set(new SecurityExchange("L"));
instrument.setString(9001, "BLAH");

However, if I add that instrument group to another fieldmap, like
QuoteRequest.NoRelatedSym nrs = new QuoteRequest.NoRelatedSym();
nrs.set(instrument);

... then the custom field won't be copied. I know that regenerating QuickFix using the extended data dictionary would solve the problem, but this should not be required.

The problem lies in MessageComponent.java:

public void copyFrom(FieldMap fields) {
try {
int[] componentFields = getFields();
for (int i = 0; i < componentFields.length; i++) {
if (fields.isSetField(componentFields[i]))

{ setField(componentFields[i], fields.getField(componentFields[i])); }

}

This shows that copyFrom (used by FieldMap.set()) only copies the fields which are present in the data dictionary.



 Comments   
Comment by Mate Varga [ 03/Oct/11 ]

If a project owner confirms that this is a bug, then I'm happy to submit a patch.

Comment by Christoph John [ 19/Dec/13 ]

Sounds like a bug to me...





[QFJ-635] Null Pointer Exception when starting a session with Apache Synapse Created: 26/Sep/11  Updated: 01/Dec/11  Resolved: 01/Dec/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1
Fix Version/s: 1.5.2

Type: Bug Priority: Critical
Reporter: Mark Curtis Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: QuickfixJ, session
Environment:

Linux, JBoss 5.1.GA, Apache Synapse 2.0


Attachments: File patch    

 Description   

QuickFIX/J versions greater than 1.4.0 do not work with Apache Synapse. See following stack trace for more details:

java.lang.NullPointerException
at quickfix.Session.<init>(Session.java:455)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:179)
at quickfix.mina.acceptor.AbstractSocketAcceptor.createSessions(AbstractSocketAcceptor.java:246)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:81)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:97)
at quickfix.SocketAcceptor.<init>(SocketAcceptor.java:37)
at org.apache.synapse.transport.fix.FIXSessionFactory.createFIXAcceptor(FIXSessionFactory.java:124)
at org.apache.synapse.transport.fix.FIXTransportListener.startListeningForService(FIXTransportListener.java:76)
at org.apache.axis2.transport.base.AbstractTransportListener.internalStartListeningForService(AbstractTransportListener.java:213)
at org.apache.axis2.transport.base.AbstractTransportListener$2.serviceAdded(AbstractTransportListener.java:126)
at org.apache.axis2.transport.base.tracker.AxisServiceTracker.serviceAdded(AxisServiceTracker.java:212)
at org.apache.axis2.transport.base.tracker.AxisServiceTracker.start(AxisServiceTracker.java:188)
at org.apache.axis2.transport.base.AbstractTransportListener.start(AbstractTransportListener.java:178)
at org.apache.axis2.engine.ListenerManager.start(ListenerManager.java:148)
at org.apache.synapse.Axis2SynapseController.start(Axis2SynapseController.java:244)
at org.apache.synapse.ServerManager.start(ServerManager.java:185)
at org.apache.synapse.core.axis2.SynapseStartUpServlet.init(SynapseStartUpServlet.java:58)



 Comments   
Comment by Mark Curtis [ 26/Sep/11 ]

Attached patch fixes issue and has been tested with banzi, executor + synapse.

Comment by Christoph John [ 01/Dec/11 ]

I just also stumbled upon this when working on the Session class. The logFactory is dereferenced although it is null-checked some lines below.
Thanks for the patch suggestion.





[QFJ-634]  SequenceReset Fail Created: 22/Sep/11  Updated: 15/Nov/12  Resolved: 08/Oct/11

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

Type: Bug Priority: Major
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 2
Labels: None


 Description   

From Edward Lee:

Hello,

I've upgraded to QuickFix/J 1.5.1 recently.
However, I encountered an issue regarding the SequenceReset and
synchronziation with other FIX session. I found that the QuickFix cannot
handle more that one SequenceReset when sending out one ResendRequest.

Here is the scenario,

At first, the FIX connection is synchronized and let say the incoming
message seqnum and outgoing message seqnum is both 100.
Now, when I reset both in and out message seqnum to 1. Then, out of sync
happened.
At this moment, I reset the outgoing message seqnum to 100 again.
Then, QuickFix sent out a resendRequest to request message 1 to 100 as it
received a logon message of message seqnum 100.
And then, the counterParty start to resend the message and the sequence is
like below

1. SequenceReset to 31
2. 10 NewOrderSingle
3. SequenceReset to 100

What I can see the behavior of the QuickFix is that it cannot process the
first SequenceReset message and hence, the incoming message seqnum is
still remaining not synchronized.

After checking the source code, I found that the issue is in the
nextSequenceReset method in Session.java as below:

if (newSequence > getExpectedTargetNum()) {
int[] range = state.getResendRange();
if (newSequence >= range[1])

{ state.setNextTargetMsgSeqNum(newSequence); }

else if (range[2] > 0 && newSequence >= range[2])

{ state.setNextTargetMsgSeqNum(newSequence + 1); String beginString = sequenceReset.getHeader().getString(BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence+1, range[1]); }

} else if (newSequence < getExpectedTargetNum()) {

getLog().onErrorEvent(
"Invalid SequenceReset: newSequence=" +
newSequence + " < expected="
+ getExpectedTargetNum());
if (resetOrDisconnectIfRequired(sequenceReset))

{ return; }
generateReject(sequenceReset,
SessionRejectReason.VALUE_IS_INCORRECT, 0);
}

When the first SequenceReset message comes, the newSequence = 30 and which
is greater than ExpectedTargetNum (i.e. 1)
Then, the range that we get is [1, 100, 0] and the problem came is the
newSequence (30) is not greater than range[1] (i.e. 100), and also
range[2] (i.e. 0) is not greater than 0.
Hence, nothing is done for the SequenceReset message.

I did make a change for the above code to:

if (newSequence > getExpectedTargetNum()) {
int[] range = state.getResendRange();
if (range[2] > 0) {
if (newSequence >= range[1]) { state.setNextTargetMsgSeqNum(newSequence); } else if(newSequence >= range[2]) { state.setNextTargetMsgSeqNum(newSequence + 1); String beginString = sequenceReset.getHeader().getString(BeginString.FIELD); sendResendRequest(beginString, range[1] + 1, newSequence+1, range[1]); }
} else { state.setNextTargetMsgSeqNum(newSequence); }
} else if (newSequence < getExpectedTargetNum()) {

getLog().onErrorEvent(
"Invalid SequenceReset: newSequence=" +
newSequence + " < expected="
+ getExpectedTargetNum());
if (resetOrDisconnectIfRequired(sequenceReset)) { return; }

generateReject(sequenceReset,
SessionRejectReason.VALUE_IS_INCORRECT, 0);
}

And now, I can successfully synchronize.

The question I have is does anyone also encounter this issue? Or did I
miss any config or setup and such that I have this issue?



 Comments   
Comment by Andrzej Hajderek [ 06/Oct/11 ]

Hi,

I have the same problem. Below is an extract from the log. The incoming Sequence Reset from 1 to 2 is not processed correctly. As result the target sequence number is not set to 2. In consequence the messages with sequence number 2 and above are queued instead of being processed:

quickfix.outgoing: 8=FIX.4.29=7235=A34=6549=AAA52=20111006-13:01:16.70156=BBB98=0108=3010=222

quickfix.incoming: 8=FIX.4.29=006835=A34=9549=BBB56=AAA52=20111006-13:01:2798=0108=3010=130

quickfix: Received logon

quickfix: MsgSeqNum too high, expecting 1 but received 95: 8=FIX.4.29=6835=A34=9549=BBB52=20111006-13:01:2756=AAA98=0108=3010=034

quickfix: Enqueued at pos 95: 8=FIX.4.29=6835=A34=9549=BBB52=20111006-13:01:2756=AAA98=0108=3010=034

quickfix.outgoing: 8=FIX.4.29=6935=234=6649=AAA52=20111006-13:01:16.90456=BBB7=116=010=061

quickfix: Sent ResendRequest FROM: 1 TO: 94

quickfix.incoming: 8=FIX.4.29=009335=434=149=BBB56=AAA43=Y52=20111006-13:01:28122=20111006-13:01:2836=2123=Y10=080

quickfix.incoming: 8=FIX.4.29=034535=8128=CCC57=DDD34=249=BBB56=AAA43=Y52=20111006-13:01:28122=20111006-12:02:1355=SMU1 17=21123141039=214=1237=NeMO-23449-131724431614738=1220=0150=2151=040=26001=LLL60=20110928-21:12:316002=HHH44=22.0200=20110922=A207=FFF167=FUT1=61A16S32-XYZ6=22.032=12442=231=22.054=175=2011092810=068

quickfix: Received SequenceReset FROM: 1 TO: 2

quickfix: MsgSeqNum too high, expecting 1 but received 2: 8=FIX.4.29=34535=834=243=Y49=BBB52=20111006-13:01:2856=AAA57=DDD122=20111006-12:02:13128=CCC1=61A16S32-XYZ6=22.014=1217=21123141020=022=A31=22.032=1237=NeMO-23449-131724431614738=1239=240=244=22.054=155=SMU1 60=20110928-21:12:3175=20110928150=2151=0167=FUT200=201109207=FFF442=26001=LLL6002=HHH10=020

quickfix.incoming: 8=FIX.4.29=036235=8128=CCC57=DDD34=349=BBB56=AAA43=Y52=20111006-13:01:28122=20111006-12:02:1355=ESU117=21185307539=214=2137=NeMO-23449-131724469749638=2120=0150=2151=040=26001=III60=20110928-21:18:536002=HHH44=24.6190476200=20110922=A207=GGG167=FUT1=0007YSXM-XYZ6=24.619047632=21442=231=24.619047654=175=2011092810=076

quickfix: Enqueued at pos 2: 8=FIX.4.29=34535=834=243=Y49=BBB52=20111006-13:01:2856=AAA57=DDD122=20111006-12:02:13128=CCC1=61A16S32-XYZ6=22.014=1217=21123141020=022=A31=22.032=1237=NeMO-23449-131724431614738=1239=240=244=22.054=155=SMU1 60=20110928-21:12:3175=20110928150=2151=0167=FUT200=201109207=FFF442=26001=LLL6002=HHH10=020

quickfix.incoming: 8=FIX.4.29=035835=8128=CCC57=EEE34=449=BBB56=AAA43=Y52=20111006-13:01:28122=20111006-12:02:1358=vvv55=ERH2 17=15554324439=214=137=BWT7-72069688681597593-09/29/201138=120=0150=2151=040=26001=JJJ60=20110929-15:55:436002=KKK44=97.96200=20120322=A207=XLIF167=FUT1=96Y05A03-XYZ6=97.9632=1442=231=97.9654=275=2011092910=114

quickfix: Already sent ResendRequest FROM: 1 TO: 94. Not sending another.

quickfix: MsgSeqNum too high, expecting 1 but received 3: 8=FIX.4.29=36235=834=343=Y49=BBB52=20111006-13:01:2856=AAA57=DDD122=20111006-12:02:13128=CCC1=0007YSXM-XYZ6=24.619047614=2117=21185307520=022=A31=24.619047632=2137=NeMO-23449-131724469749638=2139=240=244=24.619047654=155=ESU160=20110928-21:18:5375=20110928150=2151=0167=FUT200=201109207=GGG442=26001=III6002=HHH10=028

quickfix: Enqueued at pos 3: 8=FIX.4.29=36235=834=343=Y49=BBB52=20111006-13:01:2856=AAA57=DDD122=20111006-12:02:13128=CCC1=0007YSXM-XYZ6=24.619047614=2117=21185307520=022=A31=24.619047632=2137=NeMO-23449-131724469749638=2139=240=244=24.619047654=155=ESU160=20110928-21:18:5375=20110928150=2151=0167=FUT200=201109207=GGG442=26001=III6002=HHH10=028

Comment by Andrzej Hajderek [ 06/Oct/11 ]

Hi again,

I propose to change the priority to critical. The 1.5.1 release was supposed to be a bug fix release, while this bug disqualifies it as production-ready in some circumstances.

Regards,
Andrzej

Comment by Andy Malakov [ 06/Oct/11 ]

We see the same problem when talking with ULLink FIX server. Proposed patch seems to resolve this issue.

Comment by Eric Deshayes [ 08/Oct/11 ]

Committed in rev#1053





[QFJ-633] turn off Out of order repeating group members validation doesn't work in 1.5.1 Created: 12/Sep/11  Updated: 15/Nov/12  Resolved: 12/Sep/11

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.1
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: David van Coevorden Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-548 outOfOrderField checking by setting V... Closed

 Description   

In QFJ-384 this problem was fixed and for 1.5.0 it worked for me. I get the problem back in 1.5.1.



 Comments   
Comment by Eric Deshayes [ 12/Sep/11 ]

Hi,
this issue should have been fixed by QFJ-535 in 1.5.1

There was some confusion about the ValidateFieldsOutOfOrder option and ValidateUnorderedGroupFields.
ValidateFieldsOutOfOrder is used for mismatched fields between the body and the header, not the order between two fields, as per the documentation.
ValidateUnorderedGroupFields is the setting you should now be using for your current use case.

Let me know if it is still an issue.
Eric





[QFJ-632] isTimeToGenerateLogon() in Session always returns true -> Initiators reconnect immediately when a Server closes the connection Created: 02/Sep/11  Updated: 08/Nov/12  Resolved: 08/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.1, 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Bernhard Wege Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: Reconnect, ReconnectInterval

Issue Links:
Relates
is related to QFJ-419 Reconnect Interval: set different int... Closed

 Description   

The long attribute lastSessionLogon in Session never gets written and always stays 0. This makes isTimeToGenerateLogon() to always return true, because current Time - 0 will always be greater than computeNextLogonDelayMillis(). This results in Initiators reconnecting immediately and ignoring the ReconnectInterval after a Server closes the Connection.

This should affect all versions. But I only checked 1.5.1, 1.5.0 and TRUNK.

I am not sure where lastSessionLogon hast to be set, but I guess it should be in generateLogon(). Additionally I don't understand why lastSessionLogon gets set to 0 in nextLogon(). As far as I understand, it should never be necessary to reset it to 0. isTimeToGenerateLogon() is the only function that uses it.



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

Moreover, the counter "logonAttempts" is never incremented which leads to the usage of only one reconnectInterval in computeNextLogonDelayMillis(). (QFJ-419)

Comment by Christoph John [ 08/Nov/12 ]

Committed as rev #1098.





[QFJ-631] Wrong checksum calculation in "quickfix.Field.getTotal()" Created: 31/Aug/11  Updated: 02/Apr/15  Resolved: 09/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.6.0

Type: Bug Priority: Major
Reporter: John Assignee: amichair
Resolution: Fixed Votes: 0
Labels: QuickfixJ, encoding
Environment:

Java


Issue Links:
Relates
relates to QFJ-38 FIX Message support double-byte charset. Closed
relates to QFJ-382 Foreign Language Support - Multibyte ... Closed

 Description   

The "quickfix.Field.getTotal()" method computes the checksum with the following code:
for (int i = 0; i < this.data.length(); ++i)

{ sum += this.data.charAt(i); }

A problem arises if the returned character is written with more than 1 character.
The checksum calculation must be done on "byte"s (the Quickfix specification)

I wrote a correction:
byte[] bytes = null;
try {
bytes = this.data.getBytes(CharsetSupport.getCharset());
for (int i = 0; i < bytes.length; ++i)

{ sum += (((int) bytes[i]) & 0x00FF); }

} catch (UnsupportedEncodingException e)

{ throw new RuntimeException(e); }

 Comments   
Comment by John [ 31/Aug/11 ]

The same applies to "quickfix.Message":

private int checkSum(String s) {
final int offset = s.lastIndexOf("\00110=");
int sum = 0;
for (int i = 0; i < offset; i++)

{ sum += s.charAt(i); <----------- }

return (sum + 1) % 256;
}





[QFJ-630] If the quote and trade server is different then developers have no way to distinguish the session id when the configuration details for the two server are same except the host and port Created: 30/Aug/11  Updated: 13/Feb/14  Resolved: 13/Feb/14

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

Type: Bug Priority: Major
Reporter: Mansoor Haider Assignee: Laurent Danesi
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, session
Environment:

windows



 Description   

If the quote and trade server is different then the session id generated for two servers are same when the configuration details for the 2 server (quote and trade server) are same except host name and port.......In this case user of the api have no idea how to distinguish between the 2 servers...

We might need to change the createID() method of of sessionID class which will generate 2 different sessionIDs..



 Comments   
Comment by Jörg Thönnes [ 02/Sep/11 ]

Hi Mansoor,

did you check the SessionQualifier:

http://www.quickfixj.org/quickfixj/usermanual/1.5.1/usage/configuration.html

This is provided for initiator only.

Cheers, Jörg

Comment by Mansoor Haider [ 02/Sep/11 ]

Hi,

First of all the use of SessionQualifier is not recommended.
Will it ensure difference in sessionID generated??
How will I identify between different sessions??
Currently we are generating random numbers and appending it to sessionID created.Are you sure a SessionQualifier does this job??

Sorry never used SessionQualifier.Therefore does not have much knowledge regarding it.It is mentioned in documentation that it makes compatibilty with jni.We donot want it to be os dependent.

Thanks

Comment by Mansoor Haider [ 02/Sep/11 ]

Hi,

I checked the sessionID class method createID() SessionQualifier gets appended to it.I dont think that it should affect the functionality of session.

Thanks

Comment by Laurent Danesi [ 19/Oct/11 ]

SessionQualifier must be used in such a case





[QFJ-629] CLONE - Regression: QFJ-419 change forces ReconnectInterval to be in DEFAULT section Created: 24/Aug/11  Updated: 15/Nov/12  Resolved: 24/Aug/11

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

Type: Bug Priority: Default
Reporter: Kenny Sy Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm testing against the SVN trunk and one of my working configs failed with "ReconnectInterval not defined". This config has the ReconnectInterval defined only in the [SESSION] sections, and not in the [DEFAULT]. Simple one-line fix; see below.

Index: core/src/main/java/quickfix/DefaultSessionFactory.java
===================================================================
— core/src/main/java/quickfix/DefaultSessionFactory.java (revision 950)
+++ core/src/main/java/quickfix/DefaultSessionFactory.java (working copy)
@@ -306,7 +306,7 @@
private int[] getLogonIntervalsInSeconds(SessionSettings settings, SessionID sessionID) throws ConfigError {
if (settings.isSetting(sessionID, Initiator.SETTING_RECONNECT_INTERVAL)) {
try

{ - String raw = settings.getString(Initiator.SETTING_RECONNECT_INTERVAL); + String raw = settings.getString(sessionID, Initiator.SETTING_RECONNECT_INTERVAL); int[] ret = SessionSettings.parseSettingReconnectInterval(raw); if (ret != null) return ret; }

catch (Throwable e) {



 Comments   
Comment by Kenny Sy [ 24/Aug/11 ]

The same problem happen in 1.5.1.

Comment by Eric Deshayes [ 24/Aug/11 ]

Fixed in rev#1050





[QFJ-628] java.io.IOException caused by logout Created: 18/Aug/11  Updated: 20/Dec/13  Resolved: 20/Dec/13

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

Type: Other Priority: Minor
Reporter: Andrew Niland Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: QuickfixJ, session
Environment:

Windows XP
java version "1.6.0_26"



 Description   

After a logout is received I get the following message:

<20110818-09:19:28, FIX.4.2:NILAAND->ABFO-DMA-TEST, outgoing> (8=FIX.4.29=8135=534=249=NILAAND52=20110818-09:19:28.06456=ABFO-DMA-TEST58=user requested10=188)
<20110818-09:19:28, FIX.4.2:NILAAND->ABFO-DMA-TEST, incoming> (8=FIX.4.29=5935=549=ABFO-DMA-TEST56=NILAAND34=252=20110818-09:19:2710=156)
<20110818-09:19:28, FIX.4.2:NILAAND->ABFO-DMA-TEST, event> (Received logout response)
18-Aug-2011 10:19:28 quickfix.Session disconnect
INFO: [FIX.4.2:NILAAND->ABFO-DMA-TEST] Disconnecting: IO Session closed
<20110818-09:19:28, FIX.4.2:NILAAND->ABFO-DMA-TEST, error> (Error processing message: 8=FIX.4.29=5935=534=249=ABFO-DMA-TEST52=20110818-09:19:2756=NILAAND10=156
java.io.IOException: The handle is invalid
at java.io.RandomAccessFile.seek(Native Method)
at quickfix.FileStore.storeSequenceNumbers(FileStore.java:403)
at quickfix.FileStore.incrNextTargetMsgSeqNum(FileStore.java:296)
at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:354)
at quickfix.Session.nextLogout(Session.java:1275)
at quickfix.Session.next(Session.java:939)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:112)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:75)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:92)
at java.lang.Thread.run(Unknown Source)



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

Can this be reproduced reliably? It just seems the file was moved or deleted? Was the file on a network drive?





[QFJ-627] Starting a ThreadedSocketInitiator overwrites the default settings Created: 12/Aug/11  Updated: 13/Feb/14  Resolved: 13/Feb/14

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

Type: Bug Priority: Major
Reporter: Thomas Wölfle Assignee: Laurent Danesi
Resolution: Duplicate Votes: 0
Labels: None
Environment:

kubuntu 11.04
jdk 1.6.0.26



 Description   

When starting an initiator via 'initiator.start()' the default section of the provided SessionSettings are overwitten in the method 'SessionSettings.getSessionProperties(SessionID, boolean) in line 175. This results in a corrupted session settings configuration. I.e. in case the default section defines a custom data dictionary 'default_dict', the first session section defines some other data dictionary 'dict1' and a second session section defines no data dictionary then the session properties for the second session will contain the 'dict1' data dictionary instead of the 'default_dict' data dictionary. This scenario can be reproduced with the following JUnit test:

package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.Properties;

import org.junit.Test;

import quickfix.Application;
import quickfix.ApplicationAdapter;
import quickfix.ConfigError;
import quickfix.LogFactory;
import quickfix.MemoryStoreFactory;
import quickfix.MessageStoreFactory;
import quickfix.ScreenLogFactory;
import quickfix.SessionID;
import quickfix.SessionSettings;
import quickfix.ThreadedSocketAcceptor;
import quickfix.ThreadedSocketInitiator;
import quickfix.fix42.MessageFactory;

public class FIXSessionSettingsModificationTest {
@Test
public void testGetSessionProperties() throws ConfigError

{ final StringBuilder config = new StringBuilder(); config.append("[DEFAULT]\n"); config.append("DataDictionary=default_dict\n"); config.append("[SESSION]\n"); config.append("BeginString=FIX.4.2\n"); config.append("SenderCompID=senderCompID1\n"); config.append("TargetCompID=targetCompID1\n"); config.append("DataDictionary=dict1\n"); config.append("[SESSION]\n"); config.append("BeginString=FIX.4.2\n"); config.append("SenderCompID=senderCompID2\n"); config.append("TargetCompID=targetCompID2\n"); final StringBufferInputStream stream = new StringBufferInputStream(config.toString()); final SessionSettings sessionSettings = new SessionSettings(stream); final SessionID sessionID1 = new SessionID("FIX.4.2", "senderCompID1", "targetCompID1"); final SessionID sessionID2 = new SessionID("FIX.4.2", "senderCompID2", "targetCompID2"); final Properties session1Props = sessionSettings .getSessionProperties(sessionID1, true); final Properties session2Props = sessionSettings .getSessionProperties(sessionID2, true); assertEquals("Expected session 1 to use dictionary 'dict1'", "dict1", session1Props .get("DataDictionary")); assertEquals("Expected session 2 to use dictionary 'default_dict'", "default_dict", session2Props .get("DataDictionary")); }

}



 Comments   
Comment by Laurent Danesi [ 19/Oct/11 ]

Duplicates QFJ-642





[QFJ-626] ResendRequest (silently) aborted when one of the message to resend was (sent and) stored with a bad checksum Created: 11/Aug/11  Updated: 02/Apr/15  Resolved: 06/Oct/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Olivier Lourdais Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: QuickfixJ, encoding, session
Environment:

Ubuntu SMP (2.6.35-25-generic)

java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)


Attachments: File Session.patch    
Issue Links:
Relates
relates to QFJ-808 Prevent setting illegal double values... Closed

 Description   

When a bug of the application around QuickFIX/J causes the generation of a message containing non-ISO-8859-1 characters (e.g. a price set to NaN or Infinity will be formatted to a special character by java.text.DecimalFormat), the computed checksum is wrong (checksum is computed on Unicode characters, before they are converted to bytes, and non-ISO-8859-1 characters will be replaced by '?' during the chars to bytes conversion, making the checksum inconsistent).
The peer FIX application will detect the problem and skip the affected message, then it will send a ResendRequest.

To handle the ResendRequest, QuickFIX/J will retrieve asked messages in bytes version, will convert them to chars (still containing '?' instead of non-ISO-8859-1 characters), then parse them (and hopefully resend them).
When parsing the message, QuickFIX/J detects the invalid checksum and throws an InvalidMessage exception.
The problem is that this exception is not caught when iterating over the messages to parse, but in the next(Message message) method, as if the error was in the ResendRequest message.

The consequence is that following messages are never sent (and that no SequenceReset message is sent for the peer FIX application to skip the erroneous message).



 Comments   
Comment by Olivier Lourdais [ 11/Aug/11 ]

Attached patch fixes the bug, making InvalidMessage exception simply caught around message parsing.

Comment by Jason Quek [ 04/Sep/14 ]

Hi,

I would like to raise that we should throw an InvalidArgumentException if a NaN, Positive Infinity, Negative Infinity value is set on a double field rather than letting it fail when being sent over the session and ignoring the message. This could be done until multi-byte transmission is supported.

Regards,
Jason

Comment by Staffan Ulfberg [ 10/Sep/14 ]

I agree that raising an exception in the setters is the correct thing to do since there is no way to transmit a NaN or Infinity over FIX.

Just to point out, however, that adding multi-byte support would not help. The fact that Java formats NaN and infinity values using unicode characters is irrelevant for how to represent them on the wire when using FIX. FIX float fields consists of ASCII characters "-", "0" - "9" and ".", and I do not think it is desirable to make an extension to a basic FIX type in quickfixj that will not be supported by other FIX engines.

Basically I'm arguing that throwing an exception is not just a temporary fix until multi-byte support is implemented. I think it is the correct thing to do. (Another possibility would be to create a "FixFloat" class to model this FIX type that does not have an exact corresponding Java type, but that is indeed a larger project and might be unpractical for other reasons.)

Staffan

Comment by Christoph John [ 26/Sep/14 ]

Hi Staffan, so if I get you right, the following code should get placed in DoubleField.java??

    public void setValue(Double value) {
        if (Double.isInfinite(value) || Double.isNaN(value)) {
            throw new NumberFormatException("Tried to set NaN or infinite value.");
        }
        setObject(value);
    }

    public void setValue(double value) {
        if (Double.isInfinite(value) || Double.isNaN(value)) {
            throw new NumberFormatException("Tried to set NaN or infinite value.");
        }
        setObject(value);
    }
Comment by Staffan Ulfberg [ 26/Sep/14 ]

Yes, I think that would be great, but please add a check in the three constructors as well...

Staffan

Comment by Christoph John [ 29/Sep/14 ]

See QFJ-808.

Comment by Christoph John [ 06/Oct/14 ]

https://github.com/quickfix-j/quickfixj/commit/dbac498696c2425ea82576ef2b9163791a896ed2





[QFJ-625] Intermittent File Handle Issues While Generating Code Created: 29/Jul/11  Updated: 29/Jul/11

Status: Open
Project: QuickFIX/J
Component/s: Build
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Francois Auger Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, ant
Environment:

Windows 7 Professional x64 (latest updates)
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)



 Description   

Intermittently, we're having the following error while running the default ant task:

[java] SEVERE: error during code generation
[java] quickfix.codegen.CodeGenerationException: java.io.FileNotFoundException: target\generated-sources\messages\quickfix\fix50\component\UnderlyingInstrument.java (The requested operation cannot be performed on a file with a user-mapped section open)

The following patch has worked so far:

Index: quickfixj-local/core/src/main/java/quickfix/codegen/MessageCodeGenerator.java
===================================================================
— quickfixj-local/core/src/main/java/quickfix/codegen/MessageCodeGenerator.java (revision xyz)
+++ quickfixj-local/core/src/main/java/quickfix/codegen/MessageCodeGenerator.java (working copy)
@@ -269,8 +269,11 @@
}

File outputFile = new File(outputFileName);

  • if (!task.isOverwrite() && outputFile.exists()) {
  • return;
    + if (outputFile.exists())
    Unknown macro: {+ if (!task.isOverwrite()) { + return; + }+ outputFile.delete(); }

DOMSource source = new DOMSource(document);

Thanks,
François






[QFJ-624] Invalid "Timed out waiting for heartbeat" and disconnect Created: 27/Jul/11  Updated: 04/Nov/16  Resolved: 19/Dec/13

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

Type: Bug Priority: Major
Reporter: Siva Ram Assignee: Unassigned
Resolution: Incomplete Votes: 3
Labels: QuickfixJ, TestRequest, timeout
Environment:

G6 machine, OS - RHL 5.4, Java version - 1.6.0_24


Issue Links:
Duplicate
is duplicated by QFJ-668 Disconnecting: Timed out waiting for ... Closed
is duplicated by QFJ-759 "Timed out waiting for heartbeat" aft... Closed

 Description   

We have the Quickfix engine operating in Acceptor mode. We frequently see scenarios where we disconnect the clients because we "Timed out waiting for heartbeat". But I am able to confirm from the network packet capture that the client heartbeats as expected and in fact promptly responds back to the test request (which was sent before the disconnect) with a heartbeat. I did search for this online and noticed a few forums were this scenario is being discussed, but no resolutions. We have seen similar scenarios in other applications when we don't set a proper socket read timeout and I am wondering if it is the same case here.



 Comments   
Comment by Grant Birchmeier [ 27/Jul/11 ]

Have you tried posting your problem to the mailing list? That should be your first stop before submitting a bug here.
http://quickfixj.org/support/

Apologies if you did that already.

Comment by Siva Ram [ 28/Jul/11 ]

No, I didn't post it on the mailing list. Will do that.

Comment by Christoph John [ 15/Feb/12 ]

Did you manage to reproduce this reliably with a current QF/J version? Can you supply a test case?
Thanks in advance,
Chris.





[QFJ-623] How do you change CompIDs, IP and port of a session at runtime? Created: 26/Jul/11  Updated: 19/Oct/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Andrew Niland Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ
Environment:

java 1.6 on Windows



 Description   

How do you change CompIDs, IP and port of a session at runtime?

I would like to repoint the initiator engine to a different FIX server while the java app is still running.



 Comments   
Comment by Grant Birchmeier [ 26/Jul/11 ]

Did you try posting your question to the mailing list? This doesn't look like it should be a bug report.
http://quickfixj.org/support/

Comment by Laurent Danesi [ 19/Oct/11 ]

CompIDs are part of the SessionID, if you change them it is not the same Session anymore.
About the IP/port, you can specify multiple ip/port for the session and switch to them.

Regards,

Laurent DANESI





[QFJ-622] logout after each resend request Created: 25/Jul/11  Updated: 11/Oct/12  Resolved: 11/Oct/12

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

Type: Bug Priority: Default
Reporter: rikard Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: sequnece
Environment:

linux centos



 Description   

Trying to pick up after a nework failure the quickfixj engine is logging out after each resend request.
The reconnection interval is set to 15 seconds in the config file.
See log example below where a syncronisation of approx. 3 messages is done before logging out and then waiting 15 seconds(reconnection interval) for logging in again.
In this case the initiator missed 280(heartbeat) seq.no which took more than 20 minutes to syncronize.

xxx = targetcomp
yyy = sendcomp

8=FIX.4.2|9=101|35=5|49=XXX|56=YYY|34=281|369=276|52=20110720-07:24:21|58=Error ! Expecting : 278 but received : 4|10=194|
8=FIX.4.2|9=51|35=5|34=6|49=YYY|52=20110720-07:24:26.998|56=XXX|10=055|
8=FIX.4.2|9=63|35=A|34=7|49=YYY|52=20110720-07:24:41.988|56=XXX|98=0|108=30|10=092|
8=FIX.4.2|9=69|35=A|49=XXX|56=YYY|34=282|369=276|52=20110720-07:24:36|98=0|108=30|10=115|
8=FIX.4.2|9=60|35=2|34=8|49=YYY|52=20110720-07:24:41.995|56=XXX|7=3|16=0|10=173|
8=FIX.4.2|9=101|35=5|49=XXX|56=YYY|34=283|369=276|52=20110720-07:24:36|58=Error ! Expecting : 278 but received : 7|10=205|
8=FIX.4.2|9=51|35=5|34=9|49=YYY|52=20110720-07:24:42.000|56=XXX|10=030|
8=FIX.4.2|9=64|35=A|34=10|49=YYY|52=20110720-07:24:56.989|56=XXX|98=0|108=30|10=142|
8=FIX.4.2|9=69|35=A|49=XXX|56=YYY|34=284|369=276|52=20110720-07:24:51|98=0|108=30|10=114|
8=FIX.4.2|9=61|35=2|34=11|49=YYY|52=20110720-07:24:56.995|56=XXX|7=4|16=0|10=223|
8=FIX.4.2|9=102|35=5|49=XXX|56=YYY|34=285|369=276|52=20110720-07:24:51|58=Error ! Expecting : 278 but received : 10|10=247|
8=FIX.4.2|9=52|35=5|34=12|49=YYY|52=20110720-07:24:57.014|56=XXX|10=084|
8=FIX.4.2|9=64|35=A|34=13|49=YYY|52=20110720-07:25:11.990|56=XXX|98=0|108=30|10=129|
8=FIX.4.2|9=69|35=A|49=XXX|56=YYY|34=286|369=276|52=20110720-07:25:06|98=0|108=30|10=117|
8=FIX.4.2|9=61|35=2|34=14|49=YYY|52=20110720-07:25:11.997|56=XXX|7=5|16=0|10=221|
8=FIX.4.2|9=102|35=5|49=XXX|56=YYY|34=287|369=276|52=20110720-07:25:06|58=Error ! Expecting : 278 but received : 13|10=253|
8=FIX.4.2|9=64|35=A|34=15|49=YYY|52=20110720-07:25:26.989|56=XXX|98=0|108=30|10=145|
8=FIX.4.2|9=69|35=A|49=XXX|56=YYY|34=288|369=276|52=20110720-07:25:21|98=0|108=30|10=116|
8=FIX.4.2|9=61|35=2|34=16|49=YYY|52=20110720-07:25:26.995|56=XXX|7=6|16=0|10=228|
8=FIX.4.2|9=102|35=5|49=XXX|56=YYY|34=289|369=276|52=20110720-07:25:21|58=Error ! Expecting : 278 but received : 15|10=254|
8=FIX.4.2|9=64|35=A|34=17|49=YYY|52=20110720-07:25:41.989|56=XXX|98=0|108=30|10=144|
8=FIX.4.2|9=69|35=A|49=XXX|56=YYY|34=290|369=276|52=20110720-07:25:36|98=0|108=30|10=115|
8=FIX.4.2|9=61|35=2|34=18|49=YYY|52=20110720-07:25:41.995|56=XXX|7=6|16=0|10=227|



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

The problem is a sequence number mismatch. It seems you were sending seqnum 277 as last message before the crash. But after the crash you should have continued with 278 and not 1. The other side sends a logout since the sequence numbers are simply too low.





[QFJ-621] quickfixj\core\build.xml:81: The following error occurred while executing this line Created: 21/Jul/11  Updated: 13/Feb/14  Resolved: 13/Feb/14

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

Type: Other Priority: Default
Reporter: Andrew Niland Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: ant
Environment:

Windows XP. using Eclipse Java EE IDE - Indigo
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Client VM (build 20.1-b02, mixed mode, sharing)



 Description   

Hi,

I'm trying to build the quickfixj engine and am getting stuck. What should I do to fix this?

Here are the logs:

Buildfile: C:\Andrew_temp\workspace\quickfixj\core\build.xml

check.generated.isuptodate:

generate.code:

compile:

compile_main:
[javac] C:\Andrew_temp\workspace\quickfixj\core\build.xml:109: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 1850 source files to C:\Andrew_temp\workspace\quickfixj\core\target\classes\main

BUILD FAILED
C:\Andrew_temp\workspace\quickfixj\core\build.xml:81: The following error occurred while executing this line:
C:\Andrew_temp\workspace\quickfixj\core\build.xml:89: The following error occurred while executing this line:
C:\Andrew_temp\workspace\quickfixj\core\build.xml:109: Error running javac.exe compiler



 Comments   
Comment by Grant Birchmeier [ 21/Jul/11 ]

That looks like a platform issue specific to your machine. Specifically, your ant is not able to call javac.

Are you able to use ant to compile any other java projects? Are you using a recent version of java?

Comment by Andrew Niland [ 21/Jul/11 ]

Thanks for your help Grant. I was try to do a build in Eclipse. When I did the build with Ant first, everything worked





[QFJ-620] Problem validating Fix 4.4. TradeCaptureReport 35='AE' Created: 19/Jul/11  Updated: 14/Oct/16  Resolved: 14/Oct/16

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Alwyn Donnell Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

linux - RHEL 5.0


Issue Links:
Duplicate
is duplicated by QFJ-585 TradeCaptureReport.NoSides parsing fail Closed

 Description   

Trying to construct TradeCaptureReport using QuickFixJ 1.5.0

There seems to be a problem validating the fields for the TrdCapRptSideGrp repeating group .

In my message I have defined the following fields for that particular repeating group i.e. only those that are mandatory:
552=1<SOH>54=2<SOH>37=1280622950453<SOH>

When I attempt to send it I get the following reject message :
8=FIX.4.4<SOH>9=123<SOH>35=3<SOH>34=53<SOH>49=BLP<SOH>52=20110718-11:18:10.459<SOH>56=CMF<SOH>45=53<SOH>58=Tag not defined for this message type<SOH>371=37<SOH>372=AE<SOH>373=2<SOH>10=196

I know it is a mandatory field , but I tried removing it and tried sending it again to get the following error :

8=FIX.4.4<SOH>9=123<SOH>35=3<SOH>34=56<SOH>49=BLP<SOH>52=20110718-11:19:22.707<SOH>56=CMF<SOH>45=56<SOH>58=Tag not defined for this message type<SOH>371=54<SOH>372=AE<SOH>373=2<SOH>10=201

I also know that tag 54 is mandatory for this message, but I removed it anyway and of course got this error which makes sense :
8=FIX.4.4<SOH>9=134<SOH>35=3<SOH>34=59<SOH>49=BLP<SOH>52=20110718-11:19:53.589<SOH>56=CMF<SOH>45=59<SOH>58=Incorrect NumInGroup count for repeating group<SOH>371=552<SOH>372=AE<SOH>373=16<SOH>10=060

It looks like there is a problem around the validation of this repeating group. Tags 54 and 37 are manadatory for this message type, so should'nt be reporting
'Tag not defined for this message type' for these tags.



 Comments   
Comment by Michael Daloia [ 25/May/12 ]

I too am having the same issue. I send a TradeCaptureReport message (35=AE) to my simulator built with quickfix 1.13.3

Here is the TCR message being sent:
DEBUG PID:8236 05/25 11:14:58.135 trf.py 909 8=FIX.4.49=39235=AE34=249=LQNTSWXTR52=20120525-15:14:58.13456=SWXLQNTTR15=CHF22=431=10.5232=100048=CH002340545655=[N/A]60=20110613-15:15:15.23475=20120525207=LQNT487=0552=254=137=NONE453=1448=9234447=D452=7802=1523=13173803=25528=R6520=LN IP54=237=NONE453=1448=9209447=D452=17802=1523=60584803=25570=N571=_LN45768=1769=20110613-15:15:14.222770=1856=0880=LN343434310=193

The msg is being rejected by my quickfix simulator
DEBUG PID:8236 05/25 11:14:58.135 trf.py 140 toAdmin message: 8=FIX.4.49=12735=334=249=SWXLQNTTR52=20120525-15:14:58.13556=LQNTSWXTR45=258=Tag not defined for this message type371=37372=AE373=210=176

My FIX xml file for TradeCaptureReport is below. It has OrderID defined in the NoSides repeating group. It's as if the NoSides repeating groups isn't being handled properly by quickfix:

<message name='TradeCaptureReport' msgcat='app' msgtype='AE'>
<field name='TradeReportID' required='Y' />
<field name='TradeReportTransType' required='N' />
<field name='TradeReportType' required='N' />
<field name='TradeRequestID' required='N' />
<field name='TrdType' required='N' />
<field name='TrdSubType' required='N' />
<field name='SecondaryTrdType' required='N' />
<field name='TransferReason' required='N' />
<field name='ExecType' required='N' />
<field name='TotNumTradeReports' required='N' />
<field name='LastRptRequested' required='N' />
<field name='UnsolicitedIndicator' required='N' />
<field name='SubscriptionRequestType' required='N' />
<field name='TradeReportRefID' required='N' />
<field name='SecondaryTradeReportRefID' required='N' />
<field name='SecondaryTradeReportID' required='N' />
<field name='TradeLinkID' required='N' />
<field name='TrdMatchID' required='N' />
<field name='ExecID' required='N' />
<field name='OrdStatus' required='N' />
<field name='SecondaryExecID' required='N' />
<field name='ExecRestatementReason' required='N' />
<field name='PreviouslyReported' required='Y' />
<field name='PriceType' required='N' />
<field name='Currency' required='Y' />
<component name='Instrument' required='Y' />
<component name='FinancingDetails' required='N' />
<component name='OrderQtyData' required='N' />
<field name='QtyType' required='N' />
<component name='YieldData' required='N' />
<group name='NoUnderlyings' required='N'>
<component name='UnderlyingInstrument' required='N' />
</group>
<field name='UnderlyingTradingSessionID' required='N' />
<field name='UnderlyingTradingSessionSubID' required='N' />
<field name='LastQty' required='Y' />
<field name='LastPx' required='Y' />
<field name='LastParPx' required='N' />
<field name='LastSpotRate' required='N' />
<field name='LastForwardPoints' required='N' />
<field name='LastMkt' required='N' />
<field name='TradeDate' required='Y' />
<field name='ClearingBusinessDate' required='N' />
<field name='AvgPx' required='N' />
<component name='SpreadOrBenchmarkCurveData' required='N' />
<field name='AvgPxIndicator' required='N' />
<component name='PositionAmountData' required='N' />
<field name='MultiLegReportingType' required='N' />
<field name='TradeLegRefID' required='N' />
<group name='NoLegs' required='N'>
<component name='InstrumentLeg' required='N' />
<field name='LegQty' required='N' />
<field name='LegSwapType' required='N' />
<component name='LegStipulations' required='N' />
<field name='LegPositionEffect' required='N' />
<field name='LegCoveredOrUncovered' required='N' />
<component name='NestedParties' required='N' />
<field name='LegRefID' required='N' />
<field name='LegPrice' required='N' />
<field name='LegSettlType' required='N' />
<field name='LegSettlDate' required='N' />
<field name='LegLastPx' required='N' />
</group>
<field name='TransactTime' required='Y' />
<component name='TrdRegTimestamps' required='N' />
<field name='SettlType' required='N' />
<field name='SettlDate' required='N' />
<field name='MatchStatus' required='N' />
<field name='MatchType' required='N' />
<group name='NoSides' required='Y'>
<field name='Side' required='Y' />
<field name='OrderID' required='Y' />
<field name='SecondaryOrderID' required='N' />
<field name='ClOrdID' required='N' />
<field name='SecondaryClOrdID' required='N' />
<field name='ListID' required='N' />
<component name='Parties' required='N' />
<field name='Account' required='N' />
<field name='AcctIDSource' required='N' />
<field name='AccountType' required='N' />
<field name='ProcessCode' required='N' />
<field name='OddLot' required='N' />
<group name='NoClearingInstructions' required='N'>
<field name='ClearingInstruction' required='N' />
</group>
<field name='ClearingFeeIndicator' required='N' />
<field name='TradeInputSource' required='N' />
<field name='TradeInputDevice' required='N' />
<field name='OrderInputDevice' required='N' />
<field name='Currency' required='N' />
<field name='ComplianceID' required='N' />
<field name='SolicitedFlag' required='N' />
<field name='OrderCapacity' required='N' />
<field name='OrderRestrictions' required='N' />
<field name='CustOrderCapacity' required='N' />
<field name='OrdType' required='N' />
<field name='ExecInst' required='N' />
<field name='TransBkdTime' required='N' />
<field name='TradingSessionID' required='N' />
<field name='TradingSessionSubID' required='N' />
<field name='TimeBracket' required='N' />
<component name='CommissionData' required='N' />
<field name='GrossTradeAmt' required='N' />
<field name='NumDaysInterest' required='N' />
<field name='ExDate' required='N' />
<field name='AccruedInterestRate' required='N' />
<field name='AccruedInterestAmt' required='N' />
<field name='InterestAtMaturity' required='N' />
<field name='EndAccruedInterestAmt' required='N' />
<field name='StartCash' required='N' />
<field name='EndCash' required='N' />
<field name='Concession' required='N' />
<field name='TotalTakedown' required='N' />
<field name='NetMoney' required='N' />
<field name='SettlCurrAmt' required='N' />
<field name='SettlCurrency' required='N' />
<field name='SettlCurrFxRate' required='N' />
<field name='SettlCurrFxRateCalc' required='N' />
<field name='PositionEffect' required='N' />
<field name='Text' required='N' />
<field name='EncodedTextLen' required='N' />
<field name='EncodedText' required='N' />
<field name='SideMultiLegReportingType' required='N' />
<group name='NoContAmts' required='N'>
<field name='ContAmtType' required='N' />
<field name='ContAmtValue' required='N' />
<field name='ContAmtCurr' required='N' />
</group>
<component name='Stipulations' required='N' />
<group name='NoMiscFees' required='N'>
<field name='MiscFeeAmt' required='N' />
<field name='MiscFeeCurr' required='N' />
<field name='MiscFeeType' required='N' />
<field name='MiscFeeBasis' required='N' />
</group>
<field name='ExchangeRule' required='N' />
<field name='TradeAllocIndicator' required='N' />
<field name='PreallocMethod' required='N' />
<field name='AllocID' required='N' />
<group name='NoAllocs' required='N'>
<field name='AllocAccount' required='N' />
<field name='AllocAcctIDSource' required='N' />
<field name='AllocSettlCurrency' required='N' />
<field name='IndividualAllocID' required='N' />
<component name='NestedParties2' required='N' />
<field name='AllocQty' required='N' />
</group>
<field name='CopyMsgIndicator' required='N' />
<field name='PublishTrdIndicator' required='N' />
<field name='ShortSaleReason' required='N' />
</group>
</message>

Here are my quickfix settings:

UseDataDictionary=Y
ValidateUserDefinedFields=N
ValidateFieldsHaveValues=N
ValidateFieldsOutOfOrder=N
AllowUnknownMsgFields=Y

Comment by Christoph John [ 14/Oct/16 ]

Had a similar case like this today. The bottom line was that there was an unknown/user-defined field at the end of the NoSides repeating group that caused the error. So the data dictionary just needed that adaption.

Will close this issue unless there is a complete test which proves otherwise.





[QFJ-619] Late Resend Request causes sequence number mayhem : what happened? Created: 18/Jul/11  Updated: 18/Jul/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Nicolas Chaufette Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File trace.txt    

 Description   

Hello everyone,

A client seems to have a problem that I cannot reproduce. Basically, the third party asks for a resend request of a message sent 7 minutes earlier. During those 7 mintures, heartbeats have been exchanged and the sequence increased. When the Resend Request is received, this happens (look at the sequence numbers).
Is it a known bug in QuickFIX/J 1.4.0 ? fixed in 1.5.0 ?

Thanks, best regards,

Nicolas

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:30:40.704" level="Enabled" thread="QFJ Timer">
<fix:message length="79" way="outgoing"><![CDATA[8=FIX.4.4|9=57|35=0|34=260|49=NOYOBU|52=20110705-11:30:40.704|56=NOYOBU|10=215|]]></fix:message>
</fix:trace>

[... nothing of importance, just heartbeats in and out for 7 minutes...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:46.695" level="Enabled" thread="QFJ Timer">
<fix:message length="79" way="outgoing"><![CDATA[8=FIX.4.4|9=57|35=0|34=267|49=NOYOBU|52=20110705-11:37:46.695|56=NOYOBU|10=244|]]></fix:message>
</fix:trace>

[... here seqnum is 267, right? ...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:46.788" level="Enabled" thread="SocketConnectorIoProcessor-0.0">
<fix:message length="88" way="incoming"><![CDATA[8=FIX.4.4|9=0064|35=2|49=NOYOBU|56=NOYOBU|34=269|52=20110705-11:37:46|7=260|16=0|10=102|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:46.788" level="Enabled" thread="QFJ Message Processor">
<fix:event length="45"><![CDATA[Received ResendRequest FROM: 260 TO: infinity]]></fix:event>
</fix:trace>

[... counterparty asks for 260, sent 7 minutes earlier ...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:47.185" level="Enabled" thread="QFJ Message Processor">
<fix:message length="119" way="outgoing"><![CDATA[8=FIX.4.4|9=97|35=4|34=260|43=Y|49=NOYOBU|52=20110705-11:37:47.185|56=NOYOBU|122=20110705-11:37:47|36=261|123=Y|10=150|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:47.186" level="Enabled" thread="QFJ Message Processor">
<fix:event length="26"><![CDATA[Sent SequenceReset TO: 261]]></fix:event>
</fix:trace>

[... sending 260, reset to 261 ?? ...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:47.186" level="Enabled" thread="QFJ Message Processor">
<fix:message length="119" way="outgoing"><![CDATA[8=FIX.4.4|9=97|35=4|34=260|43=Y|49=NOYOBU|52=20110705-11:37:47.186|56=NOYOBU|122=20110705-11:37:47|36=267|123=Y|10=157|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:37:47.186" level="Enabled" thread="QFJ Message Processor">
<fix:event length="26"><![CDATA[Sent SequenceReset TO: 267]]></fix:event>
</fix:trace>

[... sending 260 AGAIN, reset to 267 ????? ...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:46.819" level="Enabled" thread="SocketConnectorIoProcessor-0.0">
<fix:message length="77" way="incoming"><![CDATA[8=FIX.4.4|9=0053|35=0|49=NOYOBU|56=NOYOBU|34=270|52=20110705-11:38:46|10=121|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:47.699" level="Enabled" thread="QFJ Timer">
<fix:message length="79" way="outgoing"><![CDATA[8=FIX.4.4|9=57|35=0|34=268|49=NOYOBU|52=20110705-11:38:47.698|56=NOYOBU|10=250|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:47.831" level="Enabled" thread="SocketConnectorIoProcessor-0.0">
<fix:message length="88" way="incoming"><![CDATA[8=FIX.4.4|9=0064|35=2|49=NOYOBU|56=NOYOBU|34=271|52=20110705-11:38:47|7=261|16=0|10=098|]]></fix:message>
</fix:trace>

[... and it goes on and on and on and on...]

<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:47.831" level="Enabled" thread="QFJ Message Processor">
<fix:event length="45"><![CDATA[Received ResendRequest FROM: 261 TO: infinity]]></fix:event>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:48.187" level="Enabled" thread="QFJ Message Processor">
<fix:message length="119" way="outgoing"><![CDATA[8=FIX.4.4|9=97|35=4|34=261|43=Y|49=NOYOBU|52=20110705-11:38:48.187|56=NOYOBU|122=20110705-11:38:48|36=262|123=Y|10=158|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:48.188" level="Enabled" thread="QFJ Message Processor">
<fix:event length="26"><![CDATA[Sent SequenceReset TO: 262]]></fix:event>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:48.188" level="Enabled" thread="QFJ Message Processor">
<fix:message length="119" way="outgoing"><![CDATA[8=FIX.4.4|9=97|35=4|34=261|43=Y|49=NOYOBU|52=20110705-11:38:48.188|56=NOYOBU|122=20110705-11:38:48|36=268|123=Y|10=165|]]></fix:message>
</fix:trace>
<fix:trace logger="fix-engine-05301" timestamp="2011-07-05 13:38:48.188" level="Enabled" thread="QFJ Message Processor">
<fix:event length="26"><![CDATA[Sent SequenceReset TO: 268]]></fix:event>
</fix:trace>






[QFJ-618] Documentation for ValidateUserDefinedFields is incorrect Created: 13/Jul/11  Updated: 03/Dec/14  Resolved: 03/Dec/14

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

Type: Improvement Priority: Default
Reporter: Jerome Thibodeau Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-454 Update documentation to reflect that ... Closed

 Description   

In the documentation : http://www.quickfixj.org/quickfixj/usermanual/1.5.0/usage/configuration.html

ValidateUserDefinedFields If set to N, user defined fields will not be rejected if they are not defined in the data dictionary, or are present in messages they do not belong

With default value : N

But in the code line 76 the variable checkUserDefinedFields is initialized to true.

62 public class DataDictionary {
63 private static final String FIXT_PREFIX = "FIXT";
64 private static final String FIX_PREFIX = "FIX";
65 public static final String ANY_VALUE = "_ANY_";
66 public static final String HEADER_ID = "HEADER";
67 public static final String TRAILER_ID = "TRAILER";
68 private static final String MESSAGE_CATEGORY_ADMIN = "admin".intern();
69 private static final String MESSAGE_CATEGORY_APP = "app".intern();
70
71 private static final int USER_DEFINED_TAG_MIN = 5000;
72 private static final String NO = "N";
73 private boolean hasVersion = false;
74 private boolean checkFieldsOutOfOrder = true;
75 private boolean checkFieldsHaveValues = true;
76 private boolean checkUserDefinedFields = true;



 Comments   
Comment by Christoph John [ 03/Dec/14 ]

duplicate of QFJ-454

Comment by Christoph John [ 03/Dec/14 ]

It seems the documentation for 1.5.0 was indeed incorrect, but it is corrected since 1.5.1





[QFJ-617] disconnect() might not clear logoutSent flag Created: 12/Jul/11  Updated: 12/Oct/12  Resolved: 12/Oct/12

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

Type: Bug Priority: Default
Reporter: Staffan Ulfberg Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-444 Logout logic problem Resolved

 Description   

In Session, with the help of SessionState, there is code to keep track of whether a logout message has been sent. In the disconnect method this flag is normally cleared. However, if the method returns early due to the session being already disconnected, the flag is not cleared.

So the flag remains set, and this later triggers another logout (after the session has really been re-established). (And the reason for that logout is logged incorrectly – see bug posted minutes ago.)






[QFJ-616] Incorrect log message "Timed out waiting for heartbeat" Created: 12/Jul/11  Updated: 08/Nov/12  Resolved: 07/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Staffan Ulfberg Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

This code is part of Session.java:

if (state.isLogoutTimedOut())

{ disconnect("Timed out waiting for heartbeat", true); }

I believe the log message is a copy/paste bug from a few lines lower down in the same file. What happened here is that the session tried to log out but didn't head anything back form the peer, I believe.



 Comments   
Comment by Christoph John [ 08/Nov/12 ]

Committed as #1096.





[QFJ-615] CLONE - can not parse cme definition message from cme file Created: 07/Jul/11  Updated: 19/Dec/13  Resolved: 19/Dec/13

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

Type: Other Priority: Default
Reporter: Jonathan Felch Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-614 CLONE - can not parse cme definition ... Closed

 Description   

Hello;

I can not parse cme definition message from cme file from ftp://ftp.cme.com/secdef.dat.gz

code:

DataDictionary sessionDictionary, applicationDictionary;

sessionDictionary = new DataDictionary("FIXT11.xml");
applicationDictionary = new DataDictionary("FIX50.xml");

Message message = new Message();

boolean doValidation = false;

message.fromString(messageString, sessionDictionary,
applicationDictionary, doValidation);

sample cme input and quickfixj output:

INFO: messageString
1128=89=36835=d49=CME34=42552=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=1311=[N/A]305=8309=20460001827=0864=2865=5866=200906261145=0865=7866=200909301145=210059000870=1871=24872=1947=BRL969=0.0011140=100001141=11022=GBX264=51142=F1151=BR:DOL1180=259787=19850=0.00110=165

INFO: message
9=15235=d34=42549=CME52=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=110=128

thank you;

Andrei






[QFJ-614] CLONE - can not parse cme definition message from cme file Created: 07/Jul/11  Updated: 01/Apr/14  Resolved: 01/Apr/14

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

Type: Other Priority: Default
Reporter: Jonathan Felch Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-615 CLONE - can not parse cme definition ... Closed

 Description   

Hello;

I can not parse cme definition message from cme file from ftp://ftp.cme.com/secdef.dat.gz

code:

DataDictionary sessionDictionary, applicationDictionary;

sessionDictionary = new DataDictionary("FIXT11.xml");
applicationDictionary = new DataDictionary("FIX50.xml");

Message message = new Message();

boolean doValidation = false;

message.fromString(messageString, sessionDictionary,
applicationDictionary, doValidation);

sample cme input and quickfixj output:

INFO: messageString
1128=89=36835=d49=CME34=42552=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=1311=[N/A]305=8309=20460001827=0864=2865=5866=200906261145=0865=7866=200909301145=210059000870=1871=24872=1947=BRL969=0.0011140=100001141=11022=GBX264=51142=F1151=BR:DOL1180=259787=19850=0.00110=165

INFO: message
9=15235=d34=42549=CME52=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=110=128

thank you;

Andrei



 Comments   
Comment by Jonathan Felch [ 07/Jul/11 ]

This is the same issue as QFJ-478 but my account was unable to reopen the existing issue which is not resolved.

The latest build from trunk continues to fail on a large number of records and also continues to be missing field definitions... Technically this file should be depending on FIX 5 SP2, which may be part of the problem... My attempts to generate code for FIX 5 SP 2 were unsuccessful.

Comment by Christoph John [ 01/Apr/14 ]

We should now be able to handle FIX5.0 SP2 since QF/J 1.5.3. Unfortunately the link in the description is not reachable any longer (but the ticket is some years old).





[QFJ-613] Provide correct example in chapter "Creating Your Application" Created: 21/Jun/11  Updated: 04/Aug/11  Resolved: 04/Aug/11

Status: Closed
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Improvement Priority: Default
Reporter: dario marguez Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi, I'm following the instructions on the page Creating Your QuickFIX/J Application. It tells me to create an app by implementing the Application interface, but the code for MyClass is instantiating an object for the interface. I thought this is prohibited in Java?



 Comments   
Comment by Grant Birchmeier [ 21/Jun/11 ]

I guess technically he's right, though my impression is that the code is more of an example and not intended to actually compile.

The line:
> Application application = new Application();
probably could be changed to something like:
> Application application = new YourClassThatImplementsApplication();
which I think would clear up any confusion.

Dario, though there is a slight correction needed here, did you really create this bug because you had a question and could not find anywhere else to submit it? (Forgive me if I am mistaken.) You should really be joining the mailing list and submitting questions there. Bugs should only be created when defects are found that need to be fixed.
http://www.quickfixj.org/support/
It's a good list, and you'll learn a lot by reading questions other people have posted.

Comment by Jörg Thönnes [ 21/Jun/11 ]

Please follow Grants suggestion and post question on the list.

If you have concrete text snippets how the user manual could be improved,
please attach it to this issue. We will review it and update the manual
accordingly.

Comment by Grant Birchmeier [ 21/Jun/11 ]

I've submitted a fix to this page. It's minor, but I think it's sufficient.

Here's the diff:

  • Application application = new Application();
    + // FooApplication is your class that implements the Application interface
    + Application application = new FooApplication();
    +

Dario, what do you think?

Comment by dario marguez [ 21/Jun/11 ]

Hi, it's more clear now. Thanks for pointing me over to the mailing list.

Comment by Eric Deshayes [ 04/Aug/11 ]

This documentation improvement has been committed in rev#1047.





[QFJ-612] BigDecimal for stock prices Created: 21/Jun/11  Updated: 15/Nov/12  Resolved: 21/Jun/11

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: Future Releases
Fix Version/s: 1.2.0

Type: New Feature Priority: Major
Reporter: Chintan Shah Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: QuickfixJ

Issue Links:
Duplicate
duplicates QFJ-77 Support big decimal in message genera... Closed

 Description   

Hi Folks,

I am trying to use quickfixj for our needs.

At this point I am not worried about the performance and want to be able to send orders with precise stock prices using quickfixj 1.5 I see the type NewOrderSingle takes a Price object which takes a double value. So I am getting the market data from our provider and convert those floating point values to BigDecimal. Should I just keep them in double and send orders with double values? What is the chance of raising my bid by a cent due to lack of precision in that case?

What is the quickest possible way to achive my objective?

Thanks a lot,



 Comments   
Comment by Jörg Thönnes [ 21/Jun/11 ]

This is definitely not a blocker.

But you are correct – if you want to do serious processing of financial data, BigDecimal values are much better.
Therefore, there is a message generation option to use BigDecimal:

See http://www.quickfixj.org/quickfixj/usermanual/1.5.0/usage/codegen.html
last option applies.

Comment by Jörg Thönnes [ 21/Jun/11 ]

This issue was already solved in QF/F 1.2.

Comment by Jörg Thönnes [ 21/Jun/11 ]

Please re-open if anything is missing.

Comment by Toli Kuznets [ 21/Jun/11 ]

There's an example of how to use the flags to switch on BigDecimal at http://quickfixj.org/quickfixj/usermanual/1.5.0/installation.html#build

Comment by Jörg Thönnes [ 21/Jun/11 ]

Thanks, Toli. Did not find this in the first browse.





[QFJ-611] SessionNotFound, while still getting heartbeats Created: 21/Jun/11  Updated: 24/Mar/14  Resolved: 24/Mar/14

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

Type: Other Priority: Default
Reporter: Willis Todd Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ, session
Environment:

Windows XP, Eclipse SDK Version: 3.5.2



 Description   

I am converting my app to connect to a different platform (Integral) from where I already have it working (Fortex), but I am catching a SessionNotFound when I try to send a MarketDataRequest to Integral and not when I use the same code to request data from Fortex. The only difference between the two is in the config files, which are identical other than the obvious login credentials for the two different platforms, and for Integral I have "SocketUseSSL=Y" and I am using FIX 4.3 instead of FIX 4.4. Even after I am told that the session does not exist, I continue to send and receive heartbeats for both sessions, so how am I getting a SessionNotFound and what can I do to correct it? Thanks in advance for your help!

Here is the code:

private void send2(Message aMessage, SessionID aSessionId) {
try

{ setHeader1(aMessage.getHeader(), aSessionId); System.out.println("session existence: "+Session.doesSessionExist(aSessionId)); System.out.println("session lookup: "+Session.lookupSession(aSessionId)); Session.sendToTarget(aMessage, aSessionId); }

catch (SessionNotFound aSessionNotFound)

{ aSessionNotFound.printStackTrace(); }

}

And here is the print out from the two compared, with Fortex first:

session existence: true

session lookup: FIX.4.4:SenderCompID->FTSDEMO_QUOTE.FORTEX.NET[in:2,out:2]

OUTGOING: quickfix.fix43.MarketDataRequest(8=FIX.4.49=15335=V34=249=SenderCompID50=SenderSubID52=20110621-08:57:09.28156=FTSDEMO_QUOTE.FORTEX.NET55=EUR/USD128=146=1262=1263=1264=1265=0267=0269=0460=410=220)

<20110621-08:57:09, FIX.4.4:SenderCompID->FTSDEMO_QUOTE.FORTEX.NET, outgoing> (8=FIX.4.49=15335=V34=249=SenderCompID50=SenderSubID52=20110621-08:57:09.28156=FTSDEMO_QUOTE.FORTEX.NET55=EUR/USD128=146=1262=1263=1264=1265=0267=0269=0460=410=220)

And here's what I get at this same point with Integral:

session existence: false
session lookup: null
quickfix.SessionNotFound
>>> 001
at quickfix.Session.sendToTarget(Session.java:587)
at STXjune17_2011post1$MyApp.send2(STXjune17_2011post1.java:592)
at STXjune17_2011post1$MyApp.getMarketData(STXjune17_2011post1.java:745)
at STXjune17_2011post1.main(STXjune17_2011post1.java:1153)



 Comments   
Comment by Willis Todd [ 21/Jun/11 ]

I probably should also show the code for the later two points referenced at lines 745 and 1153, so here they are. But it seems like the problem is not caused by these things to me, but rather something to do with the first code I shared.

Line 743
public void getMarketData(String symb, int depth){
System.out.println("getMarketData--------");
quickfix.fix43.MarketDataRequest mdr = new quickfix.fix43.MarketDataRequest();
mdr.setField(new DeliverToCompID());
mdr.setField(new Symbol("EUR/USD"));
mdr.setField(new MDReqID(String.valueOf(nextID())));
mdr.setField(new SubscriptionRequestType(SubscriptionRequestType.SNAPSHOT_PLUS_UPDATES));
mdr.setField(new MarketDepth(1));
mdr.setField(new Product(4));
mdr.setField(new NoRelatedSym(1));
mdr.setField(new MDUpdateType(0));
mdr.setField(new MDEntryType(MDEntryType.BID));
mdr.setField(new NoMDEntryTypes());
System.out.println("This is the message :" + mdr.toString());
send2(mdr, mQuoteSessionID);

Line 1153:

app.getMarketData("d", 0);

Comment by Willis Todd [ 24/Jun/11 ]

This problem has been resolved by using different code with Integral. I used the following code and I no longer get SessionNotFound. I hope this helps anyone how has a similar problem!

public void sendMarketRequest() throws SessionNotFound{
quickfix.fix43.MarketDataRequest sub = new quickfix.fix43.MarketDataRequest(new MDReqID("trader79"),new SubscriptionRequestType('1'), new MarketDepth (1));
sub.setField(new Product(4));
sub.setField(new NoRelatedSym(1));
sub.setField(new MDUpdateType(0));
sub.setField(new NoMDEntryTypes(0));
sub.setField(new DeliverToCompID());
sub.setField(new quickfix.field.Symbol("EUR/USD"));
setSecurityType(sub);
try

{ Session.sendToTarget(sub, mOrderSessionID); }

catch(SessionNotFound er)

{ er.printStackTrace(); }

}

Comment by Willis Todd [ 24/Jun/11 ]

I should add that I still have a problem with tags not being sent in the right order, but at least as far as the SessionNotFound problem, that is gone and my message goes out. I'm still trying to find out how to get the tags in the right order.





[QFJ-610] java.io.IOException when using FileStore Created: 17/Jun/11  Updated: 17/Jun/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Daniel Clusin Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: QuickfixJ
Environment:

uname -a: Linux 2.6.9-34.ELsmp #1 SMP Fri Feb 24 16:56:28 EST 20 06 x86_64 x86_64 x86_64 GNU/Linux
Java VM: BEA JRockit(R) R27.6.0-50_o-100423-1.5.0_15-20080626-2104-linux-x86_64,BEA Systems, Inc.



 Description   

java.io.IOException: Bad file descriptor
at java.io.RandomAccessFile.seek(Native Method)
at quickfix.FileStore.storeSequenceNumbers(FileStore.java:403)
at quickfix.FileStore.incrNextSenderMsgSeqNum(FileStore.java:288)
at quickfix.SessionState.incrNextSenderMsgSeqNum(SessionState.java:350)
at quickfix.Session.sendRaw(Session.java:2177)
at quickfix.Session.generateHeartbeat(Session.java:1786)
at quickfix.Session.next(Session.java:1759)
at quickfix.Session.next(Session.java:1032)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)

This occurred during a period of intermittent network disconnects. I did not see any forcible closes of the network sockets being done. Another time this occured is during a shutdown, after we called Initiator/Acceptor.stop

FIX.4.2:XXXX->XXXX: Error during message processing

quickfix.RuntimeError: java.io.IOException: Bad file descriptor
at quickfix.SessionState.reset(SessionState.java:373)
at quickfix.Session.resetState(Session.java:2193)
at quickfix.Session.nextLogout(Session.java:1279)
at quickfix.Session.next(Session.java:941)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)

Caused by: java.io.IOException: Bad file descriptor
at java.io.RandomAccessFile.length(Native Method)
at quickfix.FileStore.initializeCache(FileStore.java:119)
at quickfix.FileStore.initialize(FileStore.java:111)
at quickfix.FileStore.reset(FileStore.java:436)
at quickfix.SessionState.reset(SessionState.java:370)
... 4 more






[QFJ-609] Improve JMX session registration. Created: 15/Jun/11  Updated: 01/Oct/17  Resolved: 15/Jun/11

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: jmx

Issue Links:
Relates
is related to QFJ-556 ThreadedSocketAcceptor/DynamicAccept... Closed

 Comments   
Comment by Steve Bate [ 15/Jun/11 ]

Implemented a bound property on SessionConnector for the session collection. This is used by the JMX connector adapter to register sessions. This means that an initiator can be registered before it has been started and the session have been created. It also should support registration of MBeans for dynamic acceptor sessions. Also added JMX registration to the Banza program (previously only the Executator example had it).





[QFJ-608] Out of Order in repeating group if first tag of repeating group is not set (even if it is not a mandatory field) Created: 10/Jun/11  Updated: 15/Nov/12  Resolved: 11/Jun/11

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

Type: Bug Priority: Minor
Reporter: John Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

JDK 1.6_24



 Description   

In quickfix.Message, parseGroup(...) the code looks for the first field in the group as defined by the dictionary. If it is not defined, then a "REPEATING_GROUP_FIELDS_OUT_OF_ORDER" exception is triggered.

I made a TradeCaptureReport message. This type of message has a "Symbol" field in the "Instrument" component.
I used the "NoLegs" repeating group and the message parsing on the server failed because I did not put the "LegSymbol" field in the group.

My workaround is to put the "LegSymbol" field for each group. It makes the message bigger with no added value.

If there is a reason to make this check, could somebody explain ?

Thanks,
John



 Comments   
Comment by Steve Bate [ 11/Jun/11 ]

The InstrumentLeg component can be used either in a repeating group or not (see the AssignmentReport and FinancingDetails messages, for example). Theoretically, it could also be used in a repeating where it's not the first element of the group but I don't know of any examples of that.

When the InstrumentGroup component is the first element of a repeating group then the first element of the component is conditionally required. It's how FIX messages determine the start of each group in a repeating group. See the FIX specifications for more details.

Comment by Steve Bate [ 11/Jun/11 ]

Just curious, but I'm wondering why you have a multileg TradeCaptureReport where each leg has the same symbol as the top-level instrument. The typical scenario would be something like a multileg option strategy trade where the top-level instrument is the underlying instrument symbol and the leg symbols are the option symbols for each leg.

Comment by John [ 14/Jun/11 ]

Hi,
Thanks for the information, I missed the part where the spec said that it looked for the first field of a repeating group to determine the start. I confess that I have not read everything :-[.

For our use case, NoSides contains a trade and NoLegs contains the information for the quote that the client selected for the trade (so we are using a field that was not meant for that).

Why ? Because the dialog is internal to the firm and well specified/documented. So we decided not to add our own fields, having a structure, that suited well our needs, already present.

I completely lack the financial knowledge but I thought that we could set the "root" symbol for the full capture or one by "leg". Either the one or the other since I do not see what the "main" symbol is worth if each leg declares a different symbol.

Comment by John [ 14/Jun/11 ]

Your question made look closely the message fields and we might use the "UndInstrmtGrp" which is I think exactly what we are doing (How could I not see it !!!).

Thanks again





[QFJ-607] Support of the Field 369 LastMsgSeqNumProcessed Created: 31/May/11  Updated: 15/Nov/12  Resolved: 31/May/11

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

Type: New Feature Priority: Default
Reporter: Eric Deshayes Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The header field 369 LastMsgSeqNumProcessed is an optional field that has been introduced in FIX 4.2.



 Comments   
Comment by Eric Deshayes [ 31/May/11 ]

Committed in rev#1041.

Added new setting to enable the field 369 on any sent message:
EnableLastMsgSeqNumProcessed

By default, this setting is not enabled.





[QFJ-606] Logout reason "Incorrect BeginString" on UnsupportedVersion exception is ambiguous Created: 26/May/11  Updated: 26/May/11  Resolved: 26/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Duplicate Votes: 0
Labels: None


 Description   

We had the situation any FIX sessions were immediately logged out with the reason "Incorrect BeginString". But the session was configured to use "FIX.4.4" and the incoming message came with "FIX.4.4" so we wondered why this happened.

Finally, we found that the configured data dictionary had the wrong FIX version tag which was difficult to find.

Code analysis results:

  • The logout reason "Incorrect BeginString" is sent if the exception UnsupportedVersion is thrown.
  • This exception is sent on two quite different occasions:
    • Incoming BeginString does not match the session configuration.
    • On validate, configured data dictionary does not match the session configuration.
  • In both cases, the same undifferentiated exception is thrown.

Possible improvements:

  • Provide differentiating reason text to the UnsupportedVersion exception.


 Comments   
Comment by Grant Birchmeier [ 26/May/11 ]

Duplicate of 603/604/605





[QFJ-605] Logout reason "Incorrect BeginString" on UnsupportedVersion exception is ambiguous Created: 26/May/11  Updated: 26/May/11  Resolved: 26/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Duplicate Votes: 0
Labels: None


 Description   

We had the situation any FIX sessions were immediately logged out with the reason "Incorrect BeginString". But the session was configured to use "FIX.4.4" and the incoming message came with "FIX.4.4" so we wondered why this happened.

Finally, we found that the configured data dictionary had the wrong FIX version tag which was difficult to find.

Code analysis results:

  • The logout reason "Incorrect BeginString" is sent if the exception UnsupportedVersion is thrown.
  • This exception is sent on two quite different occasions:
    • Incoming BeginString does not match the session configuration.
    • On validate, configured data dictionary does not match the session configuration.
  • In both cases, the same undifferentiated exception is thrown.

Possible improvements:

  • Provide differentiating reason text to the UnsupportedVersion exception.


 Comments   
Comment by Jörg Thönnes [ 26/May/11 ]

Duplicate by mistake of Mylyn JIRA connector.





[QFJ-604] Logout reason "Incorrect BeginString" on UnsupportedVersion exception is ambiguous Created: 26/May/11  Updated: 26/May/11  Resolved: 26/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Duplicate Votes: 0
Labels: None


 Description   

We had the situation any FIX sessions were immediately logged out with the reason "Incorrect BeginString". But the session was configured to use "FIX.4.4" and the incoming message came with "FIX.4.4" so we wondered why this happened.

Finally, we found that the configured data dictionary had the wrong FIX version tag which was difficult to find.

Code analysis results:

  • The logout reason "Incorrect BeginString" is sent if the exception UnsupportedVersion is thrown.
  • This exception is sent on two quite different occasions:
    • Incoming BeginString does not match the session configuration.
    • On validate, configured data dictionary does not match the session configuration.
  • In both cases, the same undifferentiated exception is thrown.

Possible improvements:

  • Provide differentiating reason text to the UnsupportedVersion exception.


 Comments   
Comment by Jörg Thönnes [ 26/May/11 ]

Duplicate by mistake of Mylyn JIRA connector.





[QFJ-603] Logout reason "Incorrect BeginString" on UnsupportedVersion exception is ambiguous Created: 26/May/11  Updated: 19/Nov/12  Resolved: 16/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File clipboard.txt     Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip     File QFJ-603.patch    
Issue Links:
Duplicate
is duplicated by QFJ-574 Logout reason "Incorrect BeginString"... Closed

 Description   

We had the situation any FIX sessions were immediately logged out with the reason "Incorrect BeginString". But the session was configured to use "FIX.4.4" and the incoming message came with "FIX.4.4" so we wondered why this happened.

Finally, we found that the configured data dictionary had the wrong FIX version tag which was difficult to find.

Code Analysis

  • The logout reason "Incorrect BeginString" is sent if the exception UnsupportedVersion is thrown.
  • This exception is sent on two quite different occasions:
    • Incoming BeginString does not match the session configuration.
    • On validate, configured data dictionary does not match the session configuration.
  • In both cases, the same undifferentiated exception is thrown.

Improvements

  • Provide differentiating reason text to the UnsupportedVersion exception:
    • If the message version does not match the data dictionary version on message validation, then:
      • "Message version ' {1}' does not match the data dictionary version '{2}'"
        ** If the message version does not match the configured FIX session version on incoming messages, then:
        *** "Message version '{1}

        ' does not match the configured FIX session version '

        {2}

        '"



 Comments   
Comment by Jörg Thönnes [ 06/Jun/11 ]

Initial analysis.

Comment by Jörg Thönnes [ 11/Jun/11 ]

Extended DataDictionaryTest adding testMessageDataDictionaryMismatch which check that the UnsupportedVersion exception without any description is thrown. This is to check the current state.

But I also found that if bodyOnly is true, the data dictionary is not checked though used. This is unexpected
and should considered as wrong. Comments?

Comment by Jörg Thönnes [ 22/Jun/11 ]

Patch to add description to the UnsupportedVersion exception and
supply a unit test for it.

Comment by Jörg Thönnes [ 07/Aug/11 ]

Moved to a later version since we ran out of time.

Comment by Christoph John [ 14/Nov/12 ]

Attached suggested patch against trunk: !QFJ-603.patch

Comment by Jörg Thönnes [ 15/Nov/12 ]
  • applied patch
  • run units tests
  • committed code changes
Comment by Jörg Thönnes [ 16/Nov/12 ]

Resolving this issue as the build is now stable:





[QFJ-602] New setting to allow to split ResendRequest Created: 24/May/11  Updated: 15/Nov/12  Resolved: 24/May/11

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

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Some venues (CME, Currenex) reject ResendRequest if the requested number of messages if above a predefined value.
A new setting is being added ResendRequestChunkSize specify the maximum number of messages being requested.
If the gap is greater than this limit, ResendRequest will be splitted.



 Comments   
Comment by Eric Deshayes [ 24/May/11 ]

committed in rev#1038





[QFJ-601] FIX protocol version 4.4 filed InstrAttribType (871) should include the types described in "Description" section. Created: 24/May/11  Updated: 15/Nov/12  Resolved: 06/Jun/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0, 1.5.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Andrey Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: QuickfixJ

Attachments: Zip Archive mylyn-context.zip     Zip Archive mylyn-context.zip    

 Description   

Documentation Links
http://www.onixs.biz/tools/fixdictionary/4.4/tagNum_871.html
http://fixprotocol.org/FIXimate3.0/en/FIX.4.4/tag871.html

The Types which I didn't find in InstrAttribType (871) field in FIX44.xml file are:
<value enum="10" description="ORIGINAL_ISSUE_DISCOUNT"/>
<value enum="11" description="CALLABLE_PUTTABLE"/>
<value enum="12" description="ESCROWED_TO_MATURITY"/>
<value enum="13" description="ESCROWED_TO_REDEMPTION_DATE"/>
<value enum="14" description="PRE_REFUNDED"/>
<value enum="15" description="IN_DEFAULT"/>
<value enum="16" description="UNRATED"/>
<value enum="17" description="TAXABLE"/>
<value enum="18" description="INDEXED"/>
<value enum="19" description="SUBJECT_TO_ALTERNATIVE_MINIMUM_TAX"/>
<value enum="20" description="ORIGINAL_ISSUE_DISCOUNT_PRICE_SUPPLY_PRICE_IN_THE_INSTRATTRIBVALUE"/>
<value enum="21" description="CALLABLE_BELOW_MATURITY_VALUE"/>
<value enum="22" description="CALLABLE_WITHOUT_NOTICE_BY_MAIL_TO_HOLDER_UNLESS_REGISTERED"/>
<value enum="99" description="TEXT_SUPPLY_THE_TEXT_OF_THE_ATTRIBUTE_OR_DISCLAIMER_IN_THE_INSTRATTRIBVALUE"/>

Missing data affect error-checking in the InstrAttribType (871) field further in the code.



 Comments   
Comment by Eric Deshayes [ 26/May/11 ]

Committed in rev#1040

Comment by Jörg Thönnes [ 26/May/11 ]

In reply to comment #1:
> Committed in rev#1040

Ha! You were faster than me. Just picked this up.

How about replacing

      <value enum="20" description="ORIGINAL_ISSUE_DISCOUNT_PRICE_SUPPLY_PRICE_IN_THE_INSTRATTRIBVALUE"/>
      <value enum="99" description="TEXT_SUPPLY_THE_TEXT_OF_THE_ATTRIBUTE_OR_DISCLAIMER_IN_THE_INSTRATTRIBVALUE"/>

by

      <value enum="20" description="ORIGINAL_ISSUE_DISCOUNT_PRICE"/>
      <value enum="99" description="TEXT"/>

as specified in the FIXimate? To me this very long text makes no sense. I think it was
generated by some automatic conversion tool from the FIX 5.0 spec:

20 = Original issue discount price. Supply price in the InstrAttribValue (872) field
21 = Callable below maturity value
22 = Callable without notice by mail to holder unless registered
99 = Text. Supply the text of the attribute or disclaimer in the InstrAttribValue (872) field.

In addition, I would also adapt FIX 5.0 in due course.

Comment by Jörg Thönnes [ 06/Jun/11 ]

Renamed enum constants for FIX 4.4 and FIX 5.0 field 871/InstrAttribType. The trailing part of the name
for value 20 and 99 was append by mistake. In the FIXimate, this part is just an extra comment and not
part of the name.





[QFJ-600] TradingSessionStatus is considered as an admin message Created: 12/May/11  Updated: 20/May/11  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Eric Deshayes Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Following QFJ-431, TradingSessionStatus is reported by the MessageUtils.isAdminMessage as an admin message.
This is wrong.
Also, Session has a method isAdminMessage that is a duplicate of the other one.
The latter will be removed and instead the MessageUtils.isAdminMessage will be called.



 Comments   
Comment by Eric Deshayes [ 12/May/11 ]

committed on the integration branch in rev#1032





[QFJ-599] make quickfixj artifacts into osgi bundles Created: 06/May/11  Updated: 02/Apr/15  Resolved: 09/Jun/14

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

Type: Improvement Priority: Default
Reporter: Andrei Pozolotin Assignee: amichair
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Requires
requires QFJ-499 Modify build system to use Maven Closed

 Description   

spring did not convert it:
http://ebr.springsource.com/repository/app/search?query=quickfixj

but since you are converting to maven:
http://www.quickfixj.org/jira/browse/QFJ-499

you could also use bundle plugin as part of maven conversion:
http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html






[QFJ-598] Make Quickfix/J transport layer pluggable in order to replace MINA by other IO frameworks as Netty or Grizzly Created: 06/May/11  Updated: 03/Sep/13

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

Type: Improvement Priority: Default
Reporter: Andrei Pozolotin Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None


 Description   

Besides MINA there are some other Java IO frameworks as

In order to use them in the QF/J engine we need to create some API to make the IO framework pluggable.

Steps

  • Replace current MINA transport by hard-wired Netty transport:
  • Compare original code base with changed required to replace MINA by Netty:
    • In this way we could deduce some API requirements.
  • Replace MINA by Grizzly and refine API.
  • Also consider MINA 2.0 integration:
    • QFJ-664: Upgrade MINA from 1.1.8 to 2.0.4


 Comments   
Comment by Luca Burgazzoli [ 26/Feb/13 ]

Hi,
I think the modularity of the transport layer makes lot of sense thus I've create a little project that tries to integrate a netty based transport with quickfixj without have to change the quickfixj code itself (do not know if possible, I'll get it soon), you can find it on github:

http://github.com/lburgazzoli/lb-quickfixj

Comment by Jörg Thönnes [ 13/Mar/13 ]

In reply to comment #1:
> [...]
>
> http://github.com/lburgazzoli/lb-quickfixj

Sounds like a good start. Did you make some progress here?

Comment by Luca Burgazzoli [ 03/Sep/13 ]

Not so much progress here as I was busy on some other stuffs.

I'll start working again on it soon as on side project I've also did some test with reactor-tcp https://github.com/reactor/reactor as foundation for the communication layer and it works very well.

In my humble opinion it is time to:

  • define transport API
  • split transport from core




[QFJ-597] move to github Created: 06/May/11  Updated: 02/Apr/15  Resolved: 09/Jun/14

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

Type: Improvement Priority: Default
Reporter: Andrei Pozolotin Assignee: amichair
Resolution: Fixed Votes: 7
Labels: None

Issue Links:
Relates
is related to QFJ-783 Update documentation and website to r... Closed

 Description   

please consider moving quickfixj and openfast sources to github as part of migration to maven in the upcoming v. 1.6.0



 Comments   
Comment by Grant Birchmeier [ 06/May/11 ]

This is not a bug.

Send your questions and comments to the QF/J users mailing list.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Comment by Andrei Pozolotin [ 06/May/11 ]

yes.
it says: "Issue Type: Improvement"
may be you can let peole vote for this before you close it?

Comment by Grant Birchmeier [ 06/May/11 ]

Yeah, you're right. That was a bad call for this one. Reopened. Let the voting commence.

Comment by Andrei Pozolotin [ 06/May/11 ]

thank you!

Comment by Grant Birchmeier [ 16/Oct/12 ]

I am now on the GitHub bandwagon. I use it for QF/n, and I can't imagine managing the project without it. I am glad Andrei asked me to reopen this bug

Comment by amichair [ 06/May/14 ]

+1 for migration to git (whether on github or sourceforge). svn2git makes the migration quite easy.

Comment by Christoph John [ 06/May/14 ]

Still volunteers wanted

Comment by amichair [ 06/May/14 ]

Which part do you need help with? shall I pm you?

Comment by Christoph John [ 06/May/14 ]

PM'ed you.

Comment by amichair [ 09/Jun/14 ]

The official repo has been migrated to Git and moved to https://github.com/quickfix-j/quickfixj.

The old Subversion repo is still available (read-only) in case someone needs to look it up.

I'll leave this issue open though until the website, docs etc. are all updated with the new repo info.

Comment by amichair [ 09/Jun/14 ]

Closing after all, since QFJ-783 will track the website/docs update.





[QFJ-596] quickfixj modularity Created: 06/May/11  Updated: 06/May/11  Resolved: 06/May/11

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

Type: Improvement Priority: Default
Reporter: Andrei Pozolotin Assignee: Grant Birchmeier
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hello;

please let me know if there are any plans to make quickfixj more modular?

for example, I would like to replacae mina with netty;

thanks

Andrei



 Comments   
Comment by Grant Birchmeier [ 06/May/11 ]

This is not a bug.

Send your questions to the QF/J users mailing list.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Comment by Andrei Pozolotin [ 06/May/11 ]

yes.
it says: "Issue Type: Improvement"
may be you can let peole vote for this before you close it?

Comment by Grant Birchmeier [ 06/May/11 ]

Maybe that was hasty, but I've seen a handful of people submitting questions as bugs when they shouldn't be.

Instead of a vague idea like "more modular", maybe you could re-submit as a more concrete idea. For instance, instead of using your netty/mina idea as an example, why don't you suggest that exactly as your improvement?

If you see other opportunities for modularity, submit those as separate items.

If you just want to spitball/solicit ideas with other people, then the mailing list is probably best.

Comment by Andrei Pozolotin [ 06/May/11 ]

cool, got it.

is this better?
http://www.quickfixj.org/jira/browse/QFJ-598





[QFJ-595] Add a new optional setting to bypass the incoming FIX message validation against the dictionary Created: 06/May/11  Updated: 20/May/11  Resolved: 20/May/11

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

Type: New Feature Priority: Default
Reporter: Eric Deshayes Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

A new setting SETTING_VALIDATE_INCOMING_MESSAGE, set by default to "Y" can be used to bypass the dictionary validation.



 Comments   
Comment by Eric Deshayes [ 12/May/11 ]

committed on the integration branch in rev #1031





[QFJ-594] Ant Test target must let the user know that any test failed Created: 05/May/11  Updated: 15/Nov/12  Resolved: 25/May/11

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

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: ant, build


 Description   

Today, it displays build successfull even if a unit test has failed.



 Comments   
Comment by Eric Deshayes [ 05/May/11 ]

committed in rev#1030

The fix consists in adding a new target called 'checkfailures'.
This target is called if:

  • at the end of the test target (running both the unit and acceptance tests)
  • at the end of the unit tests if the test.unit target is called
  • at the end of the acceptance tests if the test.acceptance target is called
Comment by Eric Deshayes [ 25/May/11 ]

Fixed in rev#1039





[QFJ-593] Can QuickFixJ be configured with proxool join with JNDI Created: 05/May/11  Updated: 05/May/11  Resolved: 05/May/11

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

Type: Other Priority: Default
Reporter: Soledad Calvo Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I have configured QuickFixJ to use JDBC store to persist FIX messages. I am using Websphere 7 that it doesn't provided a pooling connection. According to the documentation I need to use proxool.jar

I've seen qFJ uses proxool when you don't use JNDI. Is this true?



 Comments   
Comment by Grant Birchmeier [ 05/May/11 ]

This is not a bug.

If you need help, please send questions to the quickfixj-users mailing list.
https://lists.sourceforge.net/lists/listinfo/quickfixj-users

Comment by Grant Birchmeier [ 05/May/11 ]

Not a bug.





[QFJ-592] (FIXT .1.1) Application version id can be tested before a previous logon message that sets the default has completed (race condition) Created: 04/May/11  Updated: 04/Dec/12  Resolved: 04/Dec/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Christopher Hurst Assignee: Christoph John
Resolution: Fixed Votes: 1
Labels: WorkFlow
Environment:

Found on Windows XP but not OS dependent


Issue Links:
Relates
relates to QFJ-721 non-FIXT sessions: NPE accessing Appl... Resolved

 Description   

This has been mentioned on the mailing list with no feedback so ...

Ref: FIX Session protocol Version (FIXT) 1.1. Errata

In a FIX logon 1137,1147,1408 tags can set defaults for use in future FIX messages e.g. DefaultApplVerID, the behaviour I was seeing was that
it was possible for preprocessing on future messages to occur before the logon was fully processed (race condition) and occasionally I would
get this error message even though I was replaying identical messages (timing\thread delay is the variant) ...

"12-Apr-2011 15:06:51 quickfix.mina.AbstractIoHandler messageReceived
SEVERE: Invalid message: Can't determine ApplVerID for message"

In the debugger it was obvious the thread setting ApplVerID was free to "race" the thread doing preprocessing on the subsequent message i.e
doing a get on ApplVerID, I have only reproduced this in test scenarios (though I can do it every time) as usually delay in comms etc I think
would be enough the setter always wins the race. Even if this is not real world its still a problem in debugging and unit testing, I was
actually trying to track another of my bugs but this one made that very difficult. I believe its only safe to test application version when any previous logon has completed.

The ApplVerID is set in next(Message message) in Session,java

if (msgType.equals(MsgType.LOGON)) {
if (sessionID.isFIXT())

{ targetDefaultApplVerID.set(new ApplVerID(message .getString(DefaultApplVerID.FIELD))); }

else

{ targetDefaultApplVerID.set(MessageUtils.toApplVerID(beginString)); }

}

if you put a break point on the above you'll see the next message in (different thread) can still call
ApplVerID getApplVerID(Session session, String messageString) in MessageUtils which logs that error (the set should have occurred before the get) and in my case the missing (failed validation) message killed the session.
Just using the client in debug on Eclipse with a free running Server was enough to cause a 50% failure rate with the break point it was 100% obviously.

This method in my case fails as in my workflow the default appl ver id was required to be known (which would be set by the logon).
The two fixes messages are not being executed in parallel obviously its just the up front initial verification of the second message that is that
causes the issue i.e. we are validating too early.



 Comments   
Comment by Jörg Thönnes [ 29/Nov/12 ]

QFJ-721 is most probably related, but it may occur for pre-FIX.5.0 messsages.

Comment by Christoph John [ 04/Dec/12 ]

Committed as rev. 1110.





[QFJ-591] Can multiple SocketAcceptPort be mapped to one SocketConnectPort Created: 03/May/11  Updated: 03/May/11

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

Type: Improvement Priority: Default
Reporter: Sasmit Sahu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, session


 Description   

Hi,

We have a requirement where we have one SocketConnectPort, SenderCompID and TargetCompID three diffrent internal testing environment.We need atleast 3 distinct sessions to cater to each of our internal environment.But as we have only one SocketConnectPort, how can we create 3 distinct session with same SenderCompID and TargetCompID ?Is it possible map multiple SocketAcceptPort be mapped to one SocketConnectPort.Or is there some obvious way to solve this issue which I am missing.

Thanks in advance.



 Comments   
Comment by Steve Bate [ 03/May/11 ]

I you have 3 distinct sessions, you should have 3 distinct session identifiers. Each of the distinct sessions can connect to the same acceptor port.





[QFJ-590] Incorrect BeginString set in quickfix.fix50.Message class [getHeader().setField(new BeginString("FIXT.1.1")); Created: 03/May/11  Updated: 15/Nov/12  Resolved: 03/May/11

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

Type: Bug Priority: Default
Reporter: Fabio Bernasconi Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

quickfixj [windows/unix]



 Description   

The BeginString is mistakenly set to 'FIX.1.1' in the quickfix.fix50.Message class. In other Message classes in the packages quickfix.fix* it is correctly set.
Solution: getHeader().setField(new BeginString("FIXT.5.0"));



 Comments   
Comment by Steve Bate [ 03/May/11 ]

This is the correct BeginString for FIX 5.0. The begin string identifies the transport protocol, which is FIXT.1.1 for FIX 5.0.





[QFJ-589] Remove the Quickfix/J forceResync setting and replace it with a ValidateSequenceNumbers setting Created: 03/May/11  Updated: 15/Nov/12  Resolved: 20/May/11

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

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-570 Inappropriate sequence resync Closed

 Description   

The ForceResync option has been introduced by QFJ-427.
After discussion between the developers, it has been agreed to replace it by a new setting ValidateSequenceNumbers defaulting to true.
When the setting ValidateSequenceNumbers is set to false, no check (check too high or check to low) will be done on the incoming seq num (but the store will not be artificially synched to the actual received seq num).



 Comments   
Comment by Eric Deshayes [ 05/May/11 ]

committed in rev#1029





[QFJ-588] Build failed due to a quickfix.codegen.CodeGenerationException: InstrumentLeg.java (The requested operation cannot be performed on a file with a user-mapped section open) Created: 26/Apr/11  Updated: 15/Nov/12  Resolved: 25/May/11

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

Type: Bug Priority: Critical
Reporter: Navdeep Jhajj Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: QuickfixJ
Environment:

I'm running on a windows XP SP3 environment and using quickfixj-1.50-src for the build and apache-ant-1.8



 Description   

The build did not work due to this error when I tried to build via Eclipse. I tried building outside of eclipse using the ant build: "ant jar" targeting the main build.jar in the quickfixj root. Initially, the build seemed to work but then later I started getting errors. I tried rebooting and tried different machines but keep seeming to get the same problem.

Any help would be greatly appreciated.



 Comments   
Comment by Steve Bate [ 25/May/11 ]

This is usually caused because something else has the file locked (maybe antivirus).





[QFJ-587] Issues with session log files Created: 12/Apr/11  Updated: 27/Apr/11

Status: Open
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Prabavathy Arumugam Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: QuickfixJ, sequnece, ses, session
Environment:

Solaris 10, webMethods Integration server 7.2



 Description   

I have a question on the session logs maintained by Quickfixj. We have FIX engine built on webMethods Integration servers and there are two instances of FIX engine running on two servers in parallel. The session log files are shared between the FIX engines so that the failover can be handled seamlessly. The FIX engines are configured to start up at 7:00 AM and they shut down at 7:00 PM. The session logs are not deleted at the end of the day as the Quickfixj can handle the session startup and shutdown on its own. We observed that sometimes when the session comes up in the morning, the sequence numbers starts at 1 but does not increment. That is, the FIX engine sends sequence no 1 to the client followed by sequence no reset message continuously, until the session log files are manually deleted and the FIX session is restarted. This happens at random, sometimes after being active for 3 days and sometimes after 15 days.

The logs look like,
2011-04-08 07:30:20,955|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110408-11:30:20.95556=****10=062
2011-04-08 07:30:31,113|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110408-11:30:31.11356=****10=050
2011-04-08 07:30:42,628|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110408-11:30:42.62856=****10=063
2011-04-11 07:30:00,887|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110411-11:30:00.88756=****10=058
2011-04-11 07:30:21,046|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110411-11:30:21.04656=****10=048
2011-04-11 07:30:31,201|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110411-11:30:31.20156=****10=042
2011-04-11 07:30:41,544|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110411-11:30:41.54456=****10=053
2011-04-12 07:30:00,875|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110412-11:30:00.87556=****10=056
2011-04-12 07:30:21,030|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110412-11:30:21.02956=****10=050
2011-04-12 07:30:31,182|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110412-11:30:31.18256=****10=051
2011-04-12 07:30:41,337|INFO|Admin Message sent to counter party: 8=FIX.4.49=5235=534=149=****52=20110412-11:30:41.33756=****10=054

Any suggestions or comments will be helpful. Is this a known issue? Or is there anything else that we can code for to avoid this? Thanks in advance.



 Comments   
Comment by Prabavathy Arumugam [ 27/Apr/11 ]

To update, We turned off the FIX engine on one of the instance and let it run on only one server. It ran fine for the past 20 days and we had the sequence number issue happen again today. That is the sequence number started at 1:00 today morning but it did not increment after that. We had to delete the session logs and restart the FIX engine. Is this a limitation in quickfixj framework? Is there a workaround that we can try?

Thanks!!





[QFJ-586] SQL error when restarting QuickFIX/J session (java.sql.SQLException: ORA-00001: unique constraint violated) Created: 12/Apr/11  Updated: 25/Jul/14  Resolved: 25/Jul/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3, 1.5.0
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Thomas Kinch Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows/Linux



 Description   

I am using both 1.3.3 and 1.5.0 with an Oracle DB session/message store. I have set JdbcSessionIdDefaultPropertyValue="NA" and am seeing the row get created properly, but the imcoming_seqnum and outgoing_seqnum are not being updated, and when I restart the session I get a unique constraint violation. It appears that QuickFIX/J is using the 'null' session_qualifier rather than the JdbcSessionIdDefaultPropertyValue value for evaluating whether or not to create a new row. Am I going to be forced to set all of the session fields (LocId and SessionQualifier) to non-null values to get QuickFIX/J working properly with Oracle?



 Comments   
Comment by Varun Sud [ 25/Jul/13 ]

I encountered exactly the same problems:
1. Incoming/ outgoing message sequence is not updated in Oracle DB. It was working fine with Derby which I was using previously.
2. On re-starting the session, a unique constraint violation is reported

It turned out that I was using the CHAR datatype for the BEGINSTRING column of SESSIONS table. This would have happened because I used the MySQL scripts, modified them for Derby and then for Oracle. Switching all text fields to VARCHAR2 type solved the problem for me. CHAR datatype apparently is fixed length in Oracle, so subsequent queries must also be blank-padded.

Would it be useful to add standard scripts for Derby and Oracle? (log table scripts are not available for Oracle currently)

Comment by Colin DuPlantis [ 24/Jul/14 ]

I think this issue can be closed in 1.5.3. I just tested Oracle with the provided Oracle scripts and JdbcSessionIdDefaultPropertyValue. No problems with seq num and restarts.

Comment by Christoph John [ 25/Jul/14 ]

Thanks for the hint.





[QFJ-585] TradeCaptureReport.NoSides parsing fail Created: 08/Apr/11  Updated: 20/Dec/13  Resolved: 20/Dec/13

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

Type: Other Priority: Default
Reporter: Cédric Jeanroy Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Linux, quickfixj 1.5.0, FIX44


Issue Links:
Duplicate
duplicates QFJ-620 Problem validating Fix 4.4. TradeCapt... Closed

 Description   

Dear all,

We are implementing connectivity with the SWX market using the quickfixj library but we've got a problem with TradeCaptureReport messages.

We receive the following TradeCaptureReport message from SWX test platform :
8=FIX.4.4^A9=437^A35=AE^A34=14^A49=SwxRcg1.M01^A50=SwxObe.M01.1.1^A52=20110407-09:07:04.219^A56=SQBCH-02.M01^A369=1280^A15=CHF^A17=EFR1_A568775_0O621059_2^A22=4^A31=51.1^A32=124^A37=NONE^A48=CH0010675863^A54=2^A55=[N/A]^A60=20110407-09:07:03.899^A75=20110407^A150=0^A207=XSWX^A423=2^A447=D^A448=7698^A452=17^A453=1^A487=0^A570=N^A571=NONE^A572=157598^A856=1^A6520=D^A552=1^A54=1^A37=NONE^A453=1^A448=7698^A447=D^A452=7^A802=1^A523=12589^A803=25^A576=1^A577=0^A768=1^A769=20110407-07:06:00.000^A770=1^A10=176^A

The message seems to be well formed but we first have the following warn message :
Warn: incomming message with incorrect field: 552=2:

And when we try to call the method tradeCaptureReport.getGroup(2, noSidesGroup); we get :
quickfix.FieldNotFound: 552, index=2
at quickfix.FieldMap.getGroup(FieldMap.java:684)

We have the following FIX44.xml configuration:
<message name="TradeCaptureReport" msgtype="AE" msgcat="app">
<field name="TradeReportID" required="Y" />
<field name="TradeReportTransType" required="N" />
<field name="TradeReportType" required="N" />
<field name="TradeRequestID" required="N" />
<field name="TrdType" required="N" />
<field name="TrdSubType" required="N" />
<field name="SecondaryTrdType" required="N" />
<field name="TransferReason" required="N" />
<field name="ExecType" required="N" />
<field name="TotNumTradeReports" required="N" />
<field name="LastRptRequested" required="N" />
<field name="UnsolicitedIndicator" required="N" />
<field name="SubscriptionRequestType" required="N" />
<field name="TradeReportRefID" required="N" />
<field name="SecondaryTradeReportRefID" required="N" />
<field name="SecondaryTradeReportID" required="N" />
<field name="TradeLinkID" required="N" />
<field name="TrdMatchID" required="N" />
<field name="OrigTrdMatchID" required="N" />
<field name="ExecID" required="N" />
<field name="OrdStatus" required="N" />
<field name="SecondaryExecID" required="N" />
<field name="ExecRestatementReason" required="N" />
<field name="PreviouslyReported" required="Y" />
<field name="PriceType" required="N" />
<component name="Instrument" required="Y" />
<component name="FinancingDetails" required="N" />
<component name="OrderQtyData" required="N" />
<field name="QtyType" required="N" />
<component name="YieldData" required="N" />
<group name="NoUnderlyings" required="N">
<component name="UnderlyingInstrument" required="N" />
</group>
<field name="UnderlyingTradingSessionID" required="N" />
<field name="UnderlyingTradingSessionSubID" required="N" />
<field name="LastQty" required="Y" />
<field name="LastPx" required="Y" />
<field name="LastParPx" required="N" />
<field name="LastSpotRate" required="N" />
<field name="LastForwardPoints" required="N" />
<field name="LastMkt" required="N" />
<field name="TradeDate" required="Y" />
<field name="ClearingBusinessDate" required="N" />
<field name="AvgPx" required="N" />
<component name="SpreadOrBenchmarkCurveData" required="N" />
<field name="AvgPxIndicator" required="N" />
<component name="PositionAmountData" required="N" />
<field name="MultiLegReportingType" required="N" />
<field name="TradeLegRefID" required="N" />
<group name="NoLegs" required="N">
<component name="InstrumentLeg" required="N" />
<field name="LegQty" required="N" />
<field name="LegSwapType" required="N" />
<component name="LegStipulations" required="N" />
<field name="LegPositionEffect" required="N" />
<field name="LegCoveredOrUncovered" required="N" />
<component name="NestedParties" required="N" />
<field name="LegRefID" required="N" />
<field name="LegPrice" required="N" />
<field name="LegSettlType" required="N" />
<field name="LegSettlDate" required="N" />
<field name="LegLastPx" required="N" />
</group>
<field name="TransactTime" required="Y" />
<component name="TrdRegTimestamps" required="N" />
<field name="SettlType" required="N" />
<field name="SettlDate" required="N" />
<field name="MatchStatus" required="N" />
<field name="MatchType" required="N" />
<group name="NoSides" required="Y">
<field name="Side" required="Y" />
<field name="OrderID" required="Y"/>
<field name="SecondaryOrderID" required="N" />
<field name="ClOrdID" required="N" />
<field name="SecondaryClOrdID" required="N" />
<field name="ListID" required="N" />
<field name="TradeTypeCodeList" required="N" />
<component name="Parties" required="N" />
<field name="Account" required="N" />
<field name="AcctIDSource" required="N" />
<field name="AccountType" required="N" />
<field name="ProcessCode" required="N" />
<field name="OddLot" required="N" />
<group name="NoClearingInstructions" required="N">
<field name="ClearingInstruction" required="N" />
</group>
<field name="ClearingFeeIndicator" required="N" />
<field name="TradeInputSource" required="N" />
<field name="TradeInputDevice" required="N" />
<field name="OrderInputDevice" required="N" />
<field name="Currency" required="N" />
<field name="ComplianceID" required="N" />
<field name="SolicitedFlag" required="N" />
<field name="OrderCapacity" required="N" />
<field name="OrderRestrictions" required="N" />
<field name="CustOrderCapacity" required="N" />
<field name="OrdType" required="N" />
<field name="ExecInst" required="N" />
<field name="TransBkdTime" required="N" />
<field name="TradingSessionID" required="N" />
<field name="TradingSessionSubID" required="N" />
<field name="TimeBracket" required="N" />
<component name="CommissionData" required="N" />
<field name="GrossTradeAmt" required="N" />
<field name="NumDaysInterest" required="N" />
<field name="ExDate" required="N" />
<field name="AccruedInterestRate" required="N" />
<field name="AccruedInterestAmt" required="N" />
<field name="InterestAtMaturity" required="N" />
<field name="EndAccruedInterestAmt" required="N" />
<field name="StartCash" required="N" />
<field name="EndCash" required="N" />
<field name="Concession" required="N" />
<field name="TotalTakedown" required="N" />
<field name="NetMoney" required="N" />
<field name="SettlCurrAmt" required="N" />
<field name="SettlCurrency" required="N" />
<field name="SettlCurrFxRate" required="N" />
<field name="SettlCurrFxRateCalc" required="N" />
<field name="PositionEffect" required="N" />
<field name="Text" required="N" />
<field name="EncodedTextLen" required="N" />
<field name="EncodedText" required="N" />
<field name="SideMultiLegReportingType" required="N" />
<group name="NoContAmts" required="N">
<field name="ContAmtType" required="N" />
<field name="ContAmtValue" required="N" />
<field name="ContAmtCurr" required="N" />
</group>
<component name="Stipulations" required="N" />
<group name="NoMiscFees" required="N">
<field name="MiscFeeAmt" required="N" />
<field name="MiscFeeCurr" required="N" />
<field name="MiscFeeType" required="N" />
<field name="MiscFeeBasis" required="N" />
</group>
<field name="ExchangeRule" required="N" />
<field name="TradeAllocIndicator" required="N" />
<field name="PreallocMethod" required="N" />
<field name="AllocID" required="N" />
<group name="NoAllocs" required="N">
<field name="AllocAccount" required="N" />
<field name="AllocAcctIDSource" required="N" />
<field name="AllocSettlCurrency" required="N" />
<field name="IndividualAllocID" required="N" />
<component name="NestedParties2" required="N" />
<field name="AllocQty" required="N" />
</group>
</group>
<field name="CopyMsgIndicator" required="N" />
<field name="PublishTrdIndicator" required="N" />
<field name="ShortSaleReason" required="N" />
<field name="Currency" required="N" />
</message>

Is this a bug of the quickfixj library or is there something misconfigured on our side ?

Thanks for your help



 Comments   
Comment by Jörg Thönnes [ 11/Apr/11 ]

According to the provided FIX message the fiels 552/NoSides is set to the value 1.
Therefore, this repeating group has one member and getting the second member using
tradeCaptureReport.getGroup(2, noSidesGroup) is expected to fail since the 2nd member
does not exist.

What do you expect?

Comment by Cédric Jeanroy [ 11/Apr/11 ]

Thanks for you reply. I just realized I don't send the good FIX message within the issue.

I firstly have the following log. The message contain the field 552=2.
[11/04/11 11:50:42.690] INFO [IoProcessor-0.0] [incoming] FIX.4.4:SQBCH-02.M01->SwxRcg1.M01: 8=FIX.4.4^A9=438^A35=AE^A34=865^A49=SwxRcg1.M01^A56=SQBCH-02.M0
1^A52=20110411-09:50:42.686^A50=SwxObe.M01.1.1^A369=2299^A15=CHF^A17=EFR1_A571495_0O622614_2^A22=4^A31=51.1^A32=203^A48=CH0010675863^A55=[N/A]^A60=20110411-0
9:50:42.380^A75=20110411^A150=0^A207=XSWX^A423=2^A487=0^A570=N^A571=NONE^A572=158477^A856=1^A552=2^A54=1^A37=NONE^A453=1^A448=7698^A447=D^A452=7^A802=1^A523=
12589^A803=25^A576=1^A577=0^A6520=D^A54=2^A37=NONE^A453=1^A448=7698^A447=D^A452=17^A768=1^A769=20110411-06:50:00.000^A770=1^A10=209^A

Then just after I get the following log. This is the same message, the only difference is tag 552=1. I supposed this second message is generated by the quickfix library after some parsing. Is it right ?
[11/04/11 11:50:42.887] ERROR [ssage Processor] [errorEvent] FIX.4.4:SQBCH-02.M01->SwxRcg1.M01: Warn: incomming message with incorrect field: 552=2: 8=FIX.4.
4^A9=438^A35=AE^A34=865^A49=SwxRcg1.M01^A50=SwxObe.M01.1.1^A52=20110411-09:50:42.686^A56=SQBCH-02.M01^A369=2299^A15=CHF^A17=EFR1_A571495_0O622614_2^A22=4^A31
=51.1^A32=203^A37=NONE^A48=CH0010675863^A54=2^A55=[N/A]^A60=20110411-09:50:42.380^A75=20110411^A150=0^A207=XSWX^A423=2^A447=D^A448=7698^A452=17^A453=1^A487=0
^A570=N^A571=NONE^A572=158477^A856=1^A6520=D^A552=1^A54=1^A37=NONE^A453=1^A448=7698^A447=D^A452=7^A802=1^A523=12589^A803=25^A576=1^A577=0^A768=1^A769=2011041
1-06:50:00.000^A770=1^A10=208^A

So, my question is why this tag has been changed from 552=2 to 552=1 ?
As you explain in your previous post this is the reason why I get quickfix.FieldNotFound exception.

Thanks in adavance for your help.





[QFJ-584] Repeated test request with dynamic acceptor Created: 03/Apr/11  Updated: 05/Apr/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Other Priority: Major
Reporter: Information Management Experts Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP



 Description   

Dear All,

Our application is Client-Server System. Multiple clients(initiators) connect to the server (dynamic acceptor) to exchange fix messages.
We don't have physical configuration file; we create it at runtime. Our server(as initiator) also connects to other external server(second party).
Our clients can connect to the server through internal or external network and up to 10 concurrent clients may connect to the server.When we was using threads to send and receive messages, the client was sending test request and sometimes login request(when the server didn't respond to the client test request). after we removed the threads, the problem became less but still occurring.
Our time zone is Asia/Amman (GMT+2), but we still using default UTC.Below you will find our configuration file

  1. Acceptor Configuration

[DEFAULT]

StartTime=05:00:00

EndTime=05:00:00

FileStorePath=Settings/FIXStorage/AcceptorStore

FileLogPath=Settings/FIXStorage/AcceptorStore

DataDictionary=data/tools/IMEXQuickFIXDialect42.xml

ValidateUserDefinedFields=Y

CheckLatency=N

ConnectionType=acceptor

SocketAcceptPort=2025

[SESSION]

BeginString=FIX.4.2

SenderCompID=FIX

TargetCompID=*

AcceptorTemplate=Y

  • Initiator Configuration

[DEFAULT]

StartTime=05:00:00

EndTime=05:00:00

FileStorePath=Settings/FIXStorage/InitiatorStore

FileLogPath=Settings/FIXStorage/InitiatorStore

DataDictionary=data/tools/IMEXQuickFIXDialect42.xml

ValidateUserDefinedFields=Y

CheckLatency=N

ConnectionType=initiator

ReconnectInterval=5

HeartBtInt=5

SocketConnectHost=123.123.123.123

SocketConnectPort=2025

[SESSION]

BeginString=FIX.4.2

SenderCompID= – GENERATED AT RUNTIME

TargetCompID=FIX

Thanks in advanced for your help ...



 Comments   
Comment by Laurent Danesi [ 05/Apr/11 ]

Hi,

I saw your post but I'm not sure to well understand.
What do you mean by "When we was using threads to send and receive messages"? is it ThreadedSocketAcceptor?

Regards,

Laurent DANESI
Chief Architect
smartTrade Technologies

Comment by Information Management Experts [ 05/Apr/11 ]

Dear Laurent,

First of all, thanks for your reply.

No, we didn't use ThreadedSocketAcceptor. We were creating new threads in the implementation of Application.fromApp method and when we were calling Session.sendToTarget(message, sessionID);

Also we were sending huge no of orders at the same time(up to 1000) from the external server, which means when each order arrives to our server, our server will start new thread to handle the message, then a new thread will be created to send the message again for each client.





[QFJ-583] Session.forceStoreResync doesn't check persistMessages Created: 31/Mar/11  Updated: 31/Mar/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Dmitri Lenna Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows & Linux.



 Description   

We set the "ForceResync" to true and "PersistMessages" to false. Attempting connect to a target with a different sequence number, we get a logout message with the expected sequence number and the following is called:

(in Session.java):
private void forceStoreResync(int nextTargetMsgSeqNum, int nextSenderMsgSeqNum )

in that method, a heartbeat message is created for each missing sequence number and it's stored in the Message Store without checking if persisteMessage is true.

Is there a reason for this or this a bug? If it's a bug, I'd suggest this fix:

Line 1601:

  • if (actualSenderMsgSeqNum < nextSenderMsgSeqNum) {
    + if (actualSenderMsgSeqNum < nextSenderMsgSeqNum && persistMessages ) {

Thank you.






[QFJ-582] Converters improvement for better performance Created: 30/Mar/11  Updated: 29/May/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: Future Releases

Type: Improvement Priority: Default
Reporter: Abla Nait Assignee: Eric Deshayes
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Improve performance converters (double, int) and add tests to cover all cases.



 Comments   
Comment by Jörg Thönnes [ 30/Mar/11 ]

Hi Nait,

what kind of performance improvements you are planning. I have also some thoughts collected over the last years.

Cheers, Jörg

Comment by Abla Nait [ 30/Mar/11 ]

Remove Matcher in double converter and verify only if the first charater is not '+', other cases will be handled by parseDouble; and ditto for int converter.

Comment by Abla Nait [ 30/Mar/11 ]

Hi Jorg,
this is mainly very focused parsing improvements that we've done after some profiling and that we are integrating to the trunk (as part of the integration of our changes).

I let you open another JIRA for other or deeper improvements.
We could have some talks about it to share your thoughts with ours.

Regards,
Abla

Comment by Steve Bate [ 26/Apr/11 ]

As we discussed on the developer list, the current converter implementation is not FIX-compliant. The purpose for the Regex match to validate the input before passing it to Double for parsing. If this is causing significant performance issues then we may want to implement a fast double parsing function that validates while is parses/converts the string to a double. We should also add a unit test that shows the conversion fails for formats like "1e6" (scientific notation) which is not allowed by FIX.

Comment by Eric Deshayes [ 29/Apr/11 ]

As discussed previously, changes have been reverted.
Committed in integration branch in Rev#1025.

Comment by Eric Deshayes [ 20/May/11 ]

As discussed, some improvement on the converters could be done but they should not change the FIX compliance.

Changes have been reverted and performance improvements will be handled later.





[QFJ-581] SessionConnector is logged on only if it has session Created: 25/Mar/11  Updated: 15/Nov/12  Resolved: 25/Mar/11

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

Type: Bug Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None


 Description   

SessionConnector should be logged if and only if:

  • it has sessions
  • all the sessions are logged on


 Comments   
Comment by Eric Deshayes [ 25/Mar/11 ]

the isLoggedOn also check the session logged on status





[QFJ-580] improve message group parsing Created: 25/Mar/11  Updated: 15/Nov/12  Resolved: 25/Mar/11

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

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None


 Description   

Parsing message group clones groups when it could be avoided.
Group retrieval also could return the group reference instead of having to instantiate a new group instance.






[QFJ-579] display the fix message in case of Length format error Created: 25/Mar/11  Updated: 15/Nov/12  Resolved: 25/Mar/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None


 Description   

When there is a length format error, it would be nice to see the full input FIX message.






[QFJ-578] use JMX for force test request, heartbeat and logout Created: 25/Mar/11  Updated: 15/Nov/12  Resolved: 25/Mar/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Improvement Priority: Default
Reporter: Eric Deshayes Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None


 Description   

For specific test, it is sometime needed to be able to force the sending of TestRequest, Heartbeat and Logout messages.






[QFJ-577] tags ApplID [1180] + ApplSeqNum [1181] to synchronise at the application FIX.5.0 SP2 M3 Created: 24/Mar/11  Updated: 24/Mar/11

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

Type: New Feature Priority: Default
Reporter: Soledad Calvo Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I am analyzing whether I can use quickFixJ to handle messages with my Counterparty. My Counterparty has FIX.5.0 SP2 M3 and does not support ResendRequest message.

http://www.fixprotocol.org/FIXimate3.0/en/FIX.5.0SP1/body_49485355.html?find=ApplSeqNum

To synchronise at the application level whith it I must use the tags ApplID [1180] + ApplSeqNum [1181] instead of Resend Request and Sequence Reset messages. Is there any way, without update quickFixJ, to adapt to this behavior?






[QFJ-576] Support for slf4j 1.6.3 Created: 11/Mar/11  Updated: 15/Nov/12  Resolved: 19/Oct/11

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

Type: Improvement Priority: Default
Reporter: Leonid Ilyevsky Assignee: Laurent Danesi
Resolution: Fixed Votes: 1
Labels: None


 Description   

Currently the 1.5.3 version is supported; it does not work with the official 1.6.1 release of slf4j.

Workaround: I made minor changes in the source and recompiled.



 Comments   
Comment by Laurent Danesi [ 19/Oct/11 ]

committed rev #1056





[QFJ-575] In configuration file, SocketAcceptPort property is inherited from the other session, not from "DEFAULT" Created: 11/Mar/11  Updated: 11/Mar/11

Status: Open
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Leonid Ilyevsky Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

According to documentation, any [SESSION] section of the configuration file will inherit all properties from the [DEFAULT] section.
However, I noticed that this is not true for, at least, SocketAcceptPort property.
Let say, I define a few acceptor sessions, and I skip SocketAcceptPort in one of them. Then it takes it not from DEFAULT section, but rather from the other session definition that has the same SenderCompID .
It probably makes sense as a feature (though I am not 100% sure), but in the documentation I could not find the explanation of this behavior.






[QFJ-574] Logout reason "Incorrect BeginString" on UnsupportedVersion exception is ambiguous Created: 25/Feb/11  Updated: 13/Nov/12  Resolved: 13/Nov/12

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

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-603 Logout reason "Incorrect BeginString"... Resolved

 Description   

We had the situation any FIX sessions were immediately logged out with the reason "Incorrect BeginString". But the session was configured to use "FIX.4.4" and the incoming message came with "FIX.4.4" so we wondered why this happened.

Finally, we found that the configured data dictionary had the wrong FIX version tag which was difficult to find.

Code analysis results:

  • The logout reason "Incorrect BeginString" is sent if the exception UnsupportedVersion is thrown.
  • This exception is sent on two quite different occasions:
    • Incoming BeginString does not match the session configuration.
    • On validate, configured data dictionary does not match the session configuration.
  • In both cases, the same undifferentiated exception is thrown.

Possible improvements:

  • Provide differentiating reason text to the UnsupportedVersion exception.





[QFJ-573] The text of an unrequested logout message is lost Created: 23/Feb/11  Updated: 08/Nov/12  Resolved: 07/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Tom Palmer Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File logout-text.patch    

 Description   

If the target sends an unrequested logout message the text of the message is lost as the event is logged as "Received logout request". This makes debugging these unexpected disconnects difficult.



 Comments   
Comment by Tom Palmer [ 23/Feb/11 ]

The attached patch checks for the presence of the Text field and will append this to the message if it is present.

Comment by Christoph John [ 08/Nov/12 ]

Committed as #1097.





[QFJ-572] RuntimeExceptions cause messages to be silently dropped Created: 04/Feb/11  Updated: 14/Nov/12  Resolved: 14/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: Stelios Papadopoulos Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: None


 Description   

An Invalid argument exception was thrown from methods invoked in fromApp()

java.lang.IllegalArgumentException: message 8=FIXT.1.1^A9=480^A35=d^A34=7528 ...
at package.removed.ApplicationImpl.fromApp(ApplicationImpl.java:46)
at quickfix.Session.fromCallback(Session.java:1361)
at quickfix.Session.verify(Session.java:1314)
at quickfix.Session.verify(Session.java:1390)
at quickfix.Session.next(Session.java:796)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
at java.lang.Thread.run(Thread.java:619)

This caused QuickFixJ to think that it never received the message. So on the next message the sequence was out of order:

2011-02-04 07:41:21,737 [QFJ Message Processor] INFO quickfixj.event - FIXT.1.1:IGMM-MD->NDXMD: MsgSeqNum too high, expecting 7528 but received 7529

QuickFixJ then requested the message again.

The Exception was caused by the contents of the message, so on reception of the offending message the same thing happened again.

I believe that the default behaviour should be to reject the message indicating some kind of application failure, or something else other than silently dropping the message which can cause a resend loop.



 Comments   
Comment by Thomas Wölfle [ 20/Sep/11 ]

We had exactly the same problem. In our case in a Groovy Class, which was a subclass of ApplicationAdapter, an exception has been thrown that resulted in the described behaviour. In our case it was not a RuntimeException but a CheckedException. Since Groovy does not distinguish between runtime and checked exceptions the exception was simply thrown up the call stack resulting in the described behaviour above. I.e. perhaps not only RuntimeExceptions but all Throwables have to be catched in 'quickfix.Session.next'

Comment by Christoph John [ 20/Dec/11 ]

I think this would be a good enhancement. Basically, the behaviour is in-line with the spec which says:
"The receiving application should disregard any message that is garbled, cannot be parsed or fails a data integrity check. Processing of the next valid FIX message will cause detection of a sequence gap and a Resend Request will be generated. Logic should be included in the FIX engine to recognize the possible infinite resend loop, which may be encountered in this situation."

The tricky part here might be to discover an infinite resend loop. But as a first step it might be a good improvement to generate a Reject or BusinessMessageReject message if there is a problem inside Session.next(). This should be configurable (on/off).

Comment by Grant Birchmeier [ 09/Oct/12 ]

Given Christoph's quote of the spec, it sounds like QF/J is only lacking the loop detection, correct? Aside from that, it's behaving appropriately.

An option to generate a reject seems like merely a workaround, and not an actual solution.

I'm more interested in the actual reject cause - why the hell would FromApp() be throwing an IllegalArgumentException? That sounds like a bug somewhere. Same for Thomas' report – why would message-parsing throw a CheckedException? These are exceptions that imply coding problems.

Comment by Thomas Wölfle [ 09/Oct/12 ]

As described in my initial comment the ApplicationAdapter in our System can be extended by Groovy classes. We do this in order to be able to dynamically add code to patch incoming or outgoing FIX messages via Groovy scripts. In such a Groovy script it might happen that a Java method is called that throws a checked exception. Catching checked exceptions is verified by the Java compiler but since Groovy is a dynamic language there is no compilation that verifies that no such methods are called. This results in checked exceptions that are thrown but never caught.

Comment by Christoph John [ 10/Oct/12 ]

I can understand Grant's point as well as Thomas's.

Maybe the configurable rejection can be a workaround for the time being and we will add the infinite-loop-detection in a later version (suggestions on how to dectect this are welcome ).

Comment by Thomas Wölfle [ 11/Oct/12 ]

We have solved our problem using the following patch which simply adds another catch block in the method Session.next(Message). It is almost the same code as in the catch block for 'FieldNotFound' exceptions.

— core/src/main/java/quickfix/Session.java (revision 1052)
+++ core/src/main/java/quickfix/Session.java (working copy)
@@ -1023,6 +1023,23 @@
if (resetOrDisconnectIfRequired(message))

{ return; }

+ } catch(final QuickfixRuntimeException e) {
+ getLog().onErrorEvent("Rejecting message because of FrontFIX problem: " + e + ": " + message);
+ if (resetOrDisconnectIfRequired(message))

{ + return; + }

+ if (sessionID.getBeginString().compareTo(FixVersions.BEGINSTRING_FIX42) >= 0
+ && message.isApp())

{ + generateBusinessReject(message, + BusinessRejectReason.APPLICATION_NOT_AVAILABLE, 0); + }

else {
+ if (msgType.equals(MsgType.LOGON))

{ + getLog().onErrorEvent("Required field missing from logon"); + disconnect("Required field missing from logon", true); + }

else

{ + generateReject(message, "Application not available"); + }

+ }········
}
·
nextQueued();
@@ -2478,4 +2495,9 @@
this.checkGapFieldOnAdminMessage = checkGapFieldOnAdminMessage;
}
·
-}
\ No newline at end of file
+ public static class QuickfixRuntimeException extends RuntimeException {
+ public QuickfixRuntimeException(String message, Throwable cause)

{ + super(message, cause); + }

+ }
+}

Comment by Christoph John [ 11/Oct/12 ]

Thanks for your input, but I was more referring to a suggestion for the loop-detection.
I have already prepared a similar patch which catches Throwables and is configurable.

Comment by Christoph John [ 14/Nov/12 ]

Committed as rev #1101.

  • Introduced session setting RejectMessageOnUnhandledException.
  • If enabled, an uncaught Exception or Error in the application's message processing will lead to a (BusinessMessage)Reject being sent to the counterparty and the incoming message sequence number will be incremented.
  • If disabled (default), a quickfix.RuntimeError is thrown, the problematic incoming message is discarded and the message sequence number is not incremented. Processing of the next valid message will cause detection of a sequence gap and a ResendRequest will be generated.




[QFJ-571] QFJ Timer - JDBCStore reset issues Created: 20/Dec/10  Updated: 08/Apr/14  Resolved: 08/Apr/14

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

Type: Bug Priority: Major
Reporter: Vid Cheruvu Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-645 Deadlock between message sending and ... Resolved
duplicates QFJ-700 QFJ Timer and QFJ message processor t... Closed

 Description   

Hi,

I have configured QuickFixJ to use JDBC store. In doing so, we have seen an issue with Proxool where it kills active thread that are longer than 5 minutes. We have no way to change the proxool's maximum-active-time property in Quickfixj configuration. When proxool kills the thread, QFJ failed to perform Scheduled Session reset. Please see the error log as shown below.

2010-12-18 09:32:07,312 WARN [HouseKeeper] HouseKeeper.sweep:149 - #0007 was active for 5559 milliseconds and has been removed automaticaly. Th
e Thread responsible was named 'QFJ Timer', but the last SQL it performed is unknown because the trace property is not enabled.
2010-12-18 09:32:07,316 ERROR [QFJ Timer] SessionConnector$SessionTimerTask.run:257 - Error during timer processing
quickfix.RuntimeError: java.io.IOException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection
. It has been automatically closed by Proxool for some reason (see logs).
at quickfix.SessionState.reset(SessionState.java:373)
at quickfix.Session.resetState(Session.java:2191)
at quickfix.Session.reset(Session.java:759)
at quickfix.Session.next(Session.java:1699)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:251)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.io.IOException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection. It has bee
n automatically closed by Proxool for some reason (see logs).
at quickfix.JdbcStore.reset(JdbcStore.java:195)
at quickfix.SessionState.reset(SessionState.java:370)
... 13 more
Caused by: java.sql.SQLException: Couldn't perform the operation prepareStatement: You can't perform any operations on this connection. It has b
een automatically closed by Proxool for some reason (see logs).
at org.logicalcobwebs.proxool.WrappedConnection.invoke(WrappedConnection.java:207)
at org.logicalcobwebs.proxool.WrappedConnection.intercept(WrappedConnection.java:87)
at com.sybase.jdbcx.SybConnection$$EnhancerByProxool$$ace6c3d2.prepareStatement(<generated>)
at quickfix.JdbcStore.reset(JdbcStore.java:187)
... 14 more

Kind Regards,
Vid



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

There were some synchronization problems around the Session.reset() method which might have caused this. Could you please try with QF/J 1.5.3 as soon as it is released (October/November 2012) and let us know if the problem still persists?

Thanks, Chris.

Comment by Lucian Hada [ 12/Nov/12 ]

Hi, we have the same issue using 1.5.0 and I don't see 1.5.3 out yet. Any chance this will get away with 1.5.2?
Thanks,
Lucian

Comment by Christoph John [ 12/Nov/12 ]

It is likely that the problem is still present on 1.5.2. I'm not even sure that it is fixed with 1.5.3 but it is quite likely since QFJ-645 and QFJ-700 had similar problems when trying to reset the sequence numbers.

Comment by Lucian Hada [ 12/Nov/12 ]

Thanks for answer. Are there any recommended workarounds? I didn't managed to reproduce this in a controlled test but it seems to me that once it occurred the sequence won't reset even if we restart the application and we don't see the exception anymore. Using MySQL btw.

Comment by Christoph John [ 13/Nov/12 ]

In the other issues I mentioned the problem was that there were messages sent and the session reset was done at the same time. Maybe you could define with your counterparty that they log off some time before your session's EndTime is reached. That way you could make sure that there are no messages exchanged while QF/J tries to reset the seqnums. This is the only workaround that I could think of at the moment.





[QFJ-570] Inappropriate sequence resync Created: 16/Dec/10  Updated: 20/May/11  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Olivier Lourdais Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

quickfixj-1.5.0


Issue Links:
Relates
is related to QFJ-589 Remove the Quickfix/J forceResync set... Closed

 Description   

Initial state on client side (not synchronized with server side state, because of some other bugs):

  • NextTargetMsgSeqNum=637
  • NextSenderMsgSeqNum=500544

Reception of a TradingSessionStatus message:
8=FIX.4.4|9=220|35=h|34=571|43=N|49=056001|50=1|52=20101216-07:48:45.775|56=7|57=7|97=N|335=154729|336=20101216|340=2|341=20101216-00:30:00.000|342=20101216-01:00:00.000|344=20101216-04:30:00.000|345=20101216-05:00:00.000|625=1|10=032|

The MsgSeqNum=571 causes a sequence resync:
20101216-07:48:43: Forcing sequence resync, expected target num = 637, received = 571

The Session.forceStoreResync(Message msg) does this:

  • nextTargetMsgSeqNum = 571
    -> ok
  • nextSenderMsgSeqNum = nextTargetMsgSeqNum (because NextExpectedMsgSeqNum field is not set) = 571
    -> NOK The sender MsgSeqNum should not be modified!!!

Just after that, a Heartbeat message is sent:
8=FIX.4.4|9=70|35=0|34=571|49=OSK07|50=OSK07|52=20101216-07:49:13.947|56=056001|57=1|10=154|
With MsgSeqNum=571 instead of 500544, causing a Logout by the server!



 Comments   
Comment by Olivier Lourdais [ 16/Dec/10 ]

I think the fix is quite easy:
In Session.forceStoreResync(Message msg) method, replace

final int nextSenderMsgSeqNum = msg.isSetField(NextExpectedMsgSeqNum.FIELD) ? msg
.getInt(NextExpectedMsgSeqNum.FIELD) : nextTargetMsgSeqNum;

with

final int nextSenderMsgSeqNum = msg.isSetField(NextExpectedMsgSeqNum.FIELD) ? msg
.getInt(NextExpectedMsgSeqNum.FIELD) : state.getMessageStore().getNextSenderMsgSeqNum();

Comment by Steve Bate [ 03/May/11 ]

Eric, does this issue go away since forceResync is being removed?

Comment by Eric Deshayes [ 03/May/11 ]

Yes, it will.
It will be closed with QFJ-589.





[QFJ-569] QuickFix/J is not scalable due to overly long duration lock on sequence number in Session.sendRaw Created: 10/Dec/10  Updated: 10/Dec/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Leon Chadwick Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

I have been writing a capacity test to measure the performance of our FIX engine (not quickfix based), however I can barely get my machine to use any CPU during the test despite my using a large number of threads to generate orders and respond with Acks.
Sadly I will have to now drop usage of quickfix/j as this is a showstopper for a high performance system.

After profiling, I tracked down that all these threads are generally single threaded through quickfix.Session.sendRaw() which is locking to hold onto a sequence number. A scalable solution should keep locking to a minimum duration, i.e. do as much message checking and string conversion as possible, then fill in the sequence number as a short last step whilst inside the lock.

A StringBuilder could be used to hold the toString()'d message whilst not holding the lock and leave sufficient capacity at the head of the array to shift some of the header content left/right to accomodate the sequence number field whilst during the locked region.



 Comments   
Comment by Steve Bate [ 10/Dec/10 ]

Are you trying to send all these orders through one session? If so, the incoming messages must be processed sequentially by the session protocol engine. However, that doesn't mean your application interface implementation must be single threaded. The application implementation can hand off the message processing to a worker thread pool, for example. The downside is that the FIX engine won't be able to rollback the sequence numbers if an exception occurs in the application code.

As the comments state in sendRaw(), the lock is held until the message is processed and the application callback has completed. This is necessary because any exception thrown during this time will cause the sequence number to be rolled back. In other words, the sequence number can't be incremented until these operations complete successfully.

The message throughput depends on many factors. Some of the biggest factors include the number of sessions, the implementations of the message store and message log and the response time of the application implementation. For example, any logging to the disk in the application callback could have a significant impact on message throughput and CPU utilization.

I don't know if any of this applies to your situation since you didn't include many details. However, I know of other organizations that have reported throughput in the 10's of thousands of messages/second.





[QFJ-568] MsgSeqNum too low, expecting 151 but received 150 Created: 29/Nov/10  Updated: 19/Dec/13  Resolved: 19/Dec/13

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

Type: Bug Priority: Default
Reporter: Baxter Solutions Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

We have a strange behaviour:

The user is logged in, everything is fine, but all of the sudden, his message is rejected with "MsgSeqNum too low" error, but I don't see why

2010-11-24 12:12:59,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=144^A52=20101124-12:12:59.943^A49=MMT^A56=BAXTERtest^A10=066^A
[2010-11-24 12:13:28,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=158^A49=BAXTERtest^A52=20101124-12:13:28.884^A56=MMT^A10=184^A
[2010-11-24 12:13:29,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=145^A52=20101124-12:13:29.943^A49=MMT^A56=BAXTERtest^A10=065^A
[2010-11-24 12:13:58,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=159^A49=BAXTERtest^A52=20101124-12:13:58.884^A56=MMT^A10=188^A
[2010-11-24 12:13:59,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=146^A52=20101124-12:13:59.943^A49=MMT^A56=BAXTERtest^A10=069^A
[2010-11-24 12:14:28,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=160^A49=BAXTERtest^A52=20101124-12:14:28.884^A56=MMT^A10=178^A
[2010-11-24 12:14:29,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=147^A52=20101124-12:14:29.943^A49=MMT^A56=BAXTERtest^A10=068^A
[2010-11-24 12:14:58,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=161^A49=BAXTERtest^A52=20101124-12:14:58.884^A56=MMT^A10=182^A
[2010-11-24 12:14:59,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=148^A52=20101124-12:14:59.943^A49=MMT^A56=BAXTERtest^A10=072^A
[2010-11-24 12:15:28,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=162^A49=BAXTERtest^A52=20101124-12:15:28.884^A56=MMT^A10=181^A
[2010-11-24 12:15:29,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=149^A52=20101124-12:15:29.943^A49=MMT^A56=BAXTERtest^A10=071^A
[2010-11-24 12:15:58,884] [DEBUG] [QFJ Timer] >>> 8=FIX.4.2^A9=58^A35=0^A34=163^A49=BAXTERtest^A52=20101124-12:15:58.884^A56=MMT^A10=185^A
[2010-11-24 12:15:59,955] [DEBUG] [SocketAcceptorIoProcessor-0.0] <<< 8=FIX.4.2^A9=00058^A35=0^A34=150^A52=20101124-12:15:59.943^A49=MMT^A56=BAXTERtest^A10=066^A

[2010-11-24 12:15:59,955] [DEBUG] [QFJ Message Processor] >>> 8=FIX.4.2^A9=111^A35=5^A34=164^A49=BAXTERtest^A52=20101124-12:15:59.955^A56=MMT^A58=MsgSeqNum too low, expecting 151 but received 150^A10=070^A
[2010-11-24 12:15:59,955] [DEBUG] [QFJ Message Processor] unregisterSession(): LOGOUT or connection loss, user session is removed. Key: MMT
[2010-11-24 12:15:59,964] [DEBUG] [QFJ Message Processor] unregisterSession() finished! Key: MMT

This never happened before, although we had two such incidens lately

We are using

quickfixj-all-1.4.0.jar






[QFJ-567] Would like QuickFix/J to natively support tag NextExpectedMsgSeqNum on logon as detailed in FIX Session Protocol 1.1 Errata Created: 23/Nov/10  Updated: 08/Nov/12  Resolved: 08/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0, 1.5.2
Fix Version/s: 1.5.3

Type: New Feature Priority: Default
Reporter: Christopher Hurst Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

ALL


Attachments: PDF File FIX Tag 789(NextExpectedMsgSeqNum) Description 1.7.pdf     PDF File FIX Tag 789(NextExpectedMsgSeqNum) Description.pdf     Zip Archive QuickFixJ789Change.zip     Zip Archive Tag789v1.3PDF.zip    
Issue Links:
Relates
is related to QFJ-705 Redundant ResendRequest is sent after... Closed

 Description   

The NextExpectedMsgSeqNum (789) field has been added in FIX 4.4 to the logon message to support a proposed way to resynchronize a FIX session. I was led to believe there is no internal QuickFix/J implementation pending and I have coded a configurable solution (as I have a pressing need for it), which I am currently testing I would like the solution to be integrated into QuickFix/J proper in a future version as that would make it a lot easier for me to maintain going forward.

I can supply source code changes and /or an additional document describing the work flow in various scenarios on request for feedback.



 Comments   
Comment by Christopher Hurst [ 17/Mar/11 ]

Updated version of the document following feedback.

Comment by Eric Deshayes [ 31/May/11 ]

Committed in Rev#1041.
A new setting has been added: EnableNextExpectedMsgSeqNum
By default,set to false. When set to true, the field 789 is sent on the logon message.

Comment by Christopher Hurst [ 06/Mar/12 ]

Hi,

I don't think this issue is resolved, can we change the status.

I supplied a fully tested 789 implementation all we've done in the released implementation is set to the 789 (which could have been added to a QFJ client application) to the next expected sequence number but the current implementation can't cope with any implicit resend or 789 being sent back in the logon response. Any performance benefits of 789 are lost.

The issue is you can't add this on top of QuickFIX this has to go into the core fix engine so I'm forced to branch QFJ.

I tried 1.5.1 with a sever that supports 789 and it actually failed to recover a session with the tag on (not sure why yet I'll have to dig). The server responded to the implicit logon but QFJ are requested an unnecessary resend.

Comment by Christopher Hurst [ 06/Mar/12 ]

Code changes requited.

Comment by Andrzej Hajderek [ 17/Sep/12 ]

Just proposed a small change that would push things forward just a little bit:

http://www.quickfixj.org/jira/browse/QFJ-705

Chris,

If you could comment on it, it would be great. (We're trying to connect to your MAPI engine with QuickFIX/J.)

Comment by Christopher Hurst [ 17/Sep/12 ]

Hi,

I would suggest the ideal solution was to fully support 789 (albeit optionally), I supplied a fully working solution all scenarios supported / scenario tested and soak tested against (1.5.0).
For reasons I'm not aware of, my solution wasn't used and a less than complete simplistic solution was added in its place (personally I would have suggested all or nothing was the better option in general).
As 789 functionality was added in the version I expected it to be, I assumed it was fully compliant until I later had time to inspect the code.
The less than full solution in a way complicates the problem in that we have to extend our test cases to partial support of 789.

As 789 is incomplete and required by us I had to do a less than trivial merge for 1.5.2 to enable my internal branch to work correctly again.

If you look at the code I originally submitted you can see the work I did on 1.5.0 nextLogon to compare and contrast with the suggested changes.

Chris

Comment by Christoph John [ 17/Sep/12 ]

hi,
so I think we should do the complete solution in QFJ-705
Do you agree?
cheers
Christoph

Comment by Andrzej Hajderek [ 17/Sep/12 ]

Hi,

I proposed the yet another partial solution under QFJ-705 because of the already taken incremental approach. And those 2 proposed lines of code seem to sort out our use case, in our tests.

The fact that this QFJ-567 was marked as fixed is a bit surprising, because it wasn't. At least someone could have commented on the reasons why only a fraction of the proposed solution was used.

I agree that the full solution proposed here would be best, although it will require additional work now.

Regards,
Andrzej

Comment by Christopher Hurst [ 18/Sep/12 ]

Hi,
First I suggest the initial closed report is re-opened ASAP as it holds useful detail and would preclude opening of new reports on the same issue.

I still think the full solution is the simplest. We're in a strong position to test this at the moment; that may not be the case in the future as it requires I can shadow the current builds and have access to the same test resources.

If we extend the existing acceptance scenarios in the existing 789 tests to all the scenarios in the original document we uploaded we should have full acceptance coverage.
Those scenarios were tested by hand and sanity checked between two 789 compliant engines (one QFJ 1.5.0).

I currently have a version of QF/J with my 789 changes, which I can soak test against another compliant FIX engine for increased confidence.

Obviously 789 is optional by (default) configuration so we should have no harms.
As 789 is optional and not used by default, some additional no-harms tests will be required to prove interoperability

Chris

Comment by Andrzej Hajderek [ 18/Sep/12 ]

Hi,

I agree with CH - QFJ-705 is not meant to replace QFJ-567. It is meant as a little step towards proper implementation of this QFJ-567.

The two line chane I proposed will not provide the full support for tag 789. This QFJ-567 is the best place to register and discuss the 789 support as such.

In fact it would be better to close QFJ-705 and resurrect this QFJ-567, as it was incorrectly marked as fixed in the past.

Regards,
Andrzej

Comment by Andrzej Hajderek [ 18/Sep/12 ]

BTW:

I wouldn't ignore Christopher's offer to test the full change. As far as I'm aware he's already got a production version of his COMPLETE fix running.

(Especially after he was being ignored since March .

Andrzej

Comment by Christoph John [ 18/Sep/12 ]

Agreed.

Comment by gemma hagen [ 03/Oct/12 ]

Hi,

We have the requirement to support this behaviour on logon for MAPI.
Is there a tested patch that can be applied to Quickfix 1.5.2 - if not, what are other people doing? When is 1.5.3 due?

Thanks

Gemma

Comment by Christoph John [ 12/Oct/12 ]

We plan to release end of October/beginning of November.

Comment by Christoph John [ 07/Nov/12 ]

Committed as rev #1094. Thanks to Christopher Hurst for suggested patch against 1.5.0 and doing quite some tests.





[QFJ-566] Incoming Logout message doesn't go to Application.fromAdmin() callback Created: 22/Nov/10  Updated: 22/May/15  Resolved: 01/Apr/14

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

Type: Bug Priority: Default
Reporter: Maksym Symonov Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-790 Logout message not propagated to the ... Closed

 Description   

Incoming Logout message is routed to Application.onLogout() callback, but doesn't go to Application.fromAdmin() callback. Therefore logout reason can't be extracted from the message as in onLogout() we have just SessionID of the session which is disconnected.



 Comments   
Comment by Christoph John [ 01/Apr/14 ]

Could not reproduce this in unit tests.





[QFJ-565] JMX session management does not work if there is a seqnum mismatch. Created: 10/Nov/10  Updated: 10/Nov/10

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Kode Charlie Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

I am in a catch-22, it seems. I followed instructions here,

  http://www.quickfixj.org/quickfixj/usermanual/1.5.0/usage/jmx.html

in order to enable remote jconsole / JMX controls on my FIX session.
However, because there is a seqnum mismatch, no session appears in jconsole,
so I cannot set the sender-seqnum!

In summary: for remote jconsole / JMX controls to resolve a seqnum mismatch,
it would be helpful if the NextSenderMsgSeqNum could be set independently
of whether there is a current mismatch. Otherwise, the jconsole / JMX controls
are useless in this scenario.






[QFJ-564] Operating on (modifying) repeating groups Created: 10/Nov/10  Updated: 10/Nov/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Addy Bhardwaj Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

N/A



 Description   

Currently if you want to add a value in a repeating group, there isn't a straightforward way of doing so. For instance,

//Just for illustration, if noSides group is read from TCR
TradeCaptureReport.NoSides noSidesGroup = new TradeCaptureReport.NoSides();
tradeCaptureReport.getGroup(1, noSidesGroup);

//add account information in TCR
noSidesGroup.set(new Account("accountA"));

This action doesn't modify the original TCR message as the group returned by getGroup() method is a copy of the actual group object.

Is there a reason for this behaviour? Also, I noticed that when we add a typed group object it is copied into a Group object and then stored in the underlying TreeMap of groups. The only reason I could find is that String to Object parsing doesn't create concrete group objects hence copy is required but I hoping there is another reason that I have overlooked.

ps: I have modified source code locally to improve this behaviour by

  • Removing the copy behaviour all together so concrete groups objects are kept in the message object
  • parsing string to QUICKFIXJ message object handles creation of concrete Groups as well.
    I am more than happy to provide a patch if it this functionality is desirable. It should surely help optimise the code by reducing copies and object creation.





[QFJ-563] SocketAcceptor initialization is not properly synchronized Created: 20/Oct/10  Updated: 01/Dec/11  Resolved: 01/Dec/11

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

Type: Bug Priority: Default
Reporter: Jaroslav Sedlacek Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

SocketAcceptor initialization is using Boolean object as both lock and flag. This approach has 2 major problems:
1) Public object such as Boolean.FALSE should not be used for synchronization. If it is used as lock in multiple places it can lead to performance degradation or deadlock.
2) Synchronization is done on Boolean.FALSE before initialization and on Boolean.TRUE after initialization but synchronization on 2 different locks do not constitute "happens-before" relationship. It means thread coming shortly after initialization can see changed flag and use Boolean.TRUE for locking and so it uses different lock than the lock used during initialization. As a result this thread can see objects created and updated during initialization in inconsistent state.

The problem can be fixed by using private not-share object as a lock and boolean value as flag.



 Comments   
Comment by Christoph John [ 01/Dec/11 ]

I also came across this issue when working on QFJ-643. Will take care of it.





[QFJ-562] dynamic definition of sessions on acceptor Created: 20/Oct/10  Updated: 10/Oct/12  Resolved: 10/Oct/12

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

Type: Task Priority: Major
Reporter: eaow Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

windows xp



 Description   

Please I want a full example of how to apply dynamic session on acceptor
quick fix version 1.5



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

Please direct such questions to the mailing list.
http://www.quickfixj.org/support/

Thank you.





[QFJ-561] Delimiter is misspelled as "delimeter" Created: 19/Oct/10  Updated: 11/Oct/12  Resolved: 11/Oct/12

Status: Resolved
Project: QuickFIX/J
Component/s: Documentation, Engine
Affects Version/s: 1.4.0, 1.5.0
Fix Version/s: 1.5.3

Type: Improvement Priority: Trivial
Reporter: Lo Shih Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

All Platforms



 Description   

Delimiter is misspelled as "delimeter" in the following Java source:

Source:

  • core/src/main/java/quickfix/DataDictionary.java
  • core/src/main/java/quickfix/FileLog.java
  • core/src/main/java/quickfix/Group.java (javadocs only)
  • core/src/main/java/quickfix/Message.java
  • core/src/test/java/quickfix/RepeatingGroupTest.java

API:

  • quickfix.DataDictionary.GroupInfo.getDelimeterField()
  • quickfix.DataDictionary.GroupInfo serialization if used

Please correct and add deprecated legacy cover methods.



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

Commited as rev 1092.





[QFJ-560] Need to change Tag 828, TrdType, to a string. Created: 29/Sep/10  Updated: 16/Oct/12  Resolved: 16/Oct/12

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

Type: Bug Priority: Default
Reporter: S M Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The fix message from ICE sends letters to denote a trade type. K is considered a block trade.

Type of trade, valid values
0 : Regular Trade
K: Block Trade
E: EFP Trade
S: EFS Trade
V: Bilateral Off-Exchange Trade
O: NG EFP/EFS Trade
9: CCX EFP Trade
J: EFR Trade
T - Contra Trade
Y - Cross Contra Trade
F - EFS/EFP Contra Trade



 Comments   
Comment by Laurent Danesi [ 30/Sep/10 ]

Hi,

The FIX spec (you can check on the official FIXimate site) declares this field as int:

Tag Field Name XML Name Data Type
828 TrdType @TrdTyp int

So, we cannot change it in the default DataDictionnary.
Anyway, you can create your own custom DataDictionnary that will fill your need and ICE requirements.

Regards,

Laurent DANESI

Comment by S M [ 30/Sep/10 ]

Ok thanks.

Here is a work around if someone does not want to create a custom DataDictionary.

TradeCaptureReport message;
String value = message.getString(828);

or

String value = message.getField(new StringField(828)).getValue();





[QFJ-559] IP Filtering on Acceptor Created: 29/Sep/10  Updated: 15/Nov/12  Resolved: 29/Sep/10

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: New Feature Priority: Default
Reporter: Laurent Danesi Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Comments   
Comment by Laurent Danesi [ 29/Sep/10 ]

Added AllowedRemoteAddresses setting





[QFJ-558] Can no longer send messages to initiators that have not yet been started Created: 13/Sep/10  Updated: 16/Sep/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File diff.txt     Text File diff.txt    

 Description   

We have some system states where we disable network connection but still may have messages that we wish to deliver to the gateway, i.e., message store, for future delivery to the counterparty when we re-enable the network connection. Our technique is to create a SocketAcceptor or SocketInitiator, but not to start it. Since we upgraded from QF/J 1.2.1 to QF/J 1.4.0, this is no longer working for initiators.

Traced this back to QFJ-354, revision number 874. QFJ-354 allows a SocketInitiator to be stopped and restarted. (Previously it could be stopped, but the only way to restart it was to recreate it.) As part of this change, they moved where the sessions are created out of the constructor. (Session creation is one way a session can be registered.) QFJ-354 was part of the 1.4.0 release. There was no similar change for acceptors.

I don't see any reason why the session creation cannot be moved back into the constructor. It does not interfere with the intent of QFJ-354.
Patch attached.

While in the neighbourhood, noticed the following two lines in the AbstractSocketInitiator constructor:

ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
ByteBuffer.setUseDirectBuffers(false);

This should be some sort of static initialization. e.g., for applications that use Mina for their own purposes as well as QF/J, they may need control over the buffer type and allocator, and shouldn't have to worry about QF/J changing it on the fly.



 Comments   
Comment by Rhys Yarranton [ 16/Sep/10 ]

Updated diff includes mod to ThreadedSocketInitiator.java.





[QFJ-557] Session.generateReject methods may incorrectly increment nextTargetMsgSeqNum in some scenarios Created: 10/Sep/10  Updated: 02/Apr/15  Resolved: 07/Nov/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File diff.txt     Text File QFTest.java    

 Description   

Scenario is as follows:

  • expecting 223
  • received 227 Logon, which we accepted --> "MsgSeqNum too high, expecting 223 but received 227"
  • sent resend request from 223 to 0
  • received 228, which failed data dictionary validation. --> "Message 228 Rejected: Invalid MsgType"
  • sent a Reject
  • received 223 SequenceReset, w/ PossDupFlag=Y, GapFillFlag=Y and NextSeqNo=225. This gap fill was not applied.
  • received 225 ExecutionReport w/ PossDupFlag=Y. --> "Rejected MsgSeqNum too high, expecting 224 but received 225", and "Already sent ResendRequest FROM: 223 TO: 226. Not sending another."

We were able to write a test to reproduce this. Tracing it through the debugger led to the following snippet in generateReject(Message, int, int):

            if (!msgType.equals(MsgType.LOGON) && !msgType.equals(MsgType.SEQUENCE_RESET)
                    && (msgSeqNum == getExpectedTargetNum() || !isPossibleDuplicate(message))) {
                state.incrNextTargetMsgSeqNum();

(There is a similar snippet in the other generateReject method.) The "bad" message 228 is not a Logon, not a SequenceReset and not a possible duplicate. Therefore the nextTargetMsgSeqNum is incremented, even though it should not be.

Consequently the Session thinks message 223 has too low a sequence number. Normally this would cause a log message and disconnect, but since it is flagged as a possible duplicate and is a SequenceReset, the message is silently dropped instead. See doTargetTooLow(Message) and validatePossDup(Message).

At this point we do not have a proposed fix. However, it seems clear that message 228 should not have caused an increment to nextTargetMsgSeqNum. The section "|| !isPossibleDuplicate(message)" in the snippet quoted above is a tad mysterious. Or it could be something deeper about how dictionary validation and sequence number validation should be ordered.



 Comments   
Comment by Rhys Yarranton [ 10/Sep/10 ]

Test case attached.

Comment by Rhys Yarranton [ 16/Sep/10 ]

After looking at the spec and the history of the source code in question, I suspect that the logic to increment the next expected target sequence number was taken rather literally from the spec, and then a couple of special cases were removed.

Attached is a patch that changes it to only increment if the current message has the expected sequence number. You can think of this as continuing the tradition of the existing logic.

The spec makes an implicit assumption that the message in question is in order. You could take that as an argument in favour of reordering of the logic, but it is also possible that the authors of the spec simply didn't envisage this case. Personally I think re-ordering the logic has merit.

Comment by Christoph John [ 07/Nov/13 ]

Committed as rev 1116: http://sourceforge.net/p/quickfixj/code/1116/
Thanks to Rhys Yarranton for the patch!





[QFJ-556]  ThreadedSocketAcceptor/DynamicAcceptorSessionProvider do not get checked by SessionTimerTask Created: 03/Sep/10  Updated: 01/Oct/17  Resolved: 01/Oct/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Relates
relates to QFJ-609 Improve JMX session registration. Closed

 Description   

ThreadedSocketAcceptor/DynamicAcceptorSessionProvider Sessions do not get checked by SessionTimerTask because sessionconnector is always null from ThreadPerSessionEventHandlingStrategy.

DynamicAcceptorSessionProvider.getSession(...) {
if(sessionConnector != null) {
sessionConnector.addDynamicSession(s);
}
}

ThreadPerSessionEventHandlingStrategy.getSessionConnector() {
return null;
}

simple fix i tested was to just add the connector constructor like in SingleThread version

public ThreadPerSessionEventHandlingStrategy(SessionConnector connector)

{ sessionConnector = connector; }

 Comments   
Comment by Andre Mermegas [ 03/Sep/10 ]

and of course return the field instead of null
ThreadPerSessionEventHandlingStrategy {
....
public SessionConnector getSessionConnector()

{ return sessionConnector; }

....
}

updated constructor calls in
ThreadedSocketInitiator, ThreadedSocketAcceptor
private final ThreadPerSessionEventHandlingStrategy eventHandlingStrategy = new ThreadPerSessionEventHandlingStrategy(this);

Comment by Christoph John [ 01/Oct/17 ]

Fixed by QFJ-609.





[QFJ-555] Problems with heartbeating in one session can obstruct heartbeating on other sessions Created: 01/Sep/10  Updated: 07/Jan/20

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-291 Problems with initiator reconnect wil... Closed

 Description   

SessionConnector.scheduledExecutorService is a single-threaded executor, and is used by all sessions for heartbeating. If there is a problem in one session, it can impact other sessions.

This is really QFJ-291 again. QFJ-291 was stated in terms of initiator reconnects, and the fix to it targeted that specific scenario. However, we have just encountered this problem in production involving only heartbeats. Heartbeating seems innocuous, but in fact has most of the same vulnerabilities as sending any other message (logging, toAdmin etc.).



 Comments   
Comment by Christoph John [ 07/Jan/20 ]

This will be improved with https://github.com/quickfix-j/quickfixj/issues/254.





[QFJ-554] SleepycatStore can enter infinite loop retrieving messages for resend. Created: 26/Aug/10  Updated: 26/Aug/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: James Olsen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

SleepycatStore does not check returned OperationStatus from call to com.sleepycat.je.Cursor.getNext(...):

public synchronized void get(int startSequence, int endSequence, Collection<String> messages) throws IOException {
...
if (retVal == OperationStatus.NOTFOUND)

{ log.debug(sequenceKey + "/" + messageBytes + " not matched in database " + messageDatabase.getDatabaseName()); return; } else {
Integer sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
while (sequenceNumber.intValue() <= endSequence) {
messages.add(new String(messageBytes.getData(), charsetEncoding));
if (log.isDebugEnabled()) { log.debug("Found record " + sequenceNumber + "=>" + new String(messageBytes.getData(), charsetEncoding) + " for search key/data: " + sequenceKey + "=>" + messageBytes); }
cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);
sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
}
}
...
}

Should be:

public synchronized void get(int startSequence, int endSequence, Collection<String> messages) throws IOException {
...
if (retVal == OperationStatus.NOTFOUND) { log.debug(sequenceKey + "/" + messageBytes + " not matched in database " + messageDatabase.getDatabaseName()); return; }

else {
Integer sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
while (retVal == OperationStatus.SUCCESS && sequenceNumber.intValue() <= endSequence) {
messages.add(new String(messageBytes.getData(), charsetEncoding));
if (log.isDebugEnabled())

{ log.debug("Found record " + sequenceNumber + "=>" + new String(messageBytes.getData(), charsetEncoding) + " for search key/data: " + sequenceKey + "=>" + messageBytes); }

retVal = cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);
sequenceNumber = (Integer) sequenceBinding.entryToObject(sequenceKey);
}
}
...
}



 Comments   
Comment by James Olsen [ 26/Aug/10 ]

For clarity, the changed lines are:

while (retVal == OperationStatus.SUCCESS && sequenceNumber.intValue() <= endSequence) {
...
}
retVal = cursor.getNext(sequenceKey, messageBytes, LockMode.DEFAULT);





[QFJ-553] Fields Order Created: 16/Aug/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Ahmad Al Sheikh Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Dears, I want to create NewSingleOrder message with certain fields order for the message body not the ascending based on the keys,
21;60;11;76;48;22;55;54;38;44;375;9950;9951;10026;10027;9947;9228;1002;89004;9917;204;439;1;58

your help is highly apreciated, please if you can send me an example that will cut alot of time.






[QFJ-552] Message Stores expected to be thread safe but are not Created: 05/Aug/10  Updated: 21/Apr/17

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.4.0, 1.5.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Carmelo Piccione Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Linux + JDBC + SQL Server 2005


Attachments: Java Source File SynchronizedMessageStore.java     Java Source File SynchronizedMessageStoreFactory.java    
Issue Links:
Relates
is related to QFJ-762 Message stores can become corrupted o... Open
is related to QFJ-923 FileStore is leaking file handles Closed

 Description   

SessionState.java starts with the following bit of code:

/**

  • Used by the session communications code. Not intended to be used by
  • applications.
    *
  • All dynamic data is protected by the session's intrinsic lock. The
  • log and message store implementation must be thread safe.
    */
    public final class SessionState {
    private final Object lock;
    private final Log log;

// MessageStore implementation must be thread safe
private final MessageStore messageStore;
...
}

Yet, looking at the JdbcStore.java and MemoryStore.java implementations, they are in fact not thread safe as designed (may also be true for FileStore.java, but haven't checked).

The memory store uses a regular java.util.HashMap for all its operations, which is clearly not thread safe. I have never actually seen this cause a problem in practice, however.

The jdbc store does not synchronize its use of the jdbc connection, which can lead to race conditions inside the close() method of the jtds prepared statement, as shown in the stack trace below (specifically, the jtds close() method has a boolean to determine if its connection is already closed in which case it will not doubly close it despite any subsequent calls. This value is set once the close routine is complete but occurs after the connection object has already been assigned a null value- this allows another thread to potentially access the null connection object before the boolean guard has been set). Note that this bug occurs about once a week in a production environment (usually during startup), although its frequency is probably higher than average due to many quickfixj applications accessing the same database concurrently.

Example 1:

java.lang.NullPointerException
at net.sourceforge.jtds.jdbc.JtdsStatement.close(JtdsStatement.java:868)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.close(JtdsPreparedStatement.java:485)
at org.logicalcobwebs.proxool.AbstractProxyStatement.close(AbstractProxyStatement.java:115)
at org.logicalcobwebs.proxool.ProxyStatement.invoke(ProxyStatement.java:93)
at org.logicalcobwebs.proxool.ProxyStatement.intercept(ProxyStatement.java:57)
at quickfix.JdbcUtil.close(JdbcUtil.java:143)
at quickfix.JdbcStore.storeSequenceNumbers(JdbcStore.java:288)
at quickfix.JdbcStore.setNextTargetMsgSeqNum(JdbcStore.java:272)
at quickfix.JdbcStore.incrNextTargetMsgSeqNum(JdbcStore.java:173)
at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:359)
at quickfix.Session.nextLogon(Session.java:1535)
at quickfix.Session.next(Session.java:720)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:106)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:619)

Example 2:

java.lang.NullPointerException
at net.sourceforge.jtds.jdbc.JtdsStatement.close(JtdsStatement.java:868)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.close(JtdsPreparedStatement.java:485)
at org.logicalcobwebs.proxool.AbstractProxyStatement.close(AbstractProxyStatement.java:115)
at org.logicalcobwebs.proxool.ProxyStatement.invoke(ProxyStatement.java:93)
at org.logicalcobwebs.proxool.ProxyStatement.intercept(ProxyStatement.java:57)
at quickfix.JdbcUtil.close(JdbcUtil.java:143)
at quickfix.JdbcStore.set(JdbcStore.java:259)
at quickfix.SessionState.set(SessionState.java:299)
at quickfix.Session.sendRaw(Session.java:1736)
at quickfix.Session.generateLogon(Session.java:1430)
at quickfix.Session.next(Session.java:1357)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:248)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)



 Comments   
Comment by Carmelo Piccione [ 17/Aug/10 ]

A simple but thread safe message store implementation. The constructor takes a MessageStore instance as input and delegates all method calls to it through an object lock. This is a work around which allows safe usage of the original QFJ message stores such as JdbcStore, FileStore, and MemoryStore.





[QFJ-551] Sender comp id doesnt not get reflected while creating a session if given at runtime Created: 04/Aug/10  Updated: 04/Aug/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: hitesh Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Desc:
i have a quickfix config (for initiator), which doesn't have sender comp id. from my application i get the sender comp id at runtime, which i then set it session settings object. i then create SocketInitiator, and start the initiator. in the onCreate() method, i get sessionID without the sender comp id. am i trying which is not possible? please let me know if i am doing something wrong.

Code:

public boolean initialize(String senderCompID){
SessionSettings settings = null;
try

{ settings = new SessionSettings(settingsFileName); }

catch (ConfigError e)

{ System.err.println("Could not find FIX setting file."); e.printStackTrace(); System.exit(-1); }

String fixVersion = null;
String sndrCompId = senderCompID;
settings.setString(SessionSettings.SENDERCOMPID, senderCompID); // sender compid added in the default session. also tried adding the same in NONE default session in the below lines of code.

String tgtCompId = null;
SessionID sessID;
Iterator<SessionID> ite = settings.sectionIterator();
while(ite.hasNext()) {
sessID = ite.next();
try

{ fixVersion = settings.getString(sessID, SessionSettings.BEGINSTRING); tgtCompId = settings.getString(sessID, SessionSettings.TARGETCOMPID); //settings.setString(sessID, SessionSettings.SENDERCOMPID, senderCompID); // tried adding in one of the sessions. }

catch (Exception e)

{ System.err.println("Could not get [BEGINSTRING] or [TARGETCOMPID] " + "from session id [" + sessID.toString() + "]-[" + e.toString() + "]"); }

}

String fileStorePath;
String fileLogPath;
try

{ fileStorePath = settings.getString("FileStorePath"); }

catch (Exception e)

{ fileStorePath = null; System.err.println("Could not get [FileStorePath] [" + e.toString() + "]"); }

try {
fileLogPath = settings.getString("FileLogPath");
if(fileStorePath == null)

{ fileStorePath = fileLogPath; System.out.println("[FileStorePath] set to [FileLogPath] - [" + fileStorePath + "]"); }

} catch (Exception e)

{ fileLogPath = null; System.err.println("Could not get [FileLogPath] [" + e.toString() + "]"); }

MessageStoreFactory storeFactory = new FileStoreFactory(settings);
LogFactory logFactory = new FileLogFactory(settings);
MessageFactory messageFactory = new MessageFactory();
try

{ initiator = new SocketInitiator(this, storeFactory, settings, logFactory, messageFactory); }

catch (ConfigError e)

{ System.err.println("FIXClient Could not initiate socket!"); e.printStackTrace(); System.exit(-1); }

String fixedString = fixVersion + "" + sndrCompId + "" + tgtCompId; // if i check my settings object i have sender comp id correctly inserted

// further code

initiator.start();
}






[QFJ-550] FIX 5.0 message validation against session/application DataDictionary Created: 02/Aug/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Sasha Kogan Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
is there any public API for full (against both session & app dictionaries) validation of 5.0 msgs, as DataDictionary.validate(Message message, boolean bodyOnly) is only usable for FIX 4.4 and earlier?
Such validation is done by DataDictionary's static validate(Message message, DataDictionary sessionDataDictionary, DataDictionary applicationDataDictionary), but the method has package access...
10x,
/Sasha






[QFJ-549] Cannot read Bodylength inside toApp(), toAdmin() Created: 30/Jul/10  Updated: 01/Apr/14  Resolved: 01/Apr/14

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

Type: Bug Priority: Default
Reporter: Sanghmitra Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Windows, C#



 Description   

I am using following code inside toApp() and toAdmin()
message.getHeader().getInt(BodyLength.FIELD)

But I am getting FieldNotfound exception. I can see the BodyLength tag set in the message, but still it cannot be found at the runtime.

Same code works fine in fromApp() and fromAdmin().

Also following code works fine - msg.getHeader().getField(new BeginString()).getValue();

Its Bodylength tag which gives error.

Can you provide the resolution please.



 Comments   
Comment by Christoph John [ 01/Apr/14 ]

Could not reproduce this issue in unit test.





[QFJ-548] outOfOrderField checking by setting ValidateFieldsOutOfOrder=N doesn't work Created: 26/Jul/10  Updated: 15/Nov/12  Resolved: 09/Jan/12

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Message Generation
Affects Version/s: 1.4.0, 1.5.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Pranab Kumar Naik Assignee: Christoph John
Resolution: Duplicate Votes: 0
Labels: None
Environment:

All


Issue Links:
Duplicate
duplicates QFJ-633 turn off Out of order repeating group... Closed

 Description   

Even after setting ValidateFieldsOutOfOrder=N, I am still getting the Out of order repeating group members error.



 Comments   
Comment by Christoph John [ 09/Jan/12 ]

To bypass checking of unordered group fields you should use the setting ValidateUnorderedGroupFields=N.





[QFJ-547] outOfOrderField checking by setting ValidateFieldsOutOfOrder=N doesn't work Created: 23/Jul/10  Updated: 01/Oct/17  Resolved: 01/Oct/17

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.4.0, 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Pranab Kumar Naik Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 1
Labels: None


 Description   

Even after setting ValidateFieldsOutOfOrder=N, I am still getting the Out of order repeating group members error.



 Comments   
Comment by Leon Chadwick [ 23/Nov/10 ]

I patched my source for QuickFix/J to get past this. Perhaps if this behaviour I added is correct, it should be put back into the main codebase?

In Message.parseBody(DataDictionary dd) .....

if (isHeaderField(field.getField())) {
// An acceptance test requires the sequence number to
// be available even if the related field is out of order
setField(header, field);
if ( dd.isCheckFieldsOutOfOrder() )

{ throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, field.getTag()); }

}
else

{ setField(this, field); }
Comment by Christoph John [ 01/Oct/17 ]

Should work with recent QFJ versions.





[QFJ-546] Nested Group do not support 'ValidateFieldsOutOfOrder' configure Created: 22/Jul/10  Updated: 29/Apr/11  Resolved: 29/Apr/11

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

Type: Bug Priority: Critical
Reporter: zhengzheming Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Windows.... jdk 1.5


Issue Links:
Duplicate
duplicates QFJ-535 ValidateFieldsOutOfOrder=N not applie... Closed

 Description   

The ValidateFieldsOutOfOrder configure do not support for nested group ....

this option only valid for root DataDictionary But not add to group level data dictionary.....

I think it is better rewrite the DataDictionary#setCheckFieldsOutOfOrder like this:

public void setCheckFieldsOutOfOrder(boolean flag) {

checkFieldsOutOfOrder = flag;

for (GroupInfo info:groups.values())
{
DataDictionary dic=info.getDataDictionary();

if(null!=dic)

{ dic.setCheckFieldsOutOfOrder(flag); }

}
}



 Comments   
Comment by Eric Deshayes [ 29/Apr/11 ]

This is a duplicate of QFJ-535





[QFJ-545] Wrong Example Code in UserManual Created: 22/Jul/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: gpizarro Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: GIF File Application.gif    

 Description   

The example in documentation (online and included in Release Files)
\quickfixj\doc\usermanual\usage\application.html
indicates using
Application application = new Application();
but when compiling an error arises:
Description: Cannot instantiate the type Application

since it's trying to use the imported interface quickfix.Application (from import quickfix.*

Full code can be viewed online here: http://www.quickfixj.org/quickfixj/usermanual/1.5.0/usage/application.html



 Comments   
Comment by gpizarro [ 22/Jul/10 ]

Possible error in Example





[QFJ-544] Header with BeginString=FIXT.1.1 incorrectly parsed by FIXMessageDecoder (manifests as missing messages) Created: 20/Jul/10  Updated: 04/Sep/12  Resolved: 02/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Stelios Papadopoulos Assignee: Christoph John
Resolution: Fixed Votes: 3
Labels: None

Attachments: Text File quickfixj-1.4.patch     Text File quickfixj-1.5.patch    
Issue Links:
Duplicate
is duplicated by QFJ-505 FixMessageDecoder.startsWith() wrongl... Closed
Relates
is related to QFJ-687 Lost message on package fragmentation... Closed

 Description   

When BeginString=FIXT.1.1 messages can be skipped if the buffer ends before the last '=' of "8=FIXT.1.1\0019=". That will happen if the buffer contains a correct message before that.

Example:

in messages:

8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\0018=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\001

the second message will fail to be decoded if the buffer contents presented to the FixMessageDecoder in two subsequent decode() invocations are:

"8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\0018=FIXT.1.1\0019"

and

"=12\00135=X\001108=30\00110=036\001"

I have created tests to replicate this issue (and also issue QFJ-505) and included fixes (for this and the fix proposed in QFJ-505).
Here is the diff:

Index: core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java
===================================================================
— core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (revision 46)
+++ core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (revision 49)
@@ -348,7 +348,22 @@

@Test
public void testMinaDemux() throws Exception

{ - DemuxingProtocolCodecFactory codecFactory = new DemuxingProtocolCodecFactory(); + String message = "8=FIX.4.2\0019=12\00135=X\001108=30\00110=036\001"; + + doTestMinaDemux(message); + + }

+
+ @Test
+ public void testMinaDemuxFixt() throws Exception

{ + String message = "8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\001"; + + doTestMinaDemux(message); + + }

+
+ private void doTestMinaDemux(String message) throws Exception, UnsupportedEncodingException {
+ DemuxingProtocolCodecFactory codecFactory = new DemuxingProtocolCodecFactory();
codecFactory.register(FIXMessageDecoder.class);

ProtocolDecoder decoder = codecFactory.getDecoder();
@@ -359,7 +374,7 @@
int count = 5;
String data = "";
for (int i = 0; i < count; i++)

{ - data += "8=FIX.4.2\0019=12\00135=X\001108=30\00110=036\001"; + data += message; }

for (int i = 1; i < data.length(); i++)

{ @@ -379,9 +394,8 @@ output.reset(); buffer.clear(); }

-

  • }
    -
    + }
    +
    private void assertMessageFound(String data) throws ProtocolCodecException { assertMessageFound(data, 1); }

    Index: core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java
    ===================================================================

      • core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 46)
        +++ core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 49)
        @@ -123,7 +123,7 @@
        }
        if (messageCount > 0) {
        // Mina will compact the buffer because we can't detect a header
  • if (in.remaining() < minMaskLength(HEADER_PATTERN))
    Unknown macro: {+ if (state == SEEKING_HEADER) { position = 0; } return MessageDecoderResult.OK;@@ -297,7 +297,8 @@ }

private static BufPos indexOf(ByteBuffer buffer, int position, byte[] data) {

  • for (int offset = position, limit = buffer.limit() - minMaskLength(data) + 1; offset < limit; offset++) {
    + int limit = buffer.limit() - minMaskLength(data) + 1;
    + for (int offset = position ; offset < limit; offset++)
    Unknown macro: { int length; if (buffer.get(offset) == data[0] && (length = startsWith(buffer, offset, data)) > 0) { return new BufPos(offset, length); @@ -337,6 +338,10 @@ return -1; } }

    + if(dataOffset != data.length)

    { + // when minMaskLength(data) != data.length we might run out of buffer before we run out of data + return -1; + }

    return bufferOffset - initOffset;
    }



 Comments   
Comment by Stelios Papadopoulos [ 20/Jul/10 ]

the svn references are unrelated to the QuickFixJ svn repository.

Comment by Stelios Papadopoulos [ 20/Jul/10 ]

Found the same issue in 1.5.0 here's my diffs for the tests and the fix:

Index: C:/dev/projects/QUICKFIXJ-IG/core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java
===================================================================
— C:/dev/projects/QUICKFIXJ-IG/core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (revision 52)
+++ C:/dev/projects/QUICKFIXJ-IG/core/src/test/java/quickfix/mina/message/FIXMessageDecoderTest.java (working copy)
@@ -327,7 +327,22 @@

@Test
public void testMinaDemux() throws Exception

{ - DemuxingProtocolCodecFactory codecFactory = new DemuxingProtocolCodecFactory(); + String message = "8=FIX.4.2\0019=12\00135=X\001108=30\00110=036\001"; + + doTestMinaDemux(message); + + }

+
+ @Test
+ public void testMinaDemuxFixt() throws Exception

{ + String message = "8=FIXT.1.1\0019=12\00135=X\001108=30\00110=036\001"; + + doTestMinaDemux(message); + + }

+
+ private void doTestMinaDemux(String message) throws Exception, UnsupportedEncodingException {
+ DemuxingProtocolCodecFactory codecFactory = new DemuxingProtocolCodecFactory();
codecFactory.register(FIXMessageDecoder.class);

ProtocolDecoder decoder = codecFactory.getDecoder();
@@ -338,7 +353,7 @@
int count = 5;
String data = "";
for (int i = 0; i < count; i++)

{ - data += "8=FIX.4.2\0019=12\00135=X\001108=30\00110=036\001"; + data += message; }

for (int i = 1; i < data.length(); i++)

{ @@ -358,9 +373,8 @@ output.reset(); buffer.clear(); }

+ }

  • }
    -
    private void assertMessageFound(String data) throws ProtocolCodecException { assertMessageFound(data, 1); }

Index: C:/dev/projects/QUICKFIXJ-IG/core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java
===================================================================
— C:/dev/projects/QUICKFIXJ-IG/core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (revision 52)
+++ C:/dev/projects/QUICKFIXJ-IG/core/src/main/java/quickfix/mina/message/FIXMessageDecoder.java (working copy)
@@ -123,7 +123,7 @@
}
if (messageCount > 0) {
// Mina will compact the buffer because we can't detect a header

  • if (in.remaining() < minMaskLength(HEADER_PATTERN))
    Unknown macro: {+ if (state == SEEKING_HEADER) { position = 0; } return MessageDecoderResult.OK;@@ -337,6 +337,10 @@ return -1; }

    }
    + if(dataOffset != data.length)

    { + // when minMaskLength(data) != data.length we might run out of buffer before we run out of data + return -1; + }

    return bufferOffset - initOffset;
    }

Comment by Stelios Papadopoulos [ 01/Aug/12 ]

revision numbers are unrelated to the official repository.

fix for the 1.4.x branch

Comment by Stelios Papadopoulos [ 01/Aug/12 ]

revision numbers are unrelated to the official repository.

fix for the 1.5.x branch

Comment by Christoph John [ 02/Aug/12 ]

Stelios, thanks for the patch!

Committed as r1075 on trunk.





[QFJ-543] "connector" parameter in interface AcceptorSessionProvider.getSession() is undocumented and unclear Created: 19/Jul/10  Updated: 19/Jul/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Grant Birchmeier Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

See paste below from AcceptorSessionProvider. The parameter connector is absent from the javadoc, and it's not clear what it's for. As it's an interface, the parameter's purpose should be documented.

From the two instantiations of this interface (DynamicAcceptorSessionProvider and AbstractSocketAcceptor::StaticAcceptorSessionProvider), it appears this parameter is only used for dynamic sessions and is otherwise ignored.

/**

  • Return a session for this sessionID. The session might be
  • created dynamically.
  • @param sessionID
  • @return the associated session or null if no session can be
  • associated with the given ID.
    */
    Session getSession(SessionID sessionID, SessionConnector connector);


 Comments   
Comment by Grant Birchmeier [ 19/Jul/10 ]

Paste above is from r959 (the latest at time of bug creation).





[QFJ-542] test targets wrong on installation page Created: 19/Jul/10  Updated: 19/Jul/10

Status: Open
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.5.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

On page http://www.quickfixj.org/quickfixj/usermanual/1.5.0/installation.html,

It says to use targets "test.unit" and "test.acceptance". These targets do not exist.

It appears that we are supposed to use the "test" target.






[QFJ-541] Add TOS and DSCP support to QFJ Created: 15/Jul/10  Updated: 15/Nov/12  Resolved: 15/Jul/10

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

Type: Improvement Priority: Default
Reporter: Laurent Danesi Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None





[QFJ-540] CLONE -Market Data Request Created: 12/Jul/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I am tryng to connect to integral and subscripe to Market data request.

how can i set the tag order as per what i want as currently tags are being ordered by the tag number

Integral want the tag orders as below

Tag 146 should come before tag 55, but when i am using this API tag 55 is coming before Tag146 which lead a rejection message from integral can you help me please, as i have to do the same for other tags as well on the same message, as Tag 128 should come before those tags






[QFJ-539] Acceptor sending messages to other acceptors Created: 12/Jul/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Pranab Kumar Naik Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux



 Description   

Is it possible for an acceptor to send across messages to another acceptor. I set up a session using the Begin String, Sender CompId and Target CompId, where there is a valid session on the other acceptor. Then I send across messages to the other acceptor. I see messages being sent to the other acceptor, but I don't see the messages being received by my target acceptor. Any heklp is welcome. IP addresses and ports are properly defined.






[QFJ-538] Multiple session, but uses the same host/port Created: 09/Jul/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: hitesh Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,

I am new to QuickFIX, can you please help me, if there is any feature which allows multiple sessions which uses the same host port combination.

I checked some jira cases, in which I found "http://www.quickfixj.org/jira/browse/QFJ-165", is this useful, if yes, in which version is this patch applied?
To use this I have to do the config change, do i need to do any other change other than this?

If above case is not applicable to me, then how can I achieve this, is it possible?

Thanks for the efforts you put in to answer my query.
Appreciate your help.

Regards,
Hitesh



 Comments   
Comment by Pranab Kumar Naik [ 12/Jul/10 ]

[DEFAULT]
ConnectionType=acceptor
ReconnectInterval=60
SenderCompID=SENDER
HeartBtInt=20
SocketAcceptAddress=localhost
SocketAcceptPort=8901
ResetOnLogon=Y
ResetOnLogout=Y
ValidateFieldsOutOfOrder=N
FileLogPath=Log
TransportDataDictionary=FIXT11.xml
FileStoreMaxCachedMsgs=0

  1. session definition
    [SESSION]
    BeginString=FIX.4.4
    DefaultApplVerID=FIX.4.4
    AppDataDictionary=FIX44.xml
    StartTime=07:15:00
    EndTime=18:00:00
    TargetCompID=DEV01
    FileStorePath=Log
  1. session definition
    [SESSION]
    BeginString=FIX.4.4
    DefaultApplVerID=FIX.4.4
    AppDataDictionary=FIX44.xml
    StartTime=07:15:00
    EndTime=18:00:00
    TargetCompID=DEV02
    FileStorePath=Log

You can specify multiple sessions by definign multiple session parameters. I think in the QuickfixJ sample there are examples for multiple sessions.





[QFJ-537] Session scheduling - problems with JDK Nanotime Bug Created: 28/Jun/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Other Priority: Default
Reporter: SSE Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

VMWARE 3.5/4, Solaris 10 Upgrade 6, Multiprocessor



 Description   

On Solaris 10 the gethrtime (High Resolution Time) and time (Wall Clock Time) functions are sometimes returning wrong values. The function gethrtime is wrapped in JVM to get the Nanotime that many applications use. This is causing unpredictable behavior in various applications. The tests were done for gethrtime and time function that returns wall clock time - it was going backwards. For QuickFIX/J in particular, due to nanotime returning wrong values and deltas being negative, required FIX connections were not established as expected.

Some links:

http://communities.vmware.com/thread/215461
http://bugs.sun.com/view_bug.do;jsessionid=36cc38bca9ae36e09ba7643c0f8?bug_id=6855228

Fixed: Following options were added to the VMX file on VMWARE:

monitor_control.disable_tsc_offsetting=TRUE
monitor_control.disable_rdtscopt_bt=TRUE

(internal reference: IC_57921)






[QFJ-536] Checksum patch Created: 28/Jun/10  Updated: 15/Nov/12  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Major
Reporter: SSE Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

All



 Description   

The getGroups has the side effect of modifying i.e creating the empty group inside the message beeing read (with NoXXX field set to 0). The message serialization and checksum/length calculation inside quickfixj are not consistently treated for NoXXX=0 fields
(i.e: the checksum/length calculation uses the NoXXX=0 field and serialization ignores it).

Fixed: checksum/length calculation in QuickFIX/J for groups having NoXXX=0, in case that the library and getGroups+forwarding is used in a public call.

int calculateLength() {
int result = 0;
int length = 0;
for (Iterator<Field<?>> iter = fields.values().iterator(); iter.hasNext() {
Field<?> field = iter.next();
if (field.getField() == BeginString.FIELD || field.getField() == BodyLength.FIELD

field.getField() == CheckSum.FIELD isGroupField(field.getField())) { continue; }
length = field.getLength();
result += length;
}

Iterator<Map.Entry<Integer, List<Group>>> iterator = groups.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, List<Group>> entry = iterator.next();
List<Group> groupList = entry.getValue();
if (groupList.size() > 0) { // ******* ADDED *******
IntField groupField = new IntField(((Integer) entry.getKey()).intValue());
groupField.setValue(groupList.size());
length = groupField.getLength();
result += length;
for (int i = 0; i < groupList.size(); i++) { Group group = (Group) groupList.get(i); length = group.calculateLength(); result += length; }
}
}

return result;

}

int calculateTotal() {

int result = 0;
for (Iterator<Field<?>> iter = fields.values().iterator(); iter.hasNext() {
Field<?> field = (Field<?>) iter.next();
if (field.getField() == CheckSum.FIELD || isGroupField(field.getField())) { continue; }

result += field.getTotal();
}

Iterator<Map.Entry<Integer, List<Group>>> iterator = groups.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, List<Group>> entry = iterator.next();
List<Group> groupList = entry.getValue();
if (groupList.size() > 0) { // ******* ADDED *******
IntField groupField = new IntField(((Integer) entry.getKey()).intValue());
groupField.setValue(groupList.size());
result += groupField.getTotal();
for (int i = 0; i < groupList.size(); i++)

{ Group group = (Group) groupList.get(i); result += group.calculateTotal(); }

}
}

return result;
}

(Internal reference: IC_57786)



 Comments   
Comment by Steve Bate [ 20/Mar/11 ]

These changes introduced a bug since the calculateString method was not also changed. It was possible to have a message string with a tag=0 but the length of the message is zero. This was causing unit and acceptance tests to fail. Zero length groups are now not serialized into message strings as of SVN rev #1002. However, I'm not sure this is what we really want. The QuickFIX C++ project expects zero length groups to be serialized so, assuming they had a good reason for implementing that behavior, we may be causing some subtle problem with these changes.





[QFJ-535] ValidateFieldsOutOfOrder=N not applied on all message levels Created: 28/Jun/10  Updated: 20/May/11  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Major
Reporter: SSE Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None
Environment:

All


Issue Links:
Duplicate
is duplicated by QFJ-546 Nested Group do not support 'Valid... Closed

 Description   

QuickFIX configuration flag ValidateFieldsOutOfOrder=N has been applied. Although QuickFIX/J should ignore field ordering on all repeating group levels (as specified by ValidateFieldsOutOfOrder=N), some session rejects from the engine have been observed by the clients and in internal test, which reject FIX messages because of improper field ordering (example: reversed order of PartyIDSource (447) and PartyRole (452) in the Parties group). After reviewing the QuickFIX/J source code, it has been established that the cause of the problem is that the flag is not propagated properly to second and higher groups levels in the recursive validation of the FIX message.

Fixed: propagate the flag properly.

public void setCheckFieldsHaveValues(boolean flag) {
checkFieldsHaveValues = flag;
for(GroupInfo gi : groups.values())

{ // ******* ADDED ******* gi.getDataDictionary().setCheckFieldsHaveValues(flag); }

}

(Internal reference: IC_58606)



 Comments   
Comment by Steve Bate [ 22/Apr/11 ]

This is a misunderstanding of the documented purpose of the ValidateFieldsOutOfOrder flag: "If set to N, fields that are out of order (i.e. body fields in the header, or header fields in the body) will not be rejected.". It is not related at all to group field ordering or and field ordering other than specific header fields. This option was inherited from the QuickFIX C++ implementation.

Comment by Steve Bate [ 22/Apr/11 ]

To be more precise, it allows headers fields in the body and vice versa. So it's not actually related to specific header fields, but any header/body incorrect orderings. Again, it was not intended to inhibit validation of group field ordering.

Comment by Grant Birchmeier [ 24/Apr/11 ]

Steve, I agree with your assessment. Is there a reason you didn't close this bug?

Comment by Steve Bate [ 25/Apr/11 ]

Eric checked in some changes related to this issue (SVN Rev #1019). I was wondering if he had a different interpretation of the issue.

Comment by Eric Deshayes [ 26/Apr/11 ]

Steve, we fixed the issue in our integration branch by keeping the actually implemented semantic: we check the fields orders as it is done in quickfix.Message.parseGroup(String, StringField, DataDictionary, FieldMap).
The problem was that it was properly done in first level group but not in the groups of a group.

We could add the semantic you are referring to (out of order meaning body fields in the header, or header fields in the body) if needed. If we want to have both this semantic and the current one, we would have to add a new boolean setting.

Comment by Grant Birchmeier [ 26/Apr/11 ]

Is such a feature really needed? I've had counterparties in the past who've put fields out of order, but the resulting order was always deterministic. Simply rearranging the DataDictionary was all that was needed.

Comment by Christoph John [ 05/May/11 ]

Hi guys,

I'm a little confused. Could anyone please tell me what is wrong with ValidateFieldsOutOfOrder? Is the documentation wrong or the code? There are some tickets dealing with this, e.g. QFJ-477 and QFJ-520 (dup).

Our situation: We have a customer which suddenly reported that his messages get rejected after we have switched from QuickFIX/J 1.3.1 to 1.5.0. Looking at the messages we could see that he sent tag 50 (SenderSubID) incorrectly at the end of the message. On the old and the new version we have set ValidateFieldsOutOfOrder=N.
So my assumption would be that both QuickFIX versions behave the same. But with 1.5.0 the messages get rejected.

Looking at the documentation (and also stated by Steve in the second comment: "To be more precise, it allows headers fields in the body and vice versa. So it's not actually related to specific header fields, but any header/body incorrect orderings.") I would suppose that the message could be parsed correctly with either version. But with 1.5.0 this fails.

Here is a short test which fails with 1.5.0 regardless if I set dataDictionary.setCheckFieldsOutOfOrder to true or false.

{{ @Test
public void testNewOrderSingleWithMisplacedTag50()
throws Exception {

final DataDictionary dataDictionary = new DataDictionary( "etc/FIX.4.2.xml" );

// behaviour for QuickFIX 1.3.1: true -> parsing of nos2 fails
// behaviour for QuickFIX 1.3.1: false -> parsing of nos2 succeeds
// behaviour for QuickFIX 1.5.0: true -> parsing of nos2 fails
// behaviour for QuickFIX 1.5.0: false -> parsing of nos2 fails
dataDictionary.setCheckFieldsOutOfOrder( false );

String correctFixMessage = "8=FIX.4.2|9=218|35=D|49=cust|50=trader|56=FixGateway|34=449|52=20110420-09:17:40|11=clordid|54=1|38=50|59=6|40=2|44=77.1|"
+ "432=20110531|15=CHF|22=8|55=symbol|48=CH1234.CHF|21=1|60=20110420-11:17:39.000|63=0|207=VX|10=007|";
correctFixMessage = correctFixMessage.replace( '|', '\001' );
final NewOrderSingle nos = new NewOrderSingle();
nos.fromString( correctFixMessage, dataDictionary, true );
dataDictionary.validate( nos );
assertTrue( nos.getHeader().isSetField( new SenderSubID() ) );

String incorrectFixMessage = "8=FIX.4.2|9=218|35=D|49=cust|56=FixGateway|34=449|52=20110420-09:17:40|11=clordid|54=1|38=50|59=6|40=2|44=77.1|"
+ "432=20110531|15=CHF|22=8|55=symbol|48=CH1234.CHF|21=1|60=20110420-11:17:39.000|63=0|207=VX|50=trader|10=007|";
incorrectFixMessage = incorrectFixMessage.replace( '|', '\001' );
final NewOrderSingle nos2 = new NewOrderSingle();
nos2.fromString( incorrectFixMessage, dataDictionary, true );
dataDictionary.validate( nos2 );
assertTrue( nos2.getHeader().isSetField( new SenderSubID() ) ); }}

Any help is greatly appreciated.

Thanks
Chris.

Comment by Jörg Thönnes [ 10/May/11 ]

In reply to comment #5:
> We could add the semantic you are referring to (out of order meaning body fields
> in the header, or header fields in the body) if needed. If we want to have both
> this semantic and the current one, we would have to add a new boolean setting.

Salut Eric,

could you re-add this semantic for the QF/J 1.5.1 release as you offered above?
We rely on it and it caused us major troubles with one customer.

Merci, Jörg

Comment by Eric Deshayes [ 12/May/11 ]

Hi Jörg,
I will fix the behaviour for the ValidateFieldsOutOfOrder property as per the documentation (and in sync with quickfix c++): out of order meaning body fields in the header, or header fields in the body.
I will add a new property to bypass the check on the group fields order.

Comment by Eric Deshayes [ 12/May/11 ]

committed on the integration branch in rev#1032

added new session property to ignore misordered group fields: ValidateUnorderedGroupFields.

for the initial ValidateFieldsOutOfOrder property, the expected behaviour has been implemented.
added 2 unit tests :
quickfix.DataDictionaryTest.testNewOrderSingleWithCorrectTag50()
quickfix.DataDictionaryTest.testNewOrderSingleWithMisplacedTag50()





[QFJ-534] Resend Request Synchronization Patch Created: 28/Jun/10  Updated: 12/Apr/11  Resolved: 12/Apr/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Critical
Reporter: SSE Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: None
Environment:

All


Issue Links:
Duplicate
duplicates QFJ-429 Concurrency reading / writting file s... Closed

 Description   

QuickFIX/J has an issue with the file store and message sequence numbers when simultaneously answering a ResendRequest on a connection, and processing brand new messages routed to that connection which are also to be sent to the client. The file pointers were not handled correctly for reading stored messages which are to be sent as PossDups, and for new messages to be written to the outgoing file. This caused outgoing message store file corruption, and repeated / out of sequence seqnums being sent.

Fixed: synchronization QFJ patch, where the thread is blocked from sending new messages (i.e. buffering) until a ResendRequest is fully answered.

private void nextResendRequest(Message resendRequest) throws IOException, RejectLogon,
FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType,
InvalidMessage {
if (!verify(resendRequest, false, false))

{ return; }

// ******* ADDED *******
state.lockSenderMsgSeqNum();
try

{ int beginSeqNo = resendRequest.getInt(BeginSeqNo.FIELD); int endSeqNo = resendRequest.getInt(EndSeqNo.FIELD); getLog().onEvent( "Received ResendRequest FROM: " + beginSeqNo + " TO: " + formatEndSeqNum(endSeqNo)); .... // ******* ADDED ******* }

finally

{ state.unlockSenderMsgSeqNum(); }

}

(Internal reference: IC_57785)



 Comments   
Comment by Eric Deshayes [ 12/Apr/11 ]

This issue has already been fixed in 1.5.0.

Comment by Eric Deshayes [ 12/Apr/11 ]

Duplicate of QFJ-429





[QFJ-533] NumberFormatException parsing message closes the session Created: 24/Jun/10  Updated: 23/Nov/17  Resolved: 23/Nov/17

Status: Resolved
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.5.0
Fix Version/s: 2.0.1

Type: Bug Priority: Default
Reporter: Colin Crist Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None


 Description   

The following exception unwinds the stack completely - the MINA handler does not check for this exception:

I think the handler should create a reject message and pass it back ?

Tested with the latest code (23/7/2010) from trunk.

INFO: FIX.4.4:MDFXSSUS_TUTOGB21->MDFX_SBOSUS3F: For input string: "abc"

java.lang.NumberFormatException: For input string: "abc"

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

at java.lang.Integer.parseInt(Integer.java:447)

at java.lang.Integer.parseInt(Integer.java:497)

at quickfix.Message.parseGroup(Message.java:575)

at quickfix.Message.parseBody(Message.java:554)

at quickfix.Message.parse(Message.java:467)

at quickfix.MessageUtils.parse(MessageUtils.java:151)

at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:116)

at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:703)

at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)

at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:54)

at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)

at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:62)

at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:200)

at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)

at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:54)

at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)

at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)

at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)

at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)

at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:246)

at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:206)

at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)

at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:506)

at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)

at java.lang.Thread.run(Thread.java:595)



 Comments   
Comment by Christoph John [ 23/Nov/17 ]

Fixed by https://github.com/pbyrne413 via https://github.com/quickfix-j/quickfixj/pull/150.





[QFJ-532] When creating Message from String, no MsgType is set Created: 23/Jun/10  Updated: 01/Apr/14  Resolved: 01/Apr/14

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Daniel Ludwig Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Windows XP, Java/Eclipse



 Description   

When I try to create a quickfix.Message from String, using one of the following constructors: (String, DataDictionary, Validation) or (String, Validation), no MsgType is set in the created quickfix.Message, even if included in the String itself.

The same result can be achieved, when using the fromString() Method.

My application can therefore not determine the type of Message passed.



 Comments   
Comment by Brad Harvey [ 24/Jun/10 ]

MessageUtils#parse might do the trick.

Comment by Christoph John [ 01/Apr/14 ]

Could not reproduce this in unit tests.





[QFJ-531] To set the number of logon attempts Created: 23/Jun/10  Updated: 23/Jun/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: Future Releases
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Pranab Kumar Naik Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Linux



 Description   

I was trying to set up the number of failed logon attempts after which the logon session would be created with a different host. The configuration does match with the interval between reconnects, but I thought it would be useful if the number of reconnect attempts may also be configurable from the config file. Or is there an option that I maybe missing ?






[QFJ-530] FIX Session Resets By Itself Created: 10/Jun/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: Hariharan Kilakkencherry Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Sun Solaris



 Description   

1) Wondering if someone could help with some fix session issues. This doesn't happen very often, but at least once every day, mostly during the evening. For some reason which I am not able to figure out, the session resets by itself thus causing the sequence number to be reset. Any idea why? I am trying to test the app from home , which is after like few hours of inactivity. Could that be the reason?
2) Whatever maybe the reason, we do not want the session to be reset automatically. Is there a way to prevent this from happening ?

Event Log:

20100610-02:03:05: Session FIX.4.2:QA_JPMAM->QA_COSMOS:NYEOSESSION schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC)
20100610-02:03:05: Session state is not current; resetting FIX.4.2:QA_JPMAM->QA_COSMOS:NYEOSESSION
20100610-02:03:05: Created session: FIX.4.2:QA_JPMAM->QA_COSMOS:NYEOSESSION
20100610-02:03:13: Initiated logon request
20100610-02:03:14: Disconnecting
20100610-02:03:14: quickfix.SessionException Logon state is not valid for message (MsgType=5)
20100610-02:03:43: Initiated logon request
20100610-02:03:43: Disconnecting
20100610-02:03:43: Received logout request
20100610-02:03:43: Attempt to send while not connected (message stored until connected).
20100610-02:03:44: Sent logout response

Message Log:

8=FIX.4.29=7235=A34=149=QA_JPMAM52=20100610-02:03:13.89456=QA_COSMOS98=0108=6010=035
8=FIX.4.29=9335=549=QA_COSMOS56=QA_JPMAM34=52552=20100610-02:03:1358=Expected Seq 729 but received 110=161






[QFJ-529] RTT benchmarking Created: 05/Jun/10  Updated: 05/Jun/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Wayne Zhu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

windows 7 professional 64 bits, multiple core Intel



 Description   

I have tested with a simple server and client setup using a single session in the same machine(tcp socket on local host). The client sent in new orders and got execution reports back. If the orders were sent at a high data rate for a period of 100-200ms, the round trip time for a new order and the corresponding report was not good.

My understanding is that there are two different threads in sending and receiving messages. What could be the reason causing QuickFix engine to slow down processing the incoming messages? Since there is no network overhead, it's most likely to be caused by the decoder and the way FIX message is constructed.






[QFJ-528] Message generator doesn't sanitize value descriptions before using them as identifiers. Created: 27/May/10  Updated: 27/May/10

Status: Open
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Serkan Kaba Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows 7 ıIBM JDK6



 Description   

Message generator uses enum value descriptions as constant names but doesn't sanitize them before using them as identifiers. Since the value is a free format string the generator produces invalid/uncompilable code.

I think the description tag value should be sanitized as a valid Java identifier before it's used.

Thanks in advance.

Serkan KABA






[QFJ-527] Template-based FIX sessions get disconnected on first logon Created: 18/May/10  Updated: 15/Aug/12  Resolved: 15/Aug/12

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

Type: Bug Priority: Default
Reporter: Scott Harrington Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-357 Logout message is sent before Logon o... Closed

 Description   

I have a custom AcceptorSessionProvider similar to DynamicAcceptorSessionProvider.

The Sessions that get created on-the-fly at Logon time sometimes get disconnected right away. If the SessionID has never been seen before, it works fine. The disconnect only happens if the MessageStore has a previous *.session file lying around from a previous day. Subsequent logons by the same client work fine.

The problem was that Session.checkSessionTime always returns false in the constructor, and it caches this result for 1 second. The fix is to NOT cache a negative result. Apologies for my bad habit of posting patches here in the description, but it seems silly to attach a file when the fix is just a single line change:

Index: core/src/main/java/quickfix/Session.java
===================================================================
— core/src/main/java/quickfix/Session.java (revision 950)
+++ core/src/main/java/quickfix/Session.java (working copy)
@@ -489,7 +489,7 @@
// necessary to do for every message received.
//
Date date = SystemTime.getDate();

  • if ((date.getTime() - lastSessionTimeCheck) >= 1000L) {
    + if (!lastSessionTimeResult || (date.getTime() - lastSessionTimeCheck) >= 1000L) {
    Date getSessionCreationTime = state.getCreationTime();
    lastSessionTimeResult = sessionSchedule.isSameSession(SystemTime.getUtcCalendar(date),
    SystemTime.getUtcCalendar(getSessionCreationTime));


 Comments   
Comment by Christoph John [ 15/Aug/12 ]

This was solved in the course of QFJ-357.





[QFJ-526] Regression: QFJ-419 change forces ReconnectInterval to be in DEFAULT section Created: 16/May/10  Updated: 18/May/10  Resolved: 17/May/10

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

Type: Bug Priority: Default
Reporter: Scott Harrington Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm testing against the SVN trunk and one of my working configs failed with "ReconnectInterval not defined". This config has the ReconnectInterval defined only in the [SESSION] sections, and not in the [DEFAULT]. Simple one-line fix; see below.

Index: core/src/main/java/quickfix/DefaultSessionFactory.java
===================================================================
— core/src/main/java/quickfix/DefaultSessionFactory.java (revision 950)
+++ core/src/main/java/quickfix/DefaultSessionFactory.java (working copy)
@@ -306,7 +306,7 @@
private int[] getLogonIntervalsInSeconds(SessionSettings settings, SessionID sessionID) throws ConfigError {
if (settings.isSetting(sessionID, Initiator.SETTING_RECONNECT_INTERVAL)) {
try

{ - String raw = settings.getString(Initiator.SETTING_RECONNECT_INTERVAL); + String raw = settings.getString(sessionID, Initiator.SETTING_RECONNECT_INTERVAL); int[] ret = SessionSettings.parseSettingReconnectInterval(raw); if (ret != null) return ret; }

catch (Throwable e) {



 Comments   
Comment by Laurent Danesi [ 17/May/10 ]

Thank you Scott,

I have just re-committed the fix.

Laurent

Comment by Scott Harrington [ 17/May/10 ]

Hi Laurent: Unfortunately the same mistake was repeated in nearly identical code in AbstractSocketInitiator; not sure why I tripped over it in one place and not the other. Could you please fix this one also:

Index: core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java
===================================================================
— core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (revision 950)
+++ core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (working copy)
@@ -155,7 +155,7 @@
SessionSettings settings = getSettings();
if (settings.isSetting(sessionID, Initiator.SETTING_RECONNECT_INTERVAL)) {
try

{ - String raw = settings.getString(Initiator.SETTING_RECONNECT_INTERVAL); + String raw = settings.getString(sessionID, Initiator.SETTING_RECONNECT_INTERVAL); int[] ret = SessionSettings.parseSettingReconnectInterval(raw); if (ret != null) return ret; }

catch (Throwable e) {

Comment by Laurent Danesi [ 18/May/10 ]

The second part is in now.

Thank you





[QFJ-524] Session responder lock fix for QFJ-421 got reverted in SVN Created: 14/May/10  Updated: 15/Nov/12  Resolved: 08/Jul/10

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

Type: Bug Priority: Default
Reporter: Scott Harrington Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None


 Description   

The one-line fix for QFJ-421 in Mar 2009 (r921) seems to have been accidentally reverted in Jan 2010 by r928.

Why not use an idiom such as:

private final Object responderSync = new byte[0];

Others may prefer simply a new Object() for a lock like this. I think the debate[1] over bytecode size or whatever is moot, but clearly a String was a bad choice here for maintainability reasons, i.e. it just looks like a constant value suitable to be interned.

[1] http://java.itags.org/java-core-apis/32998/ "Java Core APIs: locks: Object versus empty byte array"



 Comments   
Comment by Scott Harrington [ 15/May/10 ]

Ooh even better, use a ReentrantLock as suggested in QFJ-484.

Comment by Laurent Danesi [ 08/Jul/10 ]

Duplicate QFJ-484





[QFJ-523] Couldn't get connection because we are at maximum connection count (10/10) and there are none available Created: 13/May/10  Updated: 13/May/10

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: andrew M Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows server 2008 r2, jdk1.7.0_b89 x64 (I know...), 8 core machine.



 Description   

I'm seeing this error. It has only happened to me once so I can't reproduce it. Maybe same as this?
http://www.quickfixj.org/jira/browse/QFJ-313

java.io.IOException: Couldn't get connection because we are at maximum connection count (10/10) and there are none available
at quickfix.JdbcStore.storeSequenceNumbers(JdbcStore.java:286)
at quickfix.JdbcStore.setNextTargetMsgSeqNum(JdbcStore.java:272)
at quickfix.JdbcStore.incrNextTargetMsgSeqNum(JdbcStore.java:173)
at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:359)
at quickfix.Session.next(Session.java:799)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:85)
Caused by: java.sql.SQLException: Couldn't get connection because we are at maximum connection count (10/10) and there are none available
at org.logicalcobwebs.proxool.Prototyper.quickRefuse(Prototyper.java:309)
at org.logicalcobwebs.proxool.ConnectionPool.getConnection(ConnectionPool.java:152)
at org.logicalcobwebs.proxool.ProxoolDataSource.getConnection(ProxoolDataSource.java:97)
at quickfix.JdbcStore.storeSequenceNumbers(JdbcStore.java:279)
... 5 more






[QFJ-522] Engine incorrectly assumes CstmApplVerID implies Session and DataDictionary uniqueness Created: 10/May/10  Updated: 15/Nov/12  Resolved: 24/Apr/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0, Future Releases
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Brent Bradbury Assignee: Grant Birchmeier
Resolution: Fixed Votes: 1
Labels: None
Environment:

Centos 5.3, Sun JDK 1.6


Attachments: File CORRECTED_executorExampleAddendum.diff     File cstmApplVerIDFix.diff     File executorExampleAddendum.diff    

 Description   

To show bug:
1) Create FIXT1.1 / FIX.5.0 session with custom TransportDataDictionary and ApplicationDataDictionary
2) Start session, send session level logins
3) Try sending Application-level message to QFix/J session with CstmApplVerID (field 1129) set in the header to some value (I chose '5.4' for the value)
4) QFix/J emits exception trying to find DataDictionary FIX50_5_4, where '5_4' reflects value of the CstmApplVerID field

Why it happens:
QFix/J indexes DataDictionaries by a AppVersionKey. This key uses ApplVerID and CstmApplVerID fields to generate a unique reference to a given DataDictionary. I think it is a correct interpretation of the FIX spec to say that it should only use ApplVerID, because CstmApplVerID (1) is not a required field, and thus may or may not consistently appear in message headers, (2) does not have a required default value in a configuration file (e.g. DefaultApplVerID) (3) is defined in the FIX spec as "Used to support bilaterally agreed custom functionality", in no way affecting the DataDictionary or implying that a specific one should be used.

The fix:
I fixed this by removing all references to CstmApplVerID in the Engine, which allows CstmApplVerID to behave like a normal header field, leaving the implementation of any functionality based on its value up to the user. Most of the revolved around DefaultDataDictionaryProvider.java.



 Comments   
Comment by Brent Bradbury [ 10/May/10 ]

Apply the patch to trunk/core/src.

I'm not sure how the unit tests shake out, because I don't see where the specifics of failures/errors is shown?

Comment by Brent Bradbury [ 10/May/10 ]

Also, the patch is against rev 949 of trunk SVN.

Comment by Grant Birchmeier [ 11/Aug/10 ]

If you patch cstmApplVerIDFix.diff on a clean checkout and build, or if you patch then "ant clean" then rebuild, you'll get a compile error for the "executor" example.

It needed to be updated to match an updated interface, which is a one-line fix described in attached patch executorExampleAddendum.diff.

Comment by Grant Birchmeier [ 11/Aug/10 ]

Oops. I messed up my patch file. Use this one. Apologies.

Comment by Grant Birchmeier [ 24/Apr/11 ]

code fix in trunk r1020





[QFJ-521] Support use of partial session ID for routing purposes Created: 10/May/10  Updated: 09/Jun/11

Status: Reopened
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.3.2, 1.3.3, 1.4.0
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: Rhys Yarranton Assignee: Grant Birchmeier
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File diff3.txt    

 Description   

QFJ-272/1.3.1 added several fields to SessionID (SenderSubID, TargetSubID, SenderLocationID). These fields will be populated in MessageUtils.getReverseSessionID(...) if they are set in the Login message. They then form part of the session look-up in AbstractSocketAcceptor.StaticAcceptorSessionProvider.

In 1.2.1 and below, MessageUtils.getReverseSessionID included only the comp IDs, not the sub-IDs and SenderLocationID.

This breaks us in two ways. One is that we have been configuring our sessions by the comp IDs, which works well with the 1.2.1 code but mismatches with the 1.3.1+ code even if both sides get all their IDs right.

The other, and more important, is that several of our customer gateways will vary the SenderSubID and/or TargetSubID. For example, the FIX spec describes SenderSubID as being useful to distinguish between traders, and that messages not intended for a particular trader may optionally be flagged as ADMIN. It seems to me that the changes in QFJ-272 have resulted in a restrictions/obstacles beyond what was really intended by the spec, and certainly beyond what our customers will handle.

Fortunately there is a mechanism to provide your own AcceptorSessionProvider, which can be used to work around this issue. That said, the default behaviour is not ideal. Attached is a patch to replace StaticAcceptorSessionProvider with a new class, DefaultAcceptorProvider, which first tries a "strict" 1.3.1-style lookup, and if it fails, tries a 1.2.1-style lookup based on the Comp IDs only.

If the maintainers have an objection to the patch, I would suggest at the least that something like DefaultAcceptorProvider (plus instructions) be included in the distribution for those who cannot use StaticAcceptorSessionProvider.



 Comments   
Comment by Steve Bate [ 10/May/10 ]

The specifications include subID and locationID in information such as DeliverTo and OnBehalfOf, which are used for session routing. A route endpoint in this case is identified by CompID/SubID/LocationID in the originator sessionID and in the third-party routing cases. As you mentioned, I have seen the specification describe senderSubID as being useful to distinquish between traders, but this appears to me to still be in the context of message routing to a specific trader (or trading desk) within a broader organization (represented by the compID). Every counterparty I've worked with that used subIDs have used them for session identification and routing.

That said, from what I've seen on the FPL forums there was confusion in FIX 4.2 and before about the use of session ID fields for non-routing purposes. In FIX 4.3 and later, the Parties component is recommended for identifying traders outside the context of message routing.

I'm not the only one making the decision, but I'm open to to a feature that optionally ignores parts of the session ID for routing purposes.

Comment by Grant Birchmeier [ 19/Jul/10 ]

I am having similar issues as Rhys.

While reading the 4.4 spec to puzzle out my issues, I could not find where it says that SubID and LocationID should be used for anything substantial, let alone for message routing or session identification. Like Rhys, I'm not sure QFJ-272 is a correct interpretation. Such a change is not present in the latest QF/C++.

For now I'm integrating Rhys' patch into our local QF/J build, and being able to ignore the QFJ-272 additions is quite important for my company's usage.

Comment by Grant Birchmeier [ 19/Jul/10 ]

To integrate this patch into r958, DefaultAcceptorSessionProvider::getSession() needs a slight update to match an updated AcceptorSessionProvider interface:

  • public Session getSession(SessionID sessionID)
    + public Session getSession(SessionID sessionID, SessionConnector ignored)
Comment by Grant Birchmeier [ 12/Apr/11 ]

Committed to 1015

Comment by Jörg Thönnes [ 09/Jun/11 ]

Re-opening the issue to document the changes introduced
by this ticket.

IMHO, the handling of sub IDs and location IDs in QF/J deserves an extra section in the manual. There was some
ongoing discussion in the mailings lists and FPL forums
and it also not clear to me how QF/J handles this now.





[QFJ-520] Documentation for ValidateFieldsOutOfOrder is incorrect Created: 10/May/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File diff4.txt     Text File diff4.txt    

 Description   

The documentation for ValidateFieldsOutOfOrder reads:
"If set to N, fields that are out of order (i.e. body fields in the header, or header fields in the body) will not be rejected. Useful for connecting to systems which do not properly order fields."

Search of the source code reveals that it has to do with mis-ordered repeating group fields. It does nothing about header fields in the body or vice versa. (Verified by experiment.)



 Comments   
Comment by Rhys Yarranton [ 12/May/10 ]

On further investigation, it seems in an earlier version we were able tolerate header tags in the body. See also QFJ-477.

Also found that the behaviour around duplicate fields has changed, probably at about the same time. There is currently no way to relax it. (Believe it or not, we have seen problem gateways in production that produce dups.)

The attached patch makes ValidateFieldsOutOfOrder allow header tags in the body.
In addition, it add a new setting "ValidateDuplicateFields". Default is true.
Finally, I noticed that the DataDictionary.copyFrom method does not copy the AllowUnknownMsgFields setting. Now it does.

There may still be some holes out there. For example, suppose you turn off validation of user defined fields, and someone throws a repeating group at you that isn't in your data dictionary. I suspect this will show as a duplicate field. (Unless you use the new setting.)

Comment by Rhys Yarranton [ 25/Oct/10 ]

Revised version of diff4.txt. First one was missing DefaultSessionFactory.java.





[QFJ-519] Minor build problems in QuickFIX/J 1.4.0 Created: 04/May/10  Updated: 16/Oct/12  Resolved: 16/Oct/12

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

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Attachments: Text File QFJ-519.FIXMessageEncoder.diff.1.4.0.txt    
Issue Links:
Relates
is related to QFJ-414 quickfixj-core.jar includes FIXT11 an... Closed
is related to QFJ-498 Upgrade MINA library to latest version Closed

 Description   

1. core/build.xml line 101 specifies memoryMaximumSize="256m" for the compile. This results in out-of-memory on 64 bit Linux. 512m works.

2. core/build.xml line 101 line 125 excludes the FIX 4.x message classes from the quickfix-core.xxx.jar. The FIX 5.x messages are not excluding, bloating quickfix-core.xxx.jar by more than 4MiB. Suggestion: add
<exclude name="quickfix/fix5?/**" />

3. The Mina 1.1.0 libraries are quite out of date. The current version at time of writing was 1.1.7. There is a small API change in 1.1.7 that requires editing FIXMessageEncoder.java. Will attach patch.



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

Fixed by related issues.





[QFJ-518] Incomplete addressing on BusinessMessageReject when using a FIX routing network Created: 04/May/10  Updated: 02/Apr/15  Resolved: 08/Oct/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Cliff Evans Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None
Environment:

JDK 1.6_20



 Description   

If an exception is thrown in fromApp, e.g. FieldNotFound, and we're using FIX4.2 or greater when using a Routing Network, e.g. Autex, a BusinessMessageReject message is thrown. The message does not currently contain all of the addressing information required to successfully deliver the BMR message if the message isn't going directly to a recipient.

If the message which causes the BMR contains routing information in:

OnBehalfOfCompID (115) and OnBehalfOfSubID (116)

This information should be included in the BMR reply in:

DeliverToCompID (128) and DeliverToSubID (129)

This will allow the Routing network to correctly deliver the message to the Application of the final recipient. Not including these fields results in the message being delivered directly to the Routing Network itself which doesn't know what to do with it.



 Comments   
Comment by Cliff Evans [ 12/May/10 ]

It looks to me like there's just a missing call to:

reject.reverseRoute(header);

In the generateBusinessReject method. I can't think of any reason why you wouldn't route a BMR to the individual broker rather than the FIX routing network.





[QFJ-517] CLONE -On checksum errors, include information on the problem section of the stream Created: 29/Apr/10  Updated: 29/Apr/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1, 1.3.0, 1.3.1
Fix Version/s: 1.3.2

Type: Improvement Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

If there is a checksum error an error is logged, but it does not include the problem section of stream. This would useful in determining if it was a garble, a problem with the counterparty's software or whatever.

A patch we've tried is to add the following snippet to FIXMessageDecoder.handleError(ByteBuffer, int, String, boolean), right before the "if(disconnect))":

int mark = buffer.position();
try {
StringBuilder sb = new StringBuilder(text);
sb.append("\nBuffer debug info: ").append(getBufferDebugInfo(buffer));
buffer.position(0);
sb.append("\nBuffer contents: ");
try

{ final byte[] array = new byte[buffer.limit()]; for(int i = 0; i < array.length; ++i) array[i] = buffer.get(); sb.append(new String(array, "ISO-8859-1")); }

catch (Exception e)

{ sb.append(buffer.getHexDump()); }

text = sb.toString();
} finally

{ buffer.position(mark); }

 Comments   
Comment by Rhys Yarranton [ 29/Apr/10 ]

This is not fixed in 1.4.0.





[QFJ-516] FileStore + set() + body file empty Created: 23/Apr/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: Kamel Slimani Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

xp, sun sdk 1.5



 Description   

Hi,

i want to write (persist) a message (NewOrderSignle) using FileStore class and its set() method. The problem is that the file SESSION is well filled, while the BODY file remains empty !!! For information, the message i pass is valid, and the method FileStore.set(), when it calls the write() method of java.io.RandomAccessFile, the message is correct (not empty) ...
Any help please?



 Comments   
Comment by Steve Bate [ 23/Apr/10 ]

Unless you have a very special reason for doing it, you should not be persisting messages yourself using the FileStore. This is only for use by the Session implementation.

Comment by Kamel Slimani [ 23/Apr/10 ]

Thank you for the reply. That being said:
1/i need to store messages, then look for them, or to look (search) for a given contents (a given element) in one or several messages.
In addition to the file, I must define a cache system to store some messages.
2/A Data Base approach to store messages is not an option for me given my performance constraints (hence use of files rather than a DBMS).
3/ "Unless you have a very special reason for doing it, you should not be persisting messages yourself using the FileStore. This is only for use by the Session implementation. " : it does not explain why the call to the writeBytes method of java.io.RandomAccessFile write anything in this case.

Have you an explanation or indication for what I want to do please?





[QFJ-515] Broken Links in http://www.quickfixj.org/quickfixj/usermanual/ Created: 16/Apr/10  Updated: 16/Apr/10

Status: Open
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Dale Wilson Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Any browser; any OS. I tried Chrome, FireFOX and IE8 on Windows 7



 Description   

The page at http://www.quickfixj.org/quickfixj/usermanual/ contain links that look like:

<a href="http://http://directory.apache.org/subprojects/mina/">MINA</a>)

Note that http:// appears twice twice.






[QFJ-514] How to get all incoming messages from the message store. Created: 05/Mar/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: Tausseef Ahmad Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows xp sp2



 Description   

I would like to get the incoming messages from the message store. When i use the message store get() function, the messages which i get are all outgoing. But when i use ResendRequest() i get the desired messages but none of the events (fromApp, fromAdmin,...) are fired. The messages are there in the .message file. While using Resend Request messages are shown also on screen as well as in log file.



 Comments   
Comment by Laurent Danesi [ 05/Mar/10 ]

Hi,

In fact, QFJ does not store incoming messages in its MessageStore and it stores only outgoing message to be able to resend them on a ResendRequest Message.

Anyway, you can use an implementation of LogFactory to store them if needed by yourself.

Laurent





[QFJ-513] Sequence gets reset even with ResetOnLogon, ResetOnLogout and ResetOnDisconnect all set to N. Created: 04/Mar/10  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Paul Michael Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Below are some logs of the issue:

ABC-MARKET uses ResetOnLogon = Y
ABC-ORDER uses ResetOnLogon = N

10:27:49.581 EST INFO 3 - onLogout FIX.4.3:ABC-MARKET->XYZ
10:27:49.581 EST ERROR 3 - The FIX client FIX.4.3:ABC-MARKET->XYZ disconnected.

10:29:08.530 EST INFO 3 - >> 8=FIX.4.3|9=60|35=5|34=2286|49=XYZ|52=20100302-15:29:08|56=ABC-ORDER|10=252|
10:29:08.530 EST INFO 3 - << 8=FIX.4.3|9=64|35=5|34=2354|49=ABC-ORDER|52=20100302-15:29:08.530|56=XYZ|10=194|
10:29:08.542 EST INFO 3 - onLogout FIX.4.3:ABC-ORDER->XYZ
10:29:08.542 EST ERROR 3 - The FIX client FIX.4.3:ABC-ORDER->XYZ disconnected.

10:29:08.542 EST ERROR 3 - The next FIX.4.3:ABC-ORDER->XYZ Sending Sequence is expected to be: 2355

Sequence is reset for ABC-MARKET during reconnect (correct):

10:29:55.143 EST INFO cceptorIoHandler - MINA session created: /127.0.0.1:43238
10:29:55.143 EST INFO 3 - >> 8=FIX.4.3|9=80|35=A|34=1|49=XYZ|52=20100302-15:29:54|56=ABC-MARKET|98=0|108=30|141=Y|10=018|
10:29:55.143 EST INFO 3 - << 8=FIX.4.3|9=84|35=A|34=1|49=ABC-MARKET|52=20100302-15:29:55.143|56=XYZ|98=0|108=30|141=Y|10=221|
10:29:55.143 EST INFO 3 - onLogon FIX.4.3:ABC-MARKET->XYZ

Sequence is also reset for ABC-ORDER during reconnect (incorrect):

10:29:55.148 EST INFO cceptorIoHandler - MINA session created: /XX.XX.X.XXX:57274
10:29:55.171 EST INFO 3 - >> 8=FIX.4.3|9=78|35=A|34=2287|49=XYZ|52=20100302-15:29:54|56=ABC-ORDER|98=0|108=30|141=N|10=078|
10:29:55.171 EST INFO 3 - << 8=FIX.4.3|9=73|35=A|34=1|49=ABC-ORDER|52=20100302-15:29:55.171|56=XYZ|98=0|108=30|10=077|

Unfortunately, these are the only details I can provide for now, I'm still trying to get the exact configuration settings which caused the problem but the Reset flags as mentioned in the title are all set to N for ABC-ORDER.

I was told that this issue has occurred twice already in production (the logs are from prod) but I can't seem to create a test case which shows the exact error for this yet.

Thanks in advance.



 Comments   
Comment by Laurent Danesi [ 04/Mar/10 ]

Hi,

Could you provide us the SessionSettings and the event log, please?

Laurent

Comment by Paul Michael [ 05/Mar/10 ]

Thanks Laurent for the reply. After seeing the production logs and looking at the code, it looks like the problem is not with QuickFix/J but with our code.

Below is the scenario:

1. During EOD, the SocketAcceptor for ABC-ORDER is stopped.
2. There's a boolean flag that is triggered saying that EOD has begun.
3. The flag on step 2 will change the ResetOnLogon value to Y for ABC-ORDER.
4. The SocketAcceptor is restarted with value from step 3.
5. During startup of the SocketAcceptor, the flag for step 2 is changed to false (indicating EOD has completed).
6. Since the SocketAcceptor was started using ResetOnLogon = Y, re-logons cause the sequence to be reset and only way to fix is to stop/start Acceptor so the flag for EOD is now false and consequently ResetOnLogon used by initiator will now be false.

I have a feeling that we should be using the EOD functionality from QuickFix/J instead of our adhoc solution. But given this scenario I mentioned, and given that I'm not allowed to change much in code that's already in Production, can you recommend an alternative solution?

Currently, I'm gearing towards updating toAdmin() method to check whether our flag for EOD is true and if Y, perform the checks done inside generateLogon() of Session and set the ResetSeqNumFlag in the Logon message as necessary. One problem I see with this approach is that the resetState() method of Session is currently marked private and therefore inaccessible from the toAdmin() method of our Application implementation.

Anyway, I'll also try to update the ticket title/description to be more clear.

Many thanks.

Comment by Paul Michael [ 05/Mar/10 ]

The other approach I can think of (which is rather hacky) is to change the refreshOnLogon field of Session to non-final and provide a setter method so I can change the value to N after running EOD (which initially sets this to Y).

Can you tell me why this is a bad idea (aside from the fact that I need to make this adjustment for every new release of quickfixj)?

Anyway, thanks for your time and sorry for the newbie questions.

Comment by Steve Bate [ 05/Apr/10 ]

Those fields are final so they will be thread safe (due to immutability). We would need to make them volatile or synchronize them in some other way if they were mutable.





[QFJ-512] How do I change the order of the header tags? Created: 04/Mar/10  Updated: 15/Dec/14  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Willis Todd Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Using FIX 4.4 (QuickFIX/J) in Eclipse.


Issue Links:
Relates
is related to QFJ-416 Support Header/Trailer field ordering... Open

 Description   

I currently have a working application for one broker using FIX 4.4 and want to use it to connect to another broker using 4.4 with different information in my config file to login, but the problem I am having is that the second broker wants the first seven tags in a specific order, slightly different than my app that is currently sending them and I don't know how to change it. I'm not a professional programmer, so maybe that's why I am feeling so lost, but here is where I am at:

Their spec asks for the first 7 fields in the exact order, tag 8, 9, 35, 49, 56, 34, 52. But I have 8, 9, 35, 34, 49, 50.

8=FIX.4.4
9=139
35=A
34=1
49=senderCompIDme
50=
52=20100217-19:24:46.109
56=THEIRDEMO_QUOTE.FOREX.NET
57=56
553=userName
554=passWord123
98=0
108=30
141=Y
10=107

Seeing that tag 50 is blank, maybe I should delete that one while I'm at it? If anyone has done this, or can explain how, I am totally lost! At this point, they won't even let me login to the second one without the order of these tags being changed.
Any and everyone's help is greatly appreciated!
Thanks in advance!



 Comments   
Comment by Laurent Danesi [ 04/Mar/10 ]

Hi,

You need to modify your FIX44.xml file to set the order you want for each message (8,9,35,49,56,34 et 52 in your case).
After that, you must regenerate the Fix Messages with Ant task (or Eclipse Ant launcher) specifying this property:

<param name="generator.orderedFields" value="true"/>

This will generate FIX Messages with ordered fields and should fix your issue.

Laurent

Comment by Willis Todd [ 04/Mar/10 ]

Hey Laurent,
Thanks for the quick response! This is something I've never done before, so forgive me for sounding ignorant. So here is the first part of my xml file:

<fix major="4" minor="4">
<header>
<field name="BeginString" required="Y"/>
<field name="BodyLength" required="Y"/>
<field name="MsgType" required="Y"/>
<field name="SenderCompID" required="Y"/>
<field name="TargetCompID" required="Y"/>
<field name="OnBehalfOfCompID" required="N"/>
<field name="DeliverToCompID" required="N"/>
<field name="SecureDataLen" required="N"/>
<field name="SecureData" required="N"/>
<field name="MsgSeqNum" required="Y"/>
<field name="SenderSubID" required="N"/>
<field name="SenderLocationID" required="N"/>
<field name="TargetSubID" required="N"/>
<field name="TargetLocationID" required="N"/>
<field name="OnBehalfOfSubID" required="N"/>
<field name="OnBehalfOfLocationID" required="N"/>
<field name="DeliverToSubID" required="N"/>
<field name="DeliverToLocationID" required="N"/>
<field name="PossDupFlag" required="N"/>
<field name="PossResend" required="N"/>
<field name="SendingTime" required="Y"/>
<field name="OrigSendingTime" required="N"/>
<field name="XmlDataLen" required="N"/>
<field name="XmlData" required="N"/>
<field name="MessageEncoding" required="N"/>
<field name="LastMsgSeqNumProcessed" required="N"/>
<group name="NoHops" required="N">
<field name="HopCompID" required="N"/>
<field name="HopSendingTime" required="N"/>
<field name="HopRefID" required="N"/>
</group>
</header>

The required tags are the ones I need, and they are already in the order I need if we ignore the tags not required. So I just want to make sure this is the first part you were talking about. The part about regenerating the Fix messages with Eclipse Ant launcher is the part I have never done and I can't find. And do I just put the line of code you mentioned inside the xml file at the top? Or is that put somewhere else when I find the Ant Launcher? Again, I apologize for being such a newbie on this.
Thanks again for your help!

Comment by Laurent Danesi [ 04/Mar/10 ]

Hi,

Sorry, I will try to be more precise this time .
So, firstly you need to download the source version of quickFixJ (from SVN or in zip format).
Go to the Core folder and edit the build.xml file, you should see this property:

<property name="generator.orderedFields" value="false" />

change it to

<property name="generator.orderedFields" value="true" />

Save the file.

Put your FIX44.xml file in quickfixj/core/src/main/resources.

Finally regenerate the Java code of the FIX messages by opening a CommandLine in quickfixj/core and type:

ant generate.code.

Feel free to contact me if you need more informations.

Laurent

Comment by Willis Todd [ 04/Mar/10 ]

Thank you again Laurent!
So I thought I had what I needed, but I can't find a folder named "Core" or the build.xml anywhere within the quickFixJ folder and sub folders, so I am wondering if I am using the wrong thing. This is the file path on my computer where I am looking:
D:\quickfixj-1.4.0-bin\quickfixj
But in that folder I only see folders bin, doc, etc, lib, src.zip, a license file, and several jar files. I noticed one of them was "quickfixj-core-1.4.0" and tried looking in that, but decided that can't be what you are talking right? I did find some other files on my computer named "build.xml" but none of them had the line of code you mentioned in them and appear to be for non FIX programs anyway.
So does it look like I have downloaded the wrong thing? What I have allows me to run FIX with the one broker just fine, so I would think everything I need should be there, but it sounds now like I need to download something different? I think this is the link to the what I downloaded before and am now looking at, is this what I should be using?
http://sourceforge.net/projects/quickfixj/

Comment by Laurent Danesi [ 05/Mar/10 ]

Hi,

Yes, you are correct you need to download another package http://sourceforge.net/projects/quickfixj/files/QuickFIX_J/1.4.0/quickfixj-1.4.0-src.zip/download containing the source files thsi time instead of jar files.

Laurent

Comment by Willis Todd [ 05/Mar/10 ]

I don't know what I wasn't able to find that, but thank you very much for the link! I have done every step now except for the last one. Here's what I see in the command line when I try to do the last step:

C:\quickfixj>cd \quickfixj\core

C:\quickfixj\core>ant generate.code.
'ant' is not recognized as an internal or external command,
operable program or batch file.

C:\quickfixj\core>ant generate.code
'ant' is not recognized as an internal or external command,
operable program or batch file.

C:\quickfixj\core>

Is this because I need to install something more for me to use ant? In your first message you mentioned something about Eclipse Ant launcher, so I'm wondering if I should try that maybe? Or maybe if I did something wrong i the command line, you can tell me that.
Thanks again so much for your help, I was so lost before for like two weeks!!

Comment by Willis Todd [ 05/Mar/10 ]

I was trying to use Eclipse to do this and made a new project, then in the java settings, under the source tab, I clicked on Link Additional Source, and selected the quickfixj folder. Then I used the package explorer to right click the build.xml in the core folder and selected Run As ---> 2 Ant Build... and the Edit Configuration window comes up with jar [default] "build jar files" being the only thing selected, and I click run. But I don't see where the jar files being created, or where they are being sent to if they are created. So I don't know if that was what I was supposed to do or not. Let me what you think.
Thanks again!

Comment by Willis Todd [ 08/Mar/10 ]

So I thought maybe ant wasn't installed, so I have been working on installing it and used winant from this site:
http://code.google.com/p/winant/
And used the following link to download Java JDK 6 update 18:
http://java.sun.com/javase/downloads/widget/jdk_javafx.jsp
It still didn't quite work, but after a restart of the computer, this seems to have done the trick, as it says "BUILD SUCCESSFUL" at the end. However, I do not see any .jar files to replace the other ones I was using. So do I not need new jar files?
Thanks again! And I hope the links above will help others that have the problem I was having with ant, though probably most people coming here already know that.

Comment by Laurent Danesi [ 09/Mar/10 ]

Hi,

Great job, now you have the new source files respecting the ordered fields you provided in FIX44.xml.

You must now execute the ant task release.versioned that will generate all the jars you need. This task is in the build.xml at the root of your quickfixj project.

Laurent

Comment by Willis Todd [ 09/Mar/10 ]

Thanks again Laurent!! I did as you said above, and it did generate .jar files, though I'm not sure if it did everything it was supposed to, as I saw this at the end:

test.unit.junit:
[junit] Running quickfix.ApiCompatibilityTest
[junit] Tests run: 1715, Failures: 1, Errors: 0, Time elapsed: 32.797 sec

BUILD FAILED
C:\quickfixj-1.4.0-src\quickfixj\build.xml:130: The following error occurred whi
le executing this line:
C:\quickfixj-1.4.0-src\quickfixj\build.xml:44: The following error occurred whil
e executing this line:
C:\quickfixj-1.4.0-src\quickfixj\build.xml:27: The following error occurred whil
e executing this line:
C:\quickfixj-1.4.0-src\quickfixj\core\build.xml:175: The following error occurre
d while executing this line:
C:\quickfixj-1.4.0-src\quickfixj\core\build.xml:235: Test quickfix.ApiCompatibil
ityTest failed

Total time: 4 minutes 8 seconds
C:\quickfixj-1.4.0-src\quickfixj>

So I tried using the jar files anyway in place of the jar files I was using, but I get errors initiating sessionSettings and it never sends the fix message. I finally got it to send the fix message after including these 3 previously used jar files: mina-core-1.1.2.jar, slf4j-api-1.5.3.jar, slf4j-jdk14-1.5.3.jar, and just excluding this 1 previously used jar: quickfixj-all-1.4.0.jar. However, the fix message tags that get sent are still in the order they were before, rather than in the new order specified in the beginning of the FIX44.xml file. Is this something to do with the 3 other jar files I am using do you think? I was hoping I wouldn't need to include any of the old jar files, but then like I said, it doesn't send any fix message at all for me. What do you suggest I do?
If it's of any help, this is the print out I get when I try to run the application with only the nex jar files just generated:

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
at quickfix.SessionSettings.<init>(SessionSettings.java:64)
at quickfix.SessionSettings.<init>(SessionSettings.java:118)
at FIXTradingTester2.main(FIXTradingTester2.java:733)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more

Thanks again for all your help Laurent!
-Willis

Comment by Willis Todd [ 17/Mar/10 ]

Hey Laurent,
I talked to someone else who is more familiar with fix in c++ and less familiar with quickfixj, but they told me to do the same thing as you had and I still got the same result as above. Then he even tried to do it himself and got the same result I did with the build failed message. Like when I did it though, it did still produce jar files, though the jar files still were sending the header tags in the wrong order. I am really lost here, is there anything else that you can suggest I try?

Comment by Willis Todd [ 30/Mar/10 ]

Thanks again for your help Laurent! To anyone else having this problem, I had my jars rebuilt with a header.cfg file that specifies what order to put the tags in. If anyone else is in the same boat as I was and needs it, just let me know and I can send it to you!

Comment by Willis Todd [ 21/Jun/11 ]

Hey Aadil, I can't remember for sure if I already helped you with this or not, but in case I didn't, please feel free to e-mail me and I can share the code and rebuilt jars that worked for me. willis11of12 at rome dot com

Comment by Jörg Thönnes [ 21/Jun/11 ]

As I created QFJ-416, I was sure that the header order cannot specified. Did this change meanwhile?

Otherwise, I could pick up some tweaks out of my code...

Comment by Willis Todd [ 24/Jun/11 ]

Jörg, I can send you the jar files that were created for me that have a header order config file with them, though I recently realized that with using the newest version of quickfix/j, I don't have any problem connecting to the same platform without using it. So now I am wondering if they really did much. It seems that using it allows me to change the order of some tags, but not all of them... weird. Anyway, just send me an e-mail if you want me to send you what I have and you can check it out.

Comment by Andreea Ion [ 12/Apr/12 ]

Hy, I tried to do exactly like you but I didn't manage to succed. I am building the project in eclipse and I have the same error as you
BUILD FAILED
C:\quickfixj\core\build.xml:81: The following error occurred while executing this line:
C:\quickfixj\core\build.xml:89: The following error occurred while executing this line:
C:\quickfixj\core\build.xml:109: Error running javac.exe compiler

Can you tell me how can I do thsi work, in order to change the hearder tads .
Thank you,
Andreea

Comment by Øyvind Hansen [ 11/Dec/14 ]

Hello,

we are having the same issue with FIX 4.4. We have set up a specific order of fields in the header in the datadictionary. However, in the fix messages the header fields are sorted by fix tag number, conflicting the order in the datadictionary. Because this post is over four years old, we were wondering if this solution is still the one to go for. Our broker also wants the fields in the header in a specific order.

Thank you,
Øyvind

Comment by Christoph John [ 15/Dec/14 ]

AFAIK there currently is no other way than to rebuild QFJ as Laurent suggested in his first comment.





[QFJ-511] persistance filter idea Created: 03/Mar/10  Updated: 04/Mar/10

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

Type: Improvement Priority: Default
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None

Attachments: Text File FilterExcludingSolicited.java     Text File MessageStorePersistanceFilter.java     Text File Session.java     Text File Session.java     Text File Session.java    

 Description   

ability to add a static persistance filter to Session. to avoid writing marketdata, other user defined criteria.



 Comments   
Comment by Andre Mermegas [ 03/Mar/10 ]

example usage.

Comment by Andre Mermegas [ 04/Mar/10 ]

2nd session, has a bugfix for forceresync getting messed up by sequence numbers from the message store, it should ignore it.

Comment by Andre Mermegas [ 04/Mar/10 ]

actually I guess you could just do this

if (forceResync && isPossibleDuplicate(msg))

{ return false; }
instead of
if (forceResync && (isAdminMessage(msgType) || isPossibleDuplicate(msg))) { return false; }




[QFJ-510] ThreadPerSessionEventHandlingStrategy.MessageDispatchingThread threads live after disconnect Created: 03/Mar/10  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Improvement Priority: Default
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Attachments: Text File ThreadPerSessionEventHandlingStrategy.java     Text File ThreadPerSessionEventHandlingStrategy.java     Text File ThreadPerSessionEventHandlingStrategy.java    
Issue Links:
Duplicate
duplicates QFJ-410 ThreadPerSessionEventHandlingStrategy... Closed

 Description   

This patch ends dispatcher thread after logout.

/*******************************************************************************

  • Copyright (c) quickfixengine.org All rights reserved.
    *
  • This file is part of the QuickFIX FIX Engine
    *
  • This file may be distributed under the terms of the quickfixengine.org
  • license as defined by quickfixengine.org and appearing in the file
  • LICENSE included in the packaging of this file.
    *
  • This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
  • THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
  • PARTICULAR PURPOSE.
    *
  • See http://www.quickfixengine.org/LICENSE for licensing information.
    *
  • Contact [email protected] if any conditions of this licensing
  • are not clear to you.
    ******************************************************************************/

package quickfix.mina;

import quickfix.LogUtil;
import quickfix.Message;
import quickfix.Session;
import quickfix.SessionID;
import quickfix.SessionStateListener;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

/**

  • Processes messages in a session-specific thread.
    */
    public class ThreadPerSessionEventHandlingStrategy implements EventHandlingStrategy {
    private final Map<SessionID, MessageDispatchingThread> dispatchers = new ConcurrentHashMap<SessionID, MessageDispatchingThread>();

public void onMessage(Session quickfixSession, Message message) {
MessageDispatchingThread dispatcher = dispatchers.get(quickfixSession.getSessionID());
if (dispatcher == null)

{ dispatcher = new MessageDispatchingThread(quickfixSession); dispatchers.put(quickfixSession.getSessionID(), dispatcher); startDispatcherThread(dispatcher); }

dispatcher.enqueue(message);
}

/** There is no such thing as a SesionConnector for thread-per-session handler - we don't multiplex

  • between multiple sessions here so this is null
    */
    public SessionConnector getSessionConnector() { return null; }

protected void startDispatcherThread(MessageDispatchingThread dispatcher)

{ dispatcher.start(); }

public void stopDispatcherThreads() {
Collection<MessageDispatchingThread> dispatchersToShutdown = dispatchers.values();
dispatchers.clear();
for (MessageDispatchingThread dispatcher : dispatchersToShutdown)

{ dispatcher.stopDispatcher(); }

}

private final class MessageDispatchingThread extends Thread {
private final Session quickfixSession;
private final BlockingQueue<Message> messages = new LinkedBlockingQueue<Message>();
private volatile boolean stopped;

private MessageDispatchingThread(Session session) {
super("QF/J Session dispatcher: " + session.getSessionID());
quickfixSession = session;
quickfixSession.addStateListener(new SessionStateListener() {
public void onConnect() {
}

public void onDisconnect() {
}

public void onLogon() {
}

public void onLogout()

{ stopped = true; interrupt(); dispatchers.remove(quickfixSession.getSessionID()); }

public void onReset() {
}

public void onRefresh() {
}

public void onMissedHeartBeat() {
}

public void onHeartBeatTimeout() {
}
});
}

public void enqueue(Message message) {
try

{ messages.put(message); }

catch (InterruptedException e)

{ quickfixSession.getLog().onErrorEvent(e.toString()); }

}

public int getQueueSize()

{ return messages.size(); }

public void run() {
while (!stopped) {
try {
Message message = getNextMessage(messages);
if (quickfixSession.hasResponder())

{ quickfixSession.next(message); }

} catch (InterruptedException e) {
if (!stopped)

{ LogUtil.logThrowable(quickfixSession.getSessionID(), "Message dispatcher interrupted", e); return; }

} catch (Throwable e)

{ LogUtil.logThrowable(quickfixSession.getSessionID(), "Error during message processing", e); }

}
}

public void stopDispatcher()

{ stopped = true; }

}

private BlockingQueue<Message> getMessages(SessionID sessionID)

{ MessageDispatchingThread dispatcher = getDispatcher(sessionID); return dispatcher.messages; }

private MessageDispatchingThread getDispatcher(SessionID sessionID)

{ return dispatchers.get(sessionID); }

private Message getNextMessage(BlockingQueue<Message> messages) throws InterruptedException

{ return messages.take(); }

public int getQueueSize() {
int ret = 0;
for(MessageDispatchingThread mdt : dispatchers.values())

{ ret+=mdt.getQueueSize(); }

return ret;
}

}



 Comments   
Comment by Andre Mermegas [ 03/Mar/10 ]

alternate impl

Comment by Andre Mermegas [ 03/Mar/10 ]

to clarify attachments are 2 different implementations of same functionality





[QFJ-509] Question about performance Created: 24/Feb/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Critical
Reporter: Ilya Goberman Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP 32 bit, Java 6.



 Description   

I wrote a FIX server that streams market data to FIX subscribers. The market data volume may be heavy, so I need to find out performance benchmarks for QuickFixJ API.
I have a test set up where Server is running on 4 core XP machine streaming FIX market data messages to a subscriber running on another machine. I do not use any file IO because I do not use FileStoreFactory/FileLogFactory - so no files are created in my logs directory for both server and subscriber.
The server just sends market data messages in infinite loop without any delays. The message is MarketDataIncrementalRefresh with Bid and Offer groups containing Bid, Ask, BidSize, and AskSize - 4 fields.

Now the problem is that I cannot receive over 12,000 messages per second. My CPU is not maxed out on client or server. It is interesting that if I add another thread on the server also sending the same messages in a loop, the number of processed messages does not increase.

My question is: is it possible to process over 12,000 in configuration described above or this number "is about correct". Is there way to improve it somehow (I already eliminated file IO)? My guess there is some thread contention going on in the QuickFixJ API that prevents achieving good throughput.
Thanks



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

Are you using a single session? In any case, given that you probably aren't doing two-way communication, thread contention /shouldn't/ be the primary issue. However, if you see otherwise in your profiling please let us know. Other possibilities are garbage collection (especially if the heap size is set too low) and network bottlenecks.





[QFJ-508] Data Dictonary has incorrect definiton for QuoteRequestReject messages for FIX 4.4 Created: 22/Feb/10  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: David Brown Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

In FIX 4.4 spec QuoteRequestReject instrument repeating group should contain, amongst others, the following fields, however in the Data Dictionary shipped with QuickFix these are all outside the repeating group and so can not repeat. and valid messages fail validation:

<group name="NoQuoteQualifiers" required="N">
<field name="QuoteQualifier" required="N"/>
</group>
<field name="QuotePriceType" required="N"/>
<field name="OrdType" required="N"/>
<field name="ExpireTime" required="N"/>
<field name="TransactTime" required="N"/>
<component name="SpreadOrBenchmarkCurveData" required="N"/>
<field name="PriceType" required="N"/>
<field name="Price" required="N"/>
<field name="Price2" required="N"/>
<component name="YieldData" required="N"/>
<component name="Parties" required="N"/>



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

Those fields are in the NoRelatedSym repeating group of QuoteRequestReject

<group name="NoRelatedSym" required="Y">
<component name="Instrument" required="Y"/>
<component name="FinancingDetails" required="N"/>
<group name="NoUnderlyings" required="N">
<component name="UnderlyingInstrument" required="N"/>
</group>
<field name="PrevClosePx" required="N"/>
<field name="QuoteRequestType" required="N"/>
<field name="QuoteType" required="N"/>
. . .





[QFJ-507] CLONE -Quote subscribe Created: 12/Feb/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi Support,

Please find below my code i am using to subscribe using market data request, the isse that i want when i create this message i want tag55 to come after tag146, as per to integral they want Tag55 to come after Tag146

quickfix.fix43.MarketDataRequest sub = new MarketDataRequest(new MDReqID(reqID),new SubscriptionRequestType('1'), new MarketDepth (1));
System.out.println("This is the message :" + sub.toString());
sub.setField(new SenderSubID("SWSPBle"));
sub.setField(new Product(4));
sub.setField(new NoRelatedSym(1));

sub.setField(new MDUpdateType(0));
sub.setField(new NoMDEntryTypes(0));
sub.setField(new quickfix.field.Symbol("EUR/USD"));

the generated message is coming as below

8=FIX.4.39=16535=V34=1249=quote.SWSPB.dev.SWSPB.com52=20090903-22:29:29.22356=demo.client.fxgrid.integral.com50=SWSPBle55=EUR/USD146=1262=12263=1264=1265=0267=0460=410=014

Response from integral as below
8=FIX.4.39=17735=334=1949=demo.client.fxgrid.integral.com52=20090903-22:29:31.32756=quote.SWSPB.dev.SWSPB.com57=SWSPBle45=1258=Tag not defined for this message type371=55372=V373=210=164

can you help me here please?






[QFJ-506] How can I deactivate message logging ? Created: 29/Jan/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Stephane Thomas Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None


 Description   

Using a Fix MarketData access, I would like to deactivate message logging in FileLogPath messages.log file

indeed, this file is growing quickly and cause server crash






[QFJ-505] FixMessageDecoder.startsWith() wrongly detects pattern Created: 26/Jan/10  Updated: 31/Jul/12  Resolved: 31/Jul/12

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

Type: Bug Priority: Default
Reporter: Horia Muntean Assignee: Unassigned
Resolution: Duplicate Votes: 2
Labels: None

Attachments: Text File TestFixMessageDecoder.java    
Issue Links:
Duplicate
duplicates QFJ-544 Header with BeginString=FIXT.1.1 inco... Resolved

 Description   

I have found a nasty bug in FixMessageDecoder.parseMessage() that appears when using BeginString=FIXT.1.1

If mina provides the decoder with a ByteBuffer with an incomplete header like below the indexOf() method wrongly detects it in spite the fact the buffer does not contain a complete header.

Below you have a test case to prove it. Unfortunately I had to copy some private methods from FixMessageDecoder in order to call them.

import java.io.UnsupportedEncodingException;

import junit.framework.Assert;

import org.apache.mina.common.ByteBuffer;
import org.junit.Test;
import org.quickfixj.CharsetSupport;

public class TestFixMessageDecoder {

private static final String FIELD_DELIMITER = "\001";
private static final byte[] HEADER_PATTERN = getBytes("8=FIXt.?.?" + FIELD_DELIMITER + "9=");

@Test
public void testCompleteHeader() {
//8=FIXT.1.1_9=
byte[] completeHeader =

{0x38, 0x3D, 0x46, 0x49, 0x58, 0x54, 0x2E, 0x31, 0x2E, 0x31, 0x01, 0x39, 0x3D}

;
ByteBuffer in = ByteBuffer.wrap(completeHeader);
BufPos bufPos = indexOf(in, 0, HEADER_PATTERN);
Assert.assertTrue("We should have a complete header", bufPos._offset != -1);
}

@Test
public void testIncompleteHeader() {
//8=FIXT.1.1_9
byte[] incompleteHeader =

{0x38, 0x3D, 0x46, 0x49, 0x58, 0x54, 0x2E, 0x31, 0x2E, 0x31, 0x01, 0x39}

;
ByteBuffer in = ByteBuffer.wrap(incompleteHeader);
BufPos bufPos = indexOf(in, 0, HEADER_PATTERN);
Assert.assertTrue("There should be no header detected", bufPos._offset == -1);
}

private static byte[] getBytes(String s) {
try

{ return s.getBytes(CharsetSupport.getDefaultCharset()); }

catch (UnsupportedEncodingException e)

{ throw new RuntimeException(e); }

}

private static int startsWith(ByteBuffer buffer, int bufferOffset, byte[] data) {
if (bufferOffset + minMaskLength(data) > buffer.limit())

{ return -1; }

final int initOffset = bufferOffset;
int dataOffset = 0;
for (int bufferLimit = buffer.limit(); dataOffset < data.length
&& bufferOffset < bufferLimit; dataOffset+, bufferOffset+) {
if (buffer.get(bufferOffset) != data[dataOffset] && data[dataOffset] != '?') {
// Now check for optional characters, at this point we know we didn't
// match, so we can just check to see if we failed a match on an optional character,
// and if so then just rewind the buffer one byte and keep going.
if (Character.toUpperCase(data[dataOffset]) == buffer.get(bufferOffset))
continue;
// Didn't match the optional character, so act like it was not included and keep going
if (Character.isLetter(data[dataOffset]) && Character.isLowerCase(data[dataOffset]))

{ --bufferOffset; continue; }

return -1;
}
}
return bufferOffset - initOffset;
}

private static BufPos indexOf(ByteBuffer buffer, int position, byte[] data) {
for (int offset = position, limit = buffer.limit() - minMaskLength(data) + 1; offset < limit; offset++) {
int length;
if (buffer.get(offset) == data[0] && (length = startsWith(buffer, offset, data)) > 0)

{ return new BufPos(offset, length); }

}
return new BufPos(-1, 0);
}

private static int minMaskLength(byte[] data) {
int len = 0;
for (int i = 0; i < data.length; ++i)

{ if (Character.isLetter(data[i]) && Character.isLowerCase(data[i])) continue; ++len; }

return len;
}

static class BufPos {
int _offset;
int _length;

/**

  • @param offset
  • @param length
    */
    public BufPos(int offset, int length) { _offset = offset; _length = length; }

public String toString()

{ return _offset + "," + _length; }

};
}

The code was taken from qfj 1.4.0

Both test cases should pass but testIncompleteHeader does not since FixMessageDecoder.indexOf() wrongly detects a header pattern even if the header is not complete ( it's missing the last '=' character). This leads to state = PARSING_LENGTH and ends up miserably with a "Error in message length format" exception; (see the original FixMessageDecoder code)

This bug can pass unobserved for long time since the probability mina will deliver this certain buffer to the decoder is somehow low.



 Comments   
Comment by Horia Muntean [ 26/Jan/10 ]

We should check at the end of the method if the data[] pattern was parsed completely before returning.
If it was not, than it means that the buffer was instead parsed. So the result should be -1.
This reasoning works only if the unparsed pattern contains something else that optional characters.

private static int startsWith(ByteBuffer buffer, int bufferOffset, byte[] data) {
if (bufferOffset + minMaskLength(data) > buffer.limit())

{ return -1; }
final int initOffset = bufferOffset;
int dataOffset = 0;
for (int bufferLimit = buffer.limit(); dataOffset < data.length
&& bufferOffset < bufferLimit; dataOffset+, bufferOffset+) {
if (buffer.get(bufferOffset) != data[dataOffset] && data[dataOffset] != '?') {
// Now check for optional characters, at this point we know we didn't
// match, so we can just check to see if we failed a match on an optional character,
// and if so then just rewind the buffer one byte and keep going.
if (Character.toUpperCase(data[dataOffset]) == buffer.get(bufferOffset))
continue;
// Didn't match the optional character, so act like it was not included and keep going
if (Character.isLetter(data[dataOffset]) && Character.isLowerCase(data[dataOffset])) { --bufferOffset; continue; }
return -1;
}
}
// Make sure every byte from the pattern was parsed
if(dataOffset < data.length) { return -1; }

return bufferOffset - initOffset;
}

With the proposed fix the above tests pass. I did not checkout the head, apply the fix and rerun the project tests.

Comment by Horia Muntean [ 27/Jan/10 ]

Something happened with copy&paste in the previous comment so I attached the full test file. The change was done to the startsWith() method, just before return.

Comment by Steve Bate [ 05/Apr/10 ]

I've added your tests, but they all pass. I don't think we did anything specific to fix this issue yet so that's a bit confusing. Is there some way you could run your unit tests against the trunk version of QFJ to see if you still see failing tests?

Comment by Horia Muntean [ 07/Apr/10 ]

I am not sure to what tests you are referring to.
The tests from the attached TestFixMessageDecoder.java pass because 'startsWith' method contains the fix.
You should run the tests from the code taken from the description of this issue.

Comment by David Gibbs [ 12/Jul/10 ]

We see this issue as well. Is the FIX committed yet ?

Comment by Stelios Papadopoulos [ 20/Jul/10 ]

see QFJ-544 for a test that highlights this issue (without exposing the private function).

also the tests in QuickFixJ 1.5.0 FIXMessageDecoderTest do not test the application code, but rather the private method included in the test class.





[QFJ-504] Document all new features Created: 25/Jan/10  Updated: 03/May/10  Resolved: 03/May/10

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Comments   
Comment by Laurent Danesi [ 03/May/10 ]

The descriptions are done, I will just have to put them on the website when we will release





[QFJ-503] Update web site QFJ documentation at release time Created: 15/Jan/10  Updated: 15/Nov/12  Resolved: 08/Jul/10

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.5.0

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None





[QFJ-502] Lot of test requests sent to server Created: 15/Jan/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Tausseef Ahmad Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows Xp Service Pack 2



 Description   

i am using quickfix version 1.3.1. Recently i had an issue that there are a lot of test requests within two mins. For each test request request the server responds with a heartbeat message with correct test request id. Below are the messges.
For each test request the difference of time is 10 secs. HeartBeat interval in my settings file is 30 secs.

[Nondelimited FIX messages removed, please attach message file or replace delimiters with an ASCII character]



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

This could possibly happen if the counterparty stops sending heartbeats. QFJ will periodically send a test request to ensure the connection is still alive. Since the counterparty is responding to the test request the connection will stay alive. However, if there are still no heartbeats then the test request will be resent.





[QFJ-501] Setting session property UseDataDictionary to false does not prevent message validation Created: 14/Jan/10  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Critical
Reporter: Nickolay Dul Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-476 Message vailidation is done even if u... Closed

 Description   

UseDataDictionary property is skipped because session's DefaultDataDictionaryProvider is always created in DefaultSessionFactory



 Comments   
Comment by Nickolay Dul [ 14/Jan/10 ]

duplicate of QFJ-476 (http://www.quickfixj.org/jira/browse/QFJ-476)





[QFJ-500] quickfixj-msg-fixt11-1.4.0.jar does not contain FIXT11.xml Created: 13/Jan/10  Updated: 15/Nov/12  Resolved: 04/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Nickolay Dul Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

quickfixj lib for FIXT11 does not contain resource file FIXT11.xml

the issue was found in quickfixj/core/build.xml - line#156 (in <macrodef name="create-message-jar">)
<fileset dir="$

{main.resources.dir}

">
<include name="FIX@

{fixVersion}

.xml" />
</fileset>



 Comments   
Comment by Steve Bate [ 04/Apr/10 ]

Laurent apparently fixed this quite a while ago. It will be in the next release.





[QFJ-499] Modify build system to use Maven Created: 10/Jan/10  Updated: 02/Apr/15  Resolved: 09/Jun/14

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

Type: Task Priority: Major
Reporter: Steve Bate Assignee: amichair
Resolution: Fixed Votes: 12
Labels: None

Attachments: Zip Archive codegenerator.zip     File quickfixj.zip    
Issue Links:
Relates
relates to QFJ-783 Update documentation and website to r... Closed
Requires
is required by QFJ-782 Get rid of cyclic package dependencies Open
is required by QFJ-599 make quickfixj artifacts into osgi bu... Closed

 Description   

Things which have been done on the ant build in the meantime and which need to be considered:

  • UTF-8 encoding
  • compiler level JDK 6
  • ...


 Comments   
Comment by Toli Kuznets [ 19/Jan/10 ]

Steve,
Marketcetera is all SVN-based, let me know if you need some help or want me to take a first stab at this.

Comment by Steve Bate [ 05/Apr/10 ]

I've made changes to the project structure to make it more Maven-like. I've attempted a Maven conversion and have run into a couple of issues. The first issue is that our distribution preparation process is somewhat complex and not a great fit for Maven's assembly module. The other issue is that we cannot publish the QFJ libraries to the Maven central repository because we depend on some libraries (proxool 0.9.1 and Sleepycat JE) that are not in that repository. However, we could run our own repository on quickfixj.org to workaround that issue.

In fact, we can still post QFJ to our own repository if we'd like, even without a Maven build. Another option is to use Ivy for dependency management and then generate the QFJ POMs from that tool.

Comment by Sergey Ivanov [ 18/Apr/10 ]

Steve,

I am currently working in my spare time on a maven plugin for message source generation from a dictionary (I started by taking the code from MessageCodeGenerator and transforming it into a Maven2 mojo). Once it is completed, I shall be happy to contribute it to QuickFix/J project under your licence. It will (hopefully) make it easier to mavenise QuickFix/J build.

Comment by Steve Bate [ 18/Apr/10 ]

Sounds great. Thanks.

Comment by Claudio Bantaloukas [ 14/Sep/10 ]

I packaged the code generator as a maven project.

Sources are from the QFJ 1.5.0 release. The main stumbling block is that the xslt engine cannot load resources directly so I had to copy paste the copyright info inside the xslt file.

Apart from that, the code is an adaptation of the castor plugin.

Once installed, it can be added to the pom with the following snippet

<plugin>
<groupId>quickfixj</groupId>
<artifactId>codegenerator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<dictFile>src/main/resources/custom-fix-dict.xml</dictFile>
<packaging>com.myapp.fix</packaging>
<fieldPackage>com.myapp.fix.field</fieldPackage>
<!-- optional configs schemaDirectory, outputDirectory, decimal, orderedFields -->
</configuration>
</execution>
</executions>
</plugin>

Of course the generated projects require proper qfj library dependencies but hey, it's a start!

Comment by Claudio Bantaloukas [ 24/Jan/11 ]

I have a working build that mirrors trunk under subversion branch QFJ-499

Can someone help me test on a machine != mine?

Thanks!

Comment by Jim Scott [ 27/Apr/11 ]

I am attaching everything that I have done to mavenize quickfixj. I have left some of the files for the different subprojects in place just to show where the files go, but I deleted most of them to not have a huge zip file. I would happily post my entire copy of the 1.5 (mavenized) code base if requested.

  • I could not get the maven jalopy plugin to work, so this build will not beautify the generated code.
  • I could not find a plugin that would work anywhere near as nicely as globmap from ant to check if the generated sources are up-to-date, but it will check (although far from perfect).
  • The maven project (surefire plugin) defines the path to the test resources via system properties.
  • There are diff files for the very few changes I had to make to the tests to make them work in maven.
  • This mavenization does NOT accomodate for the jdk1.4 build from ant.
  • This mavenization does NOT accomodate for the .NET build from ant.
  • The only test I could not get to work (which is marked as exclude from testing) is quickfix/SLF4JLogTest.java

This mavenization does generate all artifacts as equivalent or better to what the current ant build generates. I say or better because certain things like the manifest file is customized within each jar. Just little things like that.

The assembly that I built can be modified very simply to produce zip as well as tar.gz.

This build also generates the source jars and javadocs to check into the maven artifact repository. So, anyone depending on the binary via maven will automatically pick up the source and javadocs.

To generate the javadocs run -PRelease and to skip running tests add -DskipTests (buids quite fast without javadocs or tests running). If you want to force the build not to generate the code use -Dskip.exec=true

All artifacts also have the proper dependencies in their pom's. e.g. if you only require fix 42, you can depend on the fix42 jar via the pom and it will automatically pull in fix41, fix40 and fix core.

Comment by Steve Bate [ 03/May/11 ]

Moved issue to 1.6.0 based on discussions from the mailing list.

Comment by Andrei Pozolotin [ 06/May/11 ]

Steve, Claudio:

please consider using sonatype oss:
https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide

for maven snapshot and release staging

thank you

Andrei.

Comment by Andrei Pozolotin [ 06/May/11 ]

please also consider conversion into osgi bundles:
http://www.quickfixj.org/jira/browse/QFJ-599

Comment by Claudio Bantaloukas [ 07/May/11 ]

Andrei, I'd love to use sonatype but we currently depend on oracle's sleepycat packages. Is it possible to upload those too in sonatype? Please see this page for the full list of dependencies. If we can upload them it would be great...

http://quickfixj.svn.sourceforge.net/viewvc/quickfixj/branches/QFJ-499/quickfixj-core/pom.xml?revision=997&view=markup

Comment by Andrei Pozolotin [ 07/May/11 ]

Claudio:

1) yes it is possible to upload non-publicly available packages to sonatype oss;

2) in case of bdb, there is no need to; bdb is available from public repo:

<repositories>
<repository>
<id>oracleReleases</id>
<name>Oracle Released Java Packages</name>
<url>http://download.oracle.com/maven</url>
<layout>default</layout>
</repository>
</repositories>

<dependencies>
<dependency>
<groupId>com.sleepycat</groupId>
<artifactId>je</artifactId>
<version>4.1.7</version>
<optional>true</optional>
</dependency>
</dependencies>

Andrei.

Comment by Andrei Pozolotin [ 07/May/11 ]

http://www.oracle.com/technetwork/database/berkeleydb/downloads/maven-087630.html

Comment by Andrei Pozolotin [ 07/May/11 ]

http://search.maven.org/#search|ga|1|je

Comment by Jim Scott [ 07/May/11 ]

I have not been able to get to the oracle maven repo in quite a long time and this still doesn't seem to work ..

If you notice in the pom I submitted I already have all the dependencies accounted for including sleepycat.

This is in the central repository:
http://repo1.maven.org/maven2/berkeleydb/je/
<dependency>
<groupId>berkeleydb</groupId>
<artifactId>je</artifactId>
<version>2.1.30</version>
<optional>true</optional>
</dependency>

Comment by Andy Flury [ 27/Jul/12 ]

is there any time schedule for finishing the mavenization? Would be great to have QFJ available from maven central or sonatype oss

Comment by Ryan Lea [ 07/Mar/13 ]

+1.

I would be more than happy to help out in any way to assist in this process as well.

Comment by Christoph John [ 09/Dec/13 ]

Hi, anyone of you guys willing to push this further? Thanks

Comment by Claudio Bantaloukas [ 10/Dec/13 ]

I'm afraid I cannot work on this right now, but if you have the time, feel free to check out the work I did on branch 499. Unfortunately it has not received attention in the last 3 years...

The new url is:
http://sourceforge.net/p/quickfixj/code/HEAD/tree/branches/QFJ-499/

Comment by Christoph John [ 17/Feb/14 ]

Hi Claudio, thanks for your contributions on this. I found it very useful. Will also check the changes done by Jim Scott.

Comment by amichair [ 09/Jun/14 ]

Thanks everyone for your contributions - I rebased Claudio's branch, modified and updated it, and added a bunch of further improvements, incorporating stuff from the other patches as well. This was done on the QFJ-499-revisited branch, now merged into master.





[QFJ-498] Upgrade MINA library to latest version Created: 10/Jan/10  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-519 Minor build problems in QuickFIX/J 1.4.0 Closed




[QFJ-497] Question: How to capture Every incoming message... Created: 06/Jan/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: nagendra Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
We are using QuickfixJ FIX44 version for our project. I could able to connect to the counter party and get the Hearbeat Messages. However, when the counter party try to send some trade messages neither I could capture nor I could log them.
After couple of days we came to know that the messages are rejected even before we capture them.

How do I capture any kind of message we send to counter party??

Thanks in Advance,
Nagendra.



 Comments   
Comment by Ahmed Al Jebouri [ 14/Jan/10 ]

can you specify what you mean by capture message before sending it, if you are the sender so you can save the message created if it is an order you can take that message and either send the data to database or log file

Regards,
Ahmed





[QFJ-496] Not able to Capture any message from the Socket Created: 06/Jan/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Critical
Reporter: nagendra Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
We are using QuickfixJ FIX44 version for our project. I could able to connect to the counter party and get the Hearbeat Messages. However, when the counter party try to send some trade messages neither I could capture nor I could log them.
After couple of days we came to know that the messages are rejected even before we capture them.

How do I capture any kind of message we send to counter party??

Thanks in Advance,
Nagendra.






[QFJ-495] Trade Captuer Report Created: 06/Jan/10  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Jerry Jones Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

java



 Description   

Could someone help me by giving me an example on how to call a trade capture request for todays trades?
I had been using FIXML over https but they switched to fix tc and I am unsure where to get proper documentation.






[QFJ-494] proected empty constructor for Sesson class Created: 29/Dec/09  Updated: 05/Apr/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: Future Releases

Type: Improvement Priority: Default
Reporter: Carlo Marchiori Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

n/a



 Description   

I'd like to create a wrapper implementation and subclass of the Session class.
This wrapper is by default stateless, delegating behaviour to a true Session object.
This is useful for example to start global transactions around the next methods.

Currently Session has two constructor that can only create 'true' Sessions.

An empty protected constructor may suffice.

In fact, it's not clear why there is a SessionFactory interface when actually one cannot modify or decorate the default Session implementation.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

IIRC, the Session interface was requested by a user for some purpose related to Spring. It's currently used for unit test support as well.

We could potentially add an interface for Session, but have you considered using some form of AOP to implement the transaction hooks.





[QFJ-493] When a gap fill satisfies a resend request, QF does not realize it Created: 25/Dec/09  Updated: 01/Apr/14  Resolved: 01/Apr/14

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

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Christoph John
Resolution: Cannot Reproduce Votes: 0
Labels: None

Attachments: Text File QFJ-493.diff.1.4.0.txt    

 Description   

In our production environment, we saw the following scenario:
They log on w/ 687
We send resent request from 684 to 0
They send a resend request (their #688)
They send gap fill from MsgSeqNum=684 to NewSeqNo=688.
They send us 689.
QF did not recognize that the resend request had been fulfilled, so it did not send another resend request when it saw 689.
The counterparty was never going to send us 688 otherwise - they had already sent it (and indeed we acted on it).
So we ended up not processing any of their messages (sequence number too high), and eventually disconnected.

We tracked the problem down to the
boolean verify(Message msg, boolean checkTooHigh, boolean checkTooLow)
method around line 1168. If the MsgSeqNum is at or beyond the end of the resend range waiting to be satisfied, then the resend request will be deemed satisfied. But for gap fills, it should really consider the entire range of the gap, i.e., MsgSeqNum to NewSeqNo - 1, which it does not. NB that in some scenarios, the next inbound message will clear the problem. But not in the one above.

We are running 1.2.1. Based on inspection of the code, I believe this also affects 1.3.x and 1.4.x.

Will attach a patch, diff.txt.



 Comments   
Comment by Rhys Yarranton [ 25/Dec/09 ]

Hmm, I can't find the link to add an attachment, so I will paste the patch here instead.

— core/src/main/java/quickfix/Session.java 2009-12-08 16:28:15.657576498 -0700
+++ core/src/main/java/quickfix/Session.java.original 2009-12-08 16:15:26.719542742 -0700
@@ -1166,13 +1166,9 @@
}

if ((checkTooHigh || checkTooLow) && state.isResendRequested()) {

  • int endPoint = msgSeqNum;
  • if(msg.getHeader().getString(MsgType.FIELD).equals(MsgType.SEQUENCE_RESET) &&
  • msg.isSetField(NewSeqNo.FIELD))
  • endPoint = Math.max(endPoint, msg.getInt(NewSeqNo.FIELD) - 1);
    synchronized (this) {
    int[] range = state.getResendRange();
  • if (endPoint >= range[1]) {
    + if (msgSeqNum >= range[1]) {
    getLog().onEvent(
    "ResendRequest for messages FROM: " + range[0] + " TO: " + range[1]
    + " has been satisfied.");
Comment by Rhys Yarranton [ 04/May/10 ]

Attachments seem to be working again. This one is a patch against 1.4.0.

Comment by Christoph John [ 01/Apr/14 ]

Was not able to reproduce this. Added unit test: http://sourceforge.net/p/quickfixj/code/1170/





[QFJ-492] re: ThreadPerSessionEventHandlingStrategy still leaks threads Created: 18/Dec/09  Updated: 15/Jan/10  Resolved: 15/Jan/10

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

Type: Bug Priority: Default
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-491 ThreadPerSessionEventHandlingStrategy... Closed

 Description   

ThreadPerSessionEventHandlingStrategy still leaks threads






[QFJ-491] ThreadPerSessionEventHandlingStrategy leaks threads Created: 18/Dec/09  Updated: 15/Nov/12  Resolved: 04/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Major
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-410 ThreadPerSessionEventHandlingStrategy... Closed
is duplicated by QFJ-492 re: ThreadPerSessionEventHandlingStra... Closed
Relates
is related to QFJ-410 ThreadPerSessionEventHandlingStrategy... Closed

 Description   

See http://www.quickfixj.org/jira/browse/QFJ-326

I'd like this to be reopened as threads still leak.
1. in ThreadPerSessionEventHandlingStrategy.stopDispatcherThreads the dispatchers.clear() is done before looping through the collection and so threads' stopDispatcher is never called
2. ThreadPerSessionEventHandlingStrategy.MessageDispatchingThread.run never terminates as this method repeatedly calls getNextMessage in a loop and getNextMessage calls messages.take which blocks indefinitely
3. also, stopDispatcherThreads should wait for threads to terminate before it returns so that everything gets cleaned up properly and in order

I've got a patch which fixes these by:
1. reordering statements in stopDispatcherThreads
2. using messages.poll which times out. Have set up a constant timeout of 10 seconds
3. waiting for threads to finish

What do people think about the timeout value? We could make this timeout configurable, or higher.



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

Can you attach your patch, please?

Comment by Jerry Shea [ 13/Feb/10 ]

Patch is attached to http://www.quickfixj.org/jira/browse/QFJ-410

Comment by Steve Bate [ 04/Apr/10 ]

See linked issue





[QFJ-490] Order of tags important for QuoteRequestReject Messages ? Created: 16/Dec/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Other Priority: Default
Reporter: Nataraj Dasgupta Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any



 Description   

Hi,

How important is the order of the FIX Tag messages in QuickFIX with respect to the 35=AG messages. FIX 4.3 Vol 3 suggests that tag 15 should be before tag 58. If Tag 15 and the tags 38,63,193 and 192 are after tag 58, should this be acceptable to QuickFIX ?

Thanks and regards,

  • Nataraj.





[QFJ-489] ResendRequest even the MsgSeqNum is correct when a lot of messages arrived at the same instance Created: 04/Dec/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Critical
Reporter: lcryst Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

WINXP



 Description   

When a lot of messages arrive at the same instance, Quickfix seems to ingore some message (they can be found in the logs),
and think that the earlier message is not arrived, so it will then send "ResendRequest" to the counterparty.

e.g. 34=2, 34=3, 34=4 has arrived at 20091203-08:47:53 [ i use the screenLogFactory]
it will complaint about: (MsgSeqNum too high, expecting 3 but received 4)
and (Sent ResendRequest FROM: 4 TO: 0)

then the MsgSeqNum will be screwed up, keep sending resend request when more messages arrived.
and there will be a messge queue stored the out of order message.
<20091203-08:47:53, FIX.4.2:INITIATOR->ACCEPTOR, event> (Processing queued message: 5, pending: [4, 6, 7, 9, 8, 11, 12, 10, 13, 15, 16, 14, 17, 19, 18, 20, 21, 23, 24, 22, 25, 27, 26])

How to prevent quickfix from ignoring the message with a smaller MsgSeqNum?
Is this a race condition? as mulitple messages arrive at the same instance.



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

QFJ might not be ignoring the message. It's possible the message is corrupt and the engine incoming sequence number is not incremented. You don't mention whether you searched the application logs for any log messages related to message validation issues.

It's not likely to be a race condition for a couple of reasons. QFJ has been tested under high load without any message loss and messages for a specific session are processed in sequence.

Comment by robert engels [ 13/Jun/11 ]

This issue needs to be re-opened, as we are having the exact same problem.

Here is a snippet from the log that clearly demonstrates the issue:

<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, incoming> (8=FIX.4.29=24035=b34=1195369=119752=20110606-07:29:22.81949=CME50=G56=EKY2Z7N57=BFHS143=US,IL58=Quote rejected: Not authorized to quote this instrument 'SenderComp EKY2Z7/ TraderID UNKNOWN for group ZE'117=101297=5300=91028=Y9772=09774=ZE10=015)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, incoming> (8=FIX.4.29=24035=b34=1196369=119752=20110606-07:29:22.82049=CME50=G56=EKY2Z7N57=BFHS143=US,IL58=Quote rejected: Not authorized to quote this instrument 'SenderComp EKY2Z7/ TraderID UNKNOWN for group U$'117=102297=5300=91028=Y9772=09774=U$10=189)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, error> (MsgSeqNum too high, expecting 1195 but received 1196)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, outgoing> (8=FIX.4.29=9135=234=119849=EKY2Z7N50=BFHS52=20110606-07:29:22.82656=CME57=G142=US,IL7=119516=010=092)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, event> (Sent ResendRequest FROM: 1195 TO: 0)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, event> (Processing queued message: 1196)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, event> (ResendRequest for messages FROM 1195 TO 1195 has been satisfied.)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, incoming> (8=FIX.4.29=27135=b34=1195369=119852=20110606-07:29:22.83043=Y49=CME50=G56=EKY2Z7N57=BFHS143=US,IL122=20110606-07:29:22.81958=Quote rejected: Not authorized to quote this instrument 'SenderComp EKY2Z7/ TraderID UNKNOWN for group ZE'117=101297=5300=91028=Y9772=09774=ZE10=021)
<20110606-07:29:22, FIX.4.2:EKY2Z7N/BFHS/US,IL->CME/G, incoming> (8=FIX.4.29=27135=b34=1196369=119852=20110606-07:29:22.83143=Y49=CME50=G56=EKY2Z7N57=BFHS143=US,IL122=20110606-07:29:22.82058=Quote rejected: Not authorized to quote this instrument 'SenderComp EKY2Z7/ TraderID UNKNOWN for group U$'117=102297=5300=91028=Y9772=09774=U$10=196)

This snippet clearly shows that message 1196 came in before 1195, even though the log shows 1195 first. Here's what happens I believe:

1. 1195 comes in and is logged, not yet on received queue
2. 1196 comes in and is logged, and is put on received queue
3. 1195 is now put on received queue (almost a thread scheduling issue?, but there should only be a single thread...)
4. at this point 1196 is on received queue before 1195
5. consumer now gets 1196 before 1195, so generates an error (asking sender for 1195), and puts 1196 on pending queue
6. system then gets 1195 from received queue and says 'resend satisfied' even before the resend of message 1195 is received (and logged)
7. then reads the out of order 1196 from pending queue
8. the resend of 1195 is received and is ignored

We are using a SocketInitiator (which uses the SingleThreaded reader).

If it is not a bug, can you explain what we could possibly be doing in our code to cause this behavior? Or what we might try to diagnose the problem?

Comment by robert engels [ 13/Jun/11 ]

I think the block() method in the SingleThreadedEventHandlingStrategy needs to be synchronized. Otherwise if multiple threads call block(), you can process message out of order. For example:

Thread A is in block(), calls getMessage() - context switch
Thread B calls block(), which calls getMessage(), and calls processMessage()

The messages are now processed out of order. These context switches are more app to happen in a heavily stressed system, with lots of active threads (which is what the original reporter implies).

Now, I don't think an outside thread should be calling block(), but it is public an it appears that some library level housekeeping code does. Could it be a timer type operation that is causing the problems?

Why is block() even exposed? But you also have the same problem if two calls to blockInThread() are made, as there will be multiple reader threads, and that is a problem...

Synchronizing block() would fix both of these cases, and is simple, but I am not sure it is the cause of the problem, or the correct solution.

Comment by Steve Bate [ 13/Jun/11 ]

The block method is exposed because it's part of the original QuickFIX JNI API. Some users apparently process their messages in the thread that calls block.

A method being public doesn't imply it is thread safe and in this case it should never be called from multiple threads. The start method should also never be called from multiple threads. Do you think this is happening in your application?

As a simple check, look for multiple QFJ Message Processor threads. This would happen if start were called from multiple threads. You can also do a thread dump and look for multiple occurrences of threads with the block method in the stack trace.

If this is the problem, we could add a guard in the start method to throw an exception if it is called from multiple threads.

Comment by robert engels [ 13/Jun/11 ]

I have done just that and I see only a single processor thread - at least in standard usage. I am afraid there may be a case, whether our code, or in the library, where there is some timeout condition (that gets triggered under heavy stress), and multiple threads are created then. I've looked through our code, and can see no place where this could occur, but I'll admit that it is somewhat complex. The issue is that we never saw this with 1.3.0, only after upgrading to 1.5.0. I'm afraid it has something to do with session handling/identification and the new method in 1.3.1+ is a contributing factor.

Regardless, since the block() is really internal, I don't think there is any performance problem of making it synchronized (since there should only be a single thread in it anyway!), and it would guard against processing messages out of order in ANY case.





[QFJ-488] No custom tags in Instrument component Created: 01/Dec/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: David Brown Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

I have added custom tags to the Instrument component in my data dictionary and it uses them correctly when validating messages containing these custom tags, however they do not appear in the set of fields for the Instrument component but appear in the enclosing group i.e. quickfix.fix44.QuoteRequest.NoRelatedSym.
Not sure if this is a bug but behaviour is not as I would expect.



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

This is after code generation with the custom dictionary?

Comment by David Brown [ 15/Jan/10 ]

No, it worked fine once I regenerated code using the custom dictionary - but I had assumed it would use the dictionary at runtime without the need to regen the code.





[QFJ-487] QuickFix FieldException has default scope Created: 26/Nov/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: David Brown Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

FieldException is thrown, for example, if a tag has no value. However, as it has default scope it is not possible to retrieve the details of which field caused the problem even though FieldException includes a publically accessible getField() method. Not sure if this is a bug or whether there it was intentionally left with default scope.






[QFJ-486] How can i keep right tag order when i parse fix message Created: 25/Nov/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: kesler.wang Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

JDK5.0



 Description   

Hi:
I met a problem when I parse fix message by quickfixj. I refer an example from here http://www.quickfixj.org/confluence/display/qfj/Using+Message+Metadata
So according to this example, I use FieldMap.iterator() to get all of the tag elements from message object, but when i loop the iterator, i find the tag order is not correct. Like the example, the tag "MsgType" is fourth, but fix protocol define it should be third.
So could you tell me how to keep the right order, or other way to create new Message when i get all of tag elements parsed by FieldMap.iterator().

My test fix message : 8=FIX.4.4\0019=263\00135=s\00149=CLIENT\00156=ASX\00134=287 ......
output result : 8=FIX.4.4\0019=263\00134=287\00135=s\00149=CLIENT......

I'm not native english speaker, i'm not sure i describe the question clearly, if you have any question, please let me know. Thank you very much.

Kind Regards
Kelser.Wang






[QFJ-485] EnabledProtocols, CipherSuites Created: 20/Nov/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

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

Type: Improvement Priority: Default
Reporter: Mohamed-Zied MAALA Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Enable to configure the cipherSuites and enabledProtocol on SSL filter



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-484] Session responder lock change inadequate Created: 17/Nov/09  Updated: 29/Apr/11  Resolved: 29/Apr/11

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

Type: Bug Priority: Default
Reporter: James Olsen Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None

Attachments: Text File QFJ-484(1_5_0).patch     Text File QFJ-484.patch    
Issue Links:
Relates
is related to QFJ-421 Session responder lock is too restric... Closed

 Description   

Using a synchronized block can result in a thread being starved of access to the responder. This should be changed to use a Lock with fair semantics.

Starvation was observed in a scenario using SocketSynchronousWrites=Y where a slow consumer could not be disconnected because the message writing thread kept re-obtaining the monitor.



 Comments   
Comment by James Olsen [ 17/Nov/09 ]

Relates to change proposed by QFJ-421.

Comment by James Olsen [ 17/Nov/09 ]

No option to attach patch, so will try in-lining:

Index: core/src/main/java/quickfix/Session.java
===================================================================
— core/src/main/java/quickfix/Session.java (revision 926)
+++ core/src/main/java/quickfix/Session.java (working copy)
@@ -27,6 +27,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;

import quickfix.Message.Header;
import quickfix.field.BeginSeqNo;
@@ -231,7 +233,7 @@

private boolean enabled;

  • private final String responderSync = "SessionResponderSync";
    + private final Lock responderSync = new ReentrantLock(true);
    // @GuardedBy(responderSync)
    private Responder responder;

@@ -330,19 +332,25 @@

  • @param responder a responder implementation
    */
    public void setResponder(Responder responder) {
  • synchronized (responderSync) {
    + responderSync.lock();
    + try
    Unknown macro: { this.responder = responder; if (responder != null) { stateListener.onConnect(); } else { stateListener.onDisconnect(); }+ }

    finally

    { + responderSync.unlock(); }
    }

    public Responder getResponder() {
    - synchronized (responderSync) {
    + responderSync.lock();
    + try { // FIXME why this???? return responder; + } finally {+ responderSync.unlock(); }

    }

@@ -1436,13 +1444,16 @@

  • @throws IOException IO error
    */
    public void disconnect() throws IOException {
  • synchronized (responderSync) {
    + responderSync.lock();
    + try
    Unknown macro: { if (!hasResponder()) { return; } getLog().onEvent("Disconnecting"); responder.disconnect(); setResponder(null);+ }

    finally

    { + responderSync.unlock(); }

    boolean logonReceived = state.isLogonReceived();
    @@ -1778,13 +1789,16 @@

    private boolean send(String messageString) {
    getLog().onOutgoing(messageString);
    - synchronized (responderSync) {
    + responderSync.lock();
    + try {
    if (!hasResponder()) { getLog().onEvent( "Attempt to send while not connected (message stored until connected)."); return false; }
    return getResponder().send(messageString);
    + } finally {+ responderSync.unlock(); }

    }

Comment by James Olsen [ 16/Feb/10 ]

Attached QFJ-484.patch based on using a re-entrant lock as discussed above and the change recommended by Parwinder Sekhon at http://www.quickfixj.org/jira/browse/QFJ-433?focusedCommentId=11014&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_11014

Parwdiner's change is critical when using synchronous writes when you have multiple sessions running.

Comment by James Olsen [ 17/Jan/11 ]

Copy of patch as applied to 1_5_0 Session source.

Comment by Eric Deshayes [ 28/Apr/11 ]

committed on integration branch rev #1024

Comment by Eric Deshayes [ 29/Apr/11 ]

After discussion, the usage of Reentrant Lock would likely cause some throughput/latency performance.
Also, the scenario that lead to that issue is not a common usecase (very slow file writing operation).
However, it highlighted a regression following the issue QFJ-421 which has been reopened.





[QFJ-483] QFJ Dictionary Generator Created: 02/Nov/09  Updated: 24/Aug/12  Resolved: 03/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: 1.5.3

Type: New Feature Priority: Default
Reporter: Morten Kristiansen Assignee: Christoph John
Resolution: Fixed Votes: 4
Labels: None

Attachments: File generator.tar    
Issue Links:
Relates
relates to QFJ-453 FIX 5.0 SP1 and SP2 Support Resolved

 Description   

We're currently working on a FIX integration towards a large European Exchange. One of the requirements from the Exchange FIX engine was to support FIX 5.0SP2. We had to do some minor fixes in the QFJ code to support this (I will not submit the changes here since I quess you have do something with the entire architecture in QFJ to support FIX 5.0 better (with the split of session and application protocol). What I would LIKE to submit, is some code we made for generating QFJ Dictionary files based on a FIX repository (we used this to generate our FIX5.0SP2.xml file).

Let me know if you would like to have a look at it. You'll probably want to do some changes to it, but it works. If you want it, where do you want the code sent/attached?



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

Yes, please attach patches for your changes (attachments have been reenabled). Thanks!

Comment by Steve Bate [ 25/Jan/10 ]

How did you handle the enum value descriptions so that they are compatible with code generation? This has been an ongoing issue with the FIX repository.

Comment by Morten Kristiansen [ 25/Jan/10 ]

Our Generator code attached.

Some notes:

You have a "fix" package where the top level class is Repository. It can bootstrap a repository based on a directory (containing a FIX repository)

Then you have a "quickfixj" package with the Generator class that uses the Repository class to generate a QJF xml dictionary file. Note that the Generator class supports a backupRepositoryDir. This code is not needed and was only used by us when generating dictionary towards the London Stock Exchange TradElect FIX Repository (see comment in Generator constructor for reason).

Let me know if you have questions.

You should be able to run this with:

java quickfixj.Generator [path to a FIX repository]

Comment by Toby Shepheard [ 29/Sep/11 ]

Thanks for this I've found it very useful for generating a 5.0SP2 version of the dictionary xml files.

Just a small note for anyone else making use of it. The newer 2010 FIX repository has changed the format somewhat, so the Generator code would need adapting. I've just used the older 2009 version (also available from the FIX website) which was fine for my needs.

Comment by Christoph John [ 02/Aug/12 ]

Committed as r1077.

Thanks to Morten for this useful contribution.
I've made some changes regarding ordering of tags, enum descriptions, etc, in order to make the dictionaries look more similar to the existing QFJ dictionaries.

Do not forget to correct the major/minor number in the session data dictionary after the generation finished.

As already stated by Toby, this generator only works with the FPL 2008/09 repository files (http://fixprotocol.org/repository-2008).

There are still some issues regarding the enums due to the description in the Enums.xml file. Some are just very long, others are named differently than before (e.g. AUTOMATED_EXECUTION_ORDER_PRIVATE_NO_BROKER_INTERVENTION vs. AUTOMATED_EXECUTION_ORDER_PRIVATE). If someone finds that disturbing, please open a bug report for this.





[QFJ-482] Provide configuration for local ip/port binding in the Initiator Created: 02/Nov/09  Updated: 15/Nov/12  Resolved: 09/Jun/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: New Feature Priority: Default
Reporter: Morten Kristiansen Assignee: Jörg Thönnes
Resolution: Fixed Votes: 3
Labels: None

Attachments: Zip Archive mylyn-context.zip     File svndiff.log    

 Description   

We're currently working on a FIX integration towards a large European Exchange. One of the requirements from the Exchange FIX engine, was that we needed to bind our Initiator socket to specific ip adresses for the different sessions. We're currently using a locally modified QFJ (based on tag QFJ_RELEASE_1_4_0), which now supports this feature (in addition to FIX 5.0SP2 support).

We thought we should give you our modifications and hope it (in some way) will be included in a future release of QFJ. I will attach a patch (svn diff of the tag mentioned and our modifications). All diffs are for supporting Initiator local ip binding. In addition we extended a little logging in IoSessionInitiator.java (log the Exception getMessage() in event log in addition to class name; didn't really give enough info!).

NOTE: The local ip binding configuration we added should perhaps be extended to be able to support different binding for each "SocketAddress[] socketAddresses" (we only added 1 localAddress for all socketAddresses).



 Comments   
Comment by Morten Kristiansen [ 02/Nov/09 ]

I didn't see any way to attach my svn diff file, so here is its contents:

Index: core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java
===================================================================
— core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (revision 12810)
+++ core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (revision 15471)
@@ -82,6 +82,7 @@
protected void createSessionInitiators(EventHandlingStrategy eventHandlingStrategy) throws ConfigError {
try {
createSessions();
+ SessionSettings settings = getSettings();
for (Session session : getSessionMap().values())

{ SessionID sessionID = session.getSessionID(); int reconnectingInterval = getReconnectIntervalInSeconds(sessionID); @@ -91,6 +92,23 @@ throw new ConfigError("Must specify at least one socket address"); }

+ // Check if use of socket local/bind address
+ SocketAddress localAddress = null;
+ if (settings.isSetting(sessionID, Initiator.SETTING_SOCKET_LOCAL_HOST)) {
+ String host = settings.getString(sessionID, Initiator.SETTING_SOCKET_LOCAL_HOST);
+ if ("localhost".equals(host))

{ + throw new ConfigError(Initiator.SETTING_SOCKET_LOCAL_HOST + " cannot be \"localhost\"!"); + }

+ int port = 0;
+ if (settings.isSetting(sessionID, Initiator.SETTING_SOCKET_LOCAL_PORT))

{ + port = (int) settings.getLong(sessionID, Initiator.SETTING_SOCKET_LOCAL_PORT); + }

+ localAddress = ProtocolFactory.createSocketAddress(TransportType.SOCKET, host, port);
+ if (log.isInfoEnabled())

{ + log.info("Using initiator local host: " + localAddress); + }

+ }
+
NetworkingOptions networkingOptions = new NetworkingOptions(getSettings()
.getSessionProperties(sessionID));

@@ -103,7 +121,7 @@
String keyStorePassword = SSLSupport.getKeystorePasswd(getSettings(), sessionID);

IoSessionInitiator ioSessionInitiator = new IoSessionInitiator(session,

  • socketAddresses, reconnectingInterval, getScheduledExecutorService(),
    + socketAddresses, localAddress, reconnectingInterval, getScheduledExecutorService(),
    networkingOptions, eventHandlingStrategy, getIoFilterChainBuilder(),
    sslEnabled, keyStoreName, keyStorePassword);

Index: core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java
===================================================================
— core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java (revision 12810)
+++ core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java (revision 15471)
@@ -56,13 +56,13 @@
private Future<?> reconnectFuture;

public IoSessionInitiator(Session fixSession, SocketAddress[] socketAddresses,

  • long reconnectIntervalInSeconds, ScheduledExecutorService executor,
    + SocketAddress localAddress, long reconnectIntervalInSeconds, ScheduledExecutorService executor,
    NetworkingOptions networkingOptions, EventHandlingStrategy eventHandlingStrategy,
    IoFilterChainBuilder userIoFilterChainBuilder, boolean sslEnabled, String keyStoreName,
    String keyStorePassword) throws ConfigError {
    this.executor = executor;
    try { - reconnectTask = new ConnectTask(sslEnabled, socketAddresses, userIoFilterChainBuilder, + reconnectTask = new ConnectTask(sslEnabled, socketAddresses, localAddress, userIoFilterChainBuilder, fixSession, reconnectIntervalInSeconds * 1000L, networkingOptions, eventHandlingStrategy, keyStoreName, keyStorePassword); }

    catch (GeneralSecurityException e) {
    @@ -72,6 +72,7 @@

private static class ConnectTask implements Runnable {
private final SocketAddress[] socketAddresses;
+ private final SocketAddress localAddress;
private final IoConnector ioConnector;
private final Session fixSession;
private final long reconnectIntervalInMillis;
@@ -87,11 +88,12 @@
private ConnectFuture connectFuture;

public ConnectTask(boolean sslEnabled, SocketAddress[] socketAddresses,

  • IoFilterChainBuilder userIoFilterChainBuilder, Session fixSession,
    + SocketAddress localAddress, IoFilterChainBuilder userIoFilterChainBuilder, Session fixSession,
    long reconnectIntervalInMillis, NetworkingOptions networkingOptions,
    EventHandlingStrategy eventHandlingStrategy, String keyStoreName,
    String keyStorePassword) throws ConfigError, GeneralSecurityException {
    this.socketAddresses = socketAddresses;
    + this.localAddress = localAddress;
    this.fixSession = fixSession;
    this.reconnectIntervalInMillis = reconnectIntervalInMillis;
    this.keyStoreName = keyStoreName;
    @@ -136,7 +138,11 @@
    lastReconnectAttemptTime = SystemTime.currentTimeMillis();
    SocketAddress nextSocketAddress = getNextSocketAddress();
    try {
  • connectFuture = ioConnector.connect(nextSocketAddress, ioHandler);
    + if (localAddress == null) { + connectFuture = ioConnector.connect(nextSocketAddress, ioHandler); + }

    else

    { + connectFuture = ioConnector.connect(nextSocketAddress, localAddress, ioHandler); + }

    pollConnectFuture();
    } catch (Throwable e)

    { handleConnectException(e); @@ -167,7 +173,7 @@ e = e.getCause(); }

    if ((e instanceof IOException) && (e.getMessage() != null))

    { - fixSession.getLog().onEvent(e.getMessage()); + fixSession.getLog().onEvent(e.getClass().getName() + ": " + e.getMessage()); }

    else

    { String msg = "Exception during connection"; LogUtil.logThrowable(fixSession.getLog(), msg, e); Index: core/src/main/java/quickfix/Initiator.java =================================================================== --- core/src/main/java/quickfix/Initiator.java (revision 12810) +++ core/src/main/java/quickfix/Initiator.java (revision 15471) @@ -51,4 +51,20 @@ * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE */ public static final String SETTING_SOCKET_CONNECT_PORT = "SocketConnectPort"; -}

    \ No newline at end of file
    +
    + /**
    + * Initiator setting for local/bind host. Only valid when session connection
    + * type is "initiator".
    + *
    + * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE
    + */
    + public static final String SETTING_SOCKET_LOCAL_HOST = "SocketLocalHost";
    +
    + /**
    + * Initiator setting for local/bind port. Only valid when session connection
    + * type is "initiator".
    + *
    + * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE
    + */
    + public static final String SETTING_SOCKET_LOCAL_PORT = "SocketLocalPort";
    +}

Comment by Morten Kristiansen [ 02/Nov/09 ]

And of course I included the wrong diff Here's the correct one (just delete the previous):

Index: core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java
===================================================================
— core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (revision 926)
+++ core/src/main/java/quickfix/mina/initiator/AbstractSocketInitiator.java (working copy)
@@ -82,6 +82,7 @@
protected void createSessionInitiators(EventHandlingStrategy eventHandlingStrategy) throws ConfigError {
try {
createSessions();
+ SessionSettings settings = getSettings();
for (Session session : getSessionMap().values())

{ SessionID sessionID = session.getSessionID(); int reconnectingInterval = getReconnectIntervalInSeconds(sessionID); @@ -91,6 +92,23 @@ throw new ConfigError("Must specify at least one socket address"); }

+ // Check if use of socket local/bind address
+ SocketAddress localAddress = null;
+ if (settings.isSetting(sessionID, Initiator.SETTING_SOCKET_LOCAL_HOST)) {
+ String host = settings.getString(sessionID, Initiator.SETTING_SOCKET_LOCAL_HOST);
+ if ("localhost".equals(host))

{ + throw new ConfigError(Initiator.SETTING_SOCKET_LOCAL_HOST + " cannot be \"localhost\"!"); + }

+ int port = 0;
+ if (settings.isSetting(sessionID, Initiator.SETTING_SOCKET_LOCAL_PORT))

{ + port = (int) settings.getLong(sessionID, Initiator.SETTING_SOCKET_LOCAL_PORT); + }

+ localAddress = ProtocolFactory.createSocketAddress(TransportType.SOCKET, host, port);
+ if (log.isInfoEnabled())

{ + log.info("Using initiator local host: " + localAddress); + }

+ }
+
NetworkingOptions networkingOptions = new NetworkingOptions(getSettings()
.getSessionProperties(sessionID));

@@ -103,7 +121,7 @@
String keyStorePassword = SSLSupport.getKeystorePasswd(getSettings(), sessionID);

IoSessionInitiator ioSessionInitiator = new IoSessionInitiator(session,

  • socketAddresses, reconnectingInterval, getScheduledExecutorService(),
    + socketAddresses, localAddress, reconnectingInterval, getScheduledExecutorService(),
    networkingOptions, eventHandlingStrategy, getIoFilterChainBuilder(),
    sslEnabled, keyStoreName, keyStorePassword);

Index: core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java
===================================================================
— core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java (revision 926)
+++ core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java (working copy)
@@ -56,13 +56,13 @@
private Future<?> reconnectFuture;

public IoSessionInitiator(Session fixSession, SocketAddress[] socketAddresses,

  • long reconnectIntervalInSeconds, ScheduledExecutorService executor,
    + SocketAddress localAddress, long reconnectIntervalInSeconds, ScheduledExecutorService executor,
    NetworkingOptions networkingOptions, EventHandlingStrategy eventHandlingStrategy,
    IoFilterChainBuilder userIoFilterChainBuilder, boolean sslEnabled, String keyStoreName,
    String keyStorePassword) throws ConfigError {
    this.executor = executor;
    try { - reconnectTask = new ConnectTask(sslEnabled, socketAddresses, userIoFilterChainBuilder, + reconnectTask = new ConnectTask(sslEnabled, socketAddresses, localAddress, userIoFilterChainBuilder, fixSession, reconnectIntervalInSeconds * 1000L, networkingOptions, eventHandlingStrategy, keyStoreName, keyStorePassword); }

    catch (GeneralSecurityException e) {
    @@ -72,6 +72,7 @@

private static class ConnectTask implements Runnable {
private final SocketAddress[] socketAddresses;
+ private final SocketAddress localAddress;
private final IoConnector ioConnector;
private final Session fixSession;
private final long reconnectIntervalInMillis;
@@ -87,11 +88,12 @@
private ConnectFuture connectFuture;

public ConnectTask(boolean sslEnabled, SocketAddress[] socketAddresses,

  • IoFilterChainBuilder userIoFilterChainBuilder, Session fixSession,
    + SocketAddress localAddress, IoFilterChainBuilder userIoFilterChainBuilder, Session fixSession,
    long reconnectIntervalInMillis, NetworkingOptions networkingOptions,
    EventHandlingStrategy eventHandlingStrategy, String keyStoreName,
    String keyStorePassword) throws ConfigError, GeneralSecurityException {
    this.socketAddresses = socketAddresses;
    + this.localAddress = localAddress;
    this.fixSession = fixSession;
    this.reconnectIntervalInMillis = reconnectIntervalInMillis;
    this.keyStoreName = keyStoreName;
    @@ -136,7 +138,11 @@
    lastReconnectAttemptTime = SystemTime.currentTimeMillis();
    SocketAddress nextSocketAddress = getNextSocketAddress();
    try {
  • connectFuture = ioConnector.connect(nextSocketAddress, ioHandler);
    + if (localAddress == null) { + connectFuture = ioConnector.connect(nextSocketAddress, ioHandler); + }

    else

    { + connectFuture = ioConnector.connect(nextSocketAddress, localAddress, ioHandler); + }

    pollConnectFuture();
    } catch (Throwable e)

    { handleConnectException(e); @@ -167,7 +173,7 @@ e = e.getCause(); }

    if ((e instanceof IOException) && (e.getMessage() != null))

    { - fixSession.getLog().onEvent(e.getMessage()); + fixSession.getLog().onEvent(e.getClass().getName() + ": " + e.getMessage()); }

    else

    { String msg = "Exception during connection"; LogUtil.logThrowable(fixSession.getLog(), msg, e); Index: core/src/main/java/quickfix/Initiator.java =================================================================== --- core/src/main/java/quickfix/Initiator.java (revision 926) +++ core/src/main/java/quickfix/Initiator.java (working copy) @@ -51,4 +51,20 @@ * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE */ public static final String SETTING_SOCKET_CONNECT_PORT = "SocketConnectPort"; -}

    \ No newline at end of file
    +
    + /**
    + * Initiator setting for local/bind host. Only valid when session connection
    + * type is "initiator".
    + *
    + * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE
    + */
    + public static final String SETTING_SOCKET_LOCAL_HOST = "SocketLocalHost";
    +
    + /**
    + * Initiator setting for local/bind port. Only valid when session connection
    + * type is "initiator".
    + *
    + * @see quickfix.SessionFactory#SETTING_CONNECTION_TYPE
    + */
    + public static final String SETTING_SOCKET_LOCAL_PORT = "SocketLocalPort";
    +}

Comment by Morten Kristiansen [ 16/Jan/10 ]

SVN diff attached

Comment by Jörg Thönnes [ 19/Jan/11 ]

This is an important feature to connect to systems protected by a firewall.

Therefore, I would like to see this for the next version, ie 1.5.1.

Comment by Eric Deshayes [ 28/Apr/11 ]

committed in the integration branch rev #1023

Comment by Jörg Thönnes [ 09/Jun/11 ]

Re-opening because the new configuration options SocketLocalHost and SocketLocalPort are not documented.

Comment by Jörg Thönnes [ 09/Jun/11 ]

Resolving as fixed since it is documented now.

Close as soon the release is complete.





[QFJ-481] Connection terminated when receiving Logon-response after Logon with ResetSeqNumFlag=Y Created: 16/Oct/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: Future Releases
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Erik Nyquist Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Ubuntu 9 Server x64



 Description   

This week I downloaded the QuickFIX/J source code from the trunk and built a version of it to test our new FIX GW.

My test program fails when I try to do send a LOGON with ResetSeqNumFlag=Y. This is written to the log;

<20091016-08:25:18, FIXT.1.1:ABN->XTRM, event> (Initiated logon request)
<20091016-08:25:30, FIXT.1.1:ABN->XTRM, incoming> (8=FIXT.1.19=007235=A34=152=20091016-08:25:2649=XTRM56=ABN1128=798=0108=301137=710=135)
<20091016-08:25:55, FIXT.1.1:ABN->XTRM, event> (Received logon request)
<20091016-08:25:55, FIXT.1.1:ABN->XTRM, event> (Disconnecting: Received logon response before sending request)

The problem has been located to the following lines of code in /quickfixj/core/src/main/java/quickfix/Session.java (rev 926):

if (state.isResetSent() && !state.isResetReceived())

{ disconnect("Received logon response before sending request", true); }

The FIX GW responds to the LOGON with a normal LOGON response. However the QUICKFIX/J engine terminates the connections because it thinks that a SequenceReset should have been received. When I comment out the lines the test program works fine.



 Comments   
Comment by Erik Nyquist [ 16/Oct/09 ]

The environment should be Windows. It is my FIX GW that runs on Linux. I do not know how to change this field.

Comment by Steve Bate [ 05/Apr/10 ]

This message indicates that the initiator is receiving a logon message before it sent one. Are you trying to connect two initiators to each other? Normally, the initiator will send a logon and the acceptor will acknowledge it – in that order.





[QFJ-480] Release notes for QuickFixJ 1.4.0 Created: 15/Oct/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Vinh Vo Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux



 Description   

Is there a web page or document detailing the release notes for QuickFixJ 1.4.0? Things like what bugs were fixed, new functionalities, and etcetera.






[QFJ-479] Add FIX50SP1 and FIX50SP2 to ApplVerID Created: 13/Oct/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Improvement Priority: Default
Reporter: David Gibbs Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-453 FIX 5.0 SP1 and SP2 Support Resolved
Relates
relates to QFJ-472 Add FIX 5.0 SP1 and SP2 to quickfix.M... Closed

 Description   

The new values for SP1 and SP2 are not represented in class ApplVerID

8 = FIX50SP1
9 = FIX50SP2






[QFJ-478] can not parse cme definition message from cme file Created: 08/Oct/09  Updated: 07/Jul/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Andrei Pozolotin Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello;

I can not parse cme definition message from cme file from ftp://ftp.cme.com/secdef.dat.gz

code:

DataDictionary sessionDictionary, applicationDictionary;

sessionDictionary = new DataDictionary("FIXT11.xml");
applicationDictionary = new DataDictionary("FIX50.xml");

Message message = new Message();

boolean doValidation = false;

message.fromString(messageString, sessionDictionary,
applicationDictionary, doValidation);

sample cme input and quickfixj output:

INFO: messageString
1128=89=36835=d49=CME34=42552=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=1311=[N/A]305=8309=20460001827=0864=2865=5866=200906261145=0865=7866=200909301145=210059000870=1871=24872=1947=BRL969=0.0011140=100001141=11022=GBX264=51142=F1151=BR:DOL1180=259787=19850=0.00110=165

INFO: message
9=15235=d34=42549=CME52=2009100416001803515=BRL22=848=2086048155=BR:C0107=BR:DOLV09P002850200=200910202=2850207=XBMF461=OPECCS462=2562=5711=110=128

thank you;

Andrei



 Comments   
Comment by Andrei Pozolotin [ 08/Oct/09 ]

this is due to:
exception=quickfix.FieldException: Out of order repeating group members, field=309

Comment by Andrei Pozolotin [ 08/Oct/09 ]

this alleviates the problem:

sessionDictionary.setCheckFieldsOutOfOrder(false);
applicationDictionary.setCheckFieldsOutOfOrder(false);

but apparently cme needs help; now this:

exception=quickfix.FieldException: Tag appears more than once, field=1145

Comment by Andrei Pozolotin [ 08/Oct/09 ]

finally, field=1145 is missing from FIX50.xml

need to add:

1) new field definition

<field number="1145" name="EventTime" type="UTCTIMEONLY"/>

2) declare this field as member of the group:

<component name="EvntGrp">
<group name="NoEvents" required="N">
<field name="EventType" required="N"/>
<field name="EventDate" required="N"/>
<field name="EventTime" required="N"/>
<field name="EventPx" required="N"/>
<field name="EventText" required="N"/>
</group>
</component>

Comment by Andrei Pozolotin [ 08/Oct/09 ]

quickfix.FieldException: Tag appears more than once, field=1022

Comment by Andrei Pozolotin [ 08/Oct/09 ]

quickfix.FieldException: Tag appears more than once, field=1017

Comment by Andrei Pozolotin [ 08/Oct/09 ]

please let me know how to attach here final FIXCME.xml that works with quickfix 1.4.0?

Comment by Jonathan Felch [ 07/Jul/11 ]

The latest build from trunk continues to fail on a large number of records and also continues to be missing field definitions... Technically this file should be depending on FIX 5 SP2, which may be part of the problem... My attempts to generate code for FIX 5 SP 2 were unsuccessful.





[QFJ-477] TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER error while creating message from another FIX message and doValidation = false Created: 02/Oct/09  Updated: 01/Aug/12  Resolved: 01/Aug/12

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Subodh Jain Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

This happens because parseBody function in Message.java does'nt take doValidation as an argument. The fix for this:
1. Change line 533 in Message.java to
private void parseBody(DataDictionary dd) throws InvalidMessage
2. Add check at line 541:
if(doValidation){
if (isHeaderField(field.getField()))

{ // An acceptance test requires the sequence number to // be available even if the related field is out of order setField(header, field); throw new FieldException(SessionRejectReason.TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER, field.getTag()); }

}



 Comments   
Comment by Subodh Jain [ 02/Oct/09 ]

Correction#1. Change line 533 in Message.java to
private void parseBody(DataDictionary dd, boolean doValidation) throws InvalidMessage {

Comment by Rhys Yarranton [ 12/May/10 ]

See also QFJ-520.

Comment by Christoph John [ 01/Aug/12 ]

Looking at the code it looks like this is fixed since 1.5.1.

The FieldException in parseBody() is only thrown if doValidation==true.





[QFJ-476] Message vailidation is done even if use data dictionary flag is set "N" Created: 01/Oct/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Subodh Jain Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-501 Setting session property UseDataDicti... Closed

 Description   

The fix I found for this is:
1. Have a boolean flag useDataDictionary in Session.java.
2. When the session is created in DefaultSessionFactory this flag is passed based on session setting.
3. In session.java validate only is useDataDictionary=true.
ie. Modify function public void next(Message message) Line 763
change
if (dataDictionaryProvider != null)
to
if (dataDictionaryProvider != null && useDataDictionary)



 Comments   
Comment by Jake Machina [ 25/Mar/10 ]

A more effective fix might be to move line 99 of DefaultSessionFactory.java into the if() block following it (line 101).

This way dataDictionaryProvider would be null if appropriate, and all the checks which already use the null value will work.

Comment by Steve Bate [ 05/Apr/10 ]

SVN #926





[QFJ-475] ThreadPerSessionEventHandlingStrategy thread not exiting Created: 30/Sep/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: jani Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

linux


Issue Links:
Duplicate
duplicates QFJ-410 ThreadPerSessionEventHandlingStrategy... Closed

 Description   

such thread do not exit on acceptor.stop()

stopDispatcherThreads iterates the collection after it clear()s it apparently so stopDispatcher() is not run on individual threads.

The the run method of ThreadPerSessionEventHandlingStrategy checks for the stopped variable and exits if set to true.
However it uses a blocking queue and if no messages come that variable is not checked so the thread can keep the app from exiting.

In stopDispatcherThreads() we can interupt the thread if the queue is empty. Alternately instead of messages.take() we can use messages.poll()
with a timeout, but than we need to check for null return.



 Comments   
Comment by jani [ 30/Sep/09 ]

I don't see how I can attach diffs so here it is what made it work for me

Index: core/src/main/java/quickfix/mina/ThreadPerSessionEventHandlingStrategy.java
===================================================================
— core/src/main/java/quickfix/mina/ThreadPerSessionEventHandlingStrategy.java (revision 926)
+++ core/src/main/java/quickfix/mina/ThreadPerSessionEventHandlingStrategy.java (working copy)
@@ -60,10 +60,10 @@

public void stopDispatcherThreads() {
Collection<MessageDispatchingThread> dispatchersToShutdown = dispatchers.values();

  • dispatchers.clear();
    for (MessageDispatchingThread dispatcher : dispatchersToShutdown) { dispatcher.stopDispatcher(); }

    + dispatchers.clear();
    }

class MessageDispatchingThread extends Thread

{ @@ -105,9 +105,11 @@ }

}
}

  • +
    public void stopDispatcher()

    { stopped = true; + if (messages.size() == 0) + interrupt(); }

    }





[QFJ-474] Need Suppressing Tag not defined exception Created: 23/Sep/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Raman Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

java 1.6.0._07
windows
quickfixj 1.4.0


Attachments: Text File diff2.txt    

 Description   

Greetings!

My configuration is as follows:
[DEFAULT]
UseDataDictionary=N
AllowUnknownMsgFields=Y
ValidateFieldsOutOfOrder=N
ValidateFieldsHaveValues=N
ValidateUserDefinedFields=N
and others
[SESSION1]
#nothing out of the ordinary as below
[SESSION2]
BeginString=FIX.4.2
SenderCompID=RBDC
TargetCompID=IRDC
SocketConnectHost=192.168.42.80
SocketConnectPort=15000

And yet, all incoming 35=8 messages are being rejected with this error msg
Rejected: Tag not defined for this message type.

What am I doing wrong?
Can we request a simple configuration setting to suppress msgtypes?

Thank you
Raman



 Comments   
Comment by Raman [ 27/Sep/09 ]

I have solved this by modifying Session.java and placing the .class ahead of quickfix.jar.
rk2153 at gmail

Comment by Rhys Yarranton [ 10/May/10 ]

Discovered the following:

  • If unknown field is defined in the data dictionary, but not on the message type in question, then AllowUnknownMsgFields = true will have an effect.
  • If the unknown fields is not in the data dictionary at all, AllowUnknownMsgFields = true will have no effect.

The problem appears to be in the order of steps in the DataDictionary.iterate() method.

  • shouldCheckTag(field) only checks against user-defined fields (>= 5000) so it returns true.
  • dd.checkValidTagNumber(field) checks against the whole dictionary's field list
  • checkIsInMessage(field, msgType) is where AllowUnknownMsgFields is consulted. But this is too late if the field wasn't in the data dictionary at all.

Also note that the documentation for AllowUnknownMsgFields is misleading. The 1.4.0 implementation can have an effect regardless of the tag number.

Attached a patch which modifies iterate to skip dd.checkValidateTagNumber(field) and checkIsInMessage(field, msgType) if AllowUnknownMsgFields is true. I left dd.checkGroupCount(...) in place.

There may be some more fishiness in this area. For example, if you set ValidateUserDefinedFields to false, dd.checkGroupCount(...) will be skipped even if the field is in the data dictionary for the message. Is that right or wrong? It is not clear what the expected behaviour should be, especially given the inaccuracies in the documentation.

Please change this from "Other" to "Bug". We have customers who do weird things in production, such as sending us "mystery tags", and much as we might like them to adhere strictly to the spec, it isn't going to happen. So it is imperative that we are able to relax validation sufficiently to handle their behaviour.





[QFJ-473] Web docs wrongly say that ValidateUserDefinedFields default is "N", it's actually "Y" Created: 20/Sep/09  Updated: 15/Nov/12  Resolved: 15/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

web manual


Issue Links:
Duplicate
duplicates QFJ-454 Update documentation to reflect that ... Closed

 Description   

Web docs erroneously say ValidateUserDefinedFields default is "N", which is wrong. (Also notice that the name of the setting is not italicized like the rest are.)

The source for DataDictionary.java that the default is actually "Y".

See http://www.quickfixj.org/jira/browse/QFJ-449 which is similar. Is the process for changes to the web docs sufficient to prevent silly errors like this in the future?






[QFJ-472] Add FIX 5.0 SP1 and SP2 to quickfix.MessageUtils Created: 15/Sep/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Improvement Priority: Default
Reporter: David Gibbs Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-453 FIX 5.0 SP1 and SP2 Support Resolved
is related to QFJ-479 Add FIX50SP1 and FIX50SP2 to ApplVerID Closed

 Description   

applVerIDtoBeginString map in quickfix.MessageUtils does not include

'8' = FIX50SP1
'9' = FIX50SP2






[QFJ-471] Issue when receive Market data request messages Created: 11/Sep/09  Updated: 19/Dec/13  Resolved: 19/Dec/13

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

Type: Bug Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

HI Support,

I am inititating market data request message V and when i receive the reply message from the counterparty you engine is sending back a rejection

can you please advise why is the engine is rejecting the received message?

Sent Message

8=FIX.4.39=18135=V34=949=quote.SWSPB.dev.SWSPB.com50=SWSPBle52=20090911-20:20:21.28556=demo.client.fxgrid.integral.com128=146=155=EUR/USD460=4262=12263=1264=0265=0267=2269=0269=110=207

Received Message:
8=FIX.4.39=31135=W34=1149=demo.client.fxgrid.integral.com52=20090911-20:20:22.79156=quote.SWSPB.dev.SWSPB.com57=SWSPBle55=EUR/USD262=12460=4268=2269=0270=015=EUR271=0276=B282=BOAN299=G-9a21e7-123aac38287-BOAN-7bb7BID290=0269=1270=015=EUR271=0276=B282=BOAN299=G-9a21e7-123aac38287-BOAN-7bb7OFFER290=010=222

The enigne message : Message 11 Rejected: Tag appears more than once:15
and then the enigne reply back with the below message
8=FIX.4.39=15635=334=1049=quote.SWSPB.dev.SWSPB.com52=20090911-20:20:22.33056=demo.client.fxgrid.integral.com45=1158=Tag appears more than once371=15372=W373=1310=147






[QFJ-470] Order Message tag as per to the provider specs Created: 10/Sep/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi Support,

i hope if you can help me, as i am trying yo using market data request, i am trying to connect to integral, and as per to there specs i have to sent the message tags as per the below order, when i am trying to generate the messages using your api it order the tags on ascending order, but what i want is to order the Tags as per to integral order, i am not sure how can i achieve this, can you help, or can you refer me to any one who can help me?

8=FIX.4.3
9=182
35=V
34=24
49=quote.SWSPB.dev.SWSPB.com
50=SWSPBle
52=20090910-08:36:13.651
56=demo.client.fxgrid.integral.com
128=
146=1
55=EUR/USD
460=4
262=12
263=1
264=1
265=0
267=2
269-0
269=1
10=008



 Comments   
Comment by Hector Solis [ 09/Dec/09 ]

I have the same problem, how did you resolved it?
Any help will be appreciated.

Thanks

Comment by Ahmed Al Jebouri [ 14/Jan/10 ]

yes i was able to solve the issue by using group, as you can check the API when create a message you can create a group within the message hope this will help you.

please do not hesitate to contact me if you need more help





[QFJ-469] Market Data Request Created: 07/Sep/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I am tryng to connect to integral and subscripe to Market data request.

how can i set the tag order as per what i want as currently tags are being ordered by the tag number

Integral want the tag orders as below

Tag 146 should come before tag 55, but when i am using this API tag 55 is coming before Tag146 which lead a rejection message from integral can you help me please, as i have to do the same for other tags as well on the same message, as Tag 128 should come before those tags



 Comments   
Comment by Ahmed Al Jebouri [ 10/Sep/09 ]

Cany any one help me here please

Comment by Pranab Kumar Naik [ 12/Jul/10 ]

DId you try out ValidateFieldsOutOfOrder=N entry in your config file ?

Comment by Ahmed Al Jebouri [ 12/Jul/10 ]

issue is fixed i used the group withing the message





[QFJ-468] Quote subscribe Created: 04/Sep/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None


 Description   

Hi Support,

Please find below my code i am using to subscribe using market data request, the isse that i want when i create this message i want tag55 to come after tag146, as per to integral they want Tag55 to come after Tag146

quickfix.fix43.MarketDataRequest sub = new MarketDataRequest(new MDReqID(reqID),new SubscriptionRequestType('1'), new MarketDepth (1));
System.out.println("This is the message :" + sub.toString());
sub.setField(new SenderSubID("SWSPBle"));
sub.setField(new Product(4));
sub.setField(new NoRelatedSym(1));

sub.setField(new MDUpdateType(0));
sub.setField(new NoMDEntryTypes(0));
sub.setField(new quickfix.field.Symbol("EUR/USD"));

the generated message is coming as below

8=FIX.4.39=16535=V34=1249=quote.SWSPB.dev.SWSPB.com52=20090903-22:29:29.22356=demo.client.fxgrid.integral.com50=SWSPBle55=EUR/USD146=1262=12263=1264=1265=0267=0460=410=014

Response from integral as below
8=FIX.4.39=17735=334=1949=demo.client.fxgrid.integral.com52=20090903-22:29:31.32756=quote.SWSPB.dev.SWSPB.com57=SWSPBle45=1258=Tag not defined for this message type371=55372=V373=210=164

can you help me here please?






[QFJ-467] Susbcribe to symbol quote Created: 01/Sep/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi support,

Just want to know how i could subscribe to symbol using MarketDataRequest, and how i can get the session id ?

Regards,



 Comments   
Comment by Toli Kuznets [ 01/Sep/09 ]

Ahmed,

You can look at the code for Marketcetera Trading Platform. We use QuickFIX/J under the hood, and we have a sample FIX-based market data simulator.

If you look at the code, we tunnel all of our market data subscription requests through the FIXMessageFactory.newMarketDataRequest() call. It's around line 172.

Hope this helps. Not sure what you mean by how you can "get the session ID". Get it from where?

Comment by Ahmed Al Jebouri [ 02/Sep/09 ]

thank you for yor reply, i 've gone through th code, but still i am not able to do a sample quote subscription.

is there any sample code on how to use the same?

i am not able to understand how i can use the same in my application

Comment by Ahmed Al Jebouri [ 02/Sep/09 ]

i tried tocopy and paste the belwo code into my application but i get lot of errors, i.e what is reqID, and in line 180 also it shows error and so on can you help me to create a sample app to subscribe to FX

public Message newMarketDataRequest(String reqID,
173 List<MSymbol> symbols,
174 String inExchange)
175 {
176 Message request = msgFactory.create(beginString, MsgType.MARKET_DATA_REQUEST);
177 request.setField(new MarketDepth(TOP_OF_BOOK_DEPTH));
178 request.setField(new MDReqID(reqID));
179 request.setChar(SubscriptionRequestType.FIELD, SubscriptionRequestType.SNAPSHOT);
180 Group entryTypeGroup = msgFactory.create(beginString, MsgType.MARKET_DATA_REQUEST, NoMDEntryTypes.FIELD);
181 entryTypeGroup.setField(new MDEntryType(MDEntryType.BID));
182 request.addGroup(entryTypeGroup);
183 entryTypeGroup.setField(new MDEntryType(MDEntryType.OFFER));
184 request.addGroup(entryTypeGroup);
185
186 int numSymbols = symbols.size();
187 if (numSymbols == 0)

{ 188 request.setInt(NoRelatedSym.FIELD, numSymbols); 189 }

190 for (MSymbol oneSymbol : symbols) {
191 if(oneSymbol != null) {
192 Group symbolGroup = msgFactory.create(beginString, MsgType.MARKET_DATA_REQUEST, NoRelatedSym.FIELD);
193 symbolGroup.setField(new Symbol(oneSymbol.getFullSymbol()));
194 if(inExchange != null &&
195 !inExchange.isEmpty())

{ 196 symbolGroup.setField(new SecurityExchange(inExchange)); 197 }

198 request.addGroup(symbolGroup);
199 }
200 }
201 return request;
202 }

Comment by Ahmed Al Jebouri [ 02/Sep/09 ]

ok i am using the below code but i am getting and error

8=FIX.4.39=17735=334=2749=demo.client.fxgrid.integral.com52=20090902-15:36:06.15156=quote.SWSPB.dev.SWSPB.com57=SWSPBle45=2758=Tag not defined for this message type371=55372=V373=210=165

can you please help?

public Message newMarketDataRequest(String reqID) throws SessionNotFound
{
//msgFactory.create
//Message request = msgFactory.create(beginString, MsgType.MARKET_DATA_REQUEST);
// request.setField(new MarketDepth (1));
// request.setField(new MDReqID(reqID));
// request.setChar(SubscriptionRequestType.FIELD, SubscriptionRequestType.SNAPSHOT);
//quickfix.fix43.MarketDataRequest sub= new MarketDataRequest();

quickfix.fix43.MarketDataRequest sub = new MarketDataRequest(new MDReqID(reqID),new SubscriptionRequestType('0'), new MarketDepth (1));
sub.setField(new quickfix.field.Symbol("EUR/USD"));
sub.setField(new SenderSubID("SWSPBle"));
sub.setField(new Product(4));
sub.setField(new NoRelatedSym(1));
sub.setField(new MDUpdateType(0));
sub.setField(new NoMDEntryTypes(1));
// sub.setField(new MDEntryType('x'));

// set(new quickfix.field.Symbol("EURUSD"));

// Group entryTypeGroup; new Group() (beginString, MsgType.MARKET_DATA_REQUEST);
//= (Message)msgFactory.create (beginString, MsgType.MARKET_DATA_REQUEST);
// entryTypeGroup.setField(new MDEntryType(MDEntryType.BID));
// request.addGroup(entryTypeGroup);
// entryTypeGroup.setField(new MDEntryType(MDEntryType.OFFER));
// request.addGroup(entryTypeGroup);

//int numSymbols = symbols.size();
// if (numSymbols == 0)

{ // request.setInt(NoRelatedSym.FIELD, numSymbols); // }

// for (MSymbol oneSymbol : symbols) {
//if(oneSymbol != null) {
// Group symbolGroup = new Group(beginString, MsgType.MARKET_DATA_REQUEST);
// symbolGroup.setField(new Symbol("EURUSD"));
// if(inExchange != null &&
// !inExchange.isEmpty())

{ // symbolGroup.setField(new SecurityExchange(inExchange)); // }

// request.addGroup(symbolGroup);
// }
// }

return sub;
}





[QFJ-466] Initiator SocketConnectorIoProcessor-0.0 deadlocks with QFJ Message Processor at logout Created: 01/Sep/09  Updated: 29/Apr/11

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: Steve Borrer Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu Linux 2.6.24-23-server #1 SMP Thu Nov 27 18:45:02 UTC 2008 x86_64 GNU/Linux



 Description   

The FIX initiator is logged out at 21:30 UTC by the acceptor (itself built with QFJ). The initiator logs out. An exception is reported in the initiator. Shortly after, the initiator initiates a logon request which is declined as it is outside the time window of the acceptor. There is then a endless sequence of 'Pending connection not established after XXXX ms' messages. See my application log below:-

20090828-21:30:00 EVENT [FIX.4.2:NONAME->SIMULA] - Received logout request
20090828-21:30:00 EVENT [FIX.4.2:NONAME->SIMULA] - Sent logout response
20090828-21:30:00 EVENT [FIX.4.2:NONAME->SIMULA] - DisconnectingAug 28, 2009 9:30:00 PM quickfix.mina.AbstractIoHandler exceptionCaught
SEVERE: socket exception (localhost/127.0.0.1:9876): Connection reset by peer

20090828-21:30:00 20090828-09:30:00 DEBUG - loggingOutState:true
20090828-21:30:00 20090828-09:30:00 DEBUG - Session logged out: FIX.4.2:NONAME->SIMULA
Aug 28, 2009 9:30:01 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:47950
20090828-21:30:02 EVENT [FIX.4.2:NONAME->SIMULA] - Initiated logon request
20090828-21:30:02 EVENT [FIX.4.2:NONAME->SIMULA] - Received logout request
20090828-21:30:02 EVENT [FIX.4.2:NONAME->SIMULA] - Disconnecting
20090828-21:30:02 20090828-09:30:02 DEBUG - loggingOutState:true
20090828-21:30:02 20090828-09:30:02 DEBUG - Session logged out: FIX.4.2:NONAME->SIMULA
20090828-21:30:02 EVENT [FIX.4.2:NONAME->SIMULA] - Attempt to send while not connected (message stored until connected).
20090828-21:30:33 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 2000 ms.
20090828-21:30:36 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 5000 ms.
20090828-21:30:39 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 8001 ms.
20090828-21:30:42 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 11001 ms.
20090828-21:30:45 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 14002 ms.
20090828-21:30:48 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 17002 ms.
20090828-21:30:51 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 20003 ms.
20090828-21:30:54 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 23003 ms.
20090828-21:30:57 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 26004 ms.
... etc

A SIGQUIT to the initiator reveals a deadlock:-

20090901-08:07:25 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 38094032 ms.
20090901-08:07:28 EVENT [FIX.4.2:NONAME->SIMULA] - Pending connection not established after 38097032 ms.
2009-09-01 08:07:28
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0-b16 mixed mode):

"Checkpointer" daemon prio=10 tid=0x00007f15040fa000 nid=0x1f7f in Object.wait() [0x0000000040d6d000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at com.sleepycat.je.utilint.DaemonThread.run(DaemonThread.java:161)

  • locked <0x00007f150f850a80> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:619)

"Cleaner-1" daemon prio=10 tid=0x00007f15040f9800 nid=0x1f7e in Object.wait() [0x0000000041293000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at com.sleepycat.je.utilint.DaemonThread.run(DaemonThread.java:161)

  • locked <0x00007f150f84ca80> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:619)

"INCompressor" daemon prio=10 tid=0x00007f1504216000 nid=0x1f7d in Object.wait() [0x0000000042400000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at com.sleepycat.je.utilint.DaemonThread.run(DaemonThread.java:163)

  • locked <0x00007f150f84ea80> (a java.lang.Object)
    at java.lang.Thread.run(Thread.java:619)

"SocketConnectorIoProcessor-0.0" daemon prio=10 tid=0x0000000040789000 nid=0x1f7c waiting for monitor entry [0x0000000042804000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.sleepycat.je.Cursor.close(Cursor.java:242)

  • waiting to lock <0x00007f150f8529d8> (a com.sleepycat.je.Cursor)
    at com.sleepycat.je.Database.close(Database.java:242)
  • locked <0x00007f150f852a18> (a com.sleepycat.je.Database)
    at quickfix.SleepycatStore.reset(SleepycatStore.java:285)
    at quickfix.SessionState.reset(SessionState.java:368)
    at quickfix.Session.resetState(Session.java:1828)
    at quickfix.Session.disconnect(Session.java:1542)
    at quickfix.mina.AbstractIoHandler.sessionClosed(AbstractIoHandler.java:100)
    at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.sessionClosed(AbstractIoFilterChain.java:677)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
    at org.apache.mina.filter.codec.ProtocolCodecFilter.sessionClosed(ProtocolCodecFilter.java:292)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
    at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
    at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:567)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
    at java.lang.Thread.run(Thread.java:619)

"OMS_Client:nt@tradera1" prio=10 tid=0x000000004060c000 nid=0x178f runnable [0x0000000042905000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

  • locked <0x00007f150ee02ab0> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
  • locked <0x00007f150ee02ab0> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at oms.SimpleReader.readMessage(SimpleReader.java:26)
    at oms.SimpleSerializer.deserialize(SimpleSerializer.java:178)
    at fixclient.OMS_Client.run(OMS_Client.java:208)

"QFJ Message Processor" daemon prio=10 tid=0x00007f1504272000 nid=0x177b waiting for monitor entry [0x0000000042602000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.sleepycat.je.Database.removeCursor(Database.java:879)

  • waiting to lock <0x00007f150f852a18> (a com.sleepycat.je.Database)
    at com.sleepycat.je.Cursor.close(Cursor.java:245)
  • locked <0x00007f150f8529d8> (a com.sleepycat.je.Cursor)
    at com.sleepycat.je.Database.putInternal(Database.java:536)
    at com.sleepycat.je.Database.put(Database.java:479)
    at quickfix.SleepycatStore.set(SleepycatStore.java:301)
    at quickfix.SessionState.set(SessionState.java:299)
    at quickfix.Session.sendRaw(Session.java:1810)
    at quickfix.Session.generateLogout(Session.java:1050)
    at quickfix.Session.generateLogout(Session.java:1041)
    at quickfix.Session.nextLogout(Session.java:1024)
    at quickfix.Session.next(Session.java:790)
    at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
    at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
    at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
    at java.lang.Thread.run(Thread.java:619)

"QFJ Timer" daemon prio=10 tid=0x00007f15042e1000 nid=0x177a in Object.wait() [0x0000000042501000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:443)
at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.TimeUnit.timedWait(TimeUnit.java:364)
at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.DelayQueue.take(DelayQueue.java:156)

  • locked <0x00007f150ec65480> (a java.lang.Object)
    at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:680)
    at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:921)
    at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:980)
    at org.quickfixj.java4.edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:528)
    at java.lang.Thread.run(Thread.java:619)

"OMS_Client:oms@tradera1" prio=10 tid=0x000000004018c000 nid=0x1773 runnable [0x0000000040b04000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

  • locked <0x00007f150ede9ec8> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
  • locked <0x00007f150ede9ec8> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at oms.SimpleReader.readMessage(SimpleReader.java:26)
    at oms.SimpleSerializer.deserialize(SimpleSerializer.java:178)
    at fixclient.OMS_Client.run(OMS_Client.java:208)

"OMS_Client:oms@tradera1" prio=10 tid=0x00000000405e8000 nid=0x1772 runnable [0x0000000040a03000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

  • locked <0x00007f150eddb7c8> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
  • locked <0x00007f150eddb7c8> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at oms.SimpleReader.readMessage(SimpleReader.java:26)
    at oms.SimpleSerializer.deserialize(SimpleSerializer.java:178)
    at fixclient.OMS_Client.run(OMS_Client.java:208)

"OMS_Client:oms@tradera1" prio=10 tid=0x0000000040477800 nid=0x1771 runnable [0x0000000040902000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)

  • locked <0x00007f150ec74260> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
  • locked <0x00007f150ec74260> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at oms.SimpleReader.readMessage(SimpleReader.java:26)
    at oms.SimpleSerializer.deserialize(SimpleSerializer.java:178)
    at fixclient.OMS_Client.run(OMS_Client.java:208)

"OMS_Interface" prio=10 tid=0x00007f15040a2000 nid=0x1770 runnable [0x0000000040c6c000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)

  • locked <0x00007f150ebcace0> (a java.net.SocksSocketImpl)
    at java.net.ServerSocket.implAccept(ServerSocket.java:453)
    at java.net.ServerSocket.accept(ServerSocket.java:421)
    at fixclient.OMS_Interface.run(OMS_Interface.java:93)
    at java.lang.Thread.run(Thread.java:619)

"OMS_Sender" prio=10 tid=0x00007f1504059800 nid=0x1735 in Object.wait() [0x00000000422ff000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at fixclient.OMS_Sender.run(OMS_Sender.java:55)

  • locked <0x00007f150ebc01c0> (a java.util.LinkedList)

"MessageQueue" prio=10 tid=0x00007f1504058800 nid=0x1734 in Object.wait() [0x00000000421fe000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)

  • waiting on <0x00007f150ebc40d8> (a java.util.LinkedList)
    at java.lang.Object.wait(Object.java:485)
    at fixclient.OMS_Interface$MessageQueue.run(OMS_Interface.java:312)
  • locked <0x00007f150ebc40d8> (a java.util.LinkedList)

"Low Memory Detector" daemon prio=10 tid=0x00000000402f2800 nid=0x1726 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"CompilerThread1" daemon prio=10 tid=0x00000000402ef800 nid=0x1724 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"CompilerThread0" daemon prio=10 tid=0x00000000402eb000 nid=0x1721 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" daemon prio=10 tid=0x00000000402e9000 nid=0x171e waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE

"Finalizer" daemon prio=10 tid=0x00000000402c6000 nid=0x1714 in Object.wait() [0x0000000041ffc000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)

  • locked <0x00007f150ebc2190> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

"Reference Handler" daemon prio=10 tid=0x00000000402c4000 nid=0x170f in Object.wait() [0x0000000041efb000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)

  • locked <0x00007f150ebc6168> (a java.lang.ref.Reference$Lock)

"main" prio=10 tid=0x0000000040112800 nid=0x16e5 in Object.wait() [0x00000000417f4000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)

  • waiting on <0x00007f150ebc4258> (a fixclient.FIX_Client)
    at java.lang.Object.wait(Object.java:485)
    at fixclient.FIX_Client.run(FIX_Client.java:218)
  • locked <0x00007f150ebc4258> (a fixclient.FIX_Client)
    at fixclient.FIX_Client.main(FIX_Client.java:325)

"VM Thread" prio=10 tid=0x00000000402bd800 nid=0x170a runnable

"GC task thread#0 (ParallelGC)" prio=10 tid=0x000000004011c800 nid=0x16ea runnable

"GC task thread#1 (ParallelGC)" prio=10 tid=0x000000004011e800 nid=0x16ee runnable

"GC task thread#2 (ParallelGC)" prio=10 tid=0x0000000040120800 nid=0x16f2 runnable

"GC task thread#3 (ParallelGC)" prio=10 tid=0x0000000040122000 nid=0x16f6 runnable

"GC task thread#4 (ParallelGC)" prio=10 tid=0x0000000040124000 nid=0x16fa runnable

"GC task thread#5 (ParallelGC)" prio=10 tid=0x0000000040126000 nid=0x16fe runnable

"GC task thread#6 (ParallelGC)" prio=10 tid=0x0000000040127800 nid=0x1702 runnable

"GC task thread#7 (ParallelGC)" prio=10 tid=0x0000000040129800 nid=0x1706 runnable

"VM Periodic Task Thread" prio=10 tid=0x00000000402f5000 nid=0x1728 waiting on condition

JNI global references: 1325

Found one Java-level deadlock:
=============================
"SocketConnectorIoProcessor-0.0":
waiting to lock monitor 0x000000004079f4d8 (object 0x00007f150f8529d8, a com.sleepycat.je.Cursor),
which is held by "QFJ Message Processor"
"QFJ Message Processor":
waiting to lock monitor 0x00000000407a0d20 (object 0x00007f150f852a18, a com.sleepycat.je.Database),
which is held by "SocketConnectorIoProcessor-0.0"

Java stack information for the threads listed above:
===================================================
"SocketConnectorIoProcessor-0.0":
at com.sleepycat.je.Cursor.close(Cursor.java:242)

  • waiting to lock <0x00007f150f8529d8> (a com.sleepycat.je.Cursor)
    at com.sleepycat.je.Database.close(Database.java:242)
  • locked <0x00007f150f852a18> (a com.sleepycat.je.Database)
    at quickfix.SleepycatStore.reset(SleepycatStore.java:285)
    at quickfix.SessionState.reset(SessionState.java:368)
    at quickfix.Session.resetState(Session.java:1828)
    at quickfix.Session.disconnect(Session.java:1542)
    at quickfix.mina.AbstractIoHandler.sessionClosed(AbstractIoHandler.java:100)
    at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.sessionClosed(AbstractIoFilterChain.java:677)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
    at org.apache.mina.filter.codec.ProtocolCodecFilter.sessionClosed(ProtocolCodecFilter.java:292)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
    at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
    at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
    at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
    at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
    at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44)
    at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:567)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
    at java.lang.Thread.run(Thread.java:619)
    "QFJ Message Processor":
    at com.sleepycat.je.Database.removeCursor(Database.java:879)
  • waiting to lock <0x00007f150f852a18> (a com.sleepycat.je.Database)
    at com.sleepycat.je.Cursor.close(Cursor.java:245)
  • locked <0x00007f150f8529d8> (a com.sleepycat.je.Cursor)
    at com.sleepycat.je.Database.putInternal(Database.java:536)
    at com.sleepycat.je.Database.put(Database.java:479)
    at quickfix.SleepycatStore.set(SleepycatStore.java:301)
    at quickfix.SessionState.set(SessionState.java:299)
    at quickfix.Session.sendRaw(Session.java:1810)
    at quickfix.Session.generateLogout(Session.java:1050)
    at quickfix.Session.generateLogout(Session.java:1041)
    at quickfix.Session.nextLogout(Session.java:1024)
    at quickfix.Session.next(Session.java:790)
    at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
    at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
    at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
    at java.lang.Thread.run(Thread.java:619)

Found 1 deadlock.

Heap
PSYoungGen total 10944K, used 3722K [0x00007f1519660000, 0x00007f151a3e0000, 0x00007f151ebb0000)
eden space 8448K, 36% used [0x00007f1519660000,0x00007f151995aaa8,0x00007f1519ea0000)
from space 2496K, 26% used [0x00007f151a170000,0x00007f151a218000,0x00007f151a3e0000)
to space 2688K, 0% used [0x00007f1519ea0000,0x00007f1519ea0000,0x00007f151a140000)
PSOldGen total 26368K, used 14066K [0x00007f150ebb0000, 0x00007f1510570000, 0x00007f1519660000)
object space 26368K, 53% used [0x00007f150ebb0000,0x00007f150f96c9f0,0x00007f1510570000)
PSPermGen total 86016K, used 66374K [0x00007f15097b0000, 0x00007f150ebb0000, 0x00007f150ebb0000)
object space 86016K, 77% used [0x00007f15097b0000,0x00007f150d881a38,0x00007f150ebb0000)



 Comments   
Comment by Eric Deshayes [ 29/Apr/11 ]

The problem is due to the usage of the SleepyCat database:

we're executing a Database.close() and Database.put() concurrently, and the javadoc for Database.close() points out that a database handle should not be closed while operations using that Database object are still running:
"The database handle should not be closed while any other handle that refers to it is not yet closed; for example, database handles should not be closed while cursor handles into the database remain open, or transactions that include operations on the database have not yet been committed or aborted."





[QFJ-465] Use stunnel with quickfix Created: 28/Aug/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File demo-stunnel-client.pem     File stunnel.conf    

 Description   

HI support,

I am a beginner developer and want to use your API to connect to integral, i will use stunnel to establish ssl, they sent me the new certificate but i am not sure how i can use it i will attach the new certificate can you advise on how to use it in stunnel.conf



 Comments   
Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

conf file

Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

cert

Comment by Laurent Danesi [ 01/Sep/09 ]

Hi,

Your stunnel seems well configured and your PEM is holding private key and public certificate. But the certificate is expired :Valid until may 7 2009.

Are you sure that your certificate is the good one?

Anyway, QFJ supports SSL connections and you can use it by converting your PEM to a Java Keystore using KeyMan or JDK commands.
Just add these parameters to your Session config:

SocketUseSSL=Y
SocketKeyStore=[your key store path]
SocketKeyStorePassword=[your password]

Laurent





[QFJ-464] Logon session Created: 28/Aug/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Ahmed Al Jebouri Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File stun.log    

 Description   

Hi, i am new to FIX and i am using the free java API from quickfix, and actually i want to establish the login session, what i want how to add the username and password to the login first message? i tried to add it to the config file but still it is not working, can you help?



 Comments   
Comment by Laurent Danesi [ 28/Aug/09 ]

Hi,

What you need is a Custom Logon: http://www.quickfixj.org/confluence/display/qfj/Implementing+Custom+Logons

Regards,

Laurent

Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

Hi Laurent,

Thank you very much for the valueable information it was very helpfull, but the FIX engine expects encrypted SSL data, can you help me in this regard, sorry to ask this kind of question i am just a beginner, hope you can help

Regards,
Ahmed

Comment by Laurent Danesi [ 28/Aug/09 ]

Hi,

The ToAdmin callback permits you to intercept administrative messages before they are sent on the line.
This will permit you to add what you want in the Logon message as your encrypted SSL data.

So you need to firstly encrypted your password and so place it in the logon message intercepted in Toadmin callback.

Is it what you wanted to know?

Laurent

Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

Hi Laurent,

thank ou for your reply, actually i am trying to connect to integral, and they told me to use stunnel, i was able to to down load it and run it on my machine but still when i am connecting to stunnil the connection get termiated, is there any way to use another SSL with integral.

may be i am not doing the right configuration, stunnil version is 4.27

Regards,
Ahmed

Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

stunil log file also below java output

run:
<20090828-12:22:47, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, event>
(Created session)
<20090828-12:22:47, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, event>
(Connecting to 127.0.0.1 on port 2508)
<20090828-12:22:47, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, outgoing>
(8=FIX.4.29=14935=A34=1349=order.SWSPB.dev.SWSPB.com50=SWSPBle52=20090828-12:22:47.48156=demo.client.fxgrid.integral.com553=trader1554=Welcome0198=0108=3010=112)
<20090828-12:22:47, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, event>
(Initiated logon request)
<20090828-12:22:48, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, event>
(Socket Error: Connection reset by peer.)
<20090828-12:22:48, FIX.4.2:order.SWSPB.dev.SWSPB.com->demo.client.fxgrid.integral.com, event>
(Disconnecting)
BUILD SUCCESSFUL (total time: 9 seconds)

Comment by Ahmed Al Jebouri [ 28/Aug/09 ]

can you advise if i want to use MINA SSL I/O filter, i already added mina-filter-ssl-1.0.1-sources.jar to my project, also please find below quick fix conf file

[DEFAULT]
ConnectionType=initiator
HeartBtInt=30
FileStorePath=store
StartTime=00:00:00
EndTime=00:00:00
UseDataDictionary=N
SocketConnectHost=70.42.18.200
SocketUseSSL=Y

[SESSION]
BeginString=FIX.4.2
SenderCompID=order.SWSPB.dev.SWSPB.com
TargetCompID=demo.client.fxgrid.integral.com
SocketConnectPort=2508
ResetSeqNumFlag=Y
SocketUseSSL=Y





[QFJ-463] Examples page in documentation results in a broken link Created: 25/Aug/09  Updated: 25/Aug/09  Resolved: 25/Aug/09

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

Type: Task Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The examples page (http://www.quickfixj.org/quickfixj/usage/examples.html ) is a broken link.
it's referenced from the main documentation page at http://www.quickfixj.org/quickfixj/



 Comments   
Comment by Toli Kuznets [ 25/Aug/09 ]

Actually, this is "user error". Somehow i ended up going to a documentation page that was not the usual "documentation page" - as a result of which all the relative links were broken.

Going through the correct "front door" to documentation page results in a page with correct links.





[QFJ-462] Building with BigDecimal flag still generates Field SettlCurrFxRate extending DoubleField Created: 12/Aug/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: ashok shamnani Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Building core by changing the following property in build.xml still generates SettlCurrFxRate field to extend DoubleField.

<property name="generator.decimal" value="true" />

Is this a bug? If not, how do we generate SettlCurrFxRate to extend DecimalField



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

The rate is defined as a "float" in the FIX spec. We only use BigDecimal for fields typed as prices, quantities, etc.





[QFJ-461] TargetSubID and SenderSubID are missing from manual's config page Created: 29/Jul/09  Updated: 15/Nov/12  Resolved: 15/Jan/10

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

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

web manual



 Description   

Configuration options SenderSubID and TargetSubID are not documented on the QF/J Manual's Configuration page.

I verified in core/src/main/java/quickfix/SessionSettings.java that these are valid config options.



 Comments   
Comment by Steve Bate [ 15/Jan/10 ]

The values are in the documentation. My guess is that the web documentation might be out of date. We should either not publish the web documentation or be sure that we update it at each release (the latter is probably a better option).





[QFJ-460] Resend Failure Created: 27/Jul/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Critical
Reporter: david Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux



 Description   

When there are need for resending messages, not all the time resend all messages successfully. Once such an error occurred we checked the message body log and found some of the fix messages were not formed correctly. For example,

8=FIX.4.29=32735=834=122049=INT_SENDER52=20090427-13:31:07.03756=INT_RECEIVER57=fviger6=22.214=10015=CAD17=20090427093035_POW_B_0000088020=029=330=Canadian Equities31=22.232=10037=20090427093035_POW_B_0000088038=10039=144=22.254=155=POW60=20090427-

09:30:35.000150=1151=06100=portfolio=CL2,assettype=Equities10=187=FIX.4.29=32935=834=44549=INT_SENDER52=20090427-13:30:24.76256=INT_RECEIVER57=fviger6=56.5114=10015=CAD17=20090427093019_CNQ_B_0000014520=029=330=Canadian

Equities31=56.5132=10037=20090427093019_CNQ_B_0000014538=10039=144=56.5154=155=CNQ60=20090427-09:30:19.000150=1151=06100=portfolio=CL2,assettype=Equities10=007

It seems that the end of the first message and the start of the second are just messed together.
As we are using this version in production and this has caused several issues. I am wondering whether this issue has been identified and resolved in the newer versions. If not I am afraid we have to seek for a different engine.

Thanks

David






[QFJ-459] java.lang.StackOverflowError when disconnecting file system Created: 20/Jul/09  Updated: 22/Jun/12  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Sylvestre COZIC Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

Mandriva Linux 2008 EDT, kernel 2.6.24.7



 Description   

The following error occurs when disconnecting the file system where log files are written on:

[java] java.lang.StackOverflowError
[java] at java.io.FileOutputStream.writeBytes(Native Method)
[java] at java.io.FileOutputStream.write(FileOutputStream.java:247)
[java] at quickfix.FileLog.writeTimeStamp(FileLog.java:116)
[java] at quickfix.FileLog.writeMessage(FileLog.java:97)
[java] at quickfix.FileLog.onEvent(FileLog.java:111)
[java] at quickfix.LogUtil.logThrowable(LogUtil.java:47)
[java] at quickfix.LogUtil.logThrowable(LogUtil.java:60)
[java] at quickfix.FileLog.writeMessage(FileLog.java:106)
[java] at quickfix.FileLog.onEvent(FileLog.java:111)
[java] at quickfix.LogUtil.logThrowable(LogUtil.java:47)
[java] at quickfix.LogUtil.logThrowable(LogUtil.java:60)
[java] at quickfix.FileLog.writeMessage(FileLog.java:106)
[java] at quickfix.FileLog.onEvent(FileLog.java:111)

Repro steps:

  • Start quickfixj engine using a directory on a removable drive (for instance usb key) as log dir
  • Disconnect removable drive while quickfixj engine is running


 Comments   
Comment by Sylvestre COZIC [ 22/Jul/09 ]

I suggest the following patch :

  • In quickfix.FileLog class, writeMessage(FileOutputStream stream, String message, boolean forceTimestamp) method:

- LogUtil.logThrowable(sessionID, "error writing message to log", e);*

+ e.printStackTrace();*

This should prevent StackOverflow error when an exception is raised while logging an exception.

I would also suggest:

  • In quickfix.Session class isStateRefreshNeeded(String msgType) method :

    - return refreshMessageStoreAtLogon && !state.isInitiator() && msgType.equals(MsgType.LOGON);

    + return refreshMessageStoreAtLogon && msgType.equals(MsgType.LOGON);

This will make sure MessageStore#refresh() is called on logon, so that in case of filesystem failure, file storing sequence numbers is reopen when trying to reconnect. By the way, I did not understood clearly why this method returns false when ConnectionType property is set to Initiator

Comment by Sylvestre COZIC [ 28/Jan/10 ]

Hello,

Do you need further information to fix this issue?

Best regards,

Comment by Eric Deshayes [ 26/Apr/11 ]

committed on integration branch rev 1018

Comment by Steve Bate [ 02/May/11 ]

It seems to me that the safest and simplest approach to avoiding the StackOverflow is to simply write the exception message, stack trace and session ID to the standard error stream. The modified code delegates the logging to the SLFJ logger but that logger may also be writing to the same removed file system. This will cause another exception which will be caught in the MINA-related code (when logging incoming messages). It's not clear to me if this will be another source of a StackOverflow or not or result in some other undesired behavior.

Comment by Eric Deshayes [ 03/May/11 ]

As discussed with Steve, it is safest to log the error to the standard error stream.
Committed on integration branch rev#1028.

Comment by Mate Varga [ 22/Jun/12 ]

A question related to this 'fix':

(FileLog.java

private void writeMessage(FileOutputStream stream, String message, boolean forceTimestamp) {
try {
if (forceTimestamp || includeTimestampForMessages)

{ writeTimeStamp(stream); }

stream.write(message.getBytes(CharsetSupport.getCharset()));
stream.write('\n');
stream.flush();
if (syncAfterWrite)

{ stream.getFD().sync(); }

} catch (IOException e)

{ //QFJ-459: no point trying to log the error in the file if we had an IOException //we will end up with a java.lang.StackOverflowError System.err.println("error writing message to log : "+message); e.printStackTrace(System.err); }

}

Why do you need to log this error? Why isn't it much-much better to throw an exception or at least call a callback registered by the application? This code can lead to the application not knowing about a possibly critical problem, i.e. qfix not being able to write to the log file stream.





[QFJ-458] ConcurrentModificationException raised from quickfix.Session.nextQueued Created: 13/Jul/09  Updated: 15/Nov/12  Resolved: 06/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Major
Reporter: Steve Borrer Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Operating system: Linux tradera2 2.6.24-23-server #1 SMP Thu Nov 27 18:45:02 UTC 2008 x86_64 GNU/Linux
java version "1.6.0_14"
16 GB RAM



 Description   

The issue occurred after I had just restarted my qfj initiator FIX engine:-

15:12:12 INFO: Socket option: SocketSynchronousWriteTimeout=30000
15:12:12 Jul 13, 2009 3:12:11 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
15:12:12 INFO: MINA session created: /127.0.0.1:53335
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Initiated logon request
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Received logon request
15:12:12 20090713-15:12:12 20090713-03:12:12 DEBUG - Session logged on: FIX.4.2:NONAME->SIMULA
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 2 but received 3[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Sent ResendRequest FROM: 2 TO: 0
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 2 but received 4[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 2 but received 5[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 2 but received 6[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 7[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 8[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 9[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - null
15:12:12 [[00;31m^Gjava.util.ConcurrentModificationException[[00m
15:12:12 at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:373)
15:12:12 at java.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:384)
15:12:12 at java.util.AbstractCollection.toString(AbstractCollection.java:421)
15:12:12 at java.lang.String.valueOf(String.java:2826)
15:12:12 at java.lang.StringBuffer.append(StringBuffer.java:219)
15:12:12 at quickfix.Session.nextQueued(Session.java:1634)
15:12:12 at quickfix.Session.nextQueued(Session.java:1624)
15:12:12 at quickfix.Session.next(Session.java:851)
15:12:12 at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
15:12:12 at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
15:12:12 at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
15:12:12 at java.lang.Thread.run(Thread.java:619)
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 10[[00m
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 11[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 12[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 [[00;31m^G20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - MsgSeqNum too high, expecting 3 but received 13[[00m
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Already sent ResendRequest FROM: 2 TO: 2. Not sending another.
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - ResendRequest for messages FROM 2 TO 2 has been satisfied.
15:12:12 20090713-15:12:12 EVENT [FIX.4.2:NONAME->SIMULA] - Processing queued message: 4, pending: [5, 6, 7, 8, 9, 10, 11, 12, 13]

The log from the FIX acceptor test harness also built with QFJ1.4.0 is :-

[[0034m15:12:11[[37m 20090713-15:12:11 EVENT [FIX.4.2:SIMULA->NONAME] - Session FIX.4.2:SIMULA->NONAME schedule is daily, 22:00:00 UTC - 21:30:00 UTC (daily, 23:00:00 BST - 22:30:00 BST)
[[0034m15:12:11[[37m 20090713-15:12:11 EVENT [FIX.4.2:SIMULA->NONAME] - Created session: FIX.4.2:SIMULA->NONAME
[[0034m15:12:11[[37m Jul 13, 2009 3:12:11 PM quickfix.mina.NetworkingOptions logOption
[[0034m15:12:11[[37m INFO: Socket option: SocketTcpNoDelay=true
[[0034m15:12:11[[37m Jul 13, 2009 3:12:11 PM quickfix.mina.NetworkingOptions logOption
[[0034m15:12:11[[37m INFO: Socket option: SocketSynchronousWrites=false
[[0034m15:12:11[[37m Jul 13, 2009 3:12:11 PM quickfix.mina.NetworkingOptions logOption
[[0034m15:12:11[[37m INFO: Socket option: SocketSynchronousWriteTimeout=30000
[[0034m15:12:11[[37m Jul 13, 2009 3:12:11 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
[[0034m15:12:11[[37m INFO: Listening for connections at 0.0.0.0/0.0.0.0:9876
[[0034m15:12:12[[37m Jul 13, 2009 3:12:11 PM quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
[[0034m15:12:12[[37m INFO: MINA session created: /127.0.0.1:53335
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Accepting session FIX.4.2:SIMULA->NONAME from /127.0.0.1:53335
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Acceptor heartbeat set to 30 seconds
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Received logon request
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Responding to logon request
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Received ResendRequest FROM: 2 TO: infinity
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Resending Message: 2
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Resending Message: 3
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Resending Message: 4
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Resending Message: 5
[[0034m15:12:12[[37m 20090713-15:12:12 EVENT [FIX.4.2:SIMULA->NONAME] - Resending Message: 6






[QFJ-457] Acceptor logout trap when the acceptor initiates the logout process Created: 11/Jul/09  Updated: 15/Nov/12  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3, 1.4.0, Future Releases
Fix Version/s: 1.5.1

Type: Bug Priority: Critical
Reporter: Stephan Assignee: Eric Deshayes
Resolution: Fixed Votes: 2
Labels: None


 Description   

This bug happens when QuickFixJ is working in acceptor mode.

If the acceptor wants to initiate the logout procedure (send logout message to an initiator), it calls the "logout()" method on the Session.

This sets the boolean "enabled" to false.

public void logout() {
setEnabled(false);
}

Then, the next() method is called by the timer SessionTimerTask. On the first call, it send the logout message to the client because the not enabled, the client is logged on and the logout hasn't been sent yet.

if (!isEnabled()) {
if (isLoggedOn()) {
if (!state.isLogoutSent())

{ getLog().onEvent("Initiated logout request"); generateLogout(state.getLogoutReason()); }
} else { return; }
}

On the next few calls on Session.next(), the timer might eventually disconnect the initiator if not logout response has been received.

if (state.isLogoutTimedOut()) {
getLog().onEvent("Timed out waiting for logout response");
disconnect();
}

The initiator is also disconnected if it send the logout message back.


Until here all is well. Now the problem begins.

Imagine that the same initiator want to reconnect. It sends the Login message to our acceptor. We receive it in the Session.next(Message message) method.
This method will call nextLogon(message) which will generate the logon message.

Then at then end of the next(Message message) method, we call next:

if (isLoggedOn()) {
next();
}


and we are faced once again with the following code which will generate a logout message immediately.

if (!isEnabled()) {
if (isLoggedOn()) {
if (!state.isLogoutSent()) { getLog().onEvent("Initiated logout request"); generateLogout(state.getLogoutReason()); }

} else

{ return; }

}

This happens because the boolean returned by isEnabled() has not been reset to true. So the session is not enabled, it is logged on and not logout has been set yet.

Remember that the enabled boolean was set to false by the acceptor to logout the initiator a moment ago.

Conclusion: the initiator canot logon anymore! It will receive a successful logon response and immediately after a logout message!

The solution is to setEnabled(true) at the login call in case quickfix is in acceptor mode.
In the next(Message message) method change the current code:

if (msgType.equals(MsgType.LOGON)) {
nextLogon(message);
} else if (msgType.equals(MsgType.HEARTBEAT)) {
nextHeartBeat(message);
}
......

for this code:

if (msgType.equals(MsgType.LOGON)) {
if (!state.isInitiator())

{ setEnabled(true); }

nextLogon(message);
} else if (msgType.equals(MsgType.HEARTBEAT)) {
nextHeartBeat(message);
}
......



 Comments   
Comment by Devendra Inamdar [ 12/Mar/10 ]

We are also facing this issue. Is this being addressed?

Comment by Eric Deshayes [ 27/Apr/11 ]

committed on integration branch revision 1022

Comment by Jörg Thönnes [ 20/May/11 ]

Is this bug related?

QFJ-357: Logout message is sent before Logon on each Session start
http://www.quickfixj.org/jira/browse/QFJ-357





[QFJ-456] NetworkingOptions should be applied before the socket is connected Created: 08/Jul/09  Updated: 24/Apr/21  Resolved: 31/Aug/20

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.2.1, 1.3.1, 1.4.0
Fix Version/s: 2.3.0

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None


 Description   

NetworkingOptions are applied in AbstractIoHandler.sessioncCeated, which is called after the socket has been connected.

Although most socket options can be changed after the socket is connected, window scaling is negotiated during the initial handshake. Therefore the receive buffer size cannot be changed to more than 64k after the socket is connected.

Aside: Mina actually handles the receive buffer size as a special case in its own logic in order to work around this.






[QFJ-455] NetworkingOptions does not read the settings correctly Created: 08/Jul/09  Updated: 15/Nov/12  Resolved: 04/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.2.1, 1.3.1, 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

1. The NetworkingOptions getBoolean and getInteger methods use the Properties.containsKey method to decided if a setting has been set. These methods are not aware of the default properties (passed through the Properties(Properties) constructor. In the case of initiators, this means anything in the default section of the config will be ignored.

2. For acceptors, the Properties passed to NetworkingOptions are those for the default section. The session-specific settings are not passed and are never used.



 Comments   
Comment by Steve Bate [ 04/Apr/10 ]

For acceptors, many sessions can share the same acceptor socket so the network settings cannot be specified per session. However, I added the ability for initiator session to inherit default properties.





[QFJ-454] Update documentation to reflect that ValidateUserDefinedFields is on by default in the code Created: 02/Jul/09  Updated: 03/Dec/14  Resolved: 02/Jul/09

Status: Closed
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Task Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-473 Web docs wrongly say that ValidateUse... Closed
is duplicated by QFJ-618 Documentation for ValidateUserDefined... Closed

 Description   

The documentation page for ValidateUserDefinedFields parameter says that it's set to N by default.
That is incorrect - the default value for it in quickfix.DataDictionary is set to true:
private boolean checkUserDefinedFields = true;

Need to update documentation accordingly.



 Comments   
Comment by Toli Kuznets [ 02/Jul/09 ]

fixed in rev 924





[QFJ-453] FIX 5.0 SP1 and SP2 Support Created: 02/Jul/09  Updated: 24/Aug/12  Resolved: 03/Aug/12

Status: Resolved
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.4.0
Fix Version/s: 1.5.3

Type: Improvement Priority: Default
Reporter: David Gibbs Assignee: Christoph John
Resolution: Fixed Votes: 8
Labels: None

Attachments: Text File FIX50sp2.patch    
Issue Links:
Duplicate
is duplicated by QFJ-388 ApplVerID of 8 with Fixt.1.1 not supp... Closed
is duplicated by QFJ-479 Add FIX50SP1 and FIX50SP2 to ApplVerID Closed
Relates
relates to QFJ-472 Add FIX 5.0 SP1 and SP2 to quickfix.M... Closed
is related to QFJ-483 QFJ Dictionary Generator Resolved
Requires
is required by QFJ-696 Possibility to set SessionStatus on L... Resolved

 Description   

FIX version 5.0 SP2 is as yet unsupported in fix data dictionaries



 Comments   
Comment by David Gibbs [ 13/Oct/09 ]

This is related to QFJ-472

Comment by David Gibbs [ 03/Jun/10 ]

I noted another approach as in QFJ-483

Comment by David Gibbs [ 04/Jun/10 ]

Hi please find attached a patch which addresses FIX 5.0 SP2 in FIXVersions.java, MessageCracker.java, MessageUtils.java and FIX50.xml, FIXT11.xml.

I tried to follow the existing idiom in QuickFIXJ for FIX 5, but took the approach of treating SP1, SP2 as specialisations of FIX50.xml. In this approach one configured instance of the FIX gateway would not support FIX50 and FIX50SP2 as distinct versions. I only added the ApplVerId to the FIX50.xml leaving it as an exercise for the user to add support for the messages and fields which they will implement.

Please note the more complete approach to the dictionary in QFJ-483.

I hope this will help, if there is any feedback to make this fit in better with plans for QuickFixJ please let me know. I can try to assist if it will help.

Comment by Christophe Domas [ 19/Jul/12 ]

Hi,

We're trying to use "Trade Capture Report message (AE)" message from LSE "Own Trade Book Download" service.

LSE use AppVerId=9 (FIX5.0SP2)

  • MessageUtils.toBeginString(ApplVerID applVerID) return null
  • DataDictionary getApplicationDataDictionary(ApplVerID applVerID) return a null dictionnary
  • in Message.parseBody(DataDictionary dd, boolean doValidation), repeating groups are discarded

Is there a workaround for this problem other than patching quickfix/j ?

Comment by Christoph John [ 03/Aug/12 ]

Christophe, I'm afraid there is no workaround.

Comment by Christoph John [ 03/Aug/12 ]

Committed as rev #1079.

Added application data dictionaries for SP1 and SP2. They were generated with the generator from QFJ-483.
Please note that code generation based on this dictionaries does not work correctly due to the following issues:

  • FIX5.0: fields LegPrice and LegOptionRatio are duplicated in some components. This is a specification problem which was rectified in SP1.
  • FIX5.0 SP1/2: component (Derivative)SecurityXML has a field of the same name which causes duplicate identifiers in the generated code
  • FIX5.0 SP2: components StrmAsgnReqGrp and StrmAsgnRptGrp are repeating groups but have no delimiter field.
    These issues can be avoided by manually tweaking the data dictionary prior to code generation.




[QFJ-452] OrigPosReqRefID is not required Created: 02/Jul/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: David Gibbs Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

In FIX44.xml... OrigPosReqRefID is markeed as required,
it appears that it is not according to FIX

<message name="PositionMaintenanceReport" msgtype="AM" msgcat="app">
<field name="PosMaintRptID" required="Y"/>
<field name="PosTransType" required="Y"/>
<field name="PosReqID" required="N"/>
<field name="PosMaintAction" required="Y"/>

<field name="OrigPosReqRefID" required="Y"/>



 Comments   
Comment by Laurent Danesi [ 17/Jul/09 ]

Hi David,

I've just checked this field on FPL website and it seems that OrigPosReqRefID is not required in PositionMaintenanceRequest (35=AL) but it is in PositionMaintenanceReport (35=AM).

Do you agree?

Laurent

Comment by David Gibbs [ 13/Oct/09 ]

Hi thanks for your comment,

It seems to be

"Reference to the PosReqID of a previous maintenance request that is being replaced or canceled."

So should it be conditionally required for a replace or cancel and probably reverse ?

For a Position Maintenance Request with PosMaintAction

2 = Replace - used to override the overall transaction quantity or specifi add messages based on the reference ID
3 = Cancel - used to remove the overall transaction or specific add messages based on reference ID
4 = Reverse - used to completelly back-out the transaction such that the transaction never existed

Perhaps it may have been a bug in the FIX 5.0 spec because in Version 5.0 Service Pack 2 - Volume 5 (pg 134) it's down as "N"

The new FIXIMATE on fix protocol site shows it as not mandatory for version 5 and 5SP2.
http://www.fixprotocol.org/FIXimate3.0/?language=en&version=FIX.5.0

thanks
Dave

Comment by David Gibbs [ 13/Oct/09 ]

Ooops sorry yes in version 4.4. it shows it as mandatory (I have been fixated on Fix 5 recently) .
This is obviously wrong because there its not mandatory on Position Maintenance Request.
What do you do with bugs in the Fix Protocol Spec ?
There are no "service packs" for FIX 4.4
regards
Dave





[QFJ-451] Hops Repeating Group in Message Header causing nullpointerException Created: 01/Jul/09  Updated: 15/Nov/12  Resolved: 20/Jul/09

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Gustavo Jacob Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP



 Description   

Hi,

While trying to parse a message with a repeating group on the header
627 (NoHops) =2
628 (HopCompID) =_TED02A
629 (HopSendingTime) =20090701-11:45:29.597
628 (HopCompID) =_GWSURV
629 (HopSendingTime) =20090701-11:50:31.284

I'm receiving the following error on my events log:

20090701-13:23:56: Error during message processing
java.lang.NullPointerException
at quickfix.DataDictionary.iterate(DataDictionary.java:624)
at quickfix.DataDictionary.validate(DataDictionary.java:589)
at quickfix.Session.next(Session.java:778)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:85)

The repeating group is defined in the dictionary, and i'm aso trating other repeating groups (not on the header) with no issue.

Thanks



 Comments   
Comment by Laurent Danesi [ 20/Jul/09 ]

Hi,

I attached the patch for your version to the issue and it will be committed for the next release.

Laurent

Comment by Gustavo Jacob [ 20/Jul/09 ]

Laurent,

Sorry but i'm new to JIRA, and i couldn't find here u have attached the file

Thanks





[QFJ-450] QuickFIX/J is reporting FIX responses from a commercial ECN as invalid ! Created: 01/Jul/09  Updated: 10/Jan/10  Resolved: 10/Jan/10

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

Type: Bug Priority: Default
Reporter: Vincent Coldrick Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows Vista Java Version 1.6



 Description   

I am using QuickFIX to send messages to a commercial ECN.
Can someone please tell me what is going wrong in the following message interchange:

Following messages were sent and received as part of an attempt to subscribe for a simple Bid/Ask update for EURUSD spot. Can anyone please explain to me what is going wrong here?

My message trying to subscribe to EURUSD for snapshot + incremental update:

<20090630-20:05:58, FIX.4.2:CLIENT->MARKET, outgoing> (8=FIX.4.2 9=125 35=V 34=2 49=CLIENT 52=20090630-20:05:58 56=MARKET
262=EURUSD1 263=1 264=1 265=1
146=1 55=EUR/USD 167=FOR
267=2 269=0 269=1 10=120 )

Snapshot reply for EURUSD, which looks fine to me, SO WHAT IS WRONG WITH TAG 269 APPEARING MORE THAN TWICE - SINCE IT IS PART OF A REPEATING GROUP indicated by 268=2???

<20090630-20:05:58, FIX.4.2:CLIENT->MARKET, incoming> (8=FIX.4.2 9=206 35=W 34=2 49=MARKET 52=20090630-20:06:06.853 56=CLIENT
55=EUR/USD 167=FOR
262=EURUSD1
268=2
269=0 270=1.4025 271=45000000 299=EUSPOTBUY1.4025 290=1
269=1 270=1.4027 271=45000000 299=EUSPOTSELL1.4027 290=1 10=235 )

<20090630-20:05:58, FIX.4.2:CLIENT->MARKET, event> (Message 2 Rejected: Tag appears more than once:269)

<20090630-20:05:58, FIX.4.2:CLIENT->MARKET, outgoing> (8=FIX.4.2 9=101 35=3 34=3 49=CLIENT 52=20090630-20:05:58 56=MARKET 45=2
58=Tag appears more than once 371=269 372=W 10=094 )

Incremental update reply for EURUSD, which looks fine to me, SO WHAT IS WRONG WITH MSGTYPE = X ???

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, incoming> (8=FIX.4.2 9=164 35=X 34=3 49=MARKET 52=20090630-20:06:08.361 56=CLIENT 262=EURUSD1
268=1 279=0
269=1 278=EUSPOTSELL1.40259 55=EUR/USD 167=FOR 207=CD 270=1.40259 271=6000000 290=1 10=058 )

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, event> (Message 3 Rejected: Invalid MsgType)

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, outgoing> (8=FIX.4.2 9=89 35=3 34=4 49=CLIENT 52=20090630-20:06:00 56=MARKET 45=3 58=Invalid MsgType 372=X 373=11 10=028 )

Another incremental update reply for EURUSD, which looks fine to me, SO WHAT IS WRONG WITH MSGTYPE = X ???

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, incoming> (8=FIX.4.2 9=163 35=X 34=4 49=MARKET 52=20090630-20:06:08.716 56=CLIENT 262=EURUSD1
268=1 279=0
269=1 278=EUSPOTSELL1.4027 55=EUR/USD 167=FOR 207=CD 270=1.4027 271=45000000 290=1 10=003 )

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, event> (Message 4 Rejected: Invalid MsgType)

<20090630-20:06:00, FIX.4.2:CLIENT->MARKET, outgoing> (8=FIX.4.2 9=89 35=3 34=5 49=CLIENT 52=20090630-20:06:00 56=MARKET 45=4 58=Invalid MsgType 372=X 373=11 10=030 )

It would be a very useful feature if QuickFIX were to offer a callback to users to peek/modify target responses prior to them being parsed by the QuickFIX engine.

Regards
defacto



 Comments   
Comment by Vincent Coldrick [ 01/Jul/09 ]

This issue has now been sorted. An invalid Dictionary XML file was at fault.
defacto

Comment by Toli Kuznets [ 01/Jul/09 ]

The initial MarketDataSnapshot (35=W) appears to be correct.

Do you initialize QFJ with a data dictionary? Can you post your QFJ configuration? perhaps you don't have the dictionary specified, in which case repeating groups may be rejected.
Make sure you have UseDataDictionary=Y set in your config file





[QFJ-449] Web docs erroneously say PersistMessages default is "N", it's actually "Y" Created: 30/Jun/09  Updated: 15/Nov/12  Resolved: 17/Jul/09

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

Type: Bug Priority: Default
Reporter: Grant Birchmeier Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

all



 Description   

Web docs erroneously say PersistMessages default is "N", which is wrong.

I confirmed in the source that the default is actually "Y".



 Comments   
Comment by Laurent Danesi [ 17/Jul/09 ]

Thank you, I've corrected the UserManual.

Laurent





[QFJ-448] Skipped heartbeats Created: 30/Jun/09  Updated: 02/Apr/15  Resolved: 03/Apr/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.3.2, 1.3.3, 1.4.0
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Scott Harrington Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File QFJ-448.patch    

 Description   

A race condition is causing occasional skipped heartbeats.

The likelihood is increased by (a) multiple sessions, (b) slow message store, (c) frequent heartbeats e.g. HeartBtInt=1.

The "QFJ Timer" thread wakes up every second and looks at all sessions to see who needs a HeartBeat to be sent. The SystemTime.currentTimeMillis() is read at the moment the outgoing message header is created.

Suppose you have a "quiet" session that is only exchanging heartbeats, and one or more other "chatty" sessions that don't always need a Heartbeat to be sent because of other traffic being sent.

Suppose at time T, all the sessions get a heartbeat, but as the heartbeats are sent by the single QFJ Timer thread, the last session's HeartBeat is sent at time T + 1 ms. This delay is a function of the CPU and MessageStore speed, not any network timings.

Then suppose at time T + 1000, only the "quiet" session needs a heartbeat.

But SessionState.isHeartBeatNeeded() only sees millisSinceLastSentTime = 999, so no heart beat is sent, and the counterparty has to send a Test Request to see if we're alive.

Of course, we are alive and the TEST exchange occurs fine, but we look sloppy.

There are already HeartBtInt "fudge factors" of 1.5 in isTestRequestNeeded() and 2.4 in isTimedOut(), I propose to introduce a 10 ms "leeway" value to the isHeartBeatNeeded() method.

This fixes my problem. A patch against svn r923 is attached.



 Comments   
Comment by Christoph John [ 03/Apr/14 ]

http://sourceforge.net/p/quickfixj/code/1171/

Comment by Glyn Walters [ 29/Aug/14 ]

We have applied this patch to a branch of 1.5.3 we're using locally while awaiting release of 1.6.0. There is another factor to the accuracy of the heartbeat timings when intervals are short though, e.g. 4 seconds with Reuters. If the SessionTImerTask happens to be the one that calls next() on Session when a heartbeat is due, then hbeats are accurate for that period. But if the message processor is the one to call next() when a hbeat happens to be due, then the timings can go off for quite a while. The SessionTimerTask interval starts to get out of sync with when the next heartbeat period is due, and usually will then be triggered again by another incoming message, rather than the timer.

With incoming messages coming at around the same frequency as the hbeat interval (because of received hbeats). The 'owner' thread of the current hbeat interval (i.e. the one most likely to trigger it) switches from time to time between SessionTimerTask and the Message Processor thread. Applying this patch mitigated some of the big gaps we could sometimes see. But if more accuracy is desired, this is the cause of some sub second jitter.

Two examples:
1/ When an incoming message triggered a heartbeat

20140829-12:49:26.809 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9819749=Sender52=20140829-11:49:26.80956=TR MATCHING57=FXM142=Target10=082
20140829-12:49:30.890 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9819849=Sender52=20140829-11:49:30.88956=TR MATCHING57=FXM142=Target10=086
20140829-12:49:34.971 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9819949=Sender52=20140829-11:49:34.97156=TR MATCHING57=FXM142=Target10=083
20140829-12:49:39.054 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9820049=Sender52=20140829-11:49:39.05456=TR MATCHING57=FXM142=Target10=063
20140829-12:49:43.118 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9820149=Sender52=20140829-11:49:43.11856=TR MATCHING57=FXM142=Target10=060
20140829-12:49:47.208 INFO [QFJ Message Processor] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9820249=Sender52=20140829-11:49:47.20856=TR MATCHING57=FXM142=Target10=065

2/ When the SessionTImerTask triggered

20140829-13:26:47.727 INFO [QFJ Timer] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9875749=Sender52=20140829-12:26:47.72756=TR MATCHING57=FXM142=Target10=082
20140829-13:26:51.728 INFO [QFJ Timer] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9875849=Sender52=20140829-12:26:51.72856=TR MATCHING57=FXM142=Target10=079
20140829-13:26:55.727 INFO [QFJ Timer] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9875949=Sender52=20140829-12:26:55.72756=TR MATCHING57=FXM142=Target10=083
20140829-13:26:59.727 INFO [QFJ Timer] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9876049=Sender52=20140829-12:26:59.72756=TR MATCHING57=FXM142=Target10=079
20140829-13:27:03.728 INFO [QFJ Timer] quickfixj.msg.outgoing - FIXT.1.1:Sender/Target->TR MATCHING/FXM: 8=FIXT.1.19=9935=034=9876149=Sender52=20140829-12:27:03.72856=TR MATCHING57=FXM142=Target10=071

Comment by Christoph John [ 29/Aug/14 ]

Hi Glyn,

when you say "triggered by an incoming message", I guess you are mostly referring to an application message. Incoming messages also go through the fromApp and fromAdmin callbacks. Depending on your implementation there sometimes is much time spent inside those callbacks. And the heartbeat is only triggered after the callback has been completed. This might be the reason for some of the higher delays (I see about 70-90 ms delay in your example).

Cheers,
Chris.

Comment by Glyn Walters [ 29/Aug/14 ]

Hi Christopher.

Thanks for the response. I think you might have misunderstood me though. It's because either thread calls next(), it makes the baseline time for the heartbeat unreliable. Say for example next() is called by QFJ Message Processor (caused by an incoming heartbeat app message) at 14:21:06.101 and a heartbeat is sent in the same millisecond. The next heartbeat due time is now 14:21:10.101. If the SessionTimerTask Executor happens to have its scheduled tasks firing at .050ms every second, the next time next() is called where state.isHeartBeatNeeded() is going to return true, is either at 14.21.11.050 (almost 1 second late), or some random time between 14.21.10.101 and then if another message happens to be processed in that time. If only the SessionTimerTask triggered calls to state.isHeartBeatNeeded(), then the calls (especially with this tolerance fix) would be very accurate.

Because of the mathematics around how that plays with a 4 second hbeat from both sides and a one second SessionTimerTask interval, in a real world situation you see logs where the heartbeat timings are quite jittery (~1 second variance) when the inbound message processing queue has been the cause of the next() call which spawned a heartbeat. The examples I gave indicate periods when we see either inaccurate hbeat timings, just because of the statistical likelihood that once next() has been called, resulting in a hbeat, from an incoming message, that pattern will predominate for a while. Whearas the other example, from later on in the same sesson, is the pattern you get when the SessionTimerTask calls next() at the right time. It also then will predominate, but with much more accurate timings.

Thanks
Glyn

Comment by Glyn Walters [ 29/Aug/14 ]

Apologies, for spelling your name wrong!

Comment by Christoph John [ 02/Sep/14 ]

Hi Glyn, never mind.
Feel free to open a JIRA ticket for that topic. Maybe it is the best to do as you suggested, i.e. only the SessionTimerTask should trigger heartbeats. Maybe it is also feasible to generate the heartbeats by a whole new thread/task? But that discussion could be done on the new ticket.





[QFJ-447] MsgSeqNum too low Created: 30/Jun/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: alexey palamarchuk Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

Windows XP



 Description   

Dear colleagues.

My integration component (listener of a FIX server) is based on QuickFix/J library. Component keeps working continuesly for a days; every midnight FIX server initiates relogon (or my component resores connection after failure). On every logon, I request FIX server to reset the sequence number. That some times (can't provide the strong algorythm to reproduce issue) causes the issue:

"MsgSeqNum too low, expecting 10656 but received 1"

As I discovered, internal session state was not reset before relogon and I tryied to logon with old sequence number values. As a solution, I overwrote toAdmin message where I explicitly reset session state before started loggon on FIX server.

Can you kindly provide solution for this issue, and give your opinion about solution that I currently use.
Thank you.



 Comments   
Comment by alexey palamarchuk [ 01/Jul/09 ]

Here is the code which is to reset session state:

                quickfix.Session session = quickfix.Session.lookupSession(sessionId);
		if(session != null)
		{
			try
			{
				session.getStore().reset();
			}
			catch(Exception ex)
			{
				log.error(ex.getMessage(), ex);
			}
		}
Comment by Paul Bobba [ 08/Jan/10 ]

I have been able to capture this scenario and access the session object through JMX and invoked the reset() method. The reset method fails to reset the sequence number. If i manually set the NextTargetMsgSeqNum through JMX the logon process is successful. Unfortunately, once disconnected again the session relapses into this state of repeated logon attempts because our session is somehow unable to reset this number. We are looking at resolving this issue by doing the same in the code as we do through jmx.

session.setNextTargetMsgSeqNum(1);





[QFJ-446] Tag appears more than once... the error happens for user defined fields which can appear more than once Created: 25/Jun/09  Updated: 01/Oct/17  Resolved: 01/Oct/17

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

Type: Improvement Priority: Default
Reporter: Ganeshan Guruswamy Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 1
Labels: None
Environment:

Tag appears more than once... the error happens for user defined fields which can appear more than once



 Description   

Tag appears more than once... the error happens for user defined fields which can appear more than once



 Comments   
Comment by Ganeshan Guruswamy [ 25/Jun/09 ]

hi... we are in the middle of a project... any help here will help...

some more information on the problem:
------------------------------------------------------

We receieve fix messages that have some user defined tags that repeat. For example when an application returns
errors... it returns same tags again with different error... quickfix/j rejects this with the error message "Tag appears more than once.."
We need to find a way where in we can ignore this error...

8=FIX.4.49=36435=AQ34=449=FCI-ST56=Smoke-Test52=20090625-10:49:52568=1569=2749=99750=2453=2448=CUONGIM1XXX447=B452=13448=CUONGBK2X447=B452=19063=29064=S120189066=%1 %2 is not required field length.7340=27342=CUONGBK2X9064=S140169066=PartyValue %1 is invalid for PartyType %2 and PartyRole %3.7340=37342=BIC9065=7342=MEOR7342=CUONGBK2X774=9955=[N/A]10=246

for example in the above message tag 9064 is repeating. quickfix rejects this message with the error...

20090625-10:51:30.859: 8=FIX.4.49=11735=334=549=Smoke-Test52=20090625-10:51:30.85956=FCI-ST45=458=Tag appears more than once371=9064372=AQ373=1310=238

can someone help us... any help will be truly appreciated...

Comment by Mehul Patel [ 05/Aug/09 ]

Isn't this the same as QFJ-404?

Comment by Christoph John [ 01/Oct/17 ]

Should work with recent QFJ version.





[QFJ-445] Problem with Acceptance Test Suite Created: 21/Jun/09  Updated: 20/May/11  Resolved: 20/May/11

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

Type: Bug Priority: Default
Reporter: Bill Harts Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

When writing a custom acceptance test script there is a bug if you include a tag with '10' as the last two digits. This is because module InitiateMessageStep.java:line 47 contains a regex pattern that scans for a Checksum tag in the message.

// Matches FIX.X.X or FIXT.X.X style begin string
private static final Pattern MESSAGE_PATTERN = Pattern.compile("I(\\d,)(8=FIXT?\\.\\d\\.\\d
001)(.
?)(10=.*|)$");

The problem is that the regex expression doesn't look to see if the '10=' falls at the beginning of a tag, thus it will erroneously match against any tag with '10=' in it such as '110=' (MinQty), '210=' (MaxShow), etc.

The fix for this is quite simple. Merely add the field separator before the '10=' which will allow a match only if '10=' falls at the beginning of a field.

// Matches FIX.X.X or FIXT.X.X style begin string
private static final Pattern MESSAGE_PATTERN = Pattern.compile("I(\\d,)(8=FIXT?\\.\\d\\.\\d\\001)(.?)(
00110=.*|)$");



 Comments   
Comment by Eric Deshayes [ 26/Apr/11 ]

Committed on integration branch rev 1021





[QFJ-444] Logout logic problem Created: 16/Jun/09  Updated: 22/Nov/12  Resolved: 12/Nov/12

Status: Resolved
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.3

Type: Bug Priority: Default
Reporter: Stephan Assignee: Christoph John
Resolution: Fixed Votes: 6
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-617 disconnect() might not clear logoutSe... Closed
Relates
is related to QFJ-718 Logout message sent after event "rese... Closed

 Description   

The problem happens when using QuickFIX as an Acceptor.

Symptoms:
A user logs in, waits 30 seconds and logout out.
One minute after, the same user logs in and 2 seconds after the login, QuickFix initiates a logout.

Why does QuickFIX initiate a log out? I've traced the problem to a Boolean in SessionState.logoutReceived that doesn't get reset to false.

Let me explain exactly what happened:

When the user initiates the logout (the fisrt time), at one time the method Session.nextLogout(Message logout) is executing.
There you do state.setLogoutReceived(true); and call disconnect() that will set state.setLogoutSent(false);
All this happens in the "QF/J Session dispatcher" thread.

In my case, in the Session.nextLogout(Message logout) method, after we have generated the logout message and before we set state.setLogoutReceived(true) , the client closes the connection. Because of this, the "SocketAcceptorIoProcessor-1.0" thread calls Session.disconnect() from AbstractIoHandler.sessionClosed(), executes the disconnect() method fully and returns. Then the "QF/J Session dispatcher" thread continues to execute and sets state.setLogoutReceived(true). When the "QF/J Session dispatcher" thread calls disconnect, the responder has been set to null and the logic ends there. Therefore the thread never reached the code that sets state.setLogoutSent(false)

The conclusion is that the Boolean logoutSent remains true in the SessionState and because of this, at the next login, the session will log out automatically after 2 seconds.

To recap, the main problem is that the state machine that is the Session is not well controlled and because of the interaction of several threads, some unforeseen things can happen. This is not a synchronization problem but rather a logical problem.

As I'm in a hurry, I've just synchronized all the methods of the Session so that only one thread at a time can access it and my problems went away, but there must be a better solution.

A last word, there was another circumstance when things went wrong at the end, so the example above is just a symptom of a larger problem.



 Comments   
Comment by Horia Muntean [ 09/Feb/10 ]

Yes, I have seen this issue as well.

QuickFIX initiates a logout after 2 seconds because the default value of LogoutTimeout is 2 seconds ( there is also a log entry: 'Timed out waiting for logout response' in the acceptor session log ) and of course because the session state is broken.

Agree that as long as there are multiple threads involved, synchronizing Session will not really solve the issue.

Maybe this issue deserves a higher priority as well?

Comment by Eric Deshayes [ 29/Apr/11 ]

The session state is based on multiple boolean fields:

  • Session.enabled
  • SessionState.logonSent
  • SessionState.logonReceived
  • SessionState.logoutSent
  • SessionState.logoutReceived

If we want to fix the issue properly, we would have to introduce a state machine and the transition between state could be done atomically.
The introduction of a State machine had already been discussed by QFJ developers some time ago (at least Steve, David and Laurent).
I do not see any easy fix without any small code change so this issue is deferred to a future release.

Eric

Comment by James Olsen [ 05/Jun/11 ]

I believe the same symptoms can occur for an Initiator when both ends are scheduled for disconnect at the same time. The QFJ Initiator will send a Logout which the other party may not respond to before disconnecting if it has already commenced it's disconnect process. After the QFJ Initiator reconnects it is still expecting the Logout response, does not receive it so disconnects again.

Comment by Mate Varga [ 24/Oct/11 ]

Same here - left the engine running for the weekend and on Monday morning the initiator cannot log in.

Comment by Mate Varga [ 18/Nov/11 ]

Guys, this issue practically renders quickfix unusable for production environments. If the client logs out, it simply cannot log in again without restarting the process. If you could at least provide a workaround for that...

Comment by Christoph John [ 12/Oct/12 ]

I think we all agree that the session state handling should be overhauled for 1.6.0.
For the time being, should we just make sure that the method Session.disconnect() assures that the flags

state.setLogoutSent(false);
state.setLogoutReceived(false);
state.setResetReceived(false);
state.setResetSent(false);

get set in a finally block so that the mentioned problem (flag logoutSent does not get set to false since disconnect() returns earlier) goes away?

Comment by Grant Birchmeier [ 16/Oct/12 ]

That might be a good stopgap solution. I have no problem with it.

Comment by Christoph John [ 12/Nov/12 ]

After looking at the code it turned out that there was a correction to this problem in 1.5.1 already. The flags logoutReceived and logoutSent get reset in the nextLogon() method.

However, it probably does not hurt the set the correct state in method disconnect(). That way the state is correct directly after the logout/disconnection.

Comment by Christoph John [ 12/Nov/12 ]

Committed as rev #1099.





[QFJ-443] UseDataDictionary=N and validation Created: 12/Jun/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Sangeetha Variath Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None


 Description   

The below bug is happening for me for Quickfix1.4.0 and not 1.3.1

I have set UseDataDictionary=N, but I see that the messages are still getting validated

20090612-12:27:27.079: Message 3487 Rejected: Required tag missing:27
20090612-12:27:27.081: Message 3488 Rejected: Required tag missing:27
20090612-12:27:27.083: Message 3489 Rejected: Required tag missing:27

20090612-12:30:39.436: Received: 8=FIX.4.29=013435=634=381349=S02356=R02352=20090612-12:30:3923=23_123589038398399155=QQQQ54=144=3.838=90059=31=1842167=CS28=N25=H40=210=032
20090612-12:30:39.436: Sending 8=FIX.4.29=10535=334=381349=R02352=20090612-12:30:39.43656=S02345=381358=Required tag missing371=27372=6373=110=169

and many more such message.

Could someone let me know if its a bug or I should set something somewhere.



 Comments   
Comment by Sangeetha Variath [ 15/Jun/09 ]

Please, could someone let me know if I can't use my application without DataDictionary turned ON.

I fixed the above code a little but then it fails with

java.lang.NullPointerException
at quickfix.MessageUtils.parse(MessageUtils.java:139)

where it is looking for datadictionaryprovider again

+Sangeetha

Comment by Nickolay Dul [ 15/Jan/10 ]

same as QFJ-476 (http://www.quickfixj.org/jira/browse/QFJ-476)





[QFJ-442] About running banzai and executor application Created: 09/Jun/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: Md Sarfaraz Asad Khan Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

window XP



 Description   

I am getting follwing error while i run banzai application

Jun 9, 2009 12:52:59 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketTcpNoDelay=true
Jun 9, 2009 12:52:59 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWrites=false
Jun 9, 2009 12:52:59 PM quickfix.mina.NetworkingOptions logOption
INFO: Socket option: SocketSynchronousWriteTimeout=30000
<20090609-07:22:59, FIX.4.4:BANZAI->EXEC, event> (Session FIX.4.4:BANZAI->EXEC schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC))
<20090609-07:22:59, FIX.4.4:BANZAI->EXEC, event> (Created session: FIX.4.4:BANZAI->EXEC)
Jun 9, 2009 12:52:59 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /172.20.16.82:1284
Jun 9, 2009 12:53:00 PM quickfix.mina.SessionConnector$SessionTimerTask run
SEVERE: Error during timer processing
quickfix.FieldException: invalid integral value:
at quickfix.FieldMap.newIncorrectDataException(FieldMap.java:467)
at quickfix.FieldMap.getInt(FieldMap.java:251)
at quickfix.Session.sendRaw(Session.java:1808)
at quickfix.Session.generateLogon(Session.java:1499)
at quickfix.Session.next(Session.java:1423)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:248)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
<20090609-07:23:10, FIX.4.4:BANZAI->EXEC, event> (Timed out waiting for logon response)
<20090609-07:23:10, FIX.4.4:BANZAI->EXEC, event> (Disconnecting)
Jun 9, 2009 12:53:10 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /172.20.16.82:1291
Jun 9, 2009 12:53:11 PM quickfix.mina.SessionConnector$SessionTimerTask run
SEVERE: Error during timer processing
quickfix.FieldException: invalid integral value:
at quickfix.FieldMap.newIncorrectDataException(FieldMap.java:467)
at quickfix.FieldMap.getInt(FieldMap.java:251)
at quickfix.Session.sendRaw(Session.java:1808)
at quickfix.Session.generateLogon(Session.java:1499)
at quickfix.Session.next(Session.java:1423)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:248)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
<20090609-07:23:21, FIX.4.4:BANZAI->EXEC, event> (Timed out waiting for logon response)
<20090609-07:23:21, FIX.4.4:BANZAI->EXEC, event> (Disconnecting)
Jun 9, 2009 12:53:21 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /172.20.16.82:1292
Jun 9, 2009 12:53:22 PM quickfix.mina.SessionConnector$SessionTimerTask run
SEVERE: Error during timer processing
quickfix.FieldException: invalid integral value:
at quickfix.FieldMap.newIncorrectDataException(FieldMap.java:467)
at quickfix.FieldMap.getInt(FieldMap.java:251)
at quickfix.Session.sendRaw(Session.java:1808)
at quickfix.Session.generateLogon(Session.java:1499)
at quickfix.Session.next(Session.java:1423)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:248)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

my executor running fine ..



 Comments   
Comment by Toli Kuznets [ 09/Jun/09 ]

Can you post your banzai config (in case you changed it)?
Can you also post the lost from the Executor to see what it's sending?

Comment by Md Sarfaraz Asad Khan [ 17/Jun/09 ]

my cfg files are ------

executor.cfg

[default]
FileStorePath=examples/target/data/executor
ConnectionType=acceptor
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SenderCompID=EXEC
TargetCompID=BANZAI
UseDataDictionary=Y
#DefaultMarketPrice=12.30
SocketAcceptAddress=172.20.16.82

[session]
BeginString=FIX.4.4
SocketAcceptPort=9880

executor_dynamic.cfg
====================
[default]
FileStorePath=examples/target/data/executor
ConnectionType=acceptor
SocketAcceptPort=9880
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ValidOrderTypes=1,2,F
SenderCompID=*
TargetCompID=*
UseDataDictionary=Y
#DefaultMarketPrice=15
SocketAcceptAddress=172.20.16.82

[session]
AcceptorTemplate=Y
DataDictionary=FIX44.xml
BeginString=FIX.4.4

benzai.cfg
=========
[default]
FileStorePath=examples/target/data/banzai
ConnectionType=initiator
SenderCompID=BANZAI
TargetCompID=EXEC
SocketConnectHost=172.20.16.82
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ReconnectInterval=5

[session]
BeginString=FIX.4.4
SocketConnectPort=9880

benzai_dynamic.cfg
===================
[default]
FileStorePath=examples/target/data/banzai
ConnectionType=initiator
SenderCompID=BANZAI
TargetCompID=EXEC
SocketConnectHost=172.20.16.82
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
ReconnectInterval=5

[session]
BeginString=FIX.4.4
SocketConnectPort=9880





[QFJ-441] Sending time accuracy problem Created: 05/Jun/09  Updated: 15/Apr/11  Resolved: 20/Mar/11

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

Type: Other Priority: Critical
Reporter: Md Sarfaraz Asad Khan Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux



 Description   

when ever we are hitting fix gateway we are trying to capture all trades till that time.

that means :

if i hit gateway at 9:30 - i fetch all trades till 9:30 (100 let)

if i hit gateway at 10:30 - i fetch all trades till 10:30 (100 of 9:30+100 trads between 9:30 to 10:30 let)

and so on till 2:30

when trade volume increases 6500 then the following error occoures : " SendingTime accuracy problem "

NOTE :- clock is synchronized and NTP is working fine on both the server .



 Comments   
Comment by Tausseef Ahmad [ 07/Jul/10 ]

CheckLatency=N

put this tag in .cfg file

Comment by Steve Bate [ 15/Apr/11 ]

During message resend, if a received resent message has an original sending time greater than the resent message sending time then this will cause the session to be terminated. This indicates some type of logical error in the server during the resend process. In other words, this situation says the message was resent before it was sent, which doesn't make sense.

The CheckLatency flag does not turn off this check. The flag is for time skew on the normal message stream.





[QFJ-440] 58=SendingTime accuracy problem Created: 02/Jun/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Critical
Reporter: Md Sarfaraz Asad Khan Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

RedHat Enterprise Linux AS (release 4)



 Description   

We are getting the message " SendingTime accuracy problem " whenever the trade volume increases in the fix server.
Can any one suggest that why the problem occures.

Please suggest me as soon as posible because my application is going through a very critical phase



 Comments   
Comment by Toli Kuznets [ 02/Jun/09 ]

This usually happens (in my experience) when the clock on your FIX client is more than 30secs away from the clock on the FIX server.

can you make sure that your clock is synchronized (using NTP, for example)? and try again in that case?

Comment by Md Sarfaraz Asad Khan [ 02/Jun/09 ]

Thanks for reply Toli Kuznets

yes the clock is synchronized and NTP is working fine on both the server .

Note :- when ever we are hitting fix gateway we are trying to capture all trades till that time.

that means :

if i hit gateway at 9:30 – i fetch all trades till 9:30 (100 let)

if i hit gateway at 10:30 – i fetch all trades till 10:30 (100 of 9:30+100 trads between 9:30 to 10:30 let)

and so on till 2:30

when trade volume increases 6500 then the following error occoures : " SendingTime accuracy problem "

Comment by Md Sarfaraz Asad Khan [ 05/Jun/09 ]

clock is synchronized and NTP is working fine on both the server .





[QFJ-439] What is time frame when heartbeat message has to be processed by Initiator. Created: 25/May/09  Updated: 15/Nov/12  Resolved: 24/Jun/09

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

Type: Other Priority: Default
Reporter: Anand Arjaria Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP



 Description   

Hi,

I am observing an issue where Initiator disonnect the connection if it misses heart beat by few millis second.
Means heartbeat is recevied but after few milliseconds of heartbeat interval i.e. 30 seconds.
So I would like to know what is the tolerance limit for heartbeat interval ? is there any formula ?
Please do the let me know.

Regards,
Anand



 Comments   
Comment by Laurent Danesi [ 26/May/09 ]

Hi,

A connection is considered as TimedOut when this function return true:

public boolean isTimedOut()

{ long millisSinceLastReceivedTime = timeSinceLastReceivedMessage(); return millisSinceLastReceivedTime >= 2.4 * getHeartBeatMillis(); }

The entrypoint is the method next() on Session object and it is called every second by a timertask.

Laurent





[QFJ-438] Using FIX XML Created: 25/May/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Mohamed Kazi Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP



 Description   

Would it be possible to have populated xml (FIX ml) messages that would typically be sent between another xml engine to QUICKFIXJ






[QFJ-437] Session time check failed Created: 22/May/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Baxter Solutions Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

If the user logged out in a previous trading session (previous week) and wants to logon at the next trading session start, the checkSessionTime() will reset the session. If the user sends the logon message immediately after the socket connection the checkSessionTime() fails because time between the socket connection (last sessiontime check) and the logon message processing is less than one second.

We suggested that Session.resetState() should be set the Session's lastSessionTimeCheck variable to 0 to solve this problem.






[QFJ-436] \\ characters are skipped from the directory name on Windows Created: 12/May/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Charles Moulliard Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi,

The appendReplacement methof of Matcher removes the backslash required under Windows to create the directory tree

private Pattern variablePattern = Pattern.compile("\\$

{(.+?)}

");

private String interpolate(String value) {

//"value"= "$

{servicemix.home}

/data/log/quickfix/files/server"

if (value == null || value.indexOf('$') == -1)

{ return value; }

StringBuffer buffer = new StringBuffer();
Matcher m = variablePattern.matcher(value);
while (m.find()) {
if (m.start() > 0 && value.charAt(m.start() - 1) == '
')

{ continue; }

String variable = m.group(1);
// variable = servicemix.home
String variableValue = variableValues.getProperty(variable);
// "variableValue"= "D:\\\\Dvlpt\\\\Java\\\\workspace-ganymede\\\\esb\\\\apache-servicemix-kernel-1.2.0-SNAPSHOT" ---> OK
if (variableValue != null)

{ m.appendReplacement(buffer, variableValue); "buffer.toString()"= "D:DvlptJavaworkspace-ganymedeesbapache-servicemix-kernel-1.2.0-SNAPSHOT" --> NOK }

}
m.appendTail(buffer);

return buffer.toString();

}



 Comments   
Comment by Steve Bate [ 10/Jan/10 ]

We are assuming the paths are in Java format rather than OS-specific format. This might be something we don't want to support. I'm open to suggestions.





[QFJ-435] OSGI Classloading issue with QuickFix (1.3.3) and quickfix.fix40 in the class DefaultMessageFactory Created: 06/May/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Charles Moulliard Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I try to use QuickFix/j (1.3.3) deployed as a bundle in an osgi server but I have a classloading issue with the DefaultMessageFactory :

smx@root:osgi> Exception in thread "SpringOsgiExtenderThread-71" java.lang.NoClassDefFoundError: quickfix/fix40/MessageFactory
at quickfix.DefaultMessageFactory.<init>(DefaultMessageFactory.java:28)

Remark : quickfix/fix40/MessageFactory classes is deployed in the osgi server

Any idea how to solve this ?






[QFJ-434] Unable to deregister jmx mbeans exported via JmxExporter Created: 06/May/09  Updated: 15/Nov/12  Resolved: 23/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Trivial
Reporter: Parwinder Sekhon Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

When I call a "stop" method on my wrapper around SocketAcceptor I would really like to be able to deregister its mbeans too.

If you want to close a SocketAcceptor or SocketInitatior and then recreate further instances of them, then there is no way to deregister their mbeans. I know I can register new ones to replace the old ones, but lacking the ability to deregister the old ones, means if I change configuration and reduce the number of available sessions for the SocketAcceptor, the old sessions are still available via JMX.



 Comments   
Comment by Steve Bate [ 23/May/11 ]

Added registration and deregistration operations to the JmxExporter (legacy export method is deprecated). Updated the Executor example to demonstration deregistration and updated the user manual.





[QFJ-433] Session can deadlock on responderSync and reduced concurrency Created: 16/Apr/09  Updated: 15/Nov/12  Resolved: 16/Apr/09

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

Type: Bug Priority: Default
Reporter: Parwinder Sekhon Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows Java 1.6


Issue Links:
Duplicate
duplicates QFJ-421 Session responder lock is too restric... Closed

 Description   

Because Session is using a String literal as a lock, the scope of this lock is not per Session instance

private String responderSync = "SessionResponderSync";
// @GuardedBy(responderSync)
private Responder responder;

As well as reducing concurrency it caused my app to deadlock, because the vm will intern "SessionResponderSync". I suggest changing this to

private String responderSync = new String("SessionResponderSync");

My deadlock was probably caused because I was trying a combination of

1) synchronous writes on both the acceptor and initiator
2) both the acceptor and initiator in the same vm process
3) switching out the LinkedBlockingQueue in the SingleThreadedEventHandlingStrategy with a bounded ArrayBlockingQueue

Here is my stack trace if it helps:

SocketConnectorIoProcessor-0.0@1168 daemon, priority=5, in group 'main', status: 'WAIT'
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1,925)
at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:252)
at quickfix.mina.SingleThreadedEventHandlingStrategy.onMessage(SingleThreadedEventHandlingStrategy.java:47)
at quickfix.mina.initiator.InitiatorIoHandler.processMessage(InitiatorIoHandler.java:54)
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:113)
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:180)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:499)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:293)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:228)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:198)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$400(SocketIoProcessor.java:45)
at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:485)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:619)

SocketAcceptorIoProcessor-0.0@1170, priority=5, in group 'main', status: 'WAIT'
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1,925)
at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:252)
at quickfix.mina.SingleThreadedEventHandlingStrategy.onMessage(SingleThreadedEventHandlingStrategy.java:47)
at quickfix.mina.acceptor.AcceptorIoHandler.processMessage(AcceptorIoHandler.java:97)
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:113)
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.messageReceived(AbstractIoFilterChain.java:570)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(SimpleProtocolDecoderOutput.java:58)
at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecFilter.java:180)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:53)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:648)
at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:499)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:299)
at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:293)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:228)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:198)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$400(SocketIoProcessor.java:45)
at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:485)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:619)

SocketConnector-0@1154 daemon, priority=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(WindowsSelectorImpl.java:-1)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:274)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:256)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:137)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.mina.transport.socket.nio.SocketConnector$Worker.run(SocketConnector.java:378)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:619)

QFJ Message Processor@1284 daemon, priority=5, in group 'main', status: 'MONITOR'
waiting for main@1
at quickfix.Session.getResponder(Session.java:382)
at quickfix.Session.hasResponder(Session.java:393)
at quickfix.Session.next(Session.java:1,417)
at quickfix.Session.next(Session.java:853)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
at java.lang.Thread.run(Thread.java:619)

QFJ Message Processor@1236 daemon, priority=5, in group 'main', status: 'MONITOR'
waiting for main@1
at quickfix.Session.getResponder(Session.java:382)
at quickfix.Session.hasResponder(Session.java:393)
at quickfix.Session.next(Session.java:1,417)
at quickfix.Session.next(Session.java:853)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
at java.lang.Thread.run(Thread.java:619)

SocketAcceptor-0@1105, priority=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(WindowsSelectorImpl.java:-1)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:274)
at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:256)
at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:137)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
at org.apache.mina.transport.socket.nio.SocketAcceptor$Worker.run(SocketAcceptor.java:220)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
at java.lang.Thread.run(Thread.java:619)

QFJ Timer@1141 daemon, priority=5, in group 'main', status: 'MONITOR'
waiting for main@1
at quickfix.Session.getResponder(Session.java:382)
at quickfix.Session.hasResponder(Session.java:393)
at quickfix.Session.next(Session.java:1,417)
at quickfix.mina.SessionConnector$SessionTimerTask.run(SessionConnector.java:248)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)

OrderBook-testExchange-EURUSD-work-1@733, priority=5, in group 'main', status: 'MONITOR'
waiting for main@1
at quickfix.Session.send(Session.java:1,856)
at quickfix.Session.sendRaw(Session.java:1,803)
at quickfix.Session.send(Session.java:1,850)
at quickfix.Session.sendToTarget(Session.java:504)
... my stack

main@1, priority=5, in group 'main', status: 'WAIT'
blocks QFJ Message Processor@1284
blocks QFJ Message Processor@1236
blocks QFJ Timer@1141
blocks OrderBook-testExchange-EURUSD-work-1@733
at java.lang.Object.wait(Object.java:-1)
at org.apache.mina.common.support.DefaultIoFuture.await0(DefaultIoFuture.java:121)
at org.apache.mina.common.support.DefaultIoFuture.awaitUninterruptibly(DefaultIoFuture.java:100)
at org.apache.mina.common.support.DefaultIoFuture.join(DefaultIoFuture.java:79)
at quickfix.mina.IoSessionResponder.send(IoSessionResponder.java:50)
at quickfix.Session.send(Session.java:1,861)
at quickfix.Session.sendRaw(Session.java:1,803)
at quickfix.Session.send(Session.java:1,850)
at quickfix.Session.sendToTarget(Session.java:504)
... my stack



 Comments   
Comment by Parwinder Sekhon [ 16/Apr/09 ]

Well that didnt quite fix it for me. fyi, I am testing a client and server under extreme load using synchronous writes. And the system seems to get very slow, or queues build up inside mina hogging memory.

I have managed to get my stress test working well by making the following modification to Session.send

private boolean send(String messageString) {
getLog().onOutgoing(messageString);
Responder responder;
synchronized (responderSync)

{ responder = this.responder; }

if (responder == null)

{ getLog().onEvent("Attempt to send while not connected (message stored until connected)."); return false; }

return responder.send(messageString);
}

As you can see, I have reduced the scope of locking, so that other bits of code can call Session.getResponder without blocking for ages (with synchronous writes, responder.send may take a while).

This with a combination of switching out the LinkedBlockingQueue in the SingleThreadedEventHandlingStrategy with a bounded ArrayBlockingQueue (sized to 64 elements) is working well now.

Comment by Steve Bate [ 16/Apr/09 ]

Already resolved. See linked issue.

Comment by Parwinder Sekhon [ 16/Apr/09 ]

Any comments/thoughts on changing Session.send to

private boolean send(String messageString) {
getLog().onOutgoing(messageString);
Responder responder;
synchronized (responderSync)

{ responder = this.responder; }

if (responder == null)

{ getLog().onEvent("Attempt to send while not connected (message stored until connected)."); return false; }

return responder.send(messageString);
}

Given responder.send can block for longer than expected if synchronous writes are enabled. Without this my stress tests (firing thousands of orders at a fix engine as fast as possible) seem to lock up and concurrency is drastically reduced as responderSync is also used to get hold of the responder from other threads.





[QFJ-432] Trace reason when session gets disconnected Created: 10/Apr/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

When a session is disconnected (Session.disconnect()), we just get a "<session> disconnected" trace. In some case, the disconnection is a normal behavior (e.g. after a logout), in some other it is not (e.g. socket failure). It is therefore difficult to troubleshot FIX connectors with this lack of information.
Add a "reason" string parameter to the disconnect method and log it.



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-431] Allow receiving admin messages when out of sequence Created: 10/Apr/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Logon / logout message can be accepted even if acceptor and initiator out of sequence.
Some other message has also to be accepted even if out of sequence. e.g., with Currenex, we get a TradingSessionStatus just after the logon response, even if we detected that the logon response was out of sequence. In this case, it will be ignored, causing the application not receiving mandatory messages.



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-430] Session without scheduled Reset Created: 10/Apr/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

In some cases, the daily or weekly session reset is not required by the application.
Add a parameter on the session such as:
NonStopSession=Y



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928

Prior to 1.4.1, this was accomplished using 00:00:00 as the start, end time.





[QFJ-429] Concurrency reading / writting file store Created: 10/Apr/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-534 Resend Request Synchronization Patch Closed

 Description   

In some case, two thread access the file store: one for writing outgoing messages, another one for reading old messages (e.g. while a sequence resend).
This can lead to a concurrency using the underlying file access and corrupt the store.
The file store has to use two separate file access to prevent this.
Patch available.



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928

Interesting. I've only seen this type of Java file-writing behavior when writing/reading from multiple processes. I've never seen it with multiple threads in a single process. Is this easy to reliably reproduce? If so, it would be good to create a unit test to demonstrate it.





[QFJ-428] FieldMap.setField(int key, Field<?> field) should be public Created: 06/Apr/09  Updated: 16/Nov/18  Resolved: 06/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-962 FieldMap.setField(int key, Field<?> f... Open

 Description   

Application that need to write data in FieldMap (Message, Groups) in a generic way need to have a public access to FieldMap.setField(int key, Field<?> field).

FieldMap dest;
final Field<?> field;

This will allow writing :

dest.setField(field.getField(), field);

Instead of:

if (field instanceof StringField)

{ dest.setField((StringField) field); }

else if (field instanceof IntField)

{ dest.setField((IntField) field); }

else if (field instanceof CharField)

{ dest.setField((CharField) field); }

else if (field instanceof DecimalField)

{ dest.setField((DecimalField) field); }

else if (field instanceof DoubleField)

{ dest.setField((DoubleField) field); }

else if (field instanceof UtcDateOnlyField)

{ dest.setField((UtcDateOnlyField) field); }

else if (field instanceof UtcTimeOnlyField)

{ dest.setField((UtcTimeOnlyField) field); }

else if (field instanceof UtcTimeStampField)

{ dest.setField((UtcTimeStampField) field); }

else if (field instanceof BooleanField)

{ dest.setField((BooleanField) field); }

else

{ throw new RuntimeException("Unhandled field type: " + field.getClass()); }




[QFJ-427] ForceResync option per session Created: 06/Apr/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: New Feature Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None


 Description   

Add a ForceResync option Y/N per session to help application developers work with servers UAT withtou the need of a perfect synchronization in the sequenceing.

This option will be used:

  • when the server rejects a logon with a logout and error message such as "expected iii but received jjj"; automatically re-sync using iii from the error message.
  • when target is too low, force the current sequence value using the target message value
  • when the target is too high and the gap is greater than a constant threshold, skip the resend process and directly resync the values

Each force-resync operation should output a warning in the logs



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928

Comment by Steve Bate [ 22/Apr/11 ]

The documentation for this option was added to the web site directly but not updated in the configuration.html file in SVN. I believe the plan is to remove this option in the next version of QFJ so maybe it's ok that it was never included in the release documentation. It would be a good idea to resync the web site with the documentation in SVN after including any other changes made directly to the web site documents.

There was a related question on the QuickFIX (C++) mailing list:

Date: Fri, 15 Apr 2011 10:44:23 -0400
From: "Li, Wei-Jen [Tech]" <[email protected]>
Subject: [Quickfix-users]  QuickFIX/J ForceResync flag
To: "'[email protected]'"
       <[email protected]>

Hello,

A few questions about the SeqNum resync issue.
The quickfixj document says when SeqNum mismatch happens, we can use ForceResync=Y to reset the number by reading "expecting xxx" in the error message.
Can I assume I always see that string in error message?
Does this only resync the incoming sequence number? What happens to the outgoing number?
And, does it matter the other side uses different FIX engine?

Thanks,
Wei-Jen




[QFJ-426] Message header will not validate when containing 'Hop' group Created: 28/Mar/09  Updated: 15/Nov/12  Resolved: 06/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Tommy Hannon Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Solaris 8-10, Java 1.6.0_11



 Description   

Our application started generating the following error after upgrading from QFJ 1.3.1 to 1.3.3

27 Mar 2009 15:24:04,115: FIX.4.4:MyComp->TheirComp: Error during message processing
java.lang.NullPointerException
at quickfix.DataDictionary.iterate(DataDictionary.java:609)
at quickfix.DataDictionary.validate(DataDictionary.java:579)
at quickfix.DataDictionary.validate(DataDictionary.java:545)
at quickfix.Session.next(Session.java:716)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:75)

I have compared the DataDictionary.java source code and discovered the following snippet has been added to the iterate()...

for (List<Group> groups : map.getGroups().values()) {
for (Group group : groups)

{ iterate(group, msgType, dd.getGroup(msgType, group.getFieldTag()).getDataDictionary()); }

}

The exception apparently occurred when recursively calling the iterate method; I assume because 'dd.getGroup(...) is returning null.

Based upon the stack trace, the header was being processed. The only group in the header is for the 'Hop' component. The error does not occur when the 'Hop' group is omitted.



 Comments   
Comment by Gustavo Jacob [ 01/Jul/09 ]

I'm having thesame issue.

Did someone found a soution for it?

Comment by Tommy Hannon [ 01/Jul/09 ]

No, I never got a reply. It may have been fixed in QFJ 1.4.0, but I have not checked myself.





[QFJ-425] Performance and type safety improvment in MessageCracker.crack Created: 27/Mar/09  Updated: 10/Oct/12  Resolved: 10/Oct/12

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Bill Nokes Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

All



 Description   

Hi,

Low priority, but using instanceof instead of msgType.equals(XXX) pattern in MesageCracker.crack
will give a marginal performance boost and improve type safety.

Instead of:

if (msgTypeValue.equals(Heartbeat.MSGTYPE))

{ onMessage((Heartbeat) message, sessionID); } else if (msgTypeValue.equals(Logon.MSGTYPE)) {

Use:

if (message instanceof Heartbeat) { onMessage((Heartbeat) message, sessionID); }

else if (message instanceof Logon) {

Also drops requirement to dig into header to get message type.

Hope this helps,
Bill



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

The MessageCracker implementation has been completely changed with QF/J 1.5.1 so this ticket has become obsolete.





[QFJ-424] What does the bool response on sendToTarget tell me Created: 24/Mar/09  Updated: 24/Jun/09  Resolved: 24/Jun/09

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

Type: Other Priority: Default
Reporter: paul ogier Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

The sendToTarget method returns a boolean. Does this boolean tell me anything, such as whether the message has reached it's destination ?

Thanks in advance.



 Comments   
Comment by Laurent Danesi [ 26/May/09 ]

Hi,

The sendToTarget return false when the Message cannot be sent to the counterpart and return true when the message was sent.
But as QuickFixJ is using MINA and asynchronous socket operations by default, you will ever get true is the socket is connected.

Laurent

Comment by paul ogier [ 26/May/09 ]

Thanks for the response.





[QFJ-423] quickfixj-msg-fixt11.jar doesn't include FIXT11.xml Created: 22/Mar/09  Updated: 23/Mar/09  Resolved: 23/Mar/09

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

Type: Bug Priority: Default
Reporter: Tom Palmer Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File build.xml.patch    

 Description   

The quickfixj-msg-fixt11.jar doesn't include the FIXT11.xml dictionary ala the other msg Jars. Apart from being a break in the pattern of the other msg Jars it also causes the quickfix.DefaultSessionFactoryTest::testFixtDataDictionaryConfiguration test to fail when running the build:

quickfix.DataDictionary$Exception: Could not find data dictionary: FIXT11.xml
at quickfix.DataDictionary.read(DataDictionary.java:808)
at quickfix.DataDictionary.<init>(DataDictionary.java:100)
at quickfix.DefaultSessionFactory.getDataDictionary(DefaultSessionFactory.java:287)
at quickfix.DefaultSessionFactory.createDataDictionary(DefaultSessionFactory.java:193)
at quickfix.DefaultSessionFactory.processFixtDataDictionaries(DefaultSessionFactory.java:221)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:103)
at quickfix.DefaultSessionFactoryTest.testFixtDataDictionaryConfiguration(DefaultSessionFactoryTest.java:90)



 Comments   
Comment by Tom Palmer [ 22/Mar/09 ]

The attached patch fixes core/build.xml to be case insensitive when it scans for which .xml file to add to the Jar. This allows us to use the same pattern for the package name without having to mangle the @

{fixVersion}

attribute into upper case and lower case versions.

Comment by Laurent Danesi [ 23/Mar/09 ]

Thank you Tom





[QFJ-422] DefaultMessageFactory doesn't set the MsgType field when it defaults to creating the Message itself Created: 21/Mar/09  Updated: 15/Nov/12  Resolved: 26/May/09

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Tom Palmer Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File DefaultMessageFactory.patch    

 Description   

If there are no version-specific MessageFactory's in the classpath the DefaultMessageFactory will create an empty message. Unfortunately it forgets to set the MsgType which other elements of the QuickFIX/J code rely upon e.g. quickfix.Session. Below is an example stack trace in that situation:

quickfix.FieldNotFound: Field [35] was not found in message.
at quickfix.FieldMap.getField(FieldMap.java:213)
at quickfix.FieldMap.getString(FieldMap.java:207)
at quickfix.Session.sendRaw(Session.java:1758)
at quickfix.Session.generateLogon(Session.java:1746)
at quickfix.Session.nextLogon(Session.java:1591)
at quickfix.Session.next(Session.java:782)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:107)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:87)
at java.lang.Thread.run(Thread.java:637)



 Comments   
Comment by Tom Palmer [ 21/Mar/09 ]

The attached patch resolves this issue and adds an additional assert to quickfix.DefaultMessageFactoryTest to make sure that the MsgType field is always set on each of the messages created.

Comment by Laurent Danesi [ 26/May/09 ]

Thank you Tom.

I will check your path and apply it.

Laurent





[QFJ-421] Session responder lock is too restrictive Created: 20/Mar/09  Updated: 15/Nov/12  Resolved: 20/May/11

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

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Eric Deshayes
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-433 Session can deadlock on responderSync... Closed
Relates
relates to QFJ-484 Session responder lock change inadequate Closed

 Description   

The Session responder lock uses an interned String which is effectively a class-level lock. This can be made less restrictive by creating a new object instance for each Session.



 Comments   
Comment by Andre Mermegas [ 26/May/10 ]

this patch was undone in svn between 926 and 928 by ld1979 , I see, may i suggest simply making the mutex an object instead, this is a lighter and better lock object than String.

private final Object responderSync = new Object();

Comment by Steve Bate [ 28/Apr/11 ]

This fix was reverted in Rev #928.

Comment by Eric Deshayes [ 29/Apr/11 ]

Fix reapplied in Rev#1026





[QFJ-420] Add a setting for Logon Interval Created: 18/Mar/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Logon try interval can not be set. Add a "LogonInterval" setting and allow complex configuration as proposed in QFJ-419 for ReconnectInterval.



 Comments   
Comment by Jörg Thönnes [ 18/Mar/09 ]

I see no difference between the ReconnectInterval and a new Logon try interval.

Please, could you elaborate how you would like to use the new setting?

Comment by Paul-Henri Giraud [ 18/Mar/09 ]

Connection tries and Logon tries are independant.
The connector firstly tries to connect (ReconnectInternval setting) then, if successfull, tries to Logon (forgot to say that those settings are for Initiator only). The time between logon attempts is currently not configurable.

Remark: we have the implementation for QFJ-420 and QFJ-419

Comment by Jörg Thönnes [ 19/Mar/09 ]

In reply to comment #2:
>
> Connection tries and Logon tries are independant.
> The connector firstly tries to connect (ReconnectInternval setting) then, if
> successfull, tries to Logon (forgot to say that those settings are for Initiator
> only).

I was thinking that the session is disconnected if the Logon fails. Therefore, I saw this as one config.

> The time between logon attempts is currently not configurable.
> Remark: we have the implementation for QFJ-420 and QFJ-419

Great, could you attach a patch to the relevant tickets?

Comment by Paul-Henri Giraud [ 19/Mar/09 ]

I'm working with Laurent Danesi at Smart Trade, we will integrate the patch directly in a future version if this improvement is accepted.

Comment by Jörg Thönnes [ 23/Mar/09 ]

In reply to comment #4:
>
> I'm working with Laurent Danesi at Smart Trade, we will integrate the patch
> directly in a future version if this improvement is accepted.

I suspected this, but did not check

Comment by Steve Bate [ 25/Jan/10 ]

SVN #928

I also am curious about the specific use cases where it's necessary to control logon and reconnect attempts independently. When we document this new feature it would be good to describe where it's necessary to use the settings independently.





[QFJ-419] Reconnect Interval: set different interval values Created: 18/Mar/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-632 isTimeToGenerateLogon() in Session al... Resolved
relates to QFJ-665 "Dangling meta character '*' near ind... Resolved

 Description   

The ReconnectInterval setting is currently a simple value, in seconds, e.g. 5. That means that the socket will try to connect each five seconds.
If the distant server never respond, this can lead to a huge amount of tries, processing and resource usage.
The tries interval should be short in the beginning, then get longer.

Here is an example of syntax that could be set instead of a simple value:
ReconnectInterval=6*5;5*15;60
This means that the connect will be tried 6 times each 5 seconds, then 5 times each 15 seconds then each 60 seconds.

Setting a simple value such as:
ReconnectInterval=30
will result in trying each 30 seconds as before.



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-418] Session Schedule settings: also try with US day names Created: 18/Mar/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The settings of the "StartDay" and "EndDay" day names must conform to the locale of the running platform, that make the installation of a QuickFIXJ application difficult when customers have several platforms languages.

It could be very interesting to always set the configuration in US day names whatever the locale setting is; and keep the ability to use local day names anyway.

The quickfix.DayConverter helper class may try to convert day names using Locale.getDefault() then using Locale.US in case of failure, then throw the ConfigError as it does now.



 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-417] JMX : add the Queue Size information in SessionAdminMBean Created: 18/Mar/09  Updated: 15/Nov/12  Resolved: 25/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Improvement Priority: Default
Reporter: Paul-Henri Giraud Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add the ability of monitoring the underlying messaging queue size, so that any slow consuming can be detected.
In org.quickfixj.jmx.mbean.connector.ConnectorAdminMBean:

/**

  • The size of the underlying event queue
  • @return size of the queue; if this counters grows, the application does not consume FIX message quick enough
    */
    int getQueueSize();


 Comments   
Comment by Steve Bate [ 25/Jan/10 ]

SVN #928





[QFJ-416] Support Header/Trailer field ordering in code generation Created: 16/Mar/09  Updated: 15/Oct/12

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: Future Releases

Type: Improvement Priority: Default
Reporter: Laurent Danesi Assignee: Laurent Danesi
Resolution: Unresolved Votes: 2
Labels: None

Issue Links:
Relates
relates to QFJ-512 How do I change the order of the head... Closed
Requires
requires QFJ-709 expose field order constructor for me... Resolved

 Description   

To fully support custom FIX dictionary, we should take care of header fields defined in XML dictionary.



 Comments   
Comment by Jörg Thönnes [ 16/Mar/09 ]

In reply to QFJ-416:
> To fully support custom FIX dictionary, we should take care of header fields
> defined in XML dictionary.

I would like to add that the ordering as defined in the data dictionary should be honoured.
Same applies to trailer fields.

Do you think this should be separate tickets?

Comment by Laurent Danesi [ 16/Mar/09 ]

Yes, please.

Comment by Steve Bate [ 16/Mar/09 ]

Ordering by default will lead to a potential performance hit for users that don't care about ordering.

Comment by Jörg Thönnes [ 16/Mar/09 ]

In reply to comment #3:
>
> Ordering by default will lead to a potential performance hit for users that
> don't care about ordering.

Yes, but at the moment it is not possible to generate ordered Header and Trailer fields since the FieldMap constructor is not exposed.

My suggestion is to expose the field order constructor and extend the message generation to honour the generator option to create ordered messages.

In addition, the field sort is generated for every single message instance, but could by generated by a factory to use a single instance for every message type.

Comment by Jörg Thönnes [ 16/Mar/09 ]

Sorry for the duplicate comments.

The JIRA version used by QuickFIX/J has a bug which triggers errors with my Eclipse Mylyn plugin. So I did not know that I already submitted the comment.

Comment by Steve Bate [ 05/Apr/10 ]

It appears the request is also to validate the ordering.

Comment by Phill Dixon [ 27/Sep/10 ]

To add a custom field to a Trailer I also found that I had to edit the quickfix.Message object as the Trailer class has a hardcoded field order and any tag added to it which did not appear resulted in an invalid tag error. This occured when sending the Logon message with the new custom field in the trailer. The DataDictionary xml file had been modified but was apparently ignored.

There is also a hardcoded case statement for isTrailerField which needs modifying.

It would be useful if the XML file was respected.





[QFJ-415] Use data dictionary to determine message category for admin messages Created: 16/Mar/09  Updated: 07/Apr/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: Future Releases

Type: Improvement Priority: Default
Reporter: Laurent Danesi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

To fully support custom FIX dictionary, we should take care of msgcat to know if the message is an admin message or application message and not use hardcoded values.



 Comments   
Comment by Steve Bate [ 16/Mar/09 ]

The data dictionary is optional, so you'll need to handle the case of not having a data dictionary to determine admin vs. application messages.

Comment by Steve Bate [ 10/Jan/10 ]

In the absence of a data dictionary we can use the hardwired admin/app classifications but allow that to be overridden by the data dictionary.

Comment by Steve Bate [ 05/Apr/10 ]

I've looked at this and it's a bit tricky since there are several places in the code where we don't have a data dictionary and we must determine if the message is an application message or not. I've added predicates to the data dictionary to determine the category of the message, but more work is needed to convert the code to use every place.





[QFJ-414] quickfixj-core.jar includes FIXT11 and FIX50 packages Created: 14/Mar/09  Updated: 16/Oct/12  Resolved: 18/Mar/09

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Tom Palmer Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File build.xml.patch    
Issue Links:
Relates
relates to QFJ-519 Minor build problems in QuickFIX/J 1.4.0 Closed

 Description   

At the moment the quickfj-core.jar includes both the quickfix.fixt11 and quickfix.fix50 packages:

tom@macbook$ jar tf core/target/quickfixj-core-\${version}.jar | egrep fixt11 | wc -l
18
tom@macbook$ jar tf core/target/quickfixj-core-\${version}.jar | egrep fix50 | wc -l
1663



 Comments   
Comment by Tom Palmer [ 14/Mar/09 ]

The attached patch filters out the quickfix.fix50 and quickfix.fixt11 packages from quickfixj-core.jar. Here's the result of running the jar/egrep command line after applying the patch and rebuilding the Jars:

tom@macbook$ jar tf core/target/quickfixj-core-\${version}.jar | egrep fixt11 | wc -l
0
tom@macbook$ jar tf core/target/quickfixj-core-\${version}.jar | egrep fix50 | wc -l
0

Comment by Laurent Danesi [ 18/Mar/09 ]

Thank you Tom, your patch will be present in the next release.

Laurent





[QFJ-413] The repeating group count check doesn't work if the count == 0 Created: 12/Mar/09  Updated: 15/Nov/12  Resolved: 23/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Francis Uy Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None


 Description   

1) repro steps:
===========
send any message with valid repeating group fields except in the count, set the value to zero.

2) bad behavior:
============
No error is thrown. the repeating group is not ignored and is parsed anyway even though the group count is zero. Note: i don't think fix protocol states how to handle this case but i would assume this is an error.

3) expected behavior:
================
normally, if the count value doesn't match the actual number of "repeating group" you get this error: "Incorrect NumInGroup count for repeating group"



 Comments   
Comment by Francis Uy [ 12/Mar/09 ]

forgot to put the code that ignores zero in FieldMap.java ...

protected void setGroupCount(int countTag, int groupSize) {
if (groupSize == 0)

{ return; }

...
...
}

Comment by Francis Uy [ 12/Mar/09 ]

this is called in Message.java->parseGroup() ... at the bottom you have ...

// For later validation that the group size matches the parsed group count
parent.setGroupCount(groupCountTag, declaredGroupCount);

Comment by Francis Uy [ 27/Mar/09 ]

possible fix is to put this as a check above the previous comment.

if (declaredGroupCount == 0 && parent.getGroupCount(groupCountTag) != 0)

{ throw new FieldException( SessionRejectReason.VALUE_IS_INCORRECT, field.getTag()); }
Comment by Steve Bate [ 06/Apr/10 ]

Just to clarify... this is an issue if the group count is zero and yet the groups are actually there.

Comment by Steve Bate [ 23/May/11 ]

SVN #1036.





[QFJ-412] DynamicAcceptorSessionProvider does not correctly handle disconnected clients Created: 10/Mar/09  Updated: 15/Nov/12  Resolved: 14/Mar/09

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File qfj-412-examples-repro.patch     Text File qfj-412.patch    

 Description   

The existing implementation of DynamicAcceptorSessionProvider does not correctly handle the case where a client disconnects due to network failure - the DynamicAcceptorSessionProvider never detects the disconnect, and the connection appears to still be "active" and the Session is never removed.
As a result, when the client subsequently tries to reconnect, QFJ thnks that is already connected and does not allow for the new connection.

The DynamicAcceptorSessionProvider is setup to accept all incoming connections (based on a specified template). Currently, a new session is created and added to the sessions list, but if you are running a SingleThreadedEventHandlingStrategy the new session is never added to the list of sessions for the SessionConnector.
As a result the main SessionConnector.SessionTimerTask loop that goes through all the known connections and calls Session.next() on them (which tries to send TestRequest to those it hasn't heard from in a while) is never executed for the dynamically-created connections.

The solution is to have the SessionConnector be available to the DynamicAcceptorSessionProvider class, and to add the session to the list of sessions at creation.

You can reproduce this by changing the Executor example to use the DynamicAcceptorSessionProvider, and then connecting to it via Banzai from a different machine.
Disconnect the network cable, wait 2 mins, try to reconnect - the vanilla version of QFJ won't let you re-login b/c it still thinks the first session is active.
With the patch, it'll detect lack of hearbeats and forcibly disconnect the session.



 Comments   
Comment by Toli Kuznets [ 10/Mar/09 ]

patch with changes to fix this bug

Comment by Toli Kuznets [ 10/Mar/09 ]

Temp changes to example Executor to reproduce this problem

Comment by Toli Kuznets [ 14/Mar/09 ]

fix checked in rev 919





[QFJ-411] Issue with formatting of Double Fields like the price field etc. Created: 04/Mar/09  Updated: 15/Nov/12  Resolved: 15/Jan/10

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

Type: Bug Priority: Major
Reporter: Ketan Chaudhry Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

OS: Solaris Software: Java JRE 1.5.0_10



 Description   

Hi,
We are using QuickFIX/J version 1.3.3 as the FIX Engine in our Financial application, which services QuoteRequests and Trade Requests received from our counterparty. While our application passes along precisely rounded (to 2 decimal places) Price field value in the Execution Report to QFJ, this precision is lost when QFJ creates the string FIX message(4.21 becomes 4.299999999998). Our counterparty truncates the values received, instead of rounding it, thus receiving 4.28 instead of 4.29). This creates a considerable pricing issue depending on the precision.

However, we would like to know if this issue been taken care of ? Are there any immediate fixes available?
Would really appreciate your help on this.

Thanks



 Comments   
Comment by Toli Kuznets [ 04/Mar/09 ]

I believe this is an inherent problem with using doubles.
You can recompile QFJ to use BigDecimals instead, which preserves the values correctly, and then puts them on the wire as a string in the right format before sending the message out.

You can recompile QFJ with -Dgenerator.decimal=true to get BigDecimals instead
See http://www.quickfixj.org/quickfixj/usermanual/usage/codegen.html ( the flag in 1.3.3 is -Dgenerator.decimal)

that should solve your problem. this is what we do.

Comment by Jörg Thönnes [ 06/Mar/09 ]

Alternatively, you can use setString() to set the String value from the BigDecimal directly.
In this way you bypass the double conversion.

Of course, Tolis suggestions to use the BigDecimal build is the more general one.





[QFJ-410] ThreadPerSessionEventHandlingStrategy still leaks threads Created: 04/Mar/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.4.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Jerry Shea Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None

Attachments: Text File 410-2.patch     Text File 410.patch     Text File ThreadPerSessionEventHandlingStrategy.java    
Issue Links:
Duplicate
is duplicated by QFJ-491 ThreadPerSessionEventHandlingStrategy... Closed
is duplicated by QFJ-475 ThreadPerSessionEventHandlingStrategy... Closed
is duplicated by QFJ-510 ThreadPerSessionEventHandlingStrategy... Closed
Relates
relates to QFJ-491 ThreadPerSessionEventHandlingStrategy... Closed

 Description   

See http://www.quickfixj.org/jira/browse/QFJ-326

I'd like this to be reopened as threads still leak.
1. in ThreadPerSessionEventHandlingStrategy.stopDispatcherThreads the dispatchers.clear() is done before looping through the collection and so threads' stopDispatcher is never called
2. ThreadPerSessionEventHandlingStrategy.MessageDispatchingThread.run never terminates as this method repeatedly calls getNextMessage in a loop and getNextMessage calls messages.take which blocks indefinitely
3. also, stopDispatcherThreads should wait for threads to terminate before it returns so that everything gets cleaned up properly and in order

I've got a patch which fixes these by:
1. reordering statements in stopDispatcherThreads
2. using messages.poll which times out. Have set up a constant timeout of 10 seconds
3. waiting for threads to finish

What do people think about the timeout value? We could make this timeout configurable, or higher.



 Comments   
Comment by Jerry Shea [ 04/Mar/09 ]

Here's the patch. I changed the timeout to 2 seconds in my testing.

Comment by Jerry Shea [ 15/Jun/09 ]

Have reduced the wait timeout to 250ms to make shutdown more responsive.

Comment by Jerry Shea [ 15/Jun/09 ]

Guys, is there any chance we could get this change assigned to 1.4.1 release? Let me know if there's anything else I can do to help this along

Comment by Andre Mermegas [ 18/Dec/09 ]

I have a similiar bugfix, i can't attach for some reason.

/*******************************************************************************

  • Copyright (c) quickfixengine.org All rights reserved.
    *
  • This file is part of the QuickFIX FIX Engine
    *
  • This file may be distributed under the terms of the quickfixengine.org
  • license as defined by quickfixengine.org and appearing in the file
  • LICENSE included in the packaging of this file.
    *
  • This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
  • THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
  • PARTICULAR PURPOSE.
    *
  • See http://www.quickfixengine.org/LICENSE for licensing information.
    *
  • Contact [email protected] if any conditions of this licensing
  • are not clear to you.
    ******************************************************************************/

package quickfix.mina;

import quickfix.LogUtil;
import quickfix.Message;
import quickfix.Session;
import quickfix.SessionID;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

/**

  • Processes messages in a session-specific thread.
    */
    public class ThreadPerSessionEventHandlingStrategy implements EventHandlingStrategy {
    private final Map<SessionID, MessageDispatchingThread> dispatchers = new ConcurrentHashMap<SessionID, MessageDispatchingThread>();

public void onMessage(Session quickfixSession, Message message) {
MessageDispatchingThread dispatcher = dispatchers
.get(quickfixSession.getSessionID());
if (dispatcher == null)

{ dispatcher = new MessageDispatchingThread(quickfixSession); dispatchers.put(quickfixSession.getSessionID(), dispatcher); startDispatcherThread(dispatcher); }

dispatcher.enqueue(message);
}

/** There is no such thing as a SesionConnector for thread-per-session handler - we don't multiplex

  • between multiple sessions here so this is null
    */
    public SessionConnector getSessionConnector() { return null; }

protected void startDispatcherThread(MessageDispatchingThread dispatcher)

{ dispatcher.start(); }

public void stopDispatcherThreads() {
Collection<MessageDispatchingThread> dispatchersToShutdown = dispatchers.values();
dispatchers.clear();
for (MessageDispatchingThread dispatcher : dispatchersToShutdown)

{ dispatcher.stopDispatcher(); }

}

private class MessageDispatchingThread extends Thread {
private final Session quickfixSession;
private final BlockingQueue<Message> messages = new LinkedBlockingQueue<Message>();
private volatile boolean stopped;

MessageDispatchingThread(Session session)

{ super("QF/J Session dispatcher: " + session.getSessionID()); quickfixSession = session; }

public void enqueue(Message message) {
try

{ messages.put(message); }

catch (InterruptedException e)

{ quickfixSession.getLog().onEvent(e.getMessage()); }

}

public Message getNextMessage(BlockingQueue<Message> messages) throws InterruptedException

{ return messages.poll(1000L, TimeUnit.MILLISECONDS); }

public int getQueueSize()

{ return messages.size(); }

public void run() {
while (!stopped) {
try {
Message message = getNextMessage(messages);
if (message != null && quickfixSession.hasResponder())

{ quickfixSession.next(message); }

} catch (InterruptedException e)

{ LogUtil.logThrowable(quickfixSession.getSessionID(), "Message dispatcher interrupted", e); return; }

catch (Throwable e)

{ LogUtil.logThrowable(quickfixSession.getSessionID(), "Error during message processing", e); }

stopped = !quickfixSession.hasResponder();
}
dispatchers.remove(quickfixSession.getSessionID());
}

public void stopDispatcher()

{ stopped = true; }

}
public int getQueueSize() {
int ret = 0;
for(MessageDispatchingThread mdt : dispatchers.values())

{ ret+=mdt.getQueueSize(); }

return ret;
}

}

Comment by Andre Mermegas [ 06/Apr/10 ]

that patch didn't work for me, threads were not ending.

attached my fix.

Comment by Andre Mermegas [ 06/Apr/10 ]

should probably make getNextMessage(...) private too.





[QFJ-409] Stack overflow when processing a large number of queued messages Created: 03/Mar/09  Updated: 16/Oct/12  Resolved: 16/Oct/12

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

Type: Bug Priority: Default
Reporter: JamesM Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Java 1.5.0_12 on Linux


Issue Links:
Duplicate
duplicates QFJ-271 StackOverflowError trying to process ... Closed

 Description   

This issue is probably related to QFJ-379: http://www.quickfixj.org/jira/browse/QFJ-379

We noticed that a stack overflow can occur when QuickFIX is processing a very large number of queued messages.

From the event log file (edited to make the situation clearer):

MsgSeqNum too high, expecting 1430 but received 4937
MsgSeqNum too high, expecting 1430 but received 4938
Received SequenceReset FROM: 1430 TO: 1939

[...]

Processing queued message: 4030, pending: [1432, 1433, 1434, ..., 1939, 4031, 4032, ..., 4937, 4938]
null
java.lang.StackOverflowError
at java.nio.Buffer.<init>(Buffer.java:176)
at java.nio.ByteBuffer.<init>(ByteBuffer.java:259)
at java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:52)
at java.nio.ByteBuffer.wrap(ByteBuffer.java:350)
at java.nio.ByteBuffer.wrap(ByteBuffer.java:373)
at java.lang.StringCoding$CharsetSE.encode(StringCoding.java:339)
at java.lang.StringCoding.encode(StringCoding.java:378)
at java.lang.String.getBytes(String.java:812)
[... application code ...]
at XXX.YYY.ZZZ.QF_FIXConnectionImpl.fromApp(QF_FIXConnectionImpl.java:219)
at quickfix.Session.fromCallback(Session.java:1314)
at quickfix.Session.verify(Session.java:1272)
at quickfix.Session.verify(Session.java:1343)
at quickfix.Session.next(Session.java:742)
at quickfix.Session.next(Session.java:1599)
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)
at quickfix.Session.next(Session.java:796)
at quickfix.Session.next(Session.java:1599)
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)
at quickfix.Session.next(Session.java:796)
at quickfix.Session.next(Session.java:1599)
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)
at quickfix.Session.next(Session.java:796)
at quickfix.Session.next(Session.java:1599)
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)
at quickfix.Session.next(Session.java:796)
at quickfix.Session.next(Session.java:1599)
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)
at quickfix.Session.next(Session.java:796)
[....]
at quickfix.Session.nextQueued(Session.java:1589)
at quickfix.Session.nextQueued(Session.java:1570)

Is anyone able to offer any suggestions? I think the next/nextQueued functions may be excessively recursive, which will cause a stack overflow error if the queue of messages to be processed is extremely large.

I also tried with a thread stack size of 128K, 256K, 512K (-Xss VM option) but see the same problem.






[QFJ-408] In response to ResendRequest, the resent message from counterparty cannot not reach/trigger the toApp callback method Created: 03/Mar/09  Updated: 15/Nov/12  Resolved: 03/Mar/09

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

Type: Bug Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None

Attachments: PDF File Re_ [Quickfixj-users] ResendReq.pdf    

 Description   

If the application send a ResendRequest using QFJ, the incoming resent message from counterparty could not reach/trigger the toApp callback method for some reason. But the resent message can actually reach messages_log table, and if the message is invalid QFJ will also reject it.



 Comments   
Comment by Steve Bate [ 03/Mar/09 ]

As we discussed on the mailing list, it is not correct for an application to explicitly request a message resend. The FIX session processes messages in the order of the message sequence numbers. Let's say the session's next expected incoming sequence number is 100. Your application requests message 75 to be resent. The session receives the message, sees the PossDup flag is set and that the sequence number is less than the expected next sequence number. The message is then dropped because it has already been processed by the application. This is normal FIX session behavior.

Comment by Alvin Wang [ 03/Mar/09 ]

Thanks. That makes more sense now. The only thing is that if the original message was rejected, my application did not get chance to process it. By customizing the dictionary to let QFJ to allow the message, we want to re-process the message.

An alternative is to read the message from messages_log table and construct the Message object from String (how to do that?) and call toApp method programmatically

This issue actually lead to a practical question. In our reality, 99% of time QFJ rejects messages for the reasons that are not our concern. we actually want to receive those messages even though they do not stick to the FIX spec. We cannot force counterparty what to do, so we have to basically keep a customized dicitonary for each counterparty. It would be nicer to allow us to configure QFJ to be more forgiving. I would classify the checks into 2 classes, one is more criitical (like having header, trailer, and checksum is correct....); while the other is less critical and QFJ can allow us to turn them off using ONE single switch.





[QFJ-407] Some classes use System.err.println instead of log.error Created: 27/Feb/09  Updated: 15/Nov/12  Resolved: 03/Mar/09

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

Type: Improvement Priority: Default
Reporter: Jerry Shea Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File 407.patch    

 Description   

For example, quickfix.FileStore

Shouldn't these classes use log.error instead? I can provide a patch if people agree.



 Comments   
Comment by Jörg Thönnes [ 27/Feb/09 ]

In reply to QFJ-407:
> For example, quickfix.FileStore
>
> Shouldn't these classes use log.error instead? I can provide a patch if people
> agree.

Hi Jerry,

I would be happy to review your patches.

Cheers, Jörg

Comment by Steve Bate [ 03/Mar/09 ]

Fixed. Thanks!

Comment by Jerry Shea [ 03/Mar/09 ]

Also FileLog & JdbcLog





[QFJ-406] No way for FileStore to be closed Created: 27/Feb/09  Updated: 15/Nov/12  Resolved: 06/Apr/10

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

Type: Improvement Priority: Default
Reporter: Jerry Shea Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Windows XP sp3, Java 6


Attachments: Text File 406.patch    
Issue Links:
Duplicate
duplicates QFJ-224 Automatically close logs and message ... Closed

 Description   

If I create a ThreadedSocketInitiator with a FileStoreFactory, start, stop and re-start it, I get the following in stderr:

File delete failed: ...\FIX.4.2-xxx.header
File delete failed: ...\FIX.4.2-xxx.body
File delete failed: ...\FIX.4.2-xxx.seqnums

This seems to be because ThreadedSocketInitiator gets a new FileStore from FileStoreFactory which then locks files (for example - initializeMessageIndex opens a FileOutputStream for the header file).

When I stop the initiator this FileStore is never closed - the FileStore doesn't actually have any kind of close or dispose method.

When I restart the initiator it gets a new FileStore which barfs with the above errors when it can't delete the files.

I'm happy to work up a patch for this but would appreciate some guidance as to what the commiters think should close the FileStore.



 Comments   
Comment by Jörg Thönnes [ 27/Feb/09 ]

In reply to QFJ-406:
> I'm happy to work up a patch for this but would appreciate some guidance as to
> what the commiters think should close the FileStore.

Would be great if you could suggest patches. Looking at the FileStore, there are already internal methods to close the files.
But these methods are called on initialize, since there is no MessageStore API method to close it.

Could you also suggest how to extend the MessageStore API to provide a close() method and more important where in the QF/J code you would call this method?

Thanks, Jörg

Comment by Steve Bate [ 03/Mar/09 ]

One approach is to create an interface for objects to listen to Connector start/stop events. The Connector implementations could automatically register stores or logs as listeners if they implement that interface.

Comment by Jerry Shea [ 03/Mar/09 ]

Hi Steve,
unfortunately the Connector does have access to, for example, message stores. It passes a MessageStoreFactory to the Session which creates a MessageStore when invoking the SessionState constructor, which keeps a handle to the message store.
The way I've implemented this initially is to add a close method to Session, SessionState, and MessageStore (and impls.) and modified SessionConnector.logoutAllSessions to call Session.close, which calls SessionState.close which calls MessageStore.close. I could add a close method to Log and all impls. too and call this in the same place? (as I use SLF4JLog I haven't noticed any issues with logs remaining open).
This solution solves my problem but I'm happy for suggestions or changes to the code to be made.
Cheers, Jerry

Comment by Jerry Shea [ 15/Jun/09 ]

Guys, is there any chance we could get this change assigned to 1.4.1 release? Let me know if there's anything else I can do to help this along

Comment by Steve Bate [ 06/Apr/10 ]

This will be worked under the original QFJ-224 issue.





[QFJ-405] Fields missing on resends Created: 26/Feb/09  Updated: 26/Feb/09

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In some circumstances fields may be omitted from re-sent messages.

We tracked this down to the following line in Session.parseMessage(String):
msg.fromString(messageData, dataDictionary, false);
In our case there was a repeating group used in outbound messages only that was not present in the data dictionary. Those fields silently disappeared.

So, a workaround is to edit the data dictionary. But given the silent misbehaviour, I would rate this a bug.

Probably could fix this by creating a subclass of Message that treats the body as an immutable string --> overrides to parseBody, calculateString, calculateLength and calculateTotal. Hopefully there is a more elegant solution.






[QFJ-404] A validation configuration to bypass checking of "Tag appears more than once" Created: 11/Feb/09  Updated: 23/Jun/16  Resolved: 06/Apr/10

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

Type: New Feature Priority: Default
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Won't Fix Votes: 4
Labels: None


 Description   

If the received message contains some custom repeating group, QFJ will reject with "Tag appears more than once" error. We had to customize the dictionary to work around. A configuration allowing bypass this will be helpful



 Comments   
Comment by Ali Asghar [ 11/Feb/09 ]

I am a developer working on a FIX implementation using QuickFix/J version 1.4. I am getting an error "Tag appears more than once". The tag it is complaining about is 9013 (a custom repeating group). You mention on the forum the you had to customize the dictionary to work around. I am new to QuickFix/J and I am not sure how to customize the data dictionary. Could you please let me know how you customized the dictionary? I am using FIX 4.4. Thanks

Comment by Steve Bate [ 03/Mar/09 ]

I don't know if you've found the information you want yet, but there is a description in the QFJ documentation. After reading that information, if you are still having problems please post a followup question.

Comment by Steve Bate [ 03/Mar/09 ]

I changed this issue to a question, but it should remain a new feature request.

Comment by Alvin Wang [ 03/Mar/09 ]

Where can I find the description in QFJ doc? Could you provide a link?

Comment by Ganeshan Guruswamy [ 25/Jun/09 ]

hi... we want a solution for same problem... "Tag appears more than once"

in my case the repeating tag is a user defined tag and want quickfix/j to ignore it...

please help

Comment by Ali Asghar [ 25/Jun/09 ]

This is a serious issue for us because we connect to Intercontinental Exchange (ICE) to receive trade data. ICE frequently adds new Custom Tags to their FIX messages and if that tag is not included in FIX44.xml then QuickFIX/J rejects messages. Even though in QuickFIX/J config file, I am setting

ValidateUserDefinedFields=N

This value should control quickfix behavior to control the user defined tag validation but it does not seem to be working.

I am using QuickFIX/J version 1.4?

Does any one know solution for this problem?

Comment by Carey Bingham [ 23/Sep/09 ]

This is also a serious issue for us for the saem reasons as Ali Asghar pointed out for ICE.

We are using the same version as well...We have turned off all validation but it seems to have no affect. Each time ICE adds custom tags or modifies the fix messages we get errors...The only solution is to revuild our dictionary and redploy the new generated classes.

Anyonw have a workaround? Or at least a fix implemented at this point.

ICE's cutover is of Nov 2 2009 and this is still a problem for us.

Comment by anton [ 13/Oct/09 ]

The problem for many of us is important, so can anybody tell us how he has solved the problem?
Someone said that we should change the data dictionary, but how?
Someone said that there is a description about this in the documentation, but I didn't found anything.

Comment by anton [ 14/Oct/09 ]

In fact I was thinging its a bug because I was receiving tag appears more then once for tag(part of group) included in the dictionary that I am using.The problem was that some of the fields before the group were out of order,-when I fixed the dictionary the problem has been solved.
The strange here is that I was not receiving msg out of order(which sould be received when the order in group is wrong) and I didn't know that the problem is in the Order of the fields in the parent-group which contains the subgroup which contains the tag that repeats more then once.
So if you have a data dictionary which contains the correct groups and tags and you are receiving this message you can check the order of the tags, because it can cause message like the above one.
Hope it helps.

Tonko Lonko

Comment by Dmitry [ 22/Mar/10 ]

I use:

UseDataDictionary=Y
DataDictionary=FIX43.xml
ValidateUserDefinedFields=N
ValidateFieldsHaveValues=N

and its work =)

Comment by Deelo [ 21/Feb/12 ]

I'm having this problem as well...did anyone figure out a solution?

Comment by Christoph John [ 21/Feb/12 ]

Did you already try the suggestions above or the setting ValidateIncomingMessage=Y?

Comment by Alvin Wang [ 15/Nov/12 ]

what is the solution/workaround of this issue?

Comment by Christoph John [ 15/Nov/12 ]

Did you try the suggestions above?
I only transitioned the issue from the "resolved" to the "closed" state, so nothing was actually changed.

Comment by Manish Patel [ 23/Jun/16 ]

Setting this worked for me:

ValidateIncomingMessage=N

It's a workaround, but really your FIX*.xml should be fixed.





[QFJ-403] Rejecting due to OrigSendingTime not being in Tag without Data Dictionary Created: 10/Feb/09  Updated: 05/Oct/14  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
duplicates QFJ-654 Rejecting due to OrigSendingTime not ... Closed
Relates
relates to QFJ-703 Do not reject PossDup message which d... Resolved

 Description   

Hi,

I'm using quickfix/J and for some reason I keep rejecting messages with reject:

20090210-16:13:01: Message 641 Rejected: Required tag missing:122

I have the following configuration options set in configuration:

UseDataDictionary=N
ValidateFieldsOutOfOrder=N
ValidateFieldsHaveValues=N
VaidateUserDefinedFields=N
CheckLatency=N

And I have also attempted to rip out OrigSendingTime from my Data Dictionary as a precautionary measure. I don't ever explicitly call this tag in code. Any help on this issue would be appreciated.

Regards,
Herman



 Comments   
Comment by Herman Hung [ 10/Feb/09 ]

At this point, I've also literally emptied my Application (quickfixj.Application). It should not be doing ANYTHING, and yet I'm still rejecting on that tag. Anyone, please help?

Regards,
Herman

Comment by Toli Kuznets [ 10/Feb/09 ]

Herman,

Can you include the logs that show the flow of messages going out and coming in preceding this error?

From the FIX spec about tag 122:

Required for message resent as a result of a Resend Request (2) . If data is not available set to same value as SendingTime (52) (Can be embedded within encrypted data section.)

It's possible that your counterparty is not sending you the message with that tag, and QFJ may be rejecting it b/c it is required in a particular case. It's impossible to say what's going on without seeing the actual message flow.

Make sure you enable logging for INFO level. Here's a sample for Log4J:

# QuickFIX/J.
log4j.logger.quickfixj.msg.incoming=INFO
log4j.logger.quickfixj.msg.outgoing=INFO
log4j.logger.quickfixj.event=INFO
Comment by Herman Hung [ 10/Feb/09 ]

Hi Toli,

Thanks for the response. I cannot attach logs at this time, but I can confirm that the scenario that you are putting forth is happening: someone is sending me FIX messages in response to a resend request and not including that tag. However, it appears that the code that processes the association of tag 122 with this event is buried inside the QuickFix/J code and is something that I would like to override. Is there anything I can do to override this check?

Regards,
Herman

Comment by Herman Hung [ 10/Feb/09 ]

(That is, anything short of editing the QuickFix/j source itself?)

Comment by Andy Malakov [ 21/Dec/10 ]

It seems that the following code fragment from Session.java is responsible for reject:

private boolean validatePossDup(Message msg) throws FieldNotFound, IOException {
final Message.Header header = msg.getHeader();
final String msgType = header.getString(MsgType.FIELD);
final Date sendingTime = header.getUtcTimeStamp(SendingTime.FIELD);

if (!msgType.equals(MsgType.SEQUENCE_RESET)) {
if (!header.isSetField(OrigSendingTime.FIELD))

{ generateReject(msg, SessionRejectReason.REQUIRED_TAG_MISSING, OrigSendingTime.FIELD); return false; }

....

It appears that some FIX implementations (e.g. ICE exchange) do not set OrigSendingTime in some of their messages during resend.

Comment by Andy Malakov [ 22/Dec/10 ]

I propose to validate OrigSendingTime field only if it is present in inbound message:

 Index: java/quickfix/Session.java
===================================================================
         Date sendingTime = header.getUtcTimeStamp(SendingTime.FIELD);
 
         if (!msgType.equals(MsgType.SEQUENCE_RESET)) {
-            if (!header.isSetField(OrigSendingTime.FIELD)) {
-                generateReject(msg, SessionRejectReason.REQUIRED_TAG_MISSING, OrigSendingTime.FIELD);
-                return false;
+        	Date origSendingTime;
+        	try {
+            	  origSendingTime = header.getUtcTimeStamp(OrigSendingTime.FIELD);
+             } catch (FieldNotFound e) {
+            	 origSendingTime = null;
               }
-
-            Date origSendingTime = header.getUtcTimeStamp(OrigSendingTime.FIELD);
-            if (origSendingTime.compareTo(sendingTime) > 0) {
+            if (origSendingTime != null && origSendingTime.compareTo(sendingTime) > 0) {
                 generateReject(msg, SessionRejectReason.SENDINGTIME_ACCURACY_PROBLEM, 0);
                 generateLogout();
                 return false;
             }
+
         }
 
         return true
Comment by MANOJ M [ 03/Oct/14 ]

Could you please let me know the resoltion for this issue? I am having same issue while connecting to ICE.

Comment by Christoph John [ 05/Oct/14 ]

See QFJ-703.





[QFJ-402] Provide useful exception description for IncorrectTagValue, NoTagValue and other FIX specific exceptions Created: 10/Feb/09  Updated: 11/Feb/09  Resolved: 10/Feb/09

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.3.2, 1.3.3
Fix Version/s: 1.4.0

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

The FieldNotFound exception contains a useful exception description, which can be fetched with e.getMessage():

    public FieldNotFound(int field) {
        super("Field ["+field+"] was not found in message.");
        this.field = field;
    }

but other FIX exceptions as IncorrectTagValue or NoTagValue etc. lacks these description text.
This is not consistent with the second constructor using a String description text.

Provide useful description text for IncorrectTagValue, NoTagValue and possibly other FIX exceptions.



 Comments   
Comment by Jörg Thönnes [ 10/Feb/09 ]

Laurent, for the moment I would like to resolve this issue as fixed.

There are a couple of other exception migrated from the C++ JNI API, which need improvements:

  • missing exception descriptions
  • constructors lacking description messages

I removed two constructors from the NoTagValue exception, but now I am unsure whether this breaks the C++ JNI API compatibility. Please re-add the constructors if you think so.

Please include this in the 1.4.0 release hopefully coming soon.





[QFJ-401] Badly behaved counterparty sending FIX.5.0 as begin string causes exceptions Created: 03/Feb/09  Updated: 29/Apr/11  Resolved: 29/Apr/11

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.5.1

Type: Bug Priority: Default
Reporter: Jay Walters Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The following context diff shows a patch which cleans up the issue by reducing the possibility of a null pointer.

      • quickfixj/core/src/main/java/quickfix/MessageUtils.java Thu Jan 15 11:47:03 2009
      • quickfixj-svn/core/src/main/java/quickfix/MessageUtils.java Tue Jan 20 15:49:54 2009
        ***************
      • 104,107 ****
      • 104,116 ----
        String customApplVerID = null;

+ MessageFactory messageFactory = session.getMessageFactory();
+ DataDictionaryProvider ddProvider = session.getDataDictionaryProvider();
+ DataDictionary sessionDataDictionary = ddProvider.getSessionDataDictionary(beginString);
+ DataDictionary payloadDataDictionary = null;
+
+ // We check and if it's a Admin message we don't need anything more
+ if (MessageUtils.isAdminMessage(msgType))

{ + payloadDataDictionary = sessionDataDictionary; + }

else {
if (FixVersions.BEGINSTRING_FIXT11.equals(beginString))

{ applVerID = getApplVerID(session, messageString); *************** *** 111,128 **** }

! MessageFactory messageFactory = session.getMessageFactory();
!
! DataDictionaryProvider ddProvider = session.getDataDictionaryProvider();
! DataDictionary sessionDataDictionary = ddProvider.getSessionDataDictionary(beginString);
! DataDictionary applicationDataDictionary = ddProvider.getApplicationDataDictionary(
! applVerID, customApplVerID);

quickfix.Message message = messageFactory.create(beginString, msgType);
! DataDictionary payloadDictionary = MessageUtils.isAdminMessage(msgType)
! ? sessionDataDictionary
! : applicationDataDictionary;
!
! message.parse(messageString, sessionDataDictionary, payloadDictionary,
! payloadDictionary != null);

return message;

— 120,130 ----
}

! payloadDataDictionary = ddProvider.getApplicationDataDictionary(applVerID,
! customApplVerID);
! }

quickfix.Message message = messageFactory.create(beginString, msgType);
! message.parse(messageString, sessionDataDictionary, payloadDataDictionary,
! payloadDataDictionary != null);

return message;



 Comments   
Comment by Jay Walters [ 03/Feb/09 ]

A little bit more in a separate file to help with the same issue.

      • quickfixj/core/src/main/java/quickfix/DataDictionary.java Thu Jan 15 11:47:03 2009
      • quickfixj-svn/core/src/main/java/quickfix/DataDictionary.java Thu Jan 15 10:33:19 2009
        ***************
      • 256,260 ****
        */
        public boolean isHeaderField(int field) { ! return messageFields.get(HEADER_ID).contains(field); }

— 256,261 ----
*/
public boolean isHeaderField(int field)

{ ! Set<Integer> hdrFields = messageFields.get(HEADER_ID); ! return (hdrFields == null) ? false : hdrFields.contains(field); }

***************

      • 1092,1096 ****
        addXMLGroup(document, componentFieldNode, msgtype, dd, isRequired);
        }
        !
        if (componentFieldNode.getNodeName().equals("component")) { String required = getAttribute(componentFieldNode, "required"); --- 1093,1097 ---- addXMLGroup(document, componentFieldNode, msgtype, dd, isRequired); }

        ! // Also need to take into account nested components
        if (componentFieldNode.getNodeName().equals("component")) {
        String required = getAttribute(componentFieldNode, "required");

Comment by Eric Deshayes [ 29/Apr/11 ]

This issue had already been fixed.
Potential null pointer prevention has been introduced in rev#926.





[QFJ-400] Make scheduledExecutorService non-static Created: 03/Feb/09  Updated: 16/Feb/09

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: Mihai Sardarescu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hello all,

In order to start our FIX connector, we have a "start" call from our middleware (there could be more than one FIX connectors started at different times on the same JVM). On this call, a logger is paased to the connector and all the log of the FIX connector should be dumped to this logger. The log of the QuickfixJ session is easily routed. However, the log messages from Mina and of the QuickfixJ initiators are more difficult to route. We use InheritableThreadLocal to pass the logger to all threads started by our FIX connector.
We encountered a problem due to the fact that the QuickfixJ SessionConnector uses a static executor service for executing SessionTimerTask tasks. Could you please change this to non-static?
For more details, please refer to thread: http://sourceforge.net/mailarchive/message.php?msg_name=1714.65.220.39.123.1208198497.squirrel%40webmail3.hrnoc.net

We expect our application to go in production very soon (at most 2 month for now).

Thank you,
Mihai



 Comments   
Comment by Steve Bate [ 05/Feb/09 ]

Please remind me why you weren't able to write a SLF4J logger implementation that delegates to the thread local logger provided by the middleware product. All logging from all threads goes through SLF4J so it seems that this would route those messages through the logger you provided.

Comment by Mihai Sardarescu [ 05/Feb/09 ]

Hi Steve,

In order to start the FIX connector, I get a start call from the middleware. On this call, a logger is passed to my code and I shall redirect all log message written by quickfixj and mina to this logger.

To do that I have used an InheritableThreadLocal that holds the middleware logger object in order to pass it to all the created by quickfixj and mina code. The loggers created by the slf4j are just proxies to the current thread middleware logger. I can thus redirect the quickfixj and mina log messages to the middleware log.

This technique does not work in case a static executor (or a static thread) is used. For example:
1. The FIX connector is started using the middleware logger LOGGER1. When loading of the quickfixj library, the static executor is initialized and the the logger attached to it is LOGGER1. All log messages written on this logger will be directed to the LOGGER1.
2. A second instance of the FIXConnector is started in the same JVM using LOGGER2. As the static executor was already initialized, the log written by quickfixj on the static executor will be also routed to LOGGER1 (and not to LOGGER2 as expected). This leads to potentials problems - what if the first instance of the FIXConnector is stopped and the LOGGER1 is closed by the middleware (etc.)

Also, I do not see the benefit of using a static scheduledExecutorService for all the initiators (which also uses a daemon worker thread). Wouldn't it be better to use a non-static executor that can be shutdown once the initiator is stopped?

Regards,
Mihai

Comment by Steve Bate [ 06/Feb/09 ]

Hello Mihai,

As we discussed before, the purpose of the static (singleton) executor is to minimize the number of threads used by QFJ for it's own purposes. The executor is shared among all initiators and acceptors.

I'm still not understanding why using a custom SLF4J implementation didn't work for you. If the custom logger implementation delegates to the /current/ middleware logger then it doesn't matter when the logger client actually retrieved the SLF4J logger instance. Actually, you could do this even without SLF4J by just implementing the QFJ Log interface. Your custom Log would delegate to the middleware logger. The middleware callback would modify the logger delegate in your Log implementation and everything that uses the Log implementation would automatically be using the new middleware logger. If the middleware logger is thread-local then that could also be supported with this approach.

I'm probably missing something, but this is my understanding at this point based on the information I have. Feel free to clarify any key issues I'm not seeing. I want to understand why this can't be done in the way I describe before changing the QFJ internals to support it.

Thanks,

Steve

Comment by Mihai Sardarescu [ 16/Feb/09 ]

Hi Steve,

The middleware provides a different logger object for each FIX connector. As I have one and only one QFJ session per connector, I have implemented a special QFJ logger that routes the log of one QFJ session to the middleware logger - this works fine and the log messages are routed to the correct logger.
However, I am missing the mina log and the low-level log of QFJ (the log that is written using slf4j). In fact, each FIX connector has its own initiator - the initiator is started upon the initialization of the connector and is stopped once the connector is destroyed. The problem is that once an initiator writes log messages from the static thread, there is no way to find out the which connector this initiator corresponds in order to route the log message to the correct logger.

To make it more clear: let's suppose I have two concurrent FIX connectors running in the same JVM having:

  • LOGGER1, LOGGER2 - the middleware loggers
  • INITIATOR1, INITIATOR2 - the initiators.
    INITIATOR1 logs something using the slf4j logger: log.debug("MESSAGE1") from the static thread THREAD1.
    INITIATOR2 logs something using the slf4j logger: log.debug("MESSAGE2") from the static thread THREAD1.
    There is no way to decide if the MESSAGE1 should be routed to LOGGER1 or LOGGER2 (the same applies for MESSAGE2). If the thread was non-static, then using inheritable thread locals could allow me to route the message to the right logger.

Thanks,
Mihai





[QFJ-399] disconnecting on logon request Created: 03/Feb/09  Updated: 03/Mar/09  Resolved: 03/Mar/09

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

Type: Other Priority: Default
Reporter: sangeetha Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

here us the scenario,

our customer is sending us some messages continously, but when application using quickfix sends a logon request it disconnects on receiving some other message

20090203-08:45:27.481: Initiated logon request
20090203-08:45:27.501: quickfix.SessionException Logon state is not valid for message (MsgType=6)
20090203-08:45:27.501: Disconnecting
20090203-08:45:27.514: Failed to verify message: 8=FIX.4.0^A9=113^A35=6^A34=2601972^A49=S005^A52=20090203-08:44:00^A56=R005^A23=XLAX:5:1224729204606970^A
27=0^A38=500^A44=7.88^A54=2^A55=UCBH^A10=055^A

1) Do you know why is it disconnecting and not waiting for logon response?
2) Do we have some way to enable detailed logging in quickfix, it looks very difficult to debug things with very little info in the log. (Disconnecing : Its not clear whois disconnecting we or the customer.). Is there any way to classify the in/out messages?



 Comments   
Comment by Toli Kuznets [ 03/Feb/09 ]

I'm assuming that you are the "acceptor".

you can enable debugging (depending on whether you use Log4J or some other logging framework in your setup).

Here's an example for Log4J:

# QuickFIX/J.
log4j.logger.quickfixj.msg.incoming=INFO
log4j.logger.quickfixj.msg.outgoing=INFO
log4j.logger.quickfixj.event=INFO

This will show you the incoming/outgoing messages

It also seems that you are getting an Indication of Interest (35=6) when you don't expect it - ie the customer hasn't logged on yet maybe?

try adding more logging and see if you have more messages to work with

Comment by sangeetha [ 09/Feb/09 ]

I also see this happening very frequently when we disconnect intraday and then try to logon intraday

20090129-21:27:00.700: Initiated logon request
20090129-21:27:10.699: Timed out waiting for logon response
I am assuming that there is some code in quickfix which is calling disconnect without calling logout also there is no error message printed other than

20090129-14:54:58.741: Disconnecting .

My application is Initiator connection and using default logging mechanism if quickfix.





[QFJ-398] Initiator did not sent correct sequence no after Resend Request message was received Created: 02/Feb/09  Updated: 19/Dec/13  Resolved: 19/Dec/13

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

Type: Bug Priority: Default
Reporter: Honi Jain Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Windows



 Description   

Description
------------------

. At the start of the session the initiator sends a LOGOUT message with seqno 1.
. Then it send a LOGON message with seqno 1.
. Receives LOGOUT message with text - Message sequence number: 1 is less than expected sequence number: 2
. sends a LOGOUT message with seqno 3
. sends a LOGON message with seqno 4
. Receives a Resend Request with begin seqno as 2 and end seqno as 3.
. But it DID NOT sent a Sequence Reset message with seqno 2.

Please note that the above problem was observed only on a particular day and after restarting the system it was resolved. So basically every other day the initiator was sending a Sequence Reset message with seqno 2. But on a particular day it didn't sent Sequence Reset message with seqno 2.

Because of this it kept receiving Resend Request message with begin seqno as 2 and end seqno as 3. Instead of sending Sequence Reset message with seqno 2, the initiator was sending Resend Request messages. Because of which it received a LOGOUT message with text 'Maximum number of consecutive resend requests exceeded. :'. The cycle continued.






[QFJ-397] log timestamps Created: 28/Jan/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Major
Reporter: sangeetha Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I see that the in the logs the messages are not always ordered. I mean we receive an IOI, send an Order as the reponse and then receive execution report as order's response, but in logs the messages are ordered as
IOI
executio report
Order

instead of
IOI
Order
Execution report

Is there any quick way to preserve the order while logging? I am raising its priority as its little urgent for me to take some actions quickly

=Sangeetha



 Comments   
Comment by Steve Bate [ 28/Jan/09 ]

It's important to include as many details as possible so that we can help you more effectively. For example, which logger implementation are you using? Which version of QFJ? That said, I don't know of any of the bundled logger implementations that would log out of order. The messages are logged as soon as they are sent or received.

Comment by sangeetha [ 29/Jan/09 ]

Sorry for not providing the full info
The manifest file in quickfixj-core.jar is showing

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 10.0-b19 (Sun Microsystems Inc.)
Main-Class: org.quickfixj.Version
Implementation-Title: QuickFIX/J Core
Implementation-Version: $

{version}

And I am using default logging that comes with quickfix. Below is my
config file Ii used (Note I did not use TimeZone, but want to use
US/Eastern soon)

[DEFAULT]
StartTime=00:00:00
EndTime=23:59:59
FileIncludeMilliseconds=Y
FileIncludeTimeStampForMessages=Y
FileLogPath=db
FileStorePath=db
MillisecondsInTimeStamp=Y
UseDataDictionary=N
SocketTcpNoDelay=Y

#ScreenLogEvents=N
#ScreenLogShowIncoming=N
#ScreenLogShowOutgoing=N
#ScreenLogShowHeartBeats=N
PersistMessages=N

[SESSION]
ConnectionType=initiator
BeginString=FIX.4.0
SenderCompID=R005
TargetCompID=S005
SocketConnectPort=10000
SocketConnectHost=xxx
HeartBtInt=30.

Here is the snapshot of the message that got logged unordered. Where the
flow that actually happened was received IOI, sent Order and received
EXE/REJ.

IOI:
20090127-15:05:22.388: Received:
8=FIX.4.0^A9=0110^A35=6^A34=352^A49=S005^A56=R005^A52=20090127-15:05:
22^A38=500^A55=QQQQ^A54=1^A23=XLAX:5:1224149972996979^A27=0^A44=29.31^A1
0=253^A

EXE/REJ:
20090127-15:05:22.415: Received:
8=FIX.4.0^A9=0211^A35=8^A34=353^A49=S005^A56=R005^A52=20090127-15:05:
22^A32=0^A38=500^A39=0^A6=0.0^A37=XLAX:5:1224149972996979^A40=2^A11=XLAX
:5:1224149972996979^A44=29.31
A14=500^A17=1224149972996980^A55=QQQQ^A20=0^A54=2^A59=3^A150=0^A31=0.0
A151=500^A10=017^A
20090127-15:05:22.415: Received:
8=FIX.4.0^A9=0217^A35=8^A34=354^A49=S005^A56=R005^A52=20090127-15:05:
22^A32=250^A38=500^A39=1^A6=29.31^A37=XLAX:5:1224149972996979^A40=2^A11=
XLAX:5:1224149972996979^A44=29
.31^A14=250^A17=1224149972996981^A55=QQQQ^A20=0^A54=2^A59=3^A150=1^A31=2
9.31^A151=250^A10=100^A
20090127-15:05:22.416: Received:
8=FIX.4.0^A9=0209^A35=8^A34=355^A49=S005^A56=R005^A52=20090127-15:05:
22^A32=0^A38=500^A39=4^A6=0.0^A37=XLAX:5:1224149972996979^A40=2^A11=XLAX
:5:1224149972996979^A44=29.31
^A14=0^A17=1224149972996982^A55=QQQQ^A20=0^A54=2^A59=3^A150=4^A31=0.0^A1
51=500^A10=191^A

ORDER:
20090127-15:05:22.426: Sending:
8=FIX.4.0^A9=166^A35=D^A34=314^A43=N^A49=R005^A52=20090127-15:05:22^A5
6=S005^A97=N^A11=XLAX:5:1224149972996979^A21=1^A23=XLAX:5:12241499729969
79^A38=500^A40=2^A44=29.31^A54
=2^A55=QQQQ^A58=TAKEN^A59=3^A10=128^A

Thanks
=Sangeetha





[QFJ-396] Thread safe or not Created: 22/Jan/09  Updated: 22/Jan/09  Resolved: 22/Jan/09

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

Type: Other Priority: Default
Reporter: sangeetha Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Are the callback methods like onCreate() fromApp() toAdmin() etc thread safe. I am asking because I have two connections in the same application, SocketAcceptor and SocketInitiator connection.



 Comments   
Comment by Steve Bate [ 22/Jan/09 ]

The callbacks may be invoked from multiple threads and it's the callback coder's responsibility to ensure their callback code is thread safe. In other words, QFJ doesn't manage threads to avoid the need for thread-safe in the callbacks (it's doesn't make the same guarantees as a J2EE EJB container, for example). The callbacks should be thread safe even if you don't have both an acceptor and an initiator.





[QFJ-395] SenderSub ID with colon truncates log file Created: 16/Jan/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows



 Description   

Hi,

When trying to create an initiator session using QuickFix/J, I use the FileStorePath parameter in my properties file to point to a folder named "logs". Normally, a series of files would be generated upon session creation (namely, FIX.4.2-<SenderCompID><SenderSubID>-<TargetCompID><TargetSubID>.body, .event, .header, .seqnums, .session, etc.

However, the SenderSubID that I'm using is something with a colon in it, such as XFC2:XFC2. In Linux, the files still generate cleanly (i.e. -> FIX.4.2(some sendercompid)XFC2:XFC2-(some targetcompid)(some targetsubid).body, etc.). However, in Windows, only one file is truncated, and it seems to be truncated at the Colon. In other words, the only file in the directory generated is:

FIX.4.2.(somesendercompid)_XFC2

with no extensions. Can anyone help me out with this please?

Thanks,
Herman



 Comments   
Comment by Laurent Danesi [ 20/Jan/09 ]

Hi Herman,

I reproduce easily your problem but this is Windows related problem: it's not possible to create a file containing colon in it.
The colon used as separator and Windows will do ugly things like you can see.

Linux will do better job with filename containing semicolon but you will not be able to create your file too.

I think that you need to workaround your problem by extending FileStoreFactory and FileStore to create your own files with good names.

Laurent

Comment by Laurent Danesi [ 20/Jan/09 ]

Anyway, I will add some checkings in FileUtils to avoid this kind of problem by removing forbidden characters.

Laurent





[QFJ-394] SocketInitiator.stop(false) always waits sessions logoutTimeout before exit Created: 15/Jan/09  Updated: 03/Feb/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Alexey Utkin Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None


 Description   

SocketInitiator.stop(false) doesn't check sessions state. It always waits session logoutTimeout

It seems a bug in SessionConnection.waitForLogout()



 Comments   
Comment by Peter Franzen [ 03/Feb/10 ]

As far as I can tell, the problem lies in SessionConnection.waitForLogout().

If a session hasn't received its logout response when this method is entered
waitForLogout() keeps it in the local set of logged on sessions until the session's
logout timeout expires.

I noticed this problem when moving from 1.2.1 to 1.3.x, it seems to have been
introduced in version 1.3.

The solution would be to check if the session has been logged out each time
the sessions in the local logged on set are checked.

This could be achieved by changing the inner while loop in waitForLogout() to

while (sessionItr.hasNext()) {
Session session = sessionItr.next();
if (elapsed >= session.getLogoutTimeout() * 1000L) {
try

{ session.disconnect(); }

catch (IOException e)

{ log.error(e.getMessage(), e); }

}
if (!session.isLoggedOn())
sessionItr.remove();
}





[QFJ-393] When using JmxExporter, restarting QFJ Initiator throws Exception re-registering mbean Created: 13/Jan/09  Updated: 11/Feb/09  Resolved: 20/Jan/09

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.3.3
Fix Version/s: 1.4.0

Type: Bug Priority: Default
Reporter: Jerry Shea Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File jmxExporter.patch     Text File jmxExporter.patch    

 Description   

See http://sourceforge.net/mailarchive/forum.php?thread_name=ce06b7320901101754l6050baf0j888ae610bdd7bf04%40mail.gmail.com&forum_name=quickfixj-users

I am using the JmxExporter class to expose QFJ to JMX. If I attempt to
shutdown and restart my QFJ instance (my stopping then restarting my
Initiator within the same process) then I get the following exception
because QFJ tries to export to JMX again.

... ... ERROR org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter -
Failed to export connector MBean
javax.management.InstanceAlreadyExistsException:
org.quickfixj:type=Session,beginString=FIX.4.2,xxxxxxxx
at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:453)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(DefaultMBeanServerInterceptor.java:1484)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:963)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:917)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:312)
at
com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:482)
at
org.quickfixj.jmx.mbean.session.SessionJmxExporter.export(SessionJmxExporter.java:28)
at
org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter.export(ConnectorJmxExporter.java:66)
at
org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter.export(ConnectorJmxExporter.java:46)
at org.quickfixj.jmx.JmxExporter.export(JmxExporter.java:60)

Spring has a solution to this kind of thing with
MBeanRegistrationSupport.setRegistrationBehaviorName<http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/jmx/support/MBeanRegistrationSupport.html#setRegistrationBehaviorName%28java.lang.String%29>.



 Comments   
Comment by Jerry Shea [ 13/Jan/09 ]

Patch attached.
Instead of calling
mbeanServer.registerMBean(connectorAdmin, connectorName);
I have moved this functionality into JmxExporter class and added code (in fact very nearly a cut'n'paste of Spring's MBeanRegistrationSupport.doRegister method) to either blow up, ignore or re-register the mbean if there is one already there.

Patch was made against 1.3.3

Comment by Laurent Danesi [ 13/Jan/09 ]

Thank you Jerry.

I will apply you patch on trunk.

Laurent

Comment by Jerry Shea [ 13/Jan/09 ]

woops - fixed a mistake in the last patch





[QFJ-392] Session Qualifier or some other field Created: 09/Jan/09  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: sangeetha Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I want to identify each session uniquely through my own Id (not version, sender or target_comp_id combination)

I mean onCreate gives a callback with SessionId, which gives a combination of version, sender_comp_id and target_compid. sessionQualifier helped in giving my own Id, but SessionQualifier is not supported with acceptor sessions, Is there some easy way I can identify the sessions with the my own id?






[QFJ-391] Same config file and application for acceptors and initiators Created: 08/Jan/09  Updated: 17/Sep/09  Resolved: 09/Jan/09

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

Type: Other Priority: Default
Reporter: sangeetha Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Is it possble to have same config file for acceptors and initiators such that ConnectionType is overrided in the Session block and I also want the same appliction to handle all the sessions irrespective of its initiator or acceptor

When I tried I get the config error while creating SocketAcceptor.

thanks
=Sangeetha



 Comments   
Comment by Steve Bate [ 09/Jan/09 ]

> Is it possble to have same config file for acceptors and initiators such that ConnectionType is overrided in the Session block

Yes. All the settings except for ConnectionType and session ID can be put in the default settings block.

> I also want the same appliction to handle all the sessions irrespective of its initiator or acceptor

This is not supported.

Comment by Christopher Cranston [ 17/Sep/09 ]

>> I also want the same appliction to handle all the sessions irrespective of its initiator or acceptor

>This is not supported.

Steve, why is this not supported? Can you explain what you mean by this? I have defined a combination of initiators and acceptors in my quickfixj config file. When the acceptor and initiator threads start in my application then the log clearly shows the acceptors waiting for connections and the initiators attempting to initiate connections. So surely it is possible to have a single application that functions through the same quickfixj callbacks regardless of the combination of initiator and acceptor sessions?

Thanks,
Chris.





[QFJ-390] BeginString checking in case of FIX 5.0 (FIXT 1.1) Created: 07/Jan/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Baxter Solutions Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

If Logon message is sent with FIXT 1.1 BeginString then application message (with FIX 5.0 BeginString) will be dropped and the server will send Logout to the client (because incorrect BeginString).

Possible solution:
Add "!sessionID.isFIXT()" condition to Session.java, near line 749 of svn rev. 899.

public void next(Message message) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage {
...
if (!sessionID.isFIXT() && !beginString.equals(sessionID.getBeginString()))

{ throw new UnsupportedVersion(); }

...
}



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

FIX.5.0 is not a valid begin string.





[QFJ-389] DataDictionary handling in case of FIX 5.0 Created: 07/Jan/09  Updated: 27/Jul/11  Resolved: 08/Jan/09

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

Type: Bug Priority: Default
Reporter: Baxter Solutions Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

On parsing FIX 5.0 application messages there is an error, thereafter NullPointerExceptions thrown.

{{
java.lang.NullPointerException
at quickfix.DataDictionary.isHeaderField(DataDictionary.java:258)
at quickfix.Message.isHeaderField(Message.java:651)
at quickfix.Message.parseHeader(Message.java:496)
at quickfix.Message.parse(Message.java:459)
at quickfix.MessageUtils.parse(MessageUtils.java:128)
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:113)
}}

This might be because FIX 5.0 DataDictionary is used for header validation instead of FIXT 1.1.

Possible solution:
MessageUtils.java, near line 116 of svn rev. 899.
{{
...
public static Message parse(Session session, String messageString) throws InvalidMessage

{ ... DataDictionary sessionDataDictionary = ddProvider .getSessionDataDictionary((FixVersions.FIX50.equals(beginString)) ? FixVersions.BEGINSTRING_FIXT11 : beginString); ... }

}}



 Comments   
Comment by Baxter Solutions [ 07/Jan/09 ]

Well, we just misunderstood the FIX 5.0 and FIXT 1.1 specification. Sorry...

Comment by Cesar Kamoy [ 27/Jul/11 ]

Very interestingly





[QFJ-388] ApplVerID of 8 with Fixt.1.1 not supported Created: 06/Jan/09  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.4.0
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: David Abbs Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

NA


Issue Links:
Duplicate
duplicates QFJ-453 FIX 5.0 SP1 and SP2 Support Resolved

 Description   

Receiving a message with a ApplVerID of 8 results in an error. Support is needed for this value.






[QFJ-387] Unsupported Message Type Created: 31/Dec/08  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Reaz Ahmed Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

DEV



 Description   

I am very new to QuickFixJ. The problem is, When ever we a QuoteReject (msgtype="b"), our system is generating a msgtype="j" with Cauase="Unsupported Message Type". I don't understand why we are generating the message where definition for msgtype="b" and the actual message we receive matches fine.

Here is the log extract:

31-12-2008:15:15:45.586,FIX.4.4:TDSECLDNDEV->GSFXDEVPRICES:GSFXDEVPRICES: 8=FIX.4.4^A9=164^A35=b^A34=19^A49=GSFXDEVPRICES^A52=20081231-15:15:45.462^A56=TDS
ECLDNDEV^A58=You do not have permissions for the requested symbol: EUR/NZD^A131=EUR.NZD.SPOT.T^A297=5^A300=9^A10=044^A

31-12-2008:15:15:45.588,FIX.4.4:TDSECLDNDEV->GSFXDEVPRICES:GSFXDEVPRICES: Message 4 Rejected: Unsupported Message Type

31-12-2008:15:15:45.588,FIX.4.4:TDSECLDNDEV->GSFXDEVPRICES:GSFXDEVPRICES: 8=FIX.4.4^A9=113^A35=j^A34=49^A49=TDSECLDNDEV^A52=20081231-15:15:45.588^A56=GSFXD
EVPRICES^A45=4^A58=Unsupported Message Type^A372=b^A380=3^A10=173^A

Please help.

Thank you.

Reaz.



 Comments   
Comment by Brad Harvey [ 01/Jan/09 ]

It sounds like you may be using the message cracker and have not implemented the appropriate method for handling the fix 4.4 quote reject.

Comment by Reaz Ahmed [ 05/Jan/09 ]

Brad,

As I am new to FIX, could you please elaborate which method I didn't implement? On my class that extends MessageCracker and implements Application I have an implementation for public void onMessage(QuoteRequest aQuoteReqtReject, SessionID aSessionId) where I just print the message received to the log.

Is this is the method you are talking about?

thanks for your reply.

Reaz.

Comment by Brad Harvey [ 06/Jan/09 ]

Hi Reaz,

Looking in the fix44.xml data dictionary I see this:

  <message name="MassQuoteAcknowledgement" msgtype="b" msgcat="app">

So I think you'll need to override onMessage(quickfix.fix44.MassQuoteAcknowledgement message, SessionID sessionID)

Also make sure you're not calling super.onMessage.

Cheers,
Brad.





[QFJ-386] Out of memory exception on massive message intake with slow application code Created: 19/Dec/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Stelian Dumitrascu Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

All platforms



 Description   

When connected late in the day to the counterparty's fix engine, QuickFIX/J has trouble dealing with the large message backlog. An analysis of the garbage collector log reveals a large amount of objects in the tenured generation that stay alive and therefore cannot be collected.

This is owing to the fact that the linked blocking queue in the following sources:

SingleThreadedEventHandlingStrategy.java
ThreadPerSessionEventHandlingStrategy.java

has the default capacity of Integer.MAX_VALUE. The message backlog is quickly loaded onto the queue and stays there until the client software is able to process it.

Proposed fix:

Define the message queue in the above sources with a reasonable capacity, ideally configurable via session settings.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

A fixed queue length would be a problem. Would we block the entire message processing chain all the way back to the sender? Or write messages to an persistent store or ???. A better solution is to either speed up the client, increase the JVM memory or read messages into a JMS queue for later processing (as examples). QFJ is not designed specifically to handle an excessively slow consumer.





[QFJ-385] If one Session reset failed, it will cause all existed session failed Created: 17/Dec/08  Updated: 17/Dec/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Mike Gu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP



 Description   

If one SessionState reset() failed, it will throw a RuntimeError and cause all existed session failed. It's unacceptable.
public void reset() {
try

{ messageStore.reset(); }

catch (IOException e)

{ throw new RuntimeError(e); }

}






[QFJ-384] turn off Out of order repeating group members validation Created: 16/Dec/08  Updated: 25/Sep/13  Resolved: 05/Apr/10

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

Type: Improvement Priority: Major
Reporter: Andre Mermegas Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-355 Implementation of the validate field ... Closed

 Description   

I would like the ability to turn off out of order repeating roup validation that was recently added into 1.3.3 i believe.



 Comments   
Comment by Laurent Danesi [ 27/Jan/09 ]

Hi Andre,

I've committed a fix for QFJ-355.
Could you check if this fix your issue or could you provide me a small TestCase class to reproduce your problem, please?

Laurent

Comment by Jaime Romanini [ 04/Feb/09 ]

Hi Andre, Laurent.

I have the following problem in a MarketDataIncrementalRefresh

Out of order repeating group members:269

The problem is what should i do to correct this, and to be able to send the message.

Best Regards.

Jaime.

Comment by Michael Schifferdecker [ 17/Feb/09 ]

Has this fix been released as part of quickfix/j v1.4?
If so, HOW can I turn off out of order repeating group members validation?
If it is not possible to turn valiation off, can I download a release prior to v1.3.3 when this feature was added so that I can make my application work?

note:
at the moment all messages of trade capture report from ICE exchange get rejected by quickfix/j
I therefore cannot use quickfix/j for trade capture unless I can turn this feature off

example error messages:
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=73335=AE49=ICE56=334=452=20090217-11:30:01.32257=1571=45487=0856=0568=1828=017=31000000266439=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=3.031=5.09018=375=2009021760=20090217-11:16:47.632552=154=137=700036711=310000002664453=11448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=3447=D452=35448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=1637=2488.0687=3.0654=70003709019=3600=780066602=CC FMK0009!603=8608=FXXXXX624=2637=2483.0687=3.0654=70003699019=310=111)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=72835=AE49=ICE56=334=552=20090217-11:30:01.32557=1571=46487=0856=0568=1828=017=700037139=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=8.031=5.09018=875=2009021760=20090217-11:17:17.620552=154=137=700037111=310000002664453=11448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=3447=D452=35448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=1637=2488.0687=8.0654=70003749019=8600=780066602=CC FMK0009!603=8608=FXXXXX624=2637=2483.0687=8.0654=70003739019=810=151)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=70935=AE49=ICE56=334=652=20090217-11:30:01.33057=1571=47487=0856=0568=1828=017=700037539=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=6.031=5.09018=675=2009021760=20090217-11:17:52.112552=154=237=700037711=310000002668453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=6.0654=70003799019=6600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=6.0654=70003789019=610=040)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=71435=AE49=ICE56=334=752=20090217-11:30:01.33357=1571=48487=0856=0568=1828=017=31000000266439=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=3.031=5.09018=375=2009021760=20090217-11:16:47.632552=154=237=700036811=310000002665453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=3.0654=70003709019=3600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=3.0654=70003699019=310=005)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=70935=AE49=ICE56=334=852=20090217-11:30:01.33757=1571=49487=0856=0568=1828=017=700037139=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=8.031=5.09018=875=2009021760=20090217-11:17:17.620552=154=237=700037211=310000002666453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=8.0654=70003749019=8600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=8.0654=70003739019=810=047)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=47035=AE49=ICE56=334=952=20090217-11:30:01.38257=1571=50487=0856=0568=1828=017=14834612402239=2570=N55=21792048=BRN FMJ0009!22=8461=FXXXXX32=1.031=43.659018=175=2009021760=20090217-09:33:01.395552=154=237=1300020211=314000000126453=8448=db_fix_api6447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=U447=D452=54448=L609447=D452=55448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=5810=150)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=47135=AE49=ICE56=334=1052=20090217-11:30:01.38457=1571=51487=0856=0568=1828=017=14722789538639=2570=N55=21792048=BRN FMJ0009!22=8461=FXXXXX32=1.031=43.629018=175=2009021760=20090217-09:18:07.094552=154=237=1300016811=314000000124453=8448=db_fix_api6447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=U447=D452=54448=L609447=D452=55448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=5810=230)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 4 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=449=350=152=20090217-11:30:30.63956=ICE45=458=Out of order repeating group members371=687372=AE373=1510=041
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=449=350=152=20090217-11:30:30.63956=ICE45=458=Out of order repeating group members371=687372=AE373=1510=041)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 5 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=549=350=152=20090217-11:30:30.64256=ICE45=558=Out of order repeating group members371=687372=AE373=1510=037
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=549=350=152=20090217-11:30:30.64256=ICE45=558=Out of order repeating group members371=687372=AE373=1510=037)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 6 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=649=350=152=20090217-11:30:30.64456=ICE45=658=Out of order repeating group members371=687372=AE373=1510=041
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=649=350=152=20090217-11:30:30.64456=ICE45=658=Out of order repeating group members371=687372=AE373=1510=041)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=7835=AQ49=ICE56=334=1152=20090217-11:30:01.40957=1568=1569=0749=0750=110=134)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 7 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=749=350=152=20090217-11:30:30.65256=ICE45=758=Out of order repeating group members371=687372=AE373=1510=042
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=749=350=152=20090217-11:30:30.65256=ICE45=758=Out of order repeating group members371=687372=AE373=1510=042)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 8 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=849=350=152=20090217-11:30:30.65456=ICE45=858=Out of order repeating group members371=687372=AE373=1510=046
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=849=350=152=20090217-11:30:30.65456=ICE45=858=Out of order repeating group members371=687372=AE373=1510=046)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 9 Rejected: Value is incorrect (out of range) for this tag:452)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=12835=334=949=350=152=20090217-11:30:30.65756=ICE45=958=Value is incorrect (out of range) for this tag371=452372=AE373=510=192
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=12835=334=949=350=152=20090217-11:30:30.65756=ICE45=958=Value is incorrect (out of range) for this tag371=452372=AE373=510=192)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 10 Rejected: Value is incorrect (out of range) for this tag:452)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=13035=334=1049=350=152=20090217-11:30:30.65956=ICE45=1058=Value is incorrect (out of range) for this tag371=452372=AE373=510=011
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=13035=334=1049=350=152=20090217-11:30:30.65956=ICE45=1058=Value is incorrect (out of range) for this tag371=452372=AE373=510=011)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:60) - FROM APPLICATION: 8=FIX.4.49=7835=AQ34=1149=ICE52=20090217-11:30:01.40956=357=1568=1569=0749=0750=110=134

Comment by Laurent Danesi [ 17/Feb/09 ]

Hi Guys,

You can disable outOfOrderField checking by setting ValidateFieldsOutOfOrder=N.
The fix was just an extension of what Steve did on it.

The fix is committed in 1.4.0. Please let me know if it fixes your use case.

Laurent

Comment by Alvin Wang [ 05/Aug/09 ]

http://www.quickfixj.org/jira/browse/QFJ-366

Comment by Danny Liu [ 21/Dec/09 ]

Did someone fix this? I am running into the same issue here as well using 1.4.0.

I tried "ValidateFieldsOutOfOrder=N" option but it didn't help.

Comment by prakash jha [ 25/Sep/13 ]

Hi,
I am having issue while fetching TradeCaptureReport message through quickFix engine [ quickfixj-all-1.5.2.jar ] over fix from Bloomberg [ for MUNI trade ].

error:
Rejecting invalid message: quickfix.FieldException: Out of order repeating group
members, field=119

tried to resolve: by following 2 ways , but did not help
1. calling on DataDictionary dd.setCheckUnorderedGroupFields( false ) before starting fix session.
2. adding ValidateFieldsOutOfOrder=N in property/config file .

if some encountered same issue earlier , please let me know at earliest. I am getting out of solutions.

Thanks
Prakash





[QFJ-383] Add ability to infer sequence reset acknowledgement Created: 11/Dec/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.3.3, 1.4.0
Fix Version/s: 1.5.0

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 3
Labels: None

Attachments: File quickfixj-InferResetSeqNumAccepted.diff    
Issue Links:
Relates
relates to QFJ-380 Incorrect response to invalid sequenc... Closed

 Description   

This is related to the linked issue and a Cameron FIX bug.



 Comments   
Comment by Steve Bate [ 11/Dec/08 ]

In the Session logon response processing, add an configuration setting to specify that if a reset was sent but not acknowledged and the sequence number = 1 then accept the logon. This is not FIX compliant but it's more friendly than disconnecting in this situation.

Comment by Joseph Walton [ 05/Feb/09 ]

We're currently looking at changing this behaviour unconditionally, for interoperability. It would really help to see this feature added.

This is a proposed patch against the trunk to add the same behaviour behind an "InferResetSeqNumAccepted", with tests.





[QFJ-382] Foreign Language Support - Multibyte Characters - Chinese Created: 09/Dec/08  Updated: 02/Nov/15  Resolved: 09/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.6.0

Type: Improvement Priority: Default
Reporter: Jason Aubrey Assignee: amichair
Resolution: Fixed Votes: 3
Labels: encoding
Environment:

All


Attachments: Zip Archive Changes.zip    
Issue Links:
Duplicate
duplicates QFJ-38 FIX Message support double-byte charset. Closed
is duplicated by QFJ-666 FIXMessageEncoder got BufferOverflowE... Closed
Relates
relates to QFJ-789 Fully support alternate encodings (ch... Open
is related to QFJ-631 Wrong checksum calculation in "quickf... Closed
is related to QFJ-282 FIXMessageEncoder#encode() may throws... Closed

 Description   

I need QFJ to support Chinese characters. So I modified my working copy to add this functionality/tests. I could simply commit the changes but I don't have write access to the repository. I'll just post the relevant changes here for now. It'd be nice if I could simply add all the diffs as attachments to this message.

Message.java
<pre>
public String toString() {

  • header.setField(new BodyLength(bodyLength()));
    + try { + header.setField(new BodyLength(bodyLength())); + }

    catch(UnsupportedEncodingException e)

    { + LoggerFactory.getLogger(getClass()).error("toString failed, unsupported encoding", e); + return ""; + }

    trailer.setField(new CheckSum(checkSum()));

StringBuffer sb = new StringBuffer();
@@ -138,7 +145,7 @@
return sb.toString();
}

  • public int bodyLength() {
    + public int bodyLength() throws UnsupportedEncodingException { return header.calculateLength() + calculateLength() + trailer.calculateLength(); }

    </pre>

Field.java
<pre>

  • /package/ int getLength() {
    + /package/ int getLength() throws UnsupportedEncodingException { calculate(); - return data.length()+1; + return data.getBytes(CharsetSupport.getCharset()).length+1; }

    </pre>

FieldTest.java
<pre>

  • public void testFieldCalculations() {
    + public void testFieldCalculationsEnglish() throws Exception { Field<String> object = new Field<String>(12, "VALUE"); object.setObject("VALUE"); assertEquals("12=VALUE", object.toString()); @@ -63,6 +65,22 @@ assertEquals(544, object.getTotal()); assertEquals(9, object.getLength()); }
    +
    + public void testFieldCalculationsChinese() throws Exception {
    + try { + CharsetSupport.setCharset("UTF-8"); + int tag = 13; + String value = "\u6D4B\u9A8C\u6570\u636E"; + Field<String> object = new Field<String>(tag, value); + assertEquals(tag + "=" + value, object.toString()); + assertEquals(119127, object.getTotal()); + assertEquals(16, object.getLength()); + } catch(Exception e) { + throw e; + } finally { + CharsetSupport.setCharset(CharsetSupport.getDefaultCharset()); + }
    + }
    </pre>

    FIXMessageEncoder.java
    <pre>
    - public void testFieldCalculations() {
    + public void testFieldCalculationsEnglish() throws Exception { Field<String> object = new Field<String>(12, "VALUE"); object.setObject("VALUE"); assertEquals("12=VALUE", object.toString());@@ -63,6 +65,22 @@ assertEquals(544, object.getTotal()); assertEquals(9, object.getLength()); }

    +
    + public void testFieldCalculationsChinese() throws Exception

    Unknown macro: {+ try { + CharsetSupport.setCharset("UTF-8"); + int tag = 13; + String value = "\u6D4B\u9A8C\u6570\u636E"; + Field<String> object = new Field<String>(tag, value); + assertEquals(tag + "=" + value, object.toString()); + assertEquals(119127, object.getTotal()); + assertEquals(16, object.getLength()); + } catch(Exception e) { + throw e; + } finally { + CharsetSupport.setCharset(CharsetSupport.getDefaultCharset()); + }
    + }
    </pre>

    FIXMessageEncoderTest.java
    <pre>

    public void testWesternEuropeanEncoding() throws Exception {
    - // Default encoding, should work
    - doEncodingTest();
    -
    - try { - // This will break because of European characters - CharsetSupport.setCharset("US-ASCII"); - doEncodingTest(); - } catch (ComparisonFailure e) { - // expected - } finally { - CharsetSupport.setCharset(CharsetSupport.getDefaultCharset()); - }
    + // äbcfödçé
    + String input = "\u00E4bcf\u00F6d\u00E7\u00E9";
    +
    + // Default encoding, should work
    + doEncodingTest(input);
    +
    + try { + // This will break because of European characters + CharsetSupport.setCharset("US-ASCII"); + doEncodingTest(input); + } catch (ComparisonFailure e) { + // expected + } finally {+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());+ } }
  • private void doEncodingTest() throws ProtocolCodecException, UnsupportedEncodingException {
  • // äbcfödçé
  • String headline = "\u00E4bcf\u00F6d\u00E7\u00E9";
    + public void testChineseEncoding() throws Exception
    Unknown macro: {+ // "test data" in Chinese+ String input = "u6D4Bu9A8Cu6570u636E";+ + try { + // This will break because the characters cannot be represented properly + doEncodingTest(input); + } catch (ComparisonFailure e) { + // expected + }++ try { + // This should work + CharsetSupport.setCharset("UTF-8"); + doEncodingTest(input); + } finally { + CharsetSupport.setCharset(CharsetSupport.getDefaultCharset()); + }
    + }
    +
    + private void doEncodingTest(String input) throws ProtocolCodecException, UnsupportedEncodingException { News news = new News(); - news.set(new Headline(headline)); + news.set(new Headline(input)); FIXMessageEncoder encoder = new FIXMessageEncoder(); ProtocolEncoderOutputForTest encoderOut = new ProtocolEncoderOutputForTest(); encoder.encode(null, news, encoderOut); @@ -84,11 +105,24 @@ }
    }

    - public void testEncodingString() throws Exception {
    + public void testEncodingStringEnglish() throws Exception { FIXMessageEncoder encoder = new FIXMessageEncoder(); ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest(); encoder.encode(null, "abcd", protocolEncoderOutputForTest); assertEquals(4, protocolEncoderOutputForTest.buffer.limit()); }
    +
    + public void testEncodingStringChinese() throws Exception {
    + FIXMessageEncoder encoder = new FIXMessageEncoder();
    + ProtocolEncoderOutputForTest protocolEncoderOutputForTest = new ProtocolEncoderOutputForTest();
    +
    + try { + CharsetSupport.setCharset("UTF-8"); + encoder.encode(null, "\u6D4B\u9A8C\u6570\u636E", protocolEncoderOutputForTest); + } finally {+ CharsetSupport.setCharset(CharsetSupport.getDefaultCharset());+ }+ assertEquals(12, protocolEncoderOutputForTest.buffer.limit());+ }

}
</pre>



 Comments   
Comment by Jason Aubrey [ 09/Dec/08 ]

The revision number of my working copy is 892 (was head revision last week at least).

Comment by Steve Bate [ 09/Dec/08 ]

Hi Jason,

Thanks for the patches. Have you verified that the checksum calculations work with these changes? The current calculation sums characters which are assumed to be 1-byte. This assumption is made to avoid the need to transcode the message string to bytes for the purpose of calculating the checksum.

Comment by Jason Aubrey [ 09/Dec/08 ]

Hi Steve,

I think there may have been some checksum related exceptions initially when sending multibyte characters due to how the buffer was allocated (based on character counts instead of byte count). However, I didn't modify the checksum code (shown below) since it still works in the same basic way.

private int checkSum(String s) {
int offset = s.lastIndexOf("\00110=");
int sum = 0;
for (int i = 0; i < offset; i++)

{ sum += s.charAt(i); }

return (sum + 1) % 256;
}

The only difference in behavior is that each character's value can be much larger than simple ASCII values. For example in utf-8, "\u65E0\u6548\u7684\u7528" which is equivalent to "无效的用" has four characters that are each four hex digits long. So if each of these were FFFF then the sum would be 4 * FFFF = 3FFFC (262,140 in base 10). Given that the sum is stored as an integer the only risk seems to be overflow, which would occur after 2,147,483,647. With four byte character encoding, the overflow would only occur after 8,192 characters (i.e. 2,147,483,647 / 262,140 ) and this assumes each character is FFFF which it would likely not be. I don't think this is a concern though. If it were a concern, 'sum' could be stored as a larger type. I didn't give any thought to the '% 256' logic since I figured it's unique enough.

Comment by amichair [ 09/Jun/14 ]

The above analysis is incorrect, since the checksum should be performed on the encoded bytes, not the source (UTF-16) characters. btw, to avoid an overflow you can use '& 0xFF' instead of '% 256'.

In any case, this is now fixed - thanks for the patches, which helped along the way.

Currently setting a charset via CharsetSupport should work with any charset that is a superset of ASCII, which luckily is most of them.

Comment by Kou Jun [ 02/Nov/15 ]

is there any sample code to send and receive Chinese characters ?
it seems still can't process Chinese characters properly!





[QFJ-381] code doesn't work when called from insite silk performer Created: 09/Dec/08  Updated: 07/Jan/09  Resolved: 07/Jan/09

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

Type: Bug Priority: Default
Reporter: Ganeshan Guruswamy Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Windows XP



 Description   

We are facing issues while logon to QuickFix engine through SilkPerformer. The Silk script calls the java method which creates the session and tries to logon. When we execute this from command prompt it runs fine but when we try to run it from Silk Performer the program cannot logon. It was not throwing
any exceptions but sometime i saw that an hs_pid_err.log is created. Here are the contents. Any help will be appreciated.

--------------------------------------------------------------------

#

  1. An unexpected error has been detected by Java Runtime Environment:
    #
  2. EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0043e531, pid=6908, tid=6724
    #
  3. Java VM: Java HotSpot(TM) Client VM (10.0-b23 mixed mode, sharing windows-x86)
  4. Problematic frame:
  5. C [perfRun.exe+0x3e531]
    #
  6. If you would like to submit a bug report, please visit:
  7. http://java.sun.com/webapps/bugreport/crash.jsp
  8. The crash happened outside the Java Virtual Machine in native code.
  9. See problematic frame for where to report the bug.
    #

--------------- T H R E A D ---------------

Current thread (0x04180400): JavaThread "QFJ Timer" daemon [_thread_in_native, id=6724, stack(0x04df0000,0x04ef0000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x000003fc

Registers:
EAX=0x00001a44, EBX=0x2804a770, ECX=0x00000000, EDX=0x00150a78
ESP=0x04eeeaac, EBP=0x04eeeab4, ESI=0x2804a770, EDI=0x04180400
EIP=0x0043e531, EFLAGS=0x00010216

Top of Stack: (sp=0x04eeeaac)
0x04eeeaac: 00000000 04eef738 04eeeac0 00461354
0x04eeeabc: 00000000 04eef738 65508f29 04180400
0x04eeeacc: 2804a770 2804a770 00000000 00000003
0x04eeeadc: 04eeed90 7c350184 00000000 00000000
0x04eeeaec: 00000000 00000000 00000007 00000000
0x04eeeafc: 00000001 00000000 00000000 00000000
0x04eeeb0c: 00000000 00000000 00000000 00000003
0x04eeeb1c: 00000002 04eeed2a fffffffe 00000040

Instructions: (pc=0x0043e531)
0x0043e521: 8b ec 83 ec 08 89 4d f8 e8 e2 58 13 00 8b 4d f8
0x0043e531: 39 81 fc 03 00 00 74 02 eb 75 8b 4d f8 e8 2d d8

Stack: [0x04df0000,0x04ef0000], sp=0x04eeeaac, free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [perfRun.exe+0x3e531]
C [perfRun.exe+0x61354]
C [perfJavaApi.dll+0x8f29]
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::StubRoutines (1)

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::Interpreter
v ~BufferBlob::StubRoutines (1)

--------------- P R O C E S S ---------------

Java Threads: ( => current thread )
0x04144800 JavaThread "SocketConnectorIoProcessor-0.0" daemon [_thread_in_native, id=8188, stack(0x050f0000,0x051f0000)]
0x0420ac00 JavaThread "SocketConnector-0" daemon [_thread_in_native, id=5252, stack(0x04ff0000,0x050f0000)]
0x04181000 JavaThread "QFJ Message Processor" daemon [_thread_blocked, id=5624, stack(0x04ef0000,0x04ff0000)]
=>0x04180400 JavaThread "QFJ Timer" daemon [_thread_in_native, id=6724, stack(0x04df0000,0x04ef0000)]
0x0160b800 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=4748, stack(0x03e10000,0x03f10000)]
0x015fd800 JavaThread "CompilerThread0" daemon [_thread_blocked, id=3960, stack(0x03d10000,0x03e10000)]
0x015fc800 JavaThread "Attach Listener" daemon [_thread_blocked, id=7576, stack(0x03c10000,0x03d10000)]
0x015fb800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=8020, stack(0x03b10000,0x03c10000)]
0x015f7400 JavaThread "Finalizer" daemon [_thread_blocked, id=3744, stack(0x03a10000,0x03b10000)]
0x015f2c00 JavaThread "Reference Handler" daemon [_thread_blocked, id=6968, stack(0x03910000,0x03a10000)]
0x015ce800 JavaThread "main" [_thread_in_native, id=1028, stack(0x00030000,0x00130000)]

Other Threads:
0x015f1c00 VMThread [stack: 0x03810000,0x03910000] [id=8128]
0x03f28800 WatcherThread [stack: 0x04310000,0x04410000] [id=592]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
def new generation total 960K, used 650K [0x24040000, 0x24140000, 0x24520000)
eden space 896K, 69% used [0x24040000, 0x240daec8, 0x24120000)
from space 64K, 48% used [0x24130000, 0x24137c80, 0x24140000)
to space 64K, 0% used [0x24120000, 0x24120000, 0x24130000)
tenured generation total 7172K, used 6334K [0x24520000, 0x24c21000, 0x28040000)
the space 7172K, 88% used [0x24520000, 0x24b4fb58, 0x24b4fc00, 0x24c21000)
compacting perm gen total 23552K, used 23491K [0x28040000, 0x29740000, 0x2c040000)
the space 23552K, 99% used [0x28040000, 0x29730fe0, 0x29731000, 0x29740000)
ro space 8192K, 66% used [0x2c040000, 0x2c590f10, 0x2c591000, 0x2c840000)
rw space 12288K, 52% used [0x2c840000, 0x2ce906d0, 0x2ce90800, 0x2d440000)

Dynamic libraries:
0x00400000 - 0x009e3000 C:\Program Files\Borland\SilkPerformer 2008\perfRun.exe
0x7c800000 - 0x7c8c0000 C:\WINDOWS\system32\ntdll.dll
0x77e40000 - 0x77f42000 C:\WINDOWS\system32\kernel32.dll
0x71bd0000 - 0x71be1000 C:\WINDOWS\system32\MPR.dll
0x77f50000 - 0x77feb000 C:\WINDOWS\system32\ADVAPI32.dll
0x77c50000 - 0x77cef000 C:\WINDOWS\system32\RPCRT4.dll
0x76f50000 - 0x76f63000 C:\WINDOWS\system32\Secur32.dll
0x77380000 - 0x77411000 C:\WINDOWS\system32\USER32.dll
0x77c00000 - 0x77c48000 C:\WINDOWS\system32\GDI32.dll
0x71c00000 - 0x71c17000 C:\WINDOWS\system32\WS2_32.dll
0x77ba0000 - 0x77bfa000 C:\WINDOWS\system32\msvcrt.dll
0x71bf0000 - 0x71bf8000 C:\WINDOWS\system32\WS2HELP.dll
0x76920000 - 0x769e2000 C:\WINDOWS\system32\USERENV.dll
0x71c40000 - 0x71c97000 C:\WINDOWS\system32\NETAPI32.dll
0x10000000 - 0x1000a000 C:\Program Files\Borland\SilkPerformer 2008\perfEncoding.dll
0x7c3a0000 - 0x7c41b000 C:\WINDOWS\system32\MSVCP71.dll
0x7c340000 - 0x7c396000 C:\WINDOWS\system32\MSVCR71.dll
0x00320000 - 0x00343000 C:\Program Files\Borland\SilkPerformer 2008\perfZZZ.dll
0x77670000 - 0x777a9000 C:\WINDOWS\system32\ole32.dll
0x77d00000 - 0x77d8b000 C:\WINDOWS\system32\OLEAUT32.dll
0x77da0000 - 0x77df2000 C:\WINDOWS\system32\SHLWAPI.dll
0x77b90000 - 0x77b98000 C:\WINDOWS\system32\VERSION.dll
0x009f0000 - 0x00b17000 C:\Program Files\Borland\SilkPerformer 2008\LIBEAY32.dll
0x71bb0000 - 0x71bb9000 C:\WINDOWS\system32\WSOCK32.dll
0x7c8d0000 - 0x7d0cf000 C:\WINDOWS\system32\SHELL32.dll
0x71c20000 - 0x71c32000 C:\WINDOWS\system32\tsappcmp.dll
0x00370000 - 0x003a3000 C:\WINDOWS\system32\qaphooks.dll
0x77420000 - 0x77523000 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.3790.3959_x-ww_D8713E55\comctl32.dll
0x6d870000 - 0x6dac0000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\client\jvm.dll
0x76aa0000 - 0x76acd000 C:\WINDOWS\system32\WINMM.dll
0x71bc0000 - 0x71bc8000 C:\WINDOWS\system32\rdpsnd.dll
0x771f0000 - 0x77201000 C:\WINDOWS\system32\WINSTA.dll
0x76b70000 - 0x76b7b000 C:\WINDOWS\system32\PSAPI.DLL
0x6d320000 - 0x6d328000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\hpi.dll
0x6d820000 - 0x6d82c000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\verify.dll
0x6d3c0000 - 0x6d3df000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\java.dll
0x6d860000 - 0x6d86f000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\zip.dll
0x65500000 - 0x6555f000 C:\Program Files\Borland\SilkPerformer 2008\perfJavaApi.dll
0x6d620000 - 0x6d633000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\net.dll
0x71b20000 - 0x71b61000 C:\WINDOWS\System32\mswsock.dll
0x76ed0000 - 0x76efa000 C:\WINDOWS\system32\DNSAPI.dll
0x76f70000 - 0x76f77000 C:\WINDOWS\System32\winrnr.dll
0x76f10000 - 0x76f3e000 C:\WINDOWS\system32\WLDAP32.dll
0x76f80000 - 0x76f85000 C:\WINDOWS\system32\rasadhlp.dll
0x5f270000 - 0x5f2ca000 C:\WINDOWS\system32\hnetcfg.dll
0x71ae0000 - 0x71ae8000 C:\WINDOWS\System32\wshtcpip.dll
0x6d640000 - 0x6d649000 D:\Program Files\Java\jdk1.6.0_07\jre\bin\nio.dll
0x68000000 - 0x68035000 C:\WINDOWS\system32\rsaenh.dll

VM Arguments:
jvm_args: vfprintf
java_command: <unknown>
Launcher Type: generic

Environment Variables:
JAVA_HOME=D:\Program Files\Java\jdk1.6.0_07
CLASSPATH=D:\SP_TESTHAR\JARS\CTMPERF.jar;D:\SP_TESTHAR\JARS\CTMExtern.jar;D:\SP_TESTHAR\JARS\DCIWebSession1_1_6.jar;D:\SP_TESTHAR\JARS\junit.jar;D:\SP_TESTHAR\JARS\ctmExternUtil.jar;D:\SP_TESTHAR\JARS\jconn2.jar;D:\SP_TESTHAR\JARS\log4j-1.2.11.jar;D:\SP_TESTHAR\JARS\xerces.zip;D:\SP_TESTHAR\JARS\ojdbc14.jar;D:\SP_TESTHAR\JARS\commons-logging.jar;D:\SP_TESTHAR\JARS\j2ssh-core-0.2.9.jar;D:\SP_TESTHARNESS\JARS\slf4j-api-1.3.0.jar;D:\SP_TESTHARNESS\JARS\slf4j-jdk14-1.3.0.jar;D:\SP_TESTHARNESS\JARS\slf4j-log4j12-1.3.0.jar;D:\SP_TESTHARNESS\JARS\mina-core-1.1.0.jar;D:\SP_TESTHARNESS\JARS\mina-core-1.1.0-sources.jar
PATH=D:\SP_TESTHARNESS\;C:\Program Files\Borland\SilkPerformer 2008\Working\Data\;C:\Program Files\Borland\SilkPerformer 2008\Working\Custom Data\;C:\Program Files\Borland\SilkPerformer 2008\;C:\sybase\JS-12_5\bin;C:\sybase\OCS-12_5\dll;C:\sybase\OCS-12_5\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\tools\macros;D:\Program Files\Java\jdk1.6.0_07\bin;C:\Program Files\MySQL\MySQL Server 4.1\bin;C:\Tools\ant165\bin;04EEE5F0ath;DCIDIR\lib;TUXDIR\bin;DCIDIR\include;6DA5D4A0ERCESROOT\bin
USERNAME=qametric2
OS=Windows_NT
PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 1, GenuineIntel

--------------- S Y S T E M ---------------

OS: Windows Server 2003 family Build 3790 Service Pack 2

CPU:total 2 (1 cores per cpu, 2 threads per core) family 15 model 4 stepping 1, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ht

Memory: 4k page, physical 2097151k(2097151k free), swap 4194303k(4194303k free)

vm_info: Java HotSpot(TM) Client VM (10.0-b23) for windows-x86 JRE (1.6.0_07-b06), built on Jun 10 2008 01:14:11 by "java_re" with MS VC++ 7.1

time: Fri Dec 05 11:10:34 2008
elapsed time: 8 seconds



 Comments   
Comment by Steve Bate [ 09/Dec/08 ]

There is really no way for us to know what's happening inside of SilkPerformer. I assume you have paid support for SilkPerformer. Have you contacted Borland about this issue? Paid support for QuickFIX/J is also available if you are interested. It's possible we could get an evaluation copy of SilkPerformer and try to diagnose your specific integration issue.





[QFJ-380] Incorrect response to invalid sequence reset acknowledgment Created: 09/Dec/08  Updated: 05/Apr/10  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0, 1.3.1, 1.3.2, 1.3.3
Fix Version/s: 1.4.0

Type: Bug Priority: Default
Reporter: Nataraj Dasgupta Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

All environments. Clients using Java Sample Code provided by QuickFIX


Issue Links:
Relates
is related to QFJ-383 Add ability to infer sequence reset a... Closed

 Description   

Hi,

We work on a number of FIX implementation where users connect to us using the QuickFIX FIX engine. Ours us a Cameron Engine. We offer 2 sessions - an Order Session and a MKD Session for each user.

We have been observing issues lately with Logon sessions with 141=Y at initial startup. There are 2 different issues we have observed that we need to attend urgently. We have worked numerous possibilities including modifying Configuration settings, but to no avail. Also, it is not viable for us to request all QuickFIX users to modify the source.

1) Client sends Logon with 141=Y with MsgSeqNum=1. Cameron replies with Logon Acnowledgment but without 141=Y and SeqNum=1. QuickFIX is unable to handle the Logon Acknowledgment with missing 141 Tag. QuickFIX assumes that the initial Logon was not acknowledged and sends a second Logon with SeqNum 2. Cameron sees a duplicate Logon request (whilst already connected) and rejects the Logon message. At this point, although both systems are connected, the Engine goes into a strange state and certain procedures such as MKD requests begin failing.

2) Client sends Logon with 141=Y. Cameron sends Logon Acknowledgment without 141=Y and SeqNum=1. QuickFIX assumes that no Logon Acknowledgement was received. QuickFIX then sends the following message, for eg., a TestRequest or Heartbeat with SeqNum=1. Cameron sees MesgSeqNum lower than the expected SeqNum of 2 and terminates the session.

Thanks. Nataraj.



 Comments   
Comment by Nataraj Dasgupta [ 09/Dec/08 ]

I should add that we have observed this behaviour with FIX 4.3.

Comment by Steve Bate [ 09/Dec/08 ]

You mention QuickFIX several time in your issue rather than QuickFIX/J which is a completely different implementation. Are you sure the issue is with QuickFIX/J (the Java implementation of the C++ QuickFIX)?

Comment by Steve Bate [ 09/Dec/08 ]

I've found the code related to this behavior and there are a couple of issues. First, it appears that Cameron FIX is behaving in a nonstandard way. According to the FIX spec (FIX 4.4, but I'm assuming it's the same in FIX 4.3):

" ... the initiator should send a Logon with ResetSeqNumFlag set to Y and with MsgSeqNum of 1. The acceptor
should respond with a Logon with ResetSeqNumFlag set to Y and with MsgSeqNum of 1. At this point
new messages from either side should continue with MsgSeqNum of 2. It should be noted that once the
initiator sends the Logon with the ResetSeqNumFlag set, the acceptor must obey this request and the
message with the last sequence number transmitted "yesterday" may no longer be available. The
connection should be shutdown and manual intervention taken if this process is initiated but not followed
properly."

Therefore, QFJ is also not behaving according to the spec. If the 141=Y value is not in the response logon message, we should drop the connection. Sending another logon is clearly incorrect behavior. However, my guess is that you'd like QFJ to accomodate the nonstandard Cameron behavior. Have you spoken to the vendor about this issue?

Comment by Nataraj Dasgupta [ 09/Dec/08 ]

Hi Steve,

Thanks for your reply. It is QuickFIX/J. Regarding the requirement to send 141 in acnowledgment if Logon has 141=Y, as per the FIX specs, is a requirement IF the logon is performed while already connected to maintain 24 hr. connectivity. The FIX specs however does not have specs for Logon Acknowledgment for the Intial Logon, ...

I'd think that this would happen for other clients too who are using the sample code to connect Cameron-QFJ and trying reset at logon ...

Thanks. Nataraj.

Comment by Nataraj Dasgupta [ 10/Dec/08 ]

Hi,

Could someone from the QF/J dev group please comment on the issue. This has been also discussed on the fixprotocol site and it is deemed that this is a potential bug in QF/J and needs to be resolved. I'd imagine that this would involve minimal code change and can be deployed soon,

Thanks. Nataraj.

Comment by Steve Bate [ 11/Dec/08 ]

I'll modify the code to disconnect in this scenario. I'll also add an feature request to add the ability to optionally infer that the reset was successful if the response logon has a sequence number of 1.

Comment by Steve Bate [ 11/Dec/08 ]

A logon with 141=Y is, by definition, always an initial login of a session.

I've responded to the comments on the FPL site. Once again, I suggest you submit a bug report to Orc Software. The root problem is with Cameron FIX. The change I have made makes QFJ response compliant with the spec but does NOT solve your problem in general. All QFJ users not upgrade immediately and the Cameron FIX behavior may cause problems with other FIX engine implementations. You need to get a patched version of Cameron FIX or modify it to respond properly to the sequence reset. Those are the only safe solutions on your end.

Comment by Nataraj Dasgupta [ 12/Dec/08 ]


Ah, Hi Steve, didn't realize you were from QFJ dev ! Sure, we can talk with Orc Software as you have pointed out. In the meantime, could you also please give me an estimate of when the updated code will be released, so that we can inform users who are currently experiencing this issue. Thanks ! - Raj.

Comment by Nataraj Dasgupta [ 14/Jan/09 ]

Hi Steve,

I am told that with the new changes, the application is still trying to reconnect. The following is the behaviour

"When quickfixj tries to connect with 141=Y and if in response there is no 141=Y, application disconnects and try to connect again. This cycle continues."

Could you please comment,

Thanks,

  • Nataraj.




[QFJ-379] Sequence number reset wipes out any pending queued messages Created: 02/Dec/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Major
Reporter: JamesM Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

QuickFIX 1.3.2



 Description   

It seems that if we should receive a sequence reset while QuickFIX is processing queued messages, those queued messages may not be processed correctly. Is this the case?

Here are log file extracts demonstrating this case. This shows a FIX-level failover between ourselves and a FIX 4.1 counterparty; we have broken the connection while receiving messages, failed over, and restored state from the message store.

Mon Dec 01 14:15:01 JST 2008 MsgSeqNum too high, expecting 1147 but received 1285
Mon Dec 01 14:15:01 JST 2008 Sent ResendRequest FROM: 1147 TO: 999999

[Here, we notice that we have just received message 1285, but we wanted 1147, because that was the extent of our processing. We ask for a resend.]

Mon Dec 01 14:15:01 JST 2008 Received ResendRequest FROM: 2 TO: 999999

[Our counterparty doesn't keep track of our messages after a failover and asks us to send everything again. We do it.]

Mon Dec 01 14:15:05 JST 2008 MsgSeqNum too high, expecting 1286 but received 1288
Mon Dec 01 14:15:05 JST 2008 Sent ResendRequest FROM: 1286 TO: 999999
Mon Dec 01 14:15:05 JST 2008 MsgSeqNum too high, expecting 1286 but received 1289
Mon Dec 01 14:15:05 JST 2008 Already sent ResendRequest FROM: 1286 TO: 1287. Not sending another.
Mon Dec 01 14:15:05 JST 2008 MsgSeqNum too high, expecting 1286 but received 1290
Mon Dec 01 14:15:05 JST 2008 Already sent ResendRequest FROM: 1286 TO: 1287. Not sending another.

[They keep sending us new messages. We queue them up].

Mon Dec 01 14:16:32 JST 2008 Received SequenceReset FROM: 1286 TO: 1744

[They send us a sequence reset, the FIX sequence number of which is 1743].

Mon Dec 01 14:16:32 JST 2008 Processing queued message: 1744, pending: [1288, 1289, 1290, ..., 1999]
Mon Dec 01 14:16:32 JST 2008 Processing queued message: 1745, pending: [1288, 1289, 1290, ..., 1999]
Mon Dec 01 14:16:32 JST 2008 Processing queued message: 1746, pending: [1288, 1289, 1290, ..., 1999]

[We start processing the queued messages. But the strange thing is that we start from 1744, and not 1288.

Mon Dec 01 14:16:35 JST 2008 Processing queued message: 1999, pending: [1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637, 1638, 1639, 1640, 1641, 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671, 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1700, 1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, 1743]

[We get to the end, and are missing all of the messages in the brackets].

Is this the appropriate behaviour? Should QuickFIX burn off messages in the queue if it receives a sequence number reset? In this case it would have been better for us if we had ignored it, since we would not have lost messages from the counterparty. We are investigating why the counterparty sent us this reset message, but since we cannot ask them to change their system, we might have to find some way of working around it.

What I suspect is happening is that the counterparty doesn't support resend requests at all and is just resetting our sequence number - but since this is the first time I've seen this behaviour, I want to make sure that the queue logic is correct in this case. It just seems strange to process it this way - normally, the messages that I have seen are 'processing message 2, remaining [3, 4, 5]': ie: the item being processed always has a sequence number that is lower than the other items in the queue.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

If a sequence reset moves the sequence number forwards, the messages in the "gap" are no longer considered valid (or needed due to the explicit request to skip those sequence numbers) and this is consistent with the spec. It's certainly a dangerous thing for a counterparty to do. You might consider intercepting and rejecting the sequence reset.





[QFJ-378] SessionSchedule incorrectly handles Daylight Savings timezone change Created: 26/Nov/08  Updated: 02/Apr/15  Resolved: 05/Nov/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: Valery Trubnikov Assignee: Christoph John
Resolution: Fixed Votes: 11
Labels: None

Attachments: File sched.diff    

 Description   

This is a follow up for a recent issue we had with our production system.
Few days after daylight switch in USA (which happened to be on November 2nd 2008) our system disconnected one hour early from the exchange.
Here is a little test case to illustrate:

public void testSettingsWithStartEndDayWithDST() throws Exception

{ SessionSettings settings = new SessionSettings(); settings.setString(Session.SETTING_TIMEZONE, "America/New_York"); settings.setString(Session.SETTING_START_DAY, DayConverter.toString(Calendar.SUNDAY)); settings.setString(Session.SETTING_START_TIME, "20:00:00"); settings.setString(Session.SETTING_END_DAY, DayConverter.toString(Calendar.FRIDAY)); settings.setString(Session.SETTING_END_TIME, "17:00:00"); // mockSystemTimeSource.setTime(getTimeStamp(2008, Calendar.NOVEMBER, 2, 18, 0, 0, // TimeZone.getTimeZone("America/New_York"))); SessionID sessionID = new SessionID("FIX.4.2", "SENDER", "TARGET"); SessionSchedule schedule = new SessionSchedule(settings, sessionID); System.out.println(schedule); //November,2 -> Sunday doIsSessionTimeTest(schedule, true, 2008, Calendar.NOVEMBER, 2, 20, 0, 0, TimeZone.getTimeZone("America/New_York")); //November,7 -> Friday doIsSessionTimeTest(schedule, true, 2008, Calendar.NOVEMBER, 7, 17, 0, 0, TimeZone.getTimeZone("America/New_York")); }

*All times below are New York times.

For the sake of the example, our system starts every Sunday at 18:00 while actual trading starts (again every Sunday) at 20:00. Trading ends next Friday at 17:00. So, if you run the test as it is, it passes.
But if you uncomment "mockSystemTimeSource.setTime" the test fails, exactly for the same reason why our system shutdown trading one hour early.

The problem is with the way SessionSchedule converts END_* configuration into actual time point. Sunday November 2nd and Monday November 7th are both EST (winter time), BUT SessionSchedule actually goes back to previous Monday (October 27) which is still EDT (summer time) and thus converts to UTC incorrectly with 1 hour shift.



 Comments   
Comment by Valery Trubnikov [ 26/Nov/08 ]

As a sidenote - the problem seems to be even more complex for systems that do not go down every week but instead rely on quickfixj to handle trading start/stop.
If such system is configured with America/New_York timezone (or any other DST-aware tz), start/stop times in SessionSchedule will be incorrect after DST switch, because they are only calculated upon program start.

Comment by Mehul Patel [ 17/Nov/10 ]

This seems to be happening in 1.4 too.

Comment by Simon Wichtermann [ 06/Dec/12 ]

Here a diff/patch that should solve the incorrect daylight saving time change handling. (Changes in SessionSchedule, dep. on rev. 1008 and SessionScheduleTest, dep. on rev. 889)
It passes all unit tests in SessionScheduleTest, including some own additional tests and the tests of Valery Trubnikov.
But so far I could not test it "in real life" in my own environment (not beeing allowed to change system date/time). So there is no guarantee yet.
Hopefully someone else can test it soon...

Comment by Jörg Thönnes [ 16/Jul/13 ]

Thanks for the patch and the extensive test case.
Recent postings on the mailing list brought my attention to this bug.

Comment by tomi [ 29/Oct/13 ]

We have also been affected by this issue. Our current solution is to restart the system... twice per year. It is quite annoying as we are only allowed restarts on a weekend, so this will happen for a whole week until next Sunday.

Would be good to get fixed.

Comment by Tommy Hannon [ 05/Nov/13 ]

We also had to restart our applications yesterday, on Sunday, to avoid problems today.

Comment by Jon Beyer [ 05/Nov/13 ]

Also experienced this nasty bug today. Our application typically runs 24/7, and allows QFJ to bring the session up and down. But we did a rare restart this morning, and QFJ seemed to lose all sense of the session state. It was not easy to get back in sync with the acceptor.

Comment by tomi [ 05/Nov/13 ]

Hi Jon, just to help you out: you might need to set 'RefreshOnLogon=Y' in your config to have the session state working correctly on restart.

Comment by Christoph John [ 05/Nov/13 ]

Committed as rev1115. http://sourceforge.net/p/quickfixj/code/1115/
Thanks to Simon Wichtermann for the patch.





[QFJ-377] FIXT 1.1 / FIX 5.x Support Created: 26/Nov/08  Updated: 11/Feb/09  Resolved: 26/Nov/08

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None





[QFJ-376] When a lot of bad data is pumped into the QF/J, it does nothing Created: 25/Nov/08  Updated: 11/Feb/09  Resolved: 26/Nov/08

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

Type: Bug Priority: Default
Reporter: aleksey ratushnyy Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Setup: QuickFix/J acceptor listening on a port.

Test case: connect to the port on which the acceptor is listening via telnet and pump the data from /dev/zero (telnet HOST PORT < /dev/zero & )

What happens?
The server is DOS'ed into an eventual OutOfMemoryError

Why?
In MINA,
org.apache.mina.filter.codec.CumulativeProtocolDecoder.decode() accumulates the data in a session buffer until it is processed.
org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory.ProtocolDecoderImpl.doDecode() is called to process the data.
It calls org.apache.mina.filter.codec.demux.MessageDecoder.decodable() method to identify which protocol to use.

In QuickFix/J,
quickfix.mina.message.FIXMessageDecoder.decodable() keeps iterating over and over again over ever increasing ByteBuffer, and keeps returning MessageDecoderResult.NEED_DATA.

What I think should be done to fix it:
quickfix.mina.message.FIXMessageDecoder.decodable() should instead return MessageDecoderResult.NOT_OK after the length of the unprocessed data grows beyond certain reasonable length comparable with the HEADER_PATTERN's potential max length. This would cause MINA to throw ProtocolDecoderException and the connection to be shut down.






[QFJ-375] Could you please make the 2.4 heartbeat timeout configurable? Created: 24/Nov/08  Updated: 17/Jun/20  Resolved: 20/May/20

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

Type: Improvement Priority: Default
Reporter: aleksey ratushnyy Assignee: Marcin L
Resolution: Fixed Votes: 0
Labels: None


 Description   

The heartbeat timeout coefficient of 2.4 is currently hardcoded in

{quickfix.SessionState.isTimedOut()}

method.

Could you please make this number configurable with 0 = no timeout?






[QFJ-374] ValidateFieldsHaveValues=N does not work for enum fields Created: 20/Nov/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Our counterparty sent us a FIX msg with '865='. Our QFJ rejected (SessionRejectReason(373)=6(INCORRECT_DATA_FORMAT_FOR_VALUE)), even though we have set ValidateFieldsHaveValues=N. I wonder if it does not work for enum fields?



 Comments   
Comment by Alvin Wang [ 25/Nov/08 ]

i found even if i change 865 to be a non-enum fields in dictionary, i still have the rejection. Then i changed its type from int to String, it seems it is ok now. so it seems the bug is that ValidateFieldsHaveValues=N does not work for int (or non-String data types), which is not directly related to enum

Comment by Steve Bate [ 26/Nov/08 ]

This should work. Do you have a JUnit test case to demonstrate the problem?

Comment by Alvin Wang [ 26/Nov/08 ]

Sorry I do not have one. It just happens in production and I've already set ValidateFieldsHaveValues=N and i thought it would forgive it anyhow.
maybe the DATA FORMAT validation happens before FieldsHaveValues validation?
thanks

Comment by Steve Bate [ 05/Apr/10 ]

Actually, ValidateFieldsHaveValues controls whether QFJ allows empty field values. It is not related to enum validation.

Comment by Alvin Wang [ 15/Nov/12 ]

but "865=" is empty value





[QFJ-373] Add a new validation configruation to bypass the data type check Created: 20/Nov/08  Updated: 26/Nov/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Default
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Comments   
Comment by Steve Bate [ 26/Nov/08 ]

Can you be more specific about what you want in this feature? Thanks.

Comment by Alvin Wang [ 26/Nov/08 ]

For example, if there is a configuration called ValidateDateType=N in the configuration file, my QFJ server will not reject a message in which there is "867=100,0" rather than "867=100.0" because I do not care about tag 867.

thanks.





[QFJ-372] Creating Custom Groups Created: 20/Nov/08  Updated: 20/Mar/11  Resolved: 20/Mar/11

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,

I would like to know how to read a non-standard group type from messages (in other words, a group not defined via FIX standard).

The group starts with tag 552 (NoSides), and proceeds with tags 54, 37, 11, 453 (NoPartyIDs, which is a sub group), and 58.
Sub group 453 contains tags 448 and 452. All I'm really concerned about is getting tag 54 from the message. As a result, I
am creating a separate class that extends the Group interface as follows:

public class NoSides extends quickfix.Group {

public NoSides()

{ super(552,54); }

}

Where, if I'm reading the documentation correctly, 552 should specify the number field of the group (NoSides), and 54 should
indicate the next field tag. However, I'm a bit confused about how to extract the Side field (field 54) from the message once I get it. I am currently
using the following code:

NoSides group = new NoSides();
StringField sidefield = new StringField(54);
System.out.println(message.getGroup(1, group).getField(sidefield).getValue());

But I don't think that that is working correctly. Any advice?

Thanks,
Herman



 Comments   
Comment by Steve Bate [ 26/Nov/08 ]

What kind of problem are you having?





[QFJ-371] fromApp method causes message reject with "Conditionally required field missing" Created: 13/Nov/08  Updated: 15/Nov/12  Resolved: 13/Nov/08

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

FIX 4.2



 Description   

Hi,

I have a fromapp method defined as follows in QuickFix/J:

// Method to determine messages that we receive from the FIX Exchange (Non-administrator class messages)
public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType

{ MsgType mtype = new MsgType(); System.out.println(message.getField(mtype).getValue()); }

When I receive a specific message, though, I send out a reject with text "Conditionally Required Field Missing":

8=FIX.4.2 9=81 35=AQ 49=FLOB 56=6000 34=54 52=20081113-13:39:41.629 57=1 568=1 569=0 749=0 750=0 10=053

8=FIX.4.2 9=115 35=j 34=54 49=6000 50=1 52=20081113-13:39:40.420 56=FLOB 45=54 58=Conditionally Required Field Missing 372=AQ 380=5 10=213

I have also tried:

// Method to determine messages that we receive from the FIX Exchange (Non-administrator class messages)
public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType

{ StringField msgtypefield = new StringField(35); message.getField(msgtypefield); }

And I send out the same reject. When I leave the fromApp method blank, then I don't reject the messages (indicating that my data dictionary settings are fine). Also, I've checked in my Data Dictionary, and I have set all fields that I'm getting in the message (except for the header and trailer) to "N". Any help would be appreciated.

Thanks and regards,
Herman



 Comments   
Comment by Laurent Danesi [ 13/Nov/08 ]

Hi Herman,

If I well understand, you want to reject a specific message with the raeson: "Conditionally Required Field Missing".

If it is, in fact, the simplest way is to throw an exception in the fromApp callback like:

// Method to determine messages that we receive from the FIX Exchange (Non-administrator class messages)
public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType
{
MsgType mtype = new MsgType();
System.out.println(message.getField(mtype).getValue());
if (mtype.equals(MsgType.TRADE_CAPTURE_REPORT_REQUEST_ACK && ...) throw new FieldNotFound("Conditionally Required Field Missing");
}

Laurent

Comment by Laurent Danesi [ 13/Nov/08 ]

Sorry but FieldNotFound need the field id but you can use another exception and put your reason like new MissingField("my reason");

Laurent

Comment by Herman Hung [ 13/Nov/08 ]

Hi...actually, I figured out the issue. I was trying to grab the MsgType from the message itself, not the message header, hence why I was rejecting the message. This issue can now be closed.

Comment by Toli Kuznets [ 13/Nov/08 ]

Herman,

The MsgType (tag 35) field lives in the header and not the body of the FIX message.
To access it correctly you need to do msg.getHeader().getField(MsgType.FIELD)

that'll solve your problem. the reason you are seeing the error is that when you do msg.getField(MsgType.FIELD), it throws a FieldNotFoundException which in turn comes back as a "Conditionally Required Field Missing" b/c the assumption in QFJ is that you are accessing a field that should be there.

hope this helps





[QFJ-370] Sending two logon messages when I only mean to send one? Created: 12/Nov/08  Updated: 26/Nov/08  Resolved: 26/Nov/08

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,

I have a FIX initiator that implements the Application interface, and uses the code below to log on to sessions. I connect just fine...however, I've noticed that I keep sending two logon messages instead of just one. Is there something that I am doing incorrectly?

[code]
// Method to determine messages that we send to the FIX Exchange (Administrator class messages)
public void toAdmin(Message message, SessionID sessionId)
{
if(isMessageOfType(message, MsgType.LOGON) && (loginsent == false))
{
loginsent = true;

// Get information from properties
String user = "user";
String password = "password";
UserNameField usefield = new UserNameField(user);
PasswordField passfield = new PasswordField(password);

// Set Message References
Message msgToMod = message;
msgToMod.setField(usefield);
msgToMod.setField(passfield);

// Send Message
try

{ Session.sendToTarget(msgToMod,sessionId); }

catch(Exception ex)

{ System.out.println("SESSION NOT FOUND!"); ex.printStackTrace(); }

}
}
[/code]

Thanks and regards,
hhung



 Comments   
Comment by Herman Hung [ 12/Nov/08 ]

Also, I am using FIX4.2. The code for the "isMessageOfType" method is:

private boolean isMessageOfType(Message message, String type) {
try

{ return type.equals(message.getHeader().getField(new MsgType()).getValue()); }

catch (FieldNotFound e)

{ e.printStackTrace(); return false; }

}

Thanks.

Comment by Laurent Danesi [ 12/Nov/08 ]

Hi Herman,

Your code seems ok but you don't need to send the message after added the username and password. The callback toAdmin is just an interceptor while sending the message.

So just try this:

[code]
// Method to determine messages that we send to the FIX Exchange (Administrator class messages)
public void toAdmin(Message message, SessionID sessionId)
{
if(isMessageOfType(message, MsgType.LOGON) && (loginsent == false))
{
loginsent = true;

// Get information from properties
String user = "user";
String password = "password";
UserNameField usefield = new UserNameField(user);
PasswordField passfield = new PasswordField(password);

// Set Message References
message.setField(usefield);
message.setField(passfield);
}
[/code]

Comment by Herman Hung [ 12/Nov/08 ]

That worked wonders...thanks for your help!

Regards,
Herman

Comment by Laurent Danesi [ 12/Nov/08 ]

You are welcome.

Laurent

Comment by Herman Hung [ 13/Nov/08 ]

This issue is resolved and can now be closed.

Regards,
Herman





[QFJ-369] Send too many logout messages when continuely received messages which has BadTime or doBadCompID Created: 06/Nov/08  Updated: 06/Nov/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Mike Gu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows XP



 Description   

Send too many logout messages when continuely received messages which has BadTime or doBadCompID.
Session.java
private void doBadCompID(Message msg) throws IOException, FieldNotFound

{ generateReject(msg, SessionRejectReason.COMPID_PROBLEM, 0); generateLogout("Bad CompID"); }

private void doBadTime(Message msg) throws IOException, FieldNotFound

{ generateReject(msg, SessionRejectReason.SENDINGTIME_ACCURACY_PROBLEM, 0); generateLogout(); }

Before Send a logout message, should check the session statues. isLogoutSent()

private void doBadCompID(Message msg) throws IOException, FieldNotFound

{ generateReject(msg, SessionRejectReason.COMPID_PROBLEM, 0); if (!state.isLogoutSent()) generateLogout("Bad CompID"); }

private void doBadTime(Message msg) throws IOException, FieldNotFound

{ generateReject(msg, SessionRejectReason.SENDINGTIME_ACCURACY_PROBLEM, 0); if (!state.isLogoutSent()) generateLogout(); }




[QFJ-368] removeGroup causes BodyLength miscalculation Created: 04/Nov/08  Updated: 11/Feb/09  Resolved: 26/Nov/08

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

Type: Bug Priority: Critical
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

I was trying to retrieve NoPartyIDs group from an Execution Report, and remove NoPartySubIDs group from the NoPartyIDs group, and then add the NoPartyIDs group to an Allocation Instruction . At this point, I suspect there is a bug in the library (removing subgroup from a group and adding that group to a message), because the BodyLength(9) in the message (Allocation Instruction) is wrong (greater than the correct number). My counterparty disconnected the session due to this error and then my FIX server resent the message with PossDupFlag(43)=Y after reconnection, then the BodyLength is correct in the resent message.

Looking at the removeGroup in FieldMap.java, I wonder if it should adjust the group count?

thanks.

public void removeGroup(int field)

{ getGroups(field).clear(); removeField(field); }

 Comments   
Comment by Alvin Wang [ 05/Nov/08 ]

here is the bug fix:

public void removeGroup(int field)

{ getGroups(field).clear(); groups.remove(field); removeField(field); }




[QFJ-367] A validation configuration to bypass checking of enumeration for a tag Created: 04/Nov/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: New Feature Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Won't Fix Votes: 1
Labels: None


 Description   

If received msg contains a custom enum value for a tag, QFJ will reject it saying "Value is incorrect (out of range) for this tag".



 Comments   
Comment by Toli Kuznets [ 04/Nov/08 ]

Wasn't this addressed by QFJ-288 ?
I can't seem to remember the syntax for the open-ended enum though, and I can't find any documentation for it.

Comment by Alvin Wang [ 04/Nov/08 ]

what do you mean "syntax"? a validation switch in the configruation file?

Comment by Laurent Danesi [ 05/Nov/08 ]

Hi Alvin,

Do you want to have a field containing an enum with a fixed number of values or an open-ended enum (with unknown number of values)?

Laurent

Comment by Alvin Wang [ 05/Nov/08 ]

Laurent, I want have a field containing an enum with a fixed number of values, but meanwhile I want QFJ have a validation switch that can bypass the checking of the valid value of that field to avoid "Value is incorrect (out of range) for this tag" rejection.
thanks

Comment by Steve Bate [ 05/Apr/10 ]

You can specify an "allowOtherValues" attribute in the data dictionary for the enumeration element. Perhaps we should consider supporting this is a session configuration?

Comment by Alvin Wang [ 15/Nov/12 ]

yes, it would be very helpful to have a session configuration!





[QFJ-366] ValidateFieldsOutOfOrder cannot handle Out of order repeating group members Created: 02/Nov/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Improvement Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None





[QFJ-365] Missing values for PartyRole in FIX44.xml Created: 31/Oct/08  Updated: 05/Apr/10  Resolved: 05/Apr/10

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

Type: Bug Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

it seems FIX44.xml has less valid values for PartyRole than FIX Spec. It only has 1-9, but spec has 1-38

Identifies the type or role of the PartyID (448) specified.
See "Appendix 6-G - Use of <Parties> Component Block"
Valid values:
1 = Executing Firm (formerly FIX 4.2 ExecBroker)
2 = Broker of Credit (formerly FIX 4.2 BrokerOfCredit)
3 = Client ID (formerly FIX 4.2 ClientID)
4 = Clearing Firm (formerly FIX 4.2 ClearingFirm)
5 = Investor ID
6 = Introducing Firm
7 = Entering Firm
8 = Locate/Lending Firm (for short-sales)
9 = Fund manager Client ID (for CIV)
10 = Settlement Location (formerly FIX 4.2 SettlLocation)
11 = Order Origination Trader (associated with Order Origination Firm - e.g. trader who initiates/submits the order)
12 = Executing Trader (associated with Executing Firm - actually executes)
13 = Order Origination Firm (e.g. buyside firm)
14 = Giveup Clearing Firm (firm to which trade is given up)
15 = Correspondant Clearing Firm
16 = Executing System
17 = Contra Firm
18 = Contra Clearing Firm
19 = Sponsoring Firm
20 = Underlying Contra Firm (...values continued in next row....)
20 = Underlying Contra Firm
21 = Clearing Organization
22 = Exchange
24 = Customer Account
25 = Correspondent Clearing Organization
26 = Correspondent Broker
27 = Buyer/Seller (Receiver/Deliverer)
28 = Custodian
29 = Intermediary
30 = Agent
31 = Sub custodian
32 = Beneficiary
33 = Interested party
34 = Regulatory body
35 = Liquidity provider
36 = Entering Trader
37 = Contra Trader
38 = Position Account
(see Volume 1: "Glossary" for value definitions)



 Comments   
Comment by Alvin Wang [ 31/Oct/08 ]

sorry.. In 1.3.3 it has been fixed. pls close this issue.





[QFJ-364] NoLegs, NoUnderlyings, and NoCapacities groups in Confirmation message in FIX44.xml should not be required Created: 31/Oct/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

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


 Description   

I found NoLegs group in Confirmation message in FIX44.xml (QFJ 1.3.3) is required. But it is not required according to the FIX spec. Same happens for NoUnderlyings and NoCapacities.

<message name="Confirmation" msgtype="AK" msgcat="app">
<field name="ConfirmID" required="Y"/>
<field name="ConfirmRefID" required="N"/>
<field name="ConfirmReqID" required="N"/>
<field name="ConfirmTransType" required="Y"/>
<field name="ConfirmType" required="Y"/>
<field name="CopyMsgIndicator" required="N"/>
<field name="LegalConfirm" required="N"/>
<field name="ConfirmStatus" required="Y"/>
<component name="Parties" required="N"/>
<group name="NoOrders" required="N">
<field name="ClOrdID" required="N"/>
<field name="OrderID" required="N"/>
<field name="SecondaryOrderID" required="N"/>
<field name="SecondaryClOrdID" required="N"/>
<field name="ListID" required="N"/>
<component name="NestedParties2" required="N"/>
<field name="OrderQty" required="N"/>
<field name="OrderAvgPx" required="N"/>
<field name="OrderBookingQty" required="N"/>
</group>
<field name="AllocID" required="N"/>
<field name="SecondaryAllocID" required="N"/>
<field name="IndividualAllocID" required="N"/>
<field name="TransactTime" required="Y"/>
<field name="TradeDate" required="Y"/>
<component name="TrdRegTimestamps" required="N"/>
<component name="Instrument" required="Y"/>
<component name="InstrumentExtension" required="N"/>
<component name="FinancingDetails" required="N"/>
<group name="NoUnderlyings" required="Y">
<component name="UnderlyingInstrument" required="N"/>
</group>
<group name="NoLegs" required="Y">
<component name="InstrumentLeg" required="N"/>
</group>
<component name="YieldData" required="N"/>
<field name="AllocQty" required="Y"/>
<field name="QtyType" required="N"/>
<field name="Side" required="Y"/>
<field name="Currency" required="N"/>
<field name="LastMkt" required="N"/>
<group name="NoCapacities" required="Y">
<field name="OrderCapacity" required="Y"/>
<field name="OrderRestrictions" required="N"/>
<field name="OrderCapacityQty" required="Y"/>
</group>



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

In the FIX spec, the components related to these groups are marked as required. A repeating group is required to have at least one field and the first field is the delimiter for each group repeat. In this case we thread the repeating group count as required because the component is required. I agree this is a bit strange in the FIX spec.





[QFJ-363] Store rejected message in message table as well Created: 31/Oct/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: New Feature Priority: Default
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

it seems to be the rejected message is stored only in messages_log, but not message table. This can cause confusion and inconvenience and I wonder why it is this way.
thanks.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

If you are speaking of the message store, that is only for message resent requests. We wouldn't want to resend rejected messages. The message log is the appropriate place for save these messages.





[QFJ-362] Enhance message and message_log table Created: 31/Oct/08  Updated: 05/Apr/10

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: Future Releases

Type: New Feature Priority: Default
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

To faciliate user to monitor and manage FIX messages, I think we should add more columns into those 2 tables:

1. time (missing in messages_log)
2. message type
3. msgseqnum (missing in messages_log)
4. id (missing in messages)
5. isInbound (Y/N. Right now, sendercompid is the company and targetcompid is the counterparty. this is confusing from FIX message point of view and it is difficult to differentiate the direction)

Also I suggest to make column naming of these 2 tables be consistent to help developer to reuse code.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

Just FYI, the messages table is for message resend and should not be used by anything other than the internal session functionality.





[QFJ-361] new Group(int, int) should use Dictionary to decide the tag order Created: 30/Oct/08  Updated: 16/Oct/12  Resolved: 16/Oct/12

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

Type: Improvement Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Right now, it is:
public Group(int field, int delim) {
this(field, delim, new int[]

{ delim }

);
}

But I think it should get the order info from the Dictionary to make more sense based on the spec. Thanks.



 Comments   
Comment by Brad Harvey [ 30/Oct/08 ]

Is http://www.quickfixj.org/quickfixj/javadoc/quickfix/MessageFactory.html#create(java.lang.String,%20java.lang.String,%20int) what you're after?

Group is a basic building block - it doesn't know about Dictionary.

Comment by Alvin Wang [ 31/Oct/08 ]

Agree... pls close this issue.

Comment by Alvin Wang [ 04/Nov/08 ]

i think Group(int, int) should be deprecated





[QFJ-360] public static Message Message.getInstance(String messageStr) Created: 30/Oct/08  Updated: 23/Mar/09  Resolved: 23/Mar/09

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

Type: New Feature Priority: Major
Reporter: Alvin Wang Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

I hope we can have a very useful method like this:
public static Message Message.getInstance(String messageStr)

For example, if the messageStr is a FIX44 Execution Report message string. this method can give me an instance of quickfix.fix44.ExecutionReport. Right now, we store all the message in database, when we retrieve them from DB, it is impossible to create a quickfix.fix44.ExecutionReport object based on a FIX44 Execution Report message string.

thanks.



 Comments   
Comment by Alvin Wang [ 31/Oct/08 ]

Pls close this issue. thanks





[QFJ-359] Multiple IP Channel Connections Created: 28/Oct/08  Updated: 26/Nov/08  Resolved: 26/Nov/08

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Is there any way to get data from multiple IP / ports over the same FIX session? I.E. If I need to connect to three FIX "Channels" through a single FIX session, do I just connect three SocketInitiator objects?



 Comments   
Comment by Steve Bate [ 28/Oct/08 ]

You can initiate connections to multiple sockets but each connection should be for a different FIX session. For initiators, you can use the "session qualifier" to connect the same sender/target comp ID to multiple sockets, but it's nonstandard.





[QFJ-358] field CxlType changed from StringField to CharField Created: 27/Oct/08  Updated: 26/Apr/11  Resolved: 26/Apr/11

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.3.2, 1.3.3
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Christoph John Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

Hi,

I have noticed that the type of the field CxlType has changed to a CharField whereas it was a StringField before (until 1.3.1).
Unfortunately this causes problems with a customer which uses QF/J 1.3.2 and we compiled our code with QF/J 1.3.1 because I thought it was no problem. Now, on execution time there is a NoSuchMethodException because the CxlType field cannot be initialized with a String anymore.
I couldn't find a note on this in JIRA or the release notes but maybe I was missing something.

Was this change intentional or is it a bug?

Thanks,
Chris.



 Comments   
Comment by Toli Kuznets [ 27/Oct/08 ]

Christoph, this may be something to do with the change made for QFJ-158.
Which version of FIX is your customer using? is it FIX.4.1?
CxlType was erroneously defined in FIX.4.1 data dictionary as a String. But CxlType should only exist in FIX.4.0 and as a Char - that's how it is defined in the FIX spec, and it was removed from QFJ dictionaries because it's not in the FIX specs anymore.

However, this was done in 1.2.1, so not sure if it has something to do with the problems you are seeing.

Comment by Christoph John [ 27/Oct/08 ]

Hi,

the customer is using FIX4.0.
I can clearly see in the QuickFIX/J source that the change in the field type was done between 1.3.1 and 1.3.2.
Now I also took a look at the data dictionaries in 1.3.1 and 1.3.2 and in the FIX40.xml files the CxlType field changed from STRING to CHAR.

Regards,
Chris

Comment by Steve Bate [ 27/Oct/08 ]

The change was intentional. The QuickFIX JNI API uses CharField as the subclass of CxlType. After a bug was fixed in the ApiCompatibilityTest unit test suite, the inconsistency between QFJ and QF JNI caused failing tests. After looking at it some more, I see that the QF XML specifications were (and are) inconsistent with the generated code. The QF project version controls its generated code so it appears the data dictionary XML changed years ago but the class was never updated in version control. The current situation is that for the JNI code, the XML says the field is a StringField and the Java code says it's a CharField.

There are a few options here. We can request a bug fix for the JNI code, I can change the field type back to STRING and disable the failing compatibility test, or we can leave it the way it is. Now that I release the QF JNI code is not consistent with the QF XML, I'd prefer option #1 or #2.

Comment by Christoph John [ 28/Oct/08 ]

I think since CharField is in line with the FIX specification my opinion is that QF/J and JNI should treat CxlType as CharField.

Comment by Steve Bate [ 26/Apr/11 ]

CxlType CharFields are correct per the FIX specification.





[QFJ-357] Logout message is sent before Logon on each Session start Created: 23/Oct/08  Updated: 15/Nov/12  Resolved: 09/Dec/11

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

Type: Bug Priority: Major
Reporter: Phil Hong Assignee: Christoph John
Resolution: Fixed Votes: 10
Labels: None
Environment:

Windows


Attachments: Text File excess_logout.patch    
Issue Links:
Relates
is related to QFJ-716 Logout message is still sent before L... Resolved
is related to QFJ-527 Template-based FIX sessions get disco... Closed

 Description   

On the StartTime of session new Session is created and suppried to Session as Responder.
("sessionCreated" function in InitiatorIoHandler class)
But, this Session is reseted and "Logout" message is sent to acceptor on "next()" function in Session class.

This is caused by the management of session state in Session class.
The session state ( especially the session creation time) is reseted every 1sec during non Session time.
But on the new Session is created and suppried as Responder,
the session creation time is not updated and the new Session is treaed to not valid Session.

It should update session state (session creation time) when new Session is suppried.

/**

  • Registers a responder with the session. This is used by the acceptor and
  • initiator implementations.
    *
  • @param responder a responder implementation
    */
    public void setResponder(Responder responder) {
    synchronized (responderSync)
    Unknown macro: { this.responder = responder; if (responder != null) { // reset session state here state.reset(); // force to verify session time lastSessionTimeCheck = 0; stateListener.onConnect(); } else { stateListener.onDisconnect(); } }

    }

We could solve this problem by this but, I'm not sure what' there side effect...



 Comments   
Comment by Phil Hong [ 07/Nov/08 ]

We've found there are a serious problem with above code.
If we restart fix service in the operation time, it will reset seqnums also.
So.. we needs another solution.

Comment by Phil Hong [ 10/Nov/08 ]

There are two session time check function in Session class.
1. isSessionTime ( used on create of new session. )
2. checkSessionTime
And It seems the difference of this two function make a problem.

Comment by zuolin [ 22/Jan/10 ]

public void reset() throws IOException {

if (hasResponder()) {
// add isLoggedOn
if (isLoggedOn())

{ generateLogout(); disconnect(); }

}
resetState();
}

Phil Hong ,Whether this can be solved

Comment by zuolin [ 22/Jan/10 ]

if (hasResponder()) {
// add isLoggedOn
if (isLoggedOn())

{ generateLogout(); }

}
disconnect();
resetState();
}

Comment by qiuyanming [ 22/Jan/10 ]

public void reset() throws IOException {

if (hasResponder()) {
if (isLoggedOn()) {
if (!state.isLogoutSent())

{ getLog().onEvent("Initiated logout request"); generateLogout(); }

}
disconnect();
}
resetState();
}
Whether this can be solved

Comment by Beat Glattfelder [ 17/Nov/10 ]

As requested by Grant Birchmeier

Comment by Grant Birchmeier [ 17/Nov/10 ]

Not that I'm any authority here. He posted the patch to the mailing list, and I suggested that here is a better place.

Here's Beat's email list message that describes his fix:
"When sessions are brought into existence before start of the session schedule, the first thing they will invariably do after connecting, is to send a logout message, reset the session and disconnect. I have found the reason for this to be in the state handling incorporated in the session.next methods, that resets the session as a side-effect when they are called outside of the session schedule. The reset in turn will send a logout if the session has an acceptor and is not considered current. So the first part of the fix is to check in addition whether the session has been logged on yet.

To further complicate the issue, such as the check whether the session schedule has cycled (isSameSession) that is checking the session start time. Since SessionState.reset() does not update the starttime if the sequence numbers are both set to 1, the session starttime would never be updated. The way the logon eventually succeeded before, is that disconnecting following the first logout created a new session object, which then was within the schedule.

I have removed that check as well, and checked the test suite is still running successfully and have attached the patch.

Session.reset():
before generating logout check if the session is already logged on
SessionState.reset():
Do not check for needReset to allow update of session start time"

Comment by Grant Birchmeier [ 17/Nov/10 ]

And here's a direct link to Beat's mail list message (click on the HTML attachment):
http://sourceforge.net/mailarchive/forum.php?thread_name=D495A8096DB7A8419680229C40455CE502AEF1A6%40ICBMS0001.incore.ch&forum_name=quickfixj-users

Comment by Christoph John [ 10/May/11 ]

What's really troubling me is that the Logout message is sent but the sequence number is not incremented. This causes a problem with some of our counterparties since they expect message sequence number n+1 but we still send n, although the initial Logout already had seqnum n.

A client of us has a rather old FIX-Engine (non-QuickFIX) and due to this bug the sequence numbers do not synchronize correctly until we manually restart the session.

I hope that this fix will be incorporated into QuickFIX/J soon.

Comment by Jörg Thönnes [ 20/May/11 ]

Are the changes done for bug

QFJ-457: Acceptor logout trap when the acceptor initiates the logout process
http://www.quickfixj.org/jira/browse/QFJ-457

related to this one?

Comment by Eric Deshayes [ 23/May/11 ]

Joerg,
this is not directly linked to QFJ-457. It has not been fixed with QFJ-457.
It does not seem to be a race condition (like QFJ-444).

Comment by Jörg Thönnes [ 31/May/11 ]

We need a solution for QF/J 1.5.1.

Comment by Jörg Thönnes [ 07/Aug/11 ]

Moved to a later version since we ran out of time.

Comment by Christian Plätzinger [ 16/Aug/11 ]

Jörg is currently on holiday until September and I am afraid he will have to time to solve it once he is back. Can you please assign the issue to someone else?

Comment by Paul McCabe [ 10/Oct/11 ]

Just an interesting note, Beat's QFJ-357 patch (excess_logout.patch) does cause a difference in quickfixJ's behaviour to logon requests sent outside of session times.

Previously, if a logon was received outside session times, then a logout response would be generated. With the patch, the logon outside of session times is ignored.

This can cause issues when connecting to another FIX engine that has no timeout and never sends another logon request (I know, it sounds ridiculous but they are out there).

I think this should be taken into account when this issue is picked up again, as I'm sure I'm not the only person who relies on this behaviour being maintained.

Comment by RK [ 17/Oct/11 ]

Has someone found a workaround for this issue? (the patch above doesn't seem to work)
Should be a high priority bug imho, even worth a 1.5.2 release...

Comment by Christoph John [ 17/Oct/11 ]

Hi,

I'm not sure (and currently don't have time to test ), but IIRC the bug is also triggered by the session time. Could you test to supply "00:00:00" as both StartTime and EndTime. Does this help?

Cheers,
Chris.

Comment by RK [ 17/Oct/11 ]

Exactly, we experience the bug only on session start time when the session is created. ("quickfix.mina.initiator.InitiatorIoHandler sessionCreated")

If I set both the StartTime and EndTime to "00:00:00" does the session reset (sequence numbers to 1:1) happen at all? We do need a reset once in 24hrs.

Comment by Christoph John [ 18/Oct/11 ]

IMHO the reset will be done (as long as there is no connection up at that time). Otherwise just stop/start the process at 00:00. But of course you should first test if setting "00:00:00" as both StartTime and EndTime helps.

Comment by Christoph John [ 27/Oct/11 ]

Guys,

I have found an ugly workaround. When I was at a customer site, I wondered why they don't get hit by this bug. It seemed it was because they already load messages into the store right after gateway start (current order status information for the connecting client to be published at Logon).

After some tests I could verify that it works in most cases. But unfortunately it does not work if the FIX process is started outside the StartTime/EndTime range. QuickFIX will then reset the state again on first logon (leading to Logout to be sent as first message). I have not tested the case where the process is never stopped since our processes are restarted each night for EOD jobs.

So, all I did was to put some code into the onCreate() callback to increment the seqnum by 1 if it is still 1.
if ( nextSenderMsgSeqNum == 1 )

{ Session.lookupSession( fixSessionId ).getStore().incrNextSenderMsgSeqNum(); }

Surprisingly, QuickFIX/J still sends out the first Logon attempt with seqNum = 1, although I incremented the seqNum when the quickfix.Session gets created. However, I have not the time to follow this up right now.

Good luck,
Chris.

Comment by Mate Varga [ 01/Nov/11 ]

This issue is of paramount importance I think – I recommend raising it's priority to major.

Comment by AE [ 14/Nov/11 ]

This bug is listed as since 1.3.3. Can anyone verify this is the case? We upgraded from 1.3.3 to 1.5 and started seeing this bug, so went back to 1.3.3 and stopped seeing it. Is it possible this bug is more prevalent in 1.5? Thanks

Comment by Christoph John [ 25/Nov/11 ]

IIRC it showed in 1.3.3 only if you used a custom StartTime and initiated the connection.

Comment by Christoph John [ 08/Dec/11 ]

Hi,
after spending some time working on this issue, I'm going to commit the changes (tomorrow at the latest) so we can have this corrected on 1.5.2. It still has an aftertaste of a workaround, so we should consider something more sophisticated for 1.6.0.

I picked up Beat's changes on the SessionState.reset() method. But this did not help in the case where a Session is created and immediately (inside one second) initiates or accepts a connection (this is happening when the Session is started within the session time). So I made sure that the first check in checkSessionTime() (which is called from the Session constructor) does not update the lastSessionTimeCheck. Hence on the next call (from Session.next()) the lastSessionTimeResult is evaluated again, returning true and in turn leading to the acceptance of the FIX connection.

I also made sure that outside session time a Logout is sent (see Paul's comment). The behaviour seemed to have changed in the meantime. When I tried to connect outside session time, I received a Logon immediately followed by Logout. I have changed Session.nextLogon() to reject the Logon outside of the session time.

Will also provide UnitTests. UnitTests and AcceptanceTests were successful.

Cheers,
Chris.





[QFJ-356] CLONE -CLONE -First login attempt of initiator afterStartTime is responded with logout Created: 22/Oct/08  Updated: 26/Nov/08  Resolved: 26/Nov/08

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

Type: Other Priority: Default
Reporter: Leo Satoshi Fischer Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

2003



 Description   

Hi Steve, it's been quite a while.
We are experiencing the bug detailed below.
Do you have a specific patch for this for 1.2.1, or is 1.3.0 stable enough
for production.

This could be related to a open bug about the timer events not being
processed in an acceptor while it's disconnected (QFJ-218). This would
cause the logout with the old sequence number to be sent the first time
someone connects. Subsequent connections should be ok and should use the
new session's sequence numbers. If we can complete the 1.3 release soon,
I'll have the fix in there. Otherwise, I'll patch 1.2.1 and release a
new version of that branch.

A temporary workaround is to call reset manually on the message
store before the new session start time.

Regards,

Steve



 Comments   
Comment by Leo Satoshi Fischer [ 24/Oct/08 ]

This is STILL an issue in 1.3.3.
Occasionally quickfix will send a logout before actually logging in a sesson at the start of a session in the morning.

It is caused by Session.checkSessionTime in CheckSession.next()
Basically while not in session time, every second, next is called and the session will reset the session, which causes a logout if there is a responder, and session state (creation time) to be reset.
Now, we pass the session start time, and a separate thread will call setResponder. This doesn't result in the session creation time being reset.
if we are lucky, the last call to next() was after the start time, and we won't reset the session.
If we are unlucky, checkSession looks at the session creation, determines we aren't the same session and calls reset, causing a logout to be sent.





[QFJ-355] Implementation of the validate field order configuration setting is incomplete Created: 06/Oct/08  Updated: 17/Feb/09  Resolved: 28/Jan/09

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

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-384 turn off Out of order repeating group... Closed

 Description   

Hello Steve,

please could you be a bit more specific about this bug?

We are using your message generation code to generate our own FIX message classes and may have also seen something related.

Thanks, Jörg



 Comments   
Comment by Andre Mermegas [ 19/Dec/08 ]

I would like to be able to turn off Out of order repeating group members validation that was added in 1.3.3

This breaks my app.

http://www.quickfixj.org/jira/browse/QFJ-384?watch=true

Comment by Michael Schifferdecker [ 17/Feb/09 ]

Has this fix been released as part of quickfix/j v1.4?
If so, HOW can I turn off out of order repeating group members validation?
If it is not possible to turn valiation off, can I download a release prior to v1.3.3 when this feature was added so that I can make my application work?

note:
at the moment all messages of trade capture report from ICE exchange get rejected by quickfix/j
I therefore cannot use quickfix/j for trade capture unless I can turn this feature off

example error messages:
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=73335=AE49=ICE56=334=452=20090217-11:30:01.32257=1571=45487=0856=0568=1828=017=31000000266439=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=3.031=5.09018=375=2009021760=20090217-11:16:47.632552=154=137=700036711=310000002664453=11448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=3447=D452=35448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=1637=2488.0687=3.0654=70003709019=3600=780066602=CC FMK0009!603=8608=FXXXXX624=2637=2483.0687=3.0654=70003699019=310=111)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=72835=AE49=ICE56=334=552=20090217-11:30:01.32557=1571=46487=0856=0568=1828=017=700037139=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=8.031=5.09018=875=2009021760=20090217-11:17:17.620552=154=137=700037111=310000002664453=11448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=3447=D452=35448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=1637=2488.0687=8.0654=70003749019=8600=780066602=CC FMK0009!603=8608=FXXXXX624=2637=2483.0687=8.0654=70003739019=810=151)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=70935=AE49=ICE56=334=652=20090217-11:30:01.33057=1571=47487=0856=0568=1828=017=700037539=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=6.031=5.09018=675=2009021760=20090217-11:17:52.112552=154=237=700037711=310000002668453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=6.0654=70003799019=6600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=6.0654=70003789019=610=040)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=71435=AE49=ICE56=334=752=20090217-11:30:01.33357=1571=48487=0856=0568=1828=017=31000000266439=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=3.031=5.09018=375=2009021760=20090217-11:16:47.632552=154=237=700036811=310000002665453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=3.0654=70003709019=3600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=3.0654=70003699019=310=005)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=70935=AE49=ICE56=334=852=20090217-11:30:01.33757=1571=49487=0856=0568=1828=017=700037139=2570=N55=78007548=CC FMH0009-CC FMK000922=8461=FXXXXX32=8.031=5.09018=875=2009021760=20090217-11:17:17.620552=154=237=700037211=310000002666453=10448=db_fix_api2447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=884447=D452=4448=L609447=D452=51448=Deutsche Bank447=D452=60448=H447=D452=54448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=58555=2600=780056602=CC FMH0009!603=8608=FXXXXX624=2637=2488.0687=8.0654=70003749019=8600=780066602=CC FMK0009!603=8608=FXXXXX624=1637=2483.0687=8.0654=70003739019=810=047)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=47035=AE49=ICE56=334=952=20090217-11:30:01.38257=1571=50487=0856=0568=1828=017=14834612402239=2570=N55=21792048=BRN FMJ0009!22=8461=FXXXXX32=1.031=43.659018=175=2009021760=20090217-09:33:01.395552=154=237=1300020211=314000000126453=8448=db_fix_api6447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=U447=D452=54448=L609447=D452=55448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=5810=150)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=47135=AE49=ICE56=334=1052=20090217-11:30:01.38457=1571=51487=0856=0568=1828=017=14722789538639=2570=N55=21792048=BRN FMJ0009!22=8461=FXXXXX32=1.031=43.629018=175=2009021760=20090217-09:18:07.094552=154=237=1300016811=314000000124453=8448=db_fix_api6447=D452=11448=Deutsche Bank AG447=D452=13448=3447=D452=56448=U447=D452=54448=L609447=D452=55448=884|884447=D452=57448=ISV-OTFR|ISV-OTFR447=D452=59448=user1|user1447=D452=5810=230)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 4 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=449=350=152=20090217-11:30:30.63956=ICE45=458=Out of order repeating group members371=687372=AE373=1510=041
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=449=350=152=20090217-11:30:30.63956=ICE45=458=Out of order repeating group members371=687372=AE373=1510=041)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 5 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=549=350=152=20090217-11:30:30.64256=ICE45=558=Out of order repeating group members371=687372=AE373=1510=037
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=549=350=152=20090217-11:30:30.64256=ICE45=558=Out of order repeating group members371=687372=AE373=1510=037)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 6 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=649=350=152=20090217-11:30:30.64456=ICE45=658=Out of order repeating group members371=687372=AE373=1510=041
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=649=350=152=20090217-11:30:30.64456=ICE45=658=Out of order repeating group members371=687372=AE373=1510=041)
<20090217-11:30:30, FIX.4.4:3/1->ICE, incoming> (8=FIX.4.49=7835=AQ49=ICE56=334=1152=20090217-11:30:01.40957=1568=1569=0749=0750=110=134)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 7 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=749=350=152=20090217-11:30:30.65256=ICE45=758=Out of order repeating group members371=687372=AE373=1510=042
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=749=350=152=20090217-11:30:30.65256=ICE45=758=Out of order repeating group members371=687372=AE373=1510=042)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 8 Rejected: Out of order repeating group members:687)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=11935=334=849=350=152=20090217-11:30:30.65456=ICE45=858=Out of order repeating group members371=687372=AE373=1510=046
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=11935=334=849=350=152=20090217-11:30:30.65456=ICE45=858=Out of order repeating group members371=687372=AE373=1510=046)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 9 Rejected: Value is incorrect (out of range) for this tag:452)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=12835=334=949=350=152=20090217-11:30:30.65756=ICE45=958=Value is incorrect (out of range) for this tag371=452372=AE373=510=192
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=12835=334=949=350=152=20090217-11:30:30.65756=ICE45=958=Value is incorrect (out of range) for this tag371=452372=AE373=510=192)
<20090217-11:30:30, FIX.4.4:3/1->ICE, event> (Message 10 Rejected: Value is incorrect (out of range) for this tag:452)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:112) - TO ADMIN: 8=FIX.4.49=13035=334=1049=350=152=20090217-11:30:30.65956=ICE45=1058=Value is incorrect (out of range) for this tag371=452372=AE373=510=011
<20090217-11:30:30, FIX.4.4:3/1->ICE, outgoing> (8=FIX.4.49=13035=334=1049=350=152=20090217-11:30:30.65956=ICE45=1058=Value is incorrect (out of range) for this tag371=452372=AE373=510=011)
[2009 Feb 17 11:30:30] [QFJ Message Processor] DEBUG (TradeCaptureService.java:60) - FROM APPLICATION: 8=FIX.4.49=7835=AQ34=1149=ICE52=20090217-11:30:01.40956=357=1568=1569=0749=0750=110=134

Comment by Steve Bate [ 17/Feb/09 ]

The change in 1.4.0 was to complete the implementation of the existing option (as documented in the session settings). Is the option not working for you? Also, have you reviewed how create a custom message dictionary for your sessions? Unless ICE is sending the fields in a random order in every message then a custom dictionary would probably solve your problem too.





[QFJ-354] Support restart after initiator stop Created: 04/Oct/08  Updated: 06/Oct/08  Resolved: 06/Oct/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-348 Unable to restart a stopped initiator... Closed




[QFJ-353] Getting "<field> does not have a 'required' attribute when creating FIX Session Created: 03/Oct/08  Updated: 15/Nov/12  Resolved: 04/Oct/08

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

Type: Other Priority: Default
Reporter: Herman Hung Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Red Hat Linux, FIX 4.2


Attachments: XML File FIX42Cboe.xml     File settings.ini    

 Description   

Hi,

Whenever I try to create a session using QuickFix/J, I am receiving an error of <field> does not have a 'required' attribute. Please advise on what this means.

Thanks,
hhung



 Comments   
Comment by Herman Hung [ 03/Oct/08 ]

DataDictionary attached.

Comment by Toli Kuznets [ 03/Oct/08 ]

Herman,
Can you post the entire error message here? And the stack trace? It's very likely that you are missing some Session configuration parameters that are required.
See configuration descriptor for possible parameters.

You need to have the BeginString, HeartBtInt, StartTime and EndTime specified, along with ConnectionType

Comment by Herman Hung [ 03/Oct/08 ]

This is the error that I'm seeing:

quickfix.ConfigError: FIX42Cboe.xml: <field> does not have a 'required' attribute

at quickfix.DataDictionary.read(DataDictionary.java:788)

at quickfix.DataDictionary.<init>(DataDictionary.java:98)

at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:93)

at quickfix.mina.SessionConnector.createSession(SessionConnector.java:114)

at quickfix.mina.initiator.AbstractSocketInitiator.createSessions(AbstractSocketInitiator.java:130)

at quickfix.mina.initiator.AbstractSocketInitiator.<init>(AbstractSocketInitiator.java:77)

at quickfix.mina.initiator.AbstractSocketInitiator.<init>(AbstractSocketInitiator.java:67)

at quickfix.SocketInitiator.<init>(SocketInitiator.java:47)

at com.bluefirecap.dropportssql.FixSessionCreator.<init>(FixSessionCreator.java:68)

at com.bluefirecap.dropportssql.FixSessionCreator.main(FixSessionCreator.java:122)

Comment by Herman Hung [ 03/Oct/08 ]

Attaching base configuration file.

Comment by Steve Bate [ 03/Oct/08 ]

This error means you don't have an XML attribute called 'required' in an XML 'field' element in the data dictionary XML file.

Comment by Herman Hung [ 04/Oct/08 ]

Hi Steve,

Thank you for your input. However, I cannot seem to find a field tag that is missing a "required" tag in the Data Dictionary.

Regards,
Herman

Comment by Steve Bate [ 04/Oct/08 ]

You misspelled 'required' in the ExecutionReport section..

...
<field name="CxlQty" rqeuired="N" />
...

Comment by Herman Hung [ 04/Oct/08 ]

That seems to have resolved the issue. Gotta love typos. Thanks for your assistance!

Regards,
Herman





[QFJ-352] Include newer 1.5.3 version of SLF4J libraries Created: 01/Oct/08  Updated: 11/Feb/09  Resolved: 26/Nov/08

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

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

SLF4J has gone up to version 1.5.3 - the main difference is introduction of TRACE level, and better support for arrays in {} formatting notation.
correspondingly, Log4J has gone up to 1.2.15 as well.

Would be nice to include new libs with the releases.



 Comments   
Comment by Toli Kuznets [ 01/Oct/08 ]

checked in rev 869

Comment by Steve Bate [ 26/Nov/08 ]

Moving issue to resolved state until release is final.





[QFJ-351] Fix orderedFields property in XSL Created: 23/Sep/08  Updated: 11/Feb/09  Resolved: 29/Oct/08

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: None
Fix Version/s: 1.4.0

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None

Attachments: File mylyn-context.zip     File mylyn-context.zip    

 Description   

Hi all,

There is a little typo in the release 1.3.2. Both MessageCodeGenerator and the
core/build.xml set the property "generator.orderedFields" while the template
MessageSubclass.xsl uses "orderedFields". So, the property doesn't work.

Thank you,
Alex



 Comments   
Comment by Jörg Thönnes [ 29/Oct/08 ]

Attached Mylyn context with the related files.

Comment by Jörg Thönnes [ 29/Oct/08 ]

Attached Mylyn context with the related files.

Comment by Jörg Thönnes [ 29/Oct/08 ]

Attached Mylyn context with the related files.

Comment by Jörg Thönnes [ 29/Oct/08 ]

Sorry for the 3 attachments, my Eclipse Mylyn plugin had some malfunction.





[QFJ-350] Sessions do not cleanup after themselves when un registered Created: 15/Sep/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Java 1.6.0_07
Windows XP


Issue Links:
Duplicate
duplicates QFJ-224 Automatically close logs and message ... Closed
Relates
relates to QFJ-287 Provide hook for manually closing Fil... Closed

 Description   

When sessions are unregistered they do not do any clean up of any resources that they may have opened. Once a session is unregistered by the static Session.unregisterSessions the session is basically dead and can no-longer be used. The unregisterSession method should check if the session's store is a FileStore and call closeFiles before/after removing from the session cache.

This is releated to QFJ-224 and QFJ-287.



 Comments   
Comment by Steve Bate [ 05/Apr/10 ]

The concrete type of the message stores are not known to the code that unregisters sessions.





[QFJ-349] Upgrade to latest version of Proxool Created: 12/Sep/08  Updated: 06/Oct/08  Resolved: 24/Sep/08

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-348] Unable to restart a stopped initiator (SocketInitator) Created: 08/Sep/08  Updated: 11/Feb/09  Resolved: 06/Oct/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.4.0

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP
Java 1.6.0_07


Issue Links:
Duplicate
is duplicated by QFJ-354 Support restart after initiator stop Closed

 Description   

The SocketInitator has a start and stop method that imply that it can be started/stopped/restarted. However, you can only start the Initiator once as the fact that it has been started is tracked by whether or not it has been initialized.

AbstractSocketInitiator.initiateSessions initializes the sessions and starts the sessionTimers.
SocketInitializer.initialize controls the flag of whether the initiator is initialized or not. An initialized initializer implies it has been started.
SocketInitializer.stop stops the sessionTimer and does not reset the initialized flag (which it shouldn't)

There are two different states that need to be tracked of an initializer.
1. whether or not it has been initialized (already tracked)
2. whether or not it has been started (implied by being initialized and needs to have its own flag).

As it stands, the only way to restart a SocketInitializer is to create an new instance and start it.



 Comments   
Comment by Steve Bate [ 06/Oct/08 ]

I accidentally created a duplicate issue for this feature. The SVN commits are keyed off the duplicate issue ID so I'll leave it in the system.





[QFJ-347] Update code to comply with JNI JAR Created: 08/Sep/08  Updated: 06/Oct/08  Resolved: 10/Sep/08

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

rev. 1999 or newer.



 Comments   
Comment by Steve Bate [ 10/Sep/08 ]

Updated to QF rev 1999. The Log backup method will not be implemented in Java.





[QFJ-346] Limit message index size in FileStore Created: 08/Sep/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-345] Support configuration for controlling synchronous write behavior Created: 08/Sep/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-307 Messages Logged as being sent but nev... Closed




[QFJ-344] Set TCP_NODELAY to true by default Created: 08/Sep/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-343] Executor creates invalid response to NewOrderSingle for FIX 4.3 and FIX 4.4 Created: 28/Aug/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP
Java 1.6.0_07



 Description   

The Executor creates and execution report to send back as an acknowledgment of order received, however the execution report is missing the symbol (TAG 55). Banzai rejects the message.

This logic for FIX 4.4 also creates a FIX 4.3 execution report instead of a FIX 4.4 execution report.






[QFJ-342] Add text reason to forced logouts/disconnects Created: 22/Aug/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

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

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

This is in reference to http://n2.nabble.com/Banzai-example-question--tt364931.html#a364932 thread

If the sender has SendingTime accuracy issues, QFJ just disconnects the session but the sender doesn't see any detailed "reasons" for why that happens.

Would be nice to see a reason for a sending time accuracy disconnect, along with others such as "multiple connections from same senderCompID".



 Comments   
Comment by Toli Kuznets [ 22/Aug/08 ]

So this turns out to be a little less straightforward and easy to fix than i hoped.
For SendingTime Accuracy problems, the workflow is this (demonstrated by putting a breakpoint in Session.doBadTime or Session.generateReject

Login comes in for a new session
bad time (sending time sync problem) is detected and generateReject is called
since we never received a valid logon for this session, generateReject throws an exception and as a result we never send the reject or logout (which could have the text message)

The connecting session is simply dropped (disconnected) - with no logouts sent.
All you see on the client side is a session disconnect

Not sure what the best way to approach this problem is. Ideally, we'd just catch the exception and send a logout (or always send a reject even if it's not logged on).

Or maybe catch the exception in Session.doBadTime(), send a logout (with error messages as logout text) and rethrow the exception to force a disconnect?
I've modified the code and acceptance tests to check for that, and it seems to work.

Steve, what are your thoughts?

Comment by Toli Kuznets [ 23/Aug/08 ]

I also wanted to send out a useful reject message for the case when you have multiple connections for the same session.
The current behaviour is to just close the session when multiple connections are detected - see AbstractIoHandler.processMessage().

I'd imagine the right behaviour is to keep existing session, and to send a reject/logout message to the 2nd connection

Fixing this is a bit more non-trivial - it'll require some fairly invasive changes to allow certain methods in Session to be public if we wanted to reuse code.
What's the right behaviour? Create a new "logout" session that only sends a logout/reject out, and then close it immediately?
What would be the best way to implement that?

Comment by Toli Kuznets [ 01/Oct/08 ]

Sending a text reason for forced logout/disconnect added in rev 870 .

Still need to figure out the best way to approach sending a rejection message on disconnect when you have multiple simultaneous connection attempts.

Comment by Toli Kuznets [ 01/Oct/08 ]

wrong link to the rev above. the right rev is here

Comment by Toli Kuznets [ 12/Nov/08 ]

I've created a tag for the QFJ-342 fix that deals with notifying on "multiple connections from same senderCompID" case.

http://quickfixj.svn.sourceforge.net/viewvc/quickfixj/branches/qfj-342/core/

The fix works fine with Executor/Banzai examples. I've written an acceptance test for it which passes as well, but somehow my fix really messes up some of the subsequent acceptance tests. And I'm not sure if it's due to the way acceptance tests are setup, or if there's a lingering error or a false assumption in the way that i have fixed code to send a reject.

I removed all acceptance tests but 2 in the branch - one that exercises QFJ-342, and another that fails subsequently. If you remove the 1b_DuplicateIdentity.def test then all the others pass as well

Not sure where to go from here - would like to speak with someone that knows more about the acceptance test suite to see what may be going on.

Acceptance tests
AcceptorIOHandler change

Comment by Steve Bate [ 05/Apr/10 ]

Resolved based on Toli's comments.





[QFJ-341] Rule80A in FIX40-43 xml files is missing the entry for I (individual investor) Created: 20/Aug/08  Updated: 06/Oct/08  Resolved: 20/Aug/08

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.3.2
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

the field is in FIX4.0-4.3 and then disappears in FIX.4.4

Rule80A class has the correct constant, but it's not included in any of the FIX4x.xml files



 Comments   
Comment by Toli Kuznets [ 20/Aug/08 ]

fix checked in rev 837





[QFJ-340] Add support for binary fields Created: 19/Aug/08  Updated: 08/Sep/08

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: Future Releases

Type: New Feature Priority: Minor
Reporter: Steve Bate Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None





[QFJ-339] Message grammar checks not handled correctly before Logon messages exchanged Created: 19/Aug/08  Updated: 15/Nov/12  Resolved: 05/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: aleksey ratushnyy Assignee: Unassigned
Resolution: Not a bug Votes: 1
Labels: None


 Description   

When message grammar validation fails (Invalid tag number, or similar errors) on any message before Logon messages are exchanged (including Logon message itself), Quickfix/J attempts to send Reject message which causes "Tried to send a reject while not logged on" SessionException

quickfix.SessionException: Tried to send a reject while not logged on: Invalid tag number (field 9001)
at quickfix.Session.generateReject(Session.java:1050)
at quickfix.Session.next(Session.java:733)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:106)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:595)

As the result, is a counterparty happens to send an incorrect or undefined tag inside Logon message, the response Logon is never sent, and the connection is never dropped, so the counterparty is only learns of the problem via timeout.



 Comments   
Comment by Kent Vogel [ 09/Oct/08 ]

This also happens for SendingTime accuracy problem.

Comment by Steve Bate [ 05/Apr/10 ]

The error message is accurate but not particularly helpful. I've modified it to specify that an error has occurred before logon. However, the session does disconnect when these types of errors occur. I've added two unit tests to explicitly verify this behavior. It's also tested in the acceptance tests.

Is it possible that the client FIX engine is not recognizing the dropped connection?

Comment by Kent Vogel [ 05/Apr/10 ]

The client recognizes the dropped connection. The problem is, that's all they get. There is not way for them to figure out what they did wrong without calling support on the other side and asking. For example, if someone tries to send a Logon message and forgets to include the password field, they get no error message back indicating that, just a dropped connection.

I have this problem with every new customer that first tries to integrate. They send their first Logon message, there's always some problem with it (SendingTime accuracy, missing Username, etc...), they get nothing, and generally assume it's a network problem, because they never received a single FIX message from us.

Comment by aleksey ratushnyy [ 05/Apr/10 ]

Hi, I have just tried this same scenario with QuickFix/J 1.4 and this is not true at least in our case:
Server is running QuickFix/J
Client sends a Logon message to the server with some field that does not belong to logon message
The server does not respond, and does not drop the connection.
If you look at the stack trace defined in the bug, nothing has really changed from what I can tell:
quickfix.Session.generateReject throws "Tried to send a reject while not logged on" SessionException which is caught by quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage() which calls
LogUtil.logThrowable(quickfixSession.getSessionID(), e.getMessage(), e); and does not do anything else

How exactly does it disconnect????????





[QFJ-338] Response to TestRequest received before the SessionState is updated Created: 19/Aug/08  Updated: 06/Oct/08  Resolved: 10/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: aleksey ratushnyy Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The problem: When a response to TestRequest is received too quickly, a false positive heartbeat timeout happens and causes disconnection.

In method quickfix.Session.next() there exists the following code:

if (state.isTestRequestNeeded())

{ generateTestRequest("TEST"); state.incrementTestRequestCounter(); getLog().onEvent("Sent test request TEST"); stateListener.onMissedHeartBeat(); }

else if (state.isHeartBeatNeeded())

{ generateHeartbeat(); }

In this code,
generateTestRequest("TEST");
sends the Test Request, a response to which can be received before line
state.incrementTestRequestCounter();
is executed.

Whenever this condition happens, there is always a false disconnect due to missed heartbeats (assuming the server does not send unsolicited heartbeats)

(why this happens:

  • quickfix.SessionState.isTestRequestNeeded() returns false up until 3*[heart beat interval]
  • quickfix.SessionState.isTimedOut() returns false only up until 2.4*[heart beat interval]
  • state.isTimedOut() returns true before state.isTestRequestNeeded(), so another TestRequest is not sent before the timeout causes the disconnection.

Note: it is not a theoretical issue, the problem does occur time to time



 Comments   
Comment by Steve Bate [ 10/Sep/08 ]

Based on my analysis, it appears it would fix the problem if I reversed the increment of the test counter and the sending of the message. Do you agree with that?

Comment by aleksey ratushnyy [ 10/Sep/08 ]

As long as you are sure it is not going to introduce any other strange race condition





[QFJ-337] IoSessionResponder.send does not return true when message is sent Created: 19/Aug/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: 1.3.2
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None
Environment:

Windows XP
Java 1.6.0_07



 Description   

IoSessionResponder.send does not return true when message is sent. isWritten does not wait to see if the data has been written. Presumably the data is being written in another thread (since a Future is returned) from ioSession.write. If the thread doing the writing has not had time to execute the isWritten will return false even though the message will be written after the isWritten has been called. The writing needs to be performed in the same thread as the call, or the current thread needs to wait for the thread doing the writing to return.

The method in question is:
return ioSession.write(data).isWritten();

When running this through the debugger the behavior is most likely correct (as can be the case with multi-threaded applications), but if running with just logging send method will return false even though the record is sent.






[QFJ-336] OutOfMemoryError in compile_main Created: 18/Aug/08  Updated: 06/Oct/08  Resolved: 19/Aug/08

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.3.2
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Dustin Vain Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Mac OS X 10.5.4
JDK 1.6.0_5



 Description   

Got the error below doing an "ant jar". Looks like the 1.6 Mac compiler needs a little more memory that whatever compiler you're using. Upping the memory to 256m on line 104 of core/build.xml resolved the issue.

compile_main:
[javac] Compiling 1431 source files to /Users/dustin/proj/quickfixj/core/target/classes/main
[javac]
[javac]
[javac] The system is out of resources.
[javac] Consult the following stack trace for details.
[javac] java.lang.OutOfMemoryError: Java heap space
[javac] at com.sun.tools.javac.util.Position$LineMapImpl.build(Position.java:139)
[javac] at com.sun.tools.javac.util.Position.makeLineMap(Position.java:63)
[javac] at com.sun.tools.javac.parser.Scanner.getLineMap(Scanner.java:1105)
[javac] at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:512)
[javac] at com.sun.tools.javac.main.JavaCompiler.parse(JavaCompiler.java:550)
[javac] at com.sun.tools.javac.main.JavaCompiler.parseFiles(JavaCompiler.java:801)
[javac] at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:727)
[javac] at com.sun.tools.javac.main.Main.compile(Main.java:353)
[javac] at com.sun.tools.javac.main.Main.compile(Main.java:279)
[javac] at com.sun.tools.javac.main.Main.compile(Main.java:270)
[javac] at com.sun.tools.javac.Main.compile(Main.java:69)
[javac] at com.sun.tools.javac.Main.main(Main.java:54)

BUILD FAILED
./build.xml:36: The following error occurred while executing this line:
./build.xml:27: The following error occurred while executing this line:
./core/build.xml:80: The following error occurred while executing this line:
./core/build.xml:85: The following error occurred while executing this line:
./core/build.xml:104: Compile failed; see the compiler error output for details.






[QFJ-335] NullPointerException in LogUtil when logging event with SingleThreadedEventHandlingStrategy Created: 16/Aug/08  Updated: 06/Oct/08  Resolved: 10/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP
Java 1.6.0_07



 Description   

When connecting and disconnecting to a server and the sequence numbers get out of sync the SingleThreadedEventHandlingStrategy tries to log an event after the initiator has closed all of its sessions. This causes the quickfix.LogUtil.logThrowable(LogUtil.java:54) to throw a NPE as there is no session to get the log from.

This is an intermittent bug as there are a number of threads involved (QFJ Timer, SocketConnectorIoProcessor-6.0, and QFJ Message Processor). One iteration logs the following message:
quickfix.SessionException Logon state is not valid for message (MsgType=5)
another has the NPE and yet another has not issues at all.

The full stack trace is:
Exception in thread "QFJ Message Processor" java.lang.NullPointerException
at quickfix.LogUtil.logThrowable(LogUtil.java:54)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:109)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:619)






[QFJ-334] New messages are interleaved with old ones during a counterparty replay request Created: 14/Aug/08  Updated: 15/Nov/12  Resolved: 09/Sep/08

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

Type: Bug Priority: Major
Reporter: JamesM Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

QuickFIX 1.3.1, Java 1.5.0_12, Linux RHEL 4.4.2



 Description   

We are testing a case where a counterparty disconnects from our acceptor when we are filling their execution requests. In this case, when they reconnect, we have a large number of messages for them (ie: our sender sequence number is larger than what they expected), and they initiate a resend request, as expected.

What surprised us was that if we are still sending new messages, those messages are interleaved with the resends. This causes our FIX client to drop the connection because it receives an out of sequence message during the replay.

From our log files (we are using a custom MessageStore implementation)

11:58:41,363 INFO Store - Get request from 20315 to 26359
11:58:41,501 INFO Store - set: sequence 26383 :: 8=FIX.4.1 [rest removed]

From the event log:

Thu Aug 14 11:58:11 JST 2008 Disconnecting
Thu Aug 14 11:58:40 JST 2008 Accepting session FIX.4.1:JPN10000XXXX->JPN123456789 from /192.168.1.2:33299
Thu Aug 14 11:58:40 JST 2008 Acceptor heartbeat set to 30 seconds
Thu Aug 14 11:58:40 JST 2008 Refreshing message/state store at logon
Thu Aug 14 11:58:40 JST 2008 Received logon request
Thu Aug 14 11:58:40 JST 2008 Responding to logon request
Thu Aug 14 11:58:41 JST 2008 Received ResendRequest FROM: 20315 TO: 999999
Thu Aug 14 11:58:41 JST 2008 Resending Message: 20315
Thu Aug 14 11:58:41 JST 2008 Resending Message: 20316
Thu Aug 14 11:58:41 JST 2008 Resending Message: 20317
Thu Aug 14 11:58:41 JST 2008 Resending Message: 20318
Thu Aug 14 11:58:41 JST 2008 Resending Message: 20319

However, the sequence of messages the counterparty received was: 21035, 26383, 21036. The counterparty immediately disconnected upon receiving 26383, because it was out of sequence; they were expecting 20316.

Doesn't this seem strange? I know that in the inbound direction [ie: if we, the acceptor, were the one making the resend request] we would queue 26383 in QuickFIX and get it after the resend is complete. Or is it just something that all FIX clients have to be able to cope with, getting new messages interleaved in a resend request, and then queuing them until they are ready to deal with it?



 Comments   
Comment by JamesM [ 15/Aug/08 ]

I was able to prevent this problem by adding an additional event to SessionStateListener so that my application is notified when a resend starts, and when it finishes.

Using this, I was able to lock out the 'send' method of our application so that it doesn't attempt to send messages during this time.

It seems like there may be a race condition for the socket; new messages seem to be interleaved between socket write() calls with those being sent by the resend. While the window for this race condition to occur is very small, it definitely seems to be a possibility if the message rate is high enough during the processing of the counterparty's resend request.

Comment by Steve Bate [ 15/Aug/08 ]

That's an interesting solution. Like you said, this is something the receiving FIX engine would usually handle. A sequence number that's too high should not cause a disconnect. If that high sequence number arrives during resend processing, then it would usually be queued until the gap is filled. A FIX engine doesn't necessarily require that the messages are received in order, but it will guarantee that it won't deliver the messages to the application out of order.





[QFJ-333] A filter chain cannot contain more than one ProtocolCodecFilter Created: 11/Aug/08  Updated: 08/Sep/08  Resolved: 08/Sep/08

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

Type: Other Priority: Blocker
Reporter: Serife Kapukaya Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP



 Description   

We have an inhouse FIX engine developed using Quickfix Engine. We are trying to connect with a client as an acceptor. But we have this error while attempting to create a session. I couldn't understand why we have this error. Because we had successful tests with different clients before. What should I do to pass over this problem?

org.apache.mina.common.IoFilterLifeCycleException: onPreAdd(): protocolCodecFilter:org.apache.mina.filter.codec.ProtocolCodecFilter@bc917c in (SOCKET, R: /194.75.231.194:52928, L: /213.143.244.124:2000, S: /213.143.244.124:2000)
at org.apache.mina.common.support.AbstractIoFilterChain.register(AbstractIoFilterChain.java:179)
at org.apache.mina.common.support.AbstractIoFilterChain.addFirst(AbstractIoFilterChain.java:124)
at quickfix.mina.AbstractIoHandler.sessionCreated(AbstractIoHandler.java:96)
at quickfix.mina.acceptor.AcceptorIoHandler.sessionCreated(AcceptorIoHandler.java:52)
at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.sessionCreated(AbstractIoFilterChain.java:652)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionCreated(AbstractIoFilterChain.java:272)
at org.apache.mina.common.support.AbstractIoFilterChain.access$700(AbstractIoFilterChain.java
Ağu 07 14:56:56 2008: :54)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionCreated(AbstractIoFilterChain.java:769)
at org.apache.mina.common.IoFilterAdapter.sessionCreated(IoFilterAdapter.java:58)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionCreated(AbstractIoFilterChain.java:272)
at org.apache.mina.common.support.AbstractIoFilterChain.access$700(AbstractIoFilterChain.java:54)
at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionCreated(AbstractIoFilterChain.java:769)
at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionCreated(AbstractIoFilterChain.java:589)
at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionCreated(AbstractIoFilterChain.java:272)
at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionCreated(AbstractIoFilterChain.java:265)
at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionCreated(IoServiceListenerSupport.java:226)
at org.apache.mina.transport.sock
Ağu 07 14:56:56 2008: et.nio.SocketIoProcessor.doAddNew(SocketIoProcessor.java:170)
at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$300(SocketIoProcessor.java:44)
at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:554)
at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
at java.lang.Thread.run(Thread.java:534)
Caused by: java.lang.IllegalStateException: A filter chain cannot contain more than one ProtocolCodecFilter.
at org.apache.mina.filter.codec.ProtocolCodecFilter.onPreAdd(ProtocolCodecFilter.java:139)
at org.apache.mina.common.support.AbstractIoFilterChain.register(AbstractIoFilterChain.java:175)
... 20 more



 Comments   
Comment by Steve Bate [ 11/Aug/08 ]

I've never seen this and nobody else has reported this type issue. The QFJ code does very little during MINA's session creation callback. Almost all of the stack trace above is in MINA code. Are you using the version of MINA included with QFJ? If so, you'll need to narrow the problem down a bit before I can help much.

Comment by Serife Kapukaya [ 13/Aug/08 ]

Yes, I am using the version of MINA included with QFJ which is 1.0.1. More than one ProtocolCodecFilter causes the problem. But the weird thing is I didn't modified either quickfix code or MINA code. And also I had successful connections with former clients.





[QFJ-332] Session sendToTarget(Message message, SessionID sessionID) throws NullPointerException Created: 11/Aug/08  Updated: 06/Oct/08  Resolved: 10/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Charlie Zhang Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

WindowsXP with Java 1.6



 Description   

Here is the excerpt from our application:

try {
...
Session.sendToTarget(message, sessionID);
...
}
catch (SessionNotFound e) {
...
}
catch (XXXException e) {
...
}

the sessionID was set to null due to some reason and we got a NullPointerException

java.lang.NullPointerException
at quickfix.Message.setSessionID(Message.java:423)
at quickfix.Session.sendToTarget(Session.java:454)

But in the sendToTaget method:

public static boolean sendToTarget(Message message, SessionID sessionID)
throws SessionNotFound

{ message.setSessionID(sessionID); Session session = lookupSession(sessionID); if(session == null) throw new SessionNotFound(); else return session.send(message); }

should the message.setSessionID(sessionID) line be put into the else block?






[QFJ-331] SessionSettings variables remove \ during replacement Created: 08/Aug/08  Updated: 09/Sep/08  Resolved: 08/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1, 1.3.2
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Jacob Northey Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

Given the following Session Settings and system property fix.home=C:\fix\home. The value resolves to C:fixhome/logs instead of the expected C:\fix\home/logs.

[DEFAULT]
...
FileLogPath=$

{fix.home}

/logs
...

To fix this add the following line to the SessionSettings.java file (after line 563):

if (variableValue != null)

{ variableValue = variableValue.replaceAll("\\\\", "\\\\\\\\"); //this is the new line m.appendReplacement(buffer, variableValue); }

 Comments   
Comment by Steve Bate [ 08/Sep/08 ]

System properties should be provided with a valid Java string (either escaped backslashes or a Java path). The problem with replacing all backslashes is that a valid Java string might already have a backslash for some other reason and the replacement would modify the string in an undesirable way.

Comment by Jacob Northey [ 09/Sep/08 ]

Unfortunately most system properties are defined with a single backslash and are unusable in configuration files. For instance the system properties user.home and user.dir cannot be used because of this. I do realize that there is an issue with breaking existing implementations. However, it seems to have more upside allowing existing system properties to be used than to break the few existing implementations which use the properties in question, considering the fix for existing implementations is to remove a single backslash. If there is a better way to work around this (without overriding system properties) I would be satisfied.





[QFJ-330] Method do get the avilable Groups in a Group list from the FieldMap Object Created: 07/Aug/08  Updated: 06/Oct/08  Resolved: 10/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Improvement Priority: Major
Reporter: Asanka Abeysinghe Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu-Gutsy, JSK 1.5


Attachments: File QFJ-330-1.patch     File QFJ-330.patch    

 Description   

Facility to get the Group in a list (List<Group> ) from the FieldMap,
With the current implementation it has to get the no of groups and a group iterator, and access by creating a group object.
To get the group (delimiter) info required to access the data dictionary. Which is bit of work than getting a list of group objects.



 Comments   
Comment by Asanka Abeysinghe [ 16/Aug/08 ]

attached the patch for the above issue.
This will make getGroups(Groupkey) method public. It will allow to extract the group objects with the delimiter that will avoid accessing data dictionary to find such info.

Comment by Asanka Abeysinghe [ 16/Aug/08 ]

correct patch is attached, Pls ignore QFJ-330.patch





[QFJ-329] Cannot access the nested repeating group info using data dictionary object Created: 07/Aug/08  Updated: 12/Feb/15

Status: Open
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.3.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Asanka Abeysinghe Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Environment:

Ubuntu-Gutsy, JDK1.5



 Description   

This is my code snippet
FileInputStream file = new FileInputStream(new java.io.File("/home/asankaa/etc/spec/FIX44.xml"));
DataDictionary dd = new DataDictionary(file);
DataDictionary.GroupInfo ddGroup1 = dd.getGroup("D",453);
System.out.println("Delimeter Group : "+ ddGroup1.getDelimeterField());
DataDictionary.GroupInfo ddGroup2 = dd.getGroup("D",802);
System.out.println("Delimeter Group : "+ ddGroup2.getDelimeterField());
When I access the group info for 453 (NoPartyIds) DD provides the correct info with 448 as the delimiter, but when trying to access info about 802 (NoPartySubId)



 Comments   
Comment by Serkan Kaba [ 08/Nov/10 ]

log4fix is unable to parse repeating groups due to this.

See: http://code.google.com/p/log4fix/issues/detail?id=9

Comment by Serkan Kaba [ 08/Nov/10 ]

I fixed the log4fix bug using hasGroup and getGroups. But this is still an issue.

Comment by lassaad ismail [ 11/Feb/15 ]

Hi Serkan

I encounter the same issue with PartySubIDs group !
Is there some fix for this?

Thanks

Comment by Christoph John [ 12/Feb/15 ]

No, unfortunately there currently is no fix for this. Maybe the link in the first comment helps? It includes a patch how Serkan worked around the issue.





[QFJ-328] ordermatch uses the wrong ExecType (tag 150) to accept a new order. Created: 05/Aug/08  Updated: 06/Oct/08  Resolved: 08/Sep/08

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.3.2
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Dale Wilson Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

QFJ on Windows XP. jdk1.5.0_15



 Description   

When ordermatch receives a new order it returns an execution report with ExecType and OrdStatus of FILLED. It should be returning NEW.

The following patch applied to rev 835 in the svn repository fixes this.

cd: quickfixj\examples\src\main\java\quickfix\examples\ordermatch

Index: Application.java
===================================================================
— Application.java (revision 835)
+++ Application.java (working copy)
@@ -147,7 +147,7 @@
}

private void acceptOrder(Order order)

{ - updateOrder(order, OrdStatus.FILLED); + updateOrder(order, OrdStatus.NEW); }

private void cancelOrder(Order order) {






[QFJ-327] Compiling the source under jdk 1.5.x; inconvertible types Created: 05/Aug/08  Updated: 08/Sep/08  Resolved: 08/Sep/08

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

Type: Other Priority: Default
Reporter: Thomas Hügel Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Just tried to compile the source with "ant jar" under jdk 1.5.x because the new release 1.3.2 seems to be compiled wiht a newer version ("Bad version number in .class File").

I got the following:
--------------------------------------------------------
compile_main:
[javac] Compiling 1431 source files to /private/tmp/qfixsrc/quickfixj/core/target/classes/main
[javac] /private/tmp/qfixsrc/quickfixj/core/src/main/java/quickfix/FieldMap.java:211: inconvertible types
[javac] found : quickfix.Field<capture of ?>
[javac] required: quickfix.StringField
[javac] StringField f = (StringField) fields.get(field);
[javac] ^
[javac] /private/tmp/qfixsrc/quickfixj/core/src/main/java/quickfix/FieldMap.java:358: inconvertible types
[javac] found : quickfix.Field<capture of ?>
[javac] required: quickfix.BytesField
[javac] else if (!(returnField instanceof BytesField))
[javac] ^
[javac] /private/tmp/qfixsrc/quickfixj/core/src/main/java/quickfix/FieldMap.java:362: inconvertible types
[javac] found : quickfix.Field<capture of ?>
[javac] required: quickfix.BytesField
[javac] return (BytesField) returnField;
[javac] ^
[javac] /private/tmp/qfixsrc/quickfixj/core/src/main/java/quickfix/DataDictionary.java:589: inconvertible types
[javac] found : quickfix.Field<capture of ?>
[javac] required: quickfix.StringField
[javac] StringField field = (StringField) iterator.next();
[javac] ^
[javac] Note: Some input files use or override a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] 4 errors

BUILD FAILED
/private/tmp/qfixsrc/quickfixj/build.xml:36: The following error occurred while executing this line:
/private/tmp/qfixsrc/quickfixj/build.xml:27: The following error occurred while executing this line:
/private/tmp/qfixsrc/quickfixj/core/build.xml:80: The following error occurred while executing this line:
/private/tmp/qfixsrc/quickfixj/core/build.xml:85: The following error occurred while executing this line:
/private/tmp/qfixsrc/quickfixj/core/build.xml:104: Compile failed; see the compiler error output for details.

--------------------------------------------------------

Do you have any suggestions how to solve the problem ?.

Thanks
Thomas



 Comments   
Comment by Steve Bate [ 06/Aug/08 ]

Are you using the newest version of JDK 1.5? There are some generics-related bugs in early versions of the compiler.

There are special JDK1.4 binary packages if that's what you need. The source must be compiled with Java 5+.

Comment by Toli Kuznets [ 07/Aug/08 ]

Thomas,

It compiles for me with java version "1.5.0_13"

if i remember correctly, you need to have Java version higher than 1.5.0_06 - there was a bug in compilation of generics in _06 so you need to get a compiler higher than that.

Here's the output of my java -version call:
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)

Comment by Thomas Hügel [ 07/Aug/08 ]

Thanks for the response. I tried with 1.5.0_06 then with 1.5.0_07 - failed; then I downloaded the last 1.5 sdk Version "1.5.0_16". This one was able to compile the source.

Comment by Christoph John [ 25/Aug/08 ]

Hi,

I am not even trying to compile the source but when I start my process which uses QuickFIX/J 1.3.2 then I also get:

Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

I have JDK 1.5.0_16. When using JDK1.6.0_07 the error does not occur.

Any thoughts?
Best regards,
Chris

Comment by Steve Bate [ 25/Aug/08 ]

It's possible the code was accidentally compiled with Java 6 instead of Java 5. I'll check into it. Thanks for the report. I'm surprised no one else has reported this issue.





[QFJ-326] ThreadPerSessionEventHandlingStrategy leaks threads! Created: 05/Aug/08  Updated: 20/Apr/09  Resolved: 26/Nov/08

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

Type: Bug Priority: Major
Reporter: Dan Mihai Dumitriu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Threads created by ThreadPerSessionEventHandlingStrategy are never shutdown. This is probably not an issue most of the time. In our case, however, we dynamically create sessions when accepting, much like in the Executor.java example. Threads are never, ever shutdown, even if the session is logged out.



 Comments   
Comment by Steve Bate [ 05/Aug/08 ]

Yes, this would be an issue with dynamically created sessions. Have you considered using the SocketAcceptor instead of ThreadedSocketAcceptor?

Comment by Dan Mihai Dumitriu [ 05/Aug/08 ]

Yea, certainly we could switch to the single threaded SocketAcceptor, for now. Longer term, however, the issue should probably be addressed. There are probably not too many people using the dynamic sessions, right?

Comment by Steve Bate [ 05/Aug/08 ]

The dynamic sessions were added primarily to support FIX simulators where you might not know the identity of counterparties before they connect. The issue you raised is valid. There are also other related issues. In general, the dynamic session support gives the ability to create new sessions on the fly but not the ability for those sessions (and associated resources) to be destroyed. For example, the sessions will not be garbage collected after logout and this could be considered a memory leak if there are a large number of dynamically created sessions.

We need functionality added to the dynamic session support to allow automatically destroying a session after logout (or maybe after it's been logged out for a specified period of time).

Comment by Jerry Shea [ 27/Feb/09 ]

I'd like this to be reopened as threads still leak.
1. in ThreadPerSessionEventHandlingStrategy.stopDispatcherThreads the dispatchers.clear() is done before looping through the collection and so threads' stopDispatcher is never called
2. ThreadPerSessionEventHandlingStrategy.MessageDispatchingThread.run never terminates as this method repeatedly calls getNextMessage in a loop and getNextMessage calls messages.take which blocks indefinitely
3. also, stopDispatcherThreads should wait for threads to terminate before it returns so that everything gets cleaned up properly and in order

I've got a patch which fixes these by:
1. reordering statements in stopDispatcherThreads
2. using messages.poll which times out. Have set up a constant timeout of 10 seconds
3. waiting for threads to finish

What do people think about the timeout value? We could make this timeout configurable, or higher.

Comment by Jerry Shea [ 02/Mar/09 ]

I can't upload the patch - is that because this issue is closed?

Comment by Jörg Thönnes [ 03/Mar/09 ]

In reply to comment #5:
>
> I can't upload the patch - is that because this issue is closed?

How about creating a follow-up ticket? This ticket has been included into version 1.4.0
and re-opening it would make it difficult to track in which version this has been really corrected.

You could refer to this ticket, of course.

Comment by Jerry Shea [ 20/Apr/09 ]

Follow up ticket created - http://www.quickfixj.org/jira/browse/QFJ-410





[QFJ-325] dead web link to License - easyfix Created: 05/Aug/08  Updated: 06/Oct/08  Resolved: 07/Aug/08

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

Type: Bug Priority: Default
Reporter: R Herrold Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

http://www.quickfixj.org/quickfixj/usermanual/ points to:

Free! It costs nothing and has a very liberal open source licence.

which is a dead link to:

http://www.quickfixj.org/quickfixj/usermanual/documentation/license.html



 Comments   
Comment by R Herrold [ 08/Aug/08 ]

I still get a 404 ?

– Russ herrold

Comment by Steve Bate [ 08/Aug/08 ]

It's updated in SVN. I haven't updated the web site yet.





[QFJ-324] Message bodylength calculation incorrect Created: 01/Aug/08  Updated: 15/Nov/12  Resolved: 19/Aug/08

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

Type: Bug Priority: Default
Reporter: Fuzzy Gruber Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

quickfix.Message.bodylength() returns a smaller value than quickfix.Message.toString().

This is because CTRL+A characters are not counted in the value of bodylength().

(If this is a feature and not a bug, it should be documented)



 Comments   
Comment by Fuzzy Gruber [ 01/Aug/08 ]

I mean quickfix.Message.toString().length()

Comment by Jörg Thönnes [ 01/Aug/08 ]

BodyLength is a Standard FIX Header tag. Its contents is defined in the FIX specification, e.g. FIX 4.4 Vol. 2, page 4:

> The message length is indicated in the BodyLength field and is verified by counting the number of characters in
> the message following the BodyLength field up to, and including, the delimiter immediately preceding the
> CheckSum tag ("10=").

So this value must differ from a plain toString().length(). And it is documented in the FIX spec.

Cheers, Jörg

Comment by Fuzzy Gruber [ 04/Aug/08 ]

Jörg,

The BodyLength FIELD you're talking about would be retrieved using:
BodyLength bodyLength = new BodyLength();
message.get(bodyLength);
int fixBodyLength = bodyLength.getValue();

I understand this to be different compared to Message.bodylength()?

Thanks

-James

Comment by Steve Bate [ 19/Aug/08 ]

The m.bodyLength() value is the same as the tag 9 (BodyLength) in a fully constructed message. You also must retrieve tag 9 from the message header, not from the body.





[QFJ-323] why i got this message when restoring logon Created: 16/Jul/08  Updated: 08/Sep/08  Resolved: 08/Sep/08

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

Type: Other Priority: Default
Reporter: Alum Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

webshpere



 Description   

I make sure there is only an ininitiator by follow code :
[code]
System.err
.println("initiator new lastNewCount=" + (newCount++));
initiator = new SocketInitiator(appMarketData, messageStoreFactory,
settings, logFactory, messageFactory);
[/code]

the "initiator new lastNewCount=" . is printed out only once time .

when the remote server shutdown for a while ( maybe 15mins) , follow message is printed out in error

-------------------------------
[08-7-15 22:25:34:453 EDT] 0000004e SystemErr R File delete failed: C:\Enviroment\FIX\FIX.4.2-***-CurrenexStream.body
[08-7-15 22:25:34:453 EDT] 0000004e SystemErr R File delete failed: C:\Enviroment\FIX\FIX.4.2-***-CurrenexStream.seqnums
[08-7-15 22:25:34:594 EDT] 00000056 SystemErr R File delete failed: C:\Enviroment\FIX\FIX.4.2-***-CurrenexStream.body
[08-7-15 22:25:34:594 EDT] 00000056 SystemErr R File delete failed: C:\Enviroment\FIX\FIX.4.2-***-CurrenexStream.seqnums

-------------------------------
I checked the log , in this while , quickfixj was trying to restore the connection .

this is the cfg file i am using :

[default]
BeginString=FIX.4.2
ConnectionType=initiator
StartTime=22:05:00
EndTime=22:00:00

[SESSION]
BeginString=FIX.4.2
SenderCompID=***
TargetCompID=***
SessionQualifier=CurrenexStream
FileStorePath=C:/Fix/
HeartBtInt=60
SocketConnectPort=442
SocketConnectHost=server
DataDictionary=C:/Fix/FIX42.xml
ResetOnLogon=Y
ResetOnLogout=N
ResetOnDisconnect=N
RefreshOnLogon=Y
SocketReceiveBufferSize=32768
SocketSendBufferSize=16834
SocketTcpNoDelay=Y

anybody give me some idea, thanks!






[QFJ-322] Bad checksum passes FIXMessageDecoder validation Created: 09/Jul/08  Updated: 06/Oct/08  Resolved: 19/Aug/08

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.3.1
Fix Version/s: 1.3.3

Type: Bug Priority: Default
Reporter: Jay Walters Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Java 6, Windows XP



 Description   

The FIXMessageDecoder.startsWith method has a bug, and the other functions in FIXMessageDecoder do not properly handle percolating the case back up to the caller. Specifically, if the pattern is matching against the end of a ByteBuffer it only matches the first character of the pattern. If the pattern doesn't match, there is no way to percolate a MessageDecoderResult.NOT_OK back up to the caller, it will just send back NEED_DATA.

It is best illustrated by running the following JUnit test

Paste into the FIXMessageDecoderTest class

public void testPatternMatching() throws Exception

{ decoder = new FIXMessageDecoder("UTF-16"); setUpBuffer("8=FIX.4.2\0019=12\00135=X\001108=30\0011wmyadz"); MessageDecoderResult decoderResult = decoder.decode(null, buffer, decoderOutput); assertEquals("wrong decoder result", MessageDecoderResult.NOT_OK, decoderResult); }

 Comments   
Comment by Steve Bate [ 10/Jul/08 ]

I have a fix for the bug in startsWith (there is also a bug in how the failed startsWith is handled). It's been awhile since I've been in the guts of MINA buffer handling, but IIRC returning a NOT_OK will result in a ProtocolCodecException being thrown by MINA and any data left in the current buffer is lost. Therefore, the intent is to log the error and then continue processing data in the buffer (which could contain another message fragment).





[QFJ-321] PersistMessages config parameter default value is wrong in the QuickFIX/J User Manual Created: 01/Jul/08  Updated: 15/Nov/12  Resolved: 01/Jul/08

Status: Closed
Project: QuickFIX/J
Component/s: Documentation, Engine
Affects Version/s: 1.3.1
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Baxter Solutions Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-290 FileStore.messageIndex is not cleared... Closed

 Description   

The QuickFIX/J User Manual says that the default value of the PersistMessages parameter is "N" (false). But in the DefaultSessionFactory its default value is true (line 150):

            boolean persistMessages = getSetting(settings, sessionID,
                    Session.SETTING_PERSIST_MESSAGES, true);

If this parameter is set to true, then there is a memory leak in the FileStore class. The size of HashMap messageIndex is growing all the time. The reset() method does not clear this map.



 Comments   
Comment by Steve Bate [ 01/Jul/08 ]

Are you using the documentation that is shipped with QFJ or the online documentation? The online documentation is sometimes a bit out of date. If it's a problem with the online documentation I'll be sure to update it when I release 1.3.2 (any day now). The PersistMessages docs should be correct in the 1.3.1 distribution. The value was changed in SVN revision 748 and the 1.3.1 release tag is revision 786.

The messageIndex is cleared by reset.

reset() -> initialize() --> initializeCache() --> initializeMessageIndex() --> messageIndex.clear() ...





[QFJ-320] Negative TimeZoneOffset newIncorrectDataException Created: 01/Jul/08  Updated: 22/Jul/14  Resolved: 22/Jul/14

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

Type: Bug Priority: Default
Reporter: Zana Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None


 Description   

When trying to retrieve a negative timezone, I get an exception quickfix.FieldMap.newIncorrectDataException(FieldMap.java:410).

It seems that it is caused by the following code in IntConverter.java, it expects only digits.
public static int convert(String value) throws FieldConvertError {
try {
for (int i = 0; i < value.length(); i++) {
if (!Character.isDigit(value.charAt))

{ throw new NumberFormatException(); }

return Integer.parseInt(value);
...

The code I am using is as follows:

TimezoneOffset timezoneOffset = new TimezoneOffset();
try {
noMDEntries.get(timezoneOffset);
} catch(FieldNotFound e) {
//field is optional
}



 Comments   
Comment by Steve Bate [ 01/Jul/08 ]

Thanks for the report. This has already been fixed in the trunk.





[QFJ-319] JDBC message store and file message store deal with Sender and Target Sub IDs differently Created: 01/Jul/08  Updated: 15/Nov/12  Resolved: 01/Jul/08

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

Type: Bug Priority: Default
Reporter: William McSherry Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None


 Description   

File message store determines uniqueness of a session by using SenderCompID, TargetCompID, SenderSubID and TargetSubID
JDBC message store determines uniqueness of a session by using only SenderCompID, TargetCompID.
Should this be consistent across all message stores.

Thanks
Bill



 Comments   
Comment by Steve Bate [ 01/Jul/08 ]

Both message stores support full session IDs. However, for the JDBC store the table must contain the appropriate columns (it detects this automatically). Do you have an older message store table schema without the additional ID columns?





[QFJ-318] FileLog for Messages Sometimes Omits Endline Between Messages Created: 27/Jun/08  Updated: 29/Sep/16  Resolved: 01/Jul/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Robert Reyes Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Red Hat SE 5 Linux


Issue Links:
Relates
is related to QFJ-677 The fix for QFJ-318 was reverted (ina... Closed

 Description   

The .messages log file does not show the endline between two distinct FIX messages. You'll notice that the field delimiter does show up after tag 10 in the first message, but then the second message is appended onto it without a new line being started.

20080626-15:42:19.969: 8=FIX.4.2☺9=208☺35=G☺34=429600☺49=SENDER☺52=20080626-15:42:19.969☺56=TARGET☺1
1=428918☺21=1☺38=5000☺40=2☺41=428899☺44=67.26☺54=1☺55=VBK☺60=20080
626-15:42:19.969☺100=ARCA☺111=1000☺115=SENDER☺10=251☺20080626-15:42:19.969: 8=FIX.4.2☺9=238☺35=8☺49
=SENDER☺56=TARGET☺34=432761☺52=20080626-15:42:19☺128=TARGET☺20=0☺17=76☺38=2700☺40=2☺44=26.7
5☺54=1☺55=EWA☺37=58☺32=200☺31=26.74☺14=1300☺6=26.74☺39=1☺151=1400☺60=20080626-15:42:19☺150=
1☺11=687☺59=0☺10=127☺



 Comments   
Comment by Robert Reyes [ 27/Jun/08 ]

It turns out that this is due to FileLog.java not synchronizing on the writeMessage method. After the two messages that printed together were finished, I saw an empty line print out.

Comment by Jörg Thönnes [ 28/Jun/08 ]

Ideally, file append mode and atomic writes should be used here. In UNIX, this would be the O_APPEND mode
and exactly on write() system call with the complete line. Then the OS will ensure, that the complete line is written
onto the end of the file.

Using synchronized writeMessage() is the second best alternative, IMHO.

Comment by Steve Bate [ 01/Jul/08 ]

The tradeoff is between creating more temporary objects to prebuild the complete log text before calling write() or to synchronize the writeMessage method. It seems to me that the synchronization might be less overall impact on performance than creating an extra temporary object for log write.





[QFJ-317] Improve processing of invalid messages Created: 19/Jun/08  Updated: 07/Aug/08  Resolved: 19/Jun/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I've seen this before, Sometimes quickfixj receive messages but doesn't call state.setLastReceivedTime(SystemTime.currentTimeMillis() because those message can't pass the verification. My solution is move
state.setLastReceivedTime(SystemTime.currentTimeMillis());
state.clearTestRequestCounter();
to the top of the Session.verify(Message msg, boolean checkTooHigh, boolean checkTooLow).

Mike Gu
[email protected]






[QFJ-316] Problem with proxool configuration leads to SQLExceptions Created: 18/Jun/08  Updated: 07/Aug/08  Resolved: 18/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Rainer Wallscheid Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Solaris 10, jdk 1.5.0_14, proxool-0.9.0RC3.jar



 Description   

There is a bug in the proxool library. The default parameter defined in the documentation are not set. Therefore parameter like MaximumConnectionCount are not set. JdbcUtil from QuickFixJ sets this parameter. But the parameter SimultaneousBuildThrottle is not set and therfore 0. This leads to SQLExcption under high load. I changed JdbcUtil.getDataSource() with the line

ds.setSimultaneousBuildThrottle(10);

after the line

ds.setMaximumConnectionCount(10);

Now I do not get SQLException anymore.

Log-Snipplet:

00:59:52,795 [QFJ Message Processor] DEBUG fix.MessageConverter - Field(s) = SenderSubID SenderLocationID TargetSubID TargetLocationID OnBehalfOfCompID Delive
rToCompID SecureDataLen SecureData PossDupFlag PossResend OrigSendingTime XmlDataLen XmlData MessageEncoding LastMsgSeqNumProcessed OnBehalfOfSendingTime are
missing but not mandatory
00:59:52,795 [QFJ Message Processor] INFO fix.MessageConverter - <?xml version="1.0" encoding="ISO-8859-1"?>
<FIXML><FIXMLMessage><Header><BeginString>FIX.4.2</BeginString><MsgType>2</MsgType><Sender><CompID>WESTLB3</CompID></Sender><Target><CompID>REDIRPT3</CompID><
/Target><MsgSeqNum>4</MsgSeqNum><SendingTime>Tue Jun 17 00:59:52 MEST 2008</SendingTime></Header><AdministrativeMessage><Heartbeat/></AdministrativeMessage><A
dministrativeMessage><ResendRequest><BeginSeqNo>2</BeginSeqNo><EndSeqNo>0</EndSeqNo></ResendRequest></AdministrativeMessage></FIXMLMessage></FIXML>
00:59:52,795 [QFJ Message Processor] INFO msg.outgoing - FIX.4.2:WESTLB3->REDIRPT3: 8=FIX.4.2^A9=67^A35=2^A34=4^A49=WESTLB3^A52=20080616-22:59:52.794^A56=RED
IRPT3^A7=2^A16=0^A10=189^A
00:59:52,797 [Thread-6] INFO quickfixj.event - FIX.4.2:WESTLB3->REDIRPT3: Processing QUEUED message: 3
00:59:52,797 [Thread-6] INFO fix.ReaderApplication - fromAdmin: FIX.4.2:WESTLB3->REDIRPT3
00:59:52,797 [Thread-6] DEBUG fix.ReaderApplication - expected sender number = 4
00:59:52,797 [Thread-6] DEBUG fix.ReaderApplication - expected target number = 3
00:59:52,798 [Thread-6] DEBUG fix.MessageConverter - Field(s) = SenderSubID SenderLocationID TargetSubID TargetLocationID OnBehalfOfCompID DeliverToCompID Sec
ureDataLen SecureData PossDupFlag PossResend OrigSendingTime XmlDataLen XmlData MessageEncoding LastMsgSeqNumProcessed OnBehalfOfSendingTime are missing but n
ot mandatory
00:59:52,798 [Thread-6] INFO fix.MessageConverter - <?xml version="1.0" encoding="ISO-8859-1"?>
<FIXML><FIXMLMessage><Header><BeginString>FIX.4.2</BeginString><MsgType>0</MsgType><Sender><CompID>REDIRPT3</CompID></Sender><Target><CompID>WESTLB3</CompID><
/Target><MsgSeqNum>3</MsgSeqNum><SendingTime>Tue Jun 17 00:59:52 MEST 2008</SendingTime></Header><AdministrativeMessage><Heartbeat><TestReqID>TEST</TestReqID>
</Heartbeat></AdministrativeMessage></FIXMLMessage></FIXML>
00:59:52,802 [Thread-6] INFO quickfixj.event - FIX.4.2:WESTLB3->REDIRPT3: error processing message
java.io.IOException: We are already in the process of making 1 connections and the number of simultaneous builds has been throttled to 0
at quickfix.JdbcStore.storeSequenceNumbers(JdbcStore.java:291)
at quickfix.JdbcStore.setNextTargetMsgSeqNum(JdbcStore.java:274)
at quickfix.JdbcStore.incrNextTargetMsgSeqNum(JdbcStore.java:161)
at quickfix.SessionState.incrNextTargetMsgSeqNum(SessionState.java:347)
at quickfix.Session.nextHeartBeat(Session.java:1134)
at quickfix.Session.next(Session.java:698)
at quickfix.Session.next(Session.java:1515)
at quickfix.Session.nextQueued(Session.java:1505)
at quickfix.Session.nextQueued(Session.java:1489)
at quickfix.Session.nextHeartBeat(Session.java:1135)
at quickfix.Session.next(Session.java:698)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:106)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.SocketInitiator.block(SocketInitiator.java:60)
at com.westlb.fix.Reader.run(Reader.java:105)
Caused by: java.sql.SQLException: We are already in the process of making 1 connections and the number of simultaneous builds has been throttled to 0
at org.logicalcobwebs.proxool.Prototyper.checkSimultaneousBuildThrottle(Prototyper.java:260)
at org.logicalcobwebs.proxool.ConnectionPool.getConnection(ConnectionPool.java:170)
at org.logicalcobwebs.proxool.ProxoolDataSource.getConnection(ProxoolDataSource.java:97)
at quickfix.JdbcStore.storeSequenceNumbers(JdbcStore.java:281)
... 14 more

00:59:52,817 [QFJ Message Processor] DEBUG proxool.quickfixj-1 - 007351 (01/02/00) - Connection #4 created on demand = ACTIVE
00:59:52,819 [QFJ Message Processor] INFO quickfixj.event - FIX.4.2:WESTLB3->REDIRPT3: Sent ResendRequest FROM: 2 TO: 0
00:59:53,362 [SocketConnectorIoProcessor-0.0] DEBUG message.FIXMessageDecoder - detected header: pos=0,lim=81,rem=81,offset=0,state=1
00:59:53,362 [SocketConnectorIoProcessor-0.0] DEBUG message.FIXMessageDecoder - body length = 59: pos=0,lim=81,rem=81,offset=15,state=3
00:59:53,362 [SocketConnectorIoProcessor-0.0] DEBUG message.FIXMessageDecoder - message body found: pos=0,lim=81,rem=81,offset=74,state=4
00:59:53,363 [SocketConnectorIoProcessor-0.0] DEBUG message.FIXMessageDecoder - found checksum: pos=0,lim=81,rem=81,offset=74,state=4
00:59:53,363 [SocketConnectorIoProcessor-0.0] DEBUG message.FIXMessageDecoder - parsed message: pos=81,lim=81,rem=0,offset=81,state=4 8=FIX.4.2^A9=59^A35=4^A4
9=REDIRPT3^A56=WESTLB3^A34=4^A52=20080616-22:59:53^A36=4^A10=078^A
00:59:53,363 [SocketConnectorIoProcessor-0.0] INFO msg.incoming - FIX.4.2:WESTLB3->REDIRPT3: 8=FIX.4.2^A9=59^A35=4^A49=REDIRPT3^A56=WESTLB3^A34=4^A52=2008061
6-22:59:53^A36=4^A10=078^A
00:59:53,363 [Thread-6] INFO fix.ReaderApplication - fromAdmin: FIX.4.2:WESTLB3->REDIRPT3






[QFJ-315] Field type EXCHANGE is mapped to type CHAR, whereas the ENUM should be of String type. Breaks generating source code. Created: 04/Jun/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

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

Type: Bug Priority: Major
Reporter: Emil Crumhorn Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP Pro



 Description   

In the Fields.xsl file used at code generation time, there are three field types mapped and a default as follows;

<xsl:template name="values">
<xsl:for-each select="value">
<xsl:choose>
<xsl:when test="../@type='STRING'">public static final String <xsl:value-of select="@description"/> = "<xsl:value-of select="@enum"/>";
</xsl:when>
<xsl:when test="../@type='BOOLEAN'">public static final boolean <xsl:value-of select="@description"/> = <xsl:call-template name="y-or-n-to-bool" />;
</xsl:when>
<xsl:when test="../@type='INT'">public static final int <xsl:value-of select="@description"/> = <xsl:value-of select="@enum"/>;
</xsl:when>
<xsl:otherwise>public static final char <xsl:value-of select="@description"/> = '<xsl:value-of select="@enum"/>';
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>

The missing entry for "EXCHANGE" should be:

<xsl:when test="../@type='EXCHANGE'">public static final String <xsl:value-of select="@description"/> = "<xsl:value-of select="@enum"/>";
</xsl:when>

The default FIX44.xml file does not actually have any entries listed for "SecurityExchange" and thus this issue never crops up when genrating the QuickFix/J source on the normal FIX44.xml file (or other versions), however, if any entry is added under the fields as the following example;

<field name="SourceExchange" number="6565" type="EXCHANGE">
<value description="SCOACH SWITZERLAND" enum="XQMH"/>
<value description="SWISS EXCHANGE" enum="XSWX"/>
<value description="VIRT-X" enum="XVTX"/>
</field>

the code generation will try to generate the type EXCHANGE to be a "char" enum, with field names that are longer than 1 char, or in the above case; "XQMH" etc. And as such the code will not compile. Full result:

public class SecurityExchange extends StringField
{
static final long serialVersionUID = 20050617;

public static final int FIELD = 207;
public static final char SCOACH_SWITZERLAND = 'XQMH';
public static final char SWX_SWISS_EXCHANGE = 'XSWX';
public static final char SWX_EUROPE = 'XVTX';

public SecurityExchange()

{ super(207); }

public SecurityExchange(String data)

{ super(207, data); }

}

For more details on the ENUM values, here is a FIX reference document outlining all of it:

http://www.onixs.biz/fixdictionary/4.4/app_6_c.html

As a side note, It also seems that other custom field types that are defaulted to String.class in FieldType.java will fall into the "char" enum mapping as there is no "catch clause" for them in the xsl definition. Example:

public final static FieldType Exchange = new FieldType("EXCHANGE");
public final static FieldType MonthYear = new FieldType("MONTHYEAR");
public final static FieldType Time = new FieldType("TIME");

among others.






[QFJ-314] JMXExporter should escape the values of targetCompId and other session params Created: 03/Jun/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Major
Reporter: Dan Mihai Dumitriu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The problem is that sometimes the SenderSubID contains the ':' character, and that totally messes up the JMX ObjectName. For instance, if the SessionSubID=ABC:ABC, the JMXExporter will create a name that violates the JMX naming spec.

The culprit code is below, which basically creates an ObjectName of the form "org.quickfixj:key1=value1,key2=value2,key3=value3". If any key or value has a ':' or a '=' or a ',' in it, it will be messed up. These characters should be escaped, like with '_'.

public class ObjectNameFactory {

private StringBuffer sb = new StringBuffer();

public void addProperty(String name, String value) {
if (value != null && value.length() > 0) {
if (sb.length() > 0)

{ sb.append(','); }

sb.append(name).append('=').append(value);
}
}

public ObjectName createName() throws MalformedObjectNameException

{ return ObjectName.getInstance("org.quickfixj:" + sb); }

}



 Comments   
Comment by Steve Bate [ 17/Jun/08 ]

The factory was modified to quote any values with otherwise invalid characters in them. Valid strings are not quoted since some JMX tools have problems with the quotes.





[QFJ-313] Couldn't get connection because we are at maximum connection count (10/10) and there are none available Created: 29/May/08  Updated: 15/Nov/12  Resolved: 17/Jun/08

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

Type: Other Priority: Default
Reporter: Kanupriya Dhingra Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP
S/W : JAVA1.5



 Description   

Hi,

I am trying to use JDBC log Factory. In Acceptor configuration file, i am using 5 FIX versions(4.0 to 4.4) . I used JDBC store factory. it is working properly, But while logging in Jdbc it gives me error, maximum connection count has reached, there r none connection available.... If I tries to log with Single FIX version in Acceptor coniguration, it works fine. is there any limitation on the number of connections?

Following is expection trace for your reference...

JdbcLog cannot log SQLException due to recursive log errors!
java.sql.SQLException: Couldn't get connection because we are at maximum connection count (10/10) and there are none available
at org.logicalcobwebs.proxool.Prototyper.quickRefuse(Prototyper.java:309)
at org.logicalcobwebs.proxool.ConnectionPool.getConnection(ConnectionPool.java:158)
at org.logicalcobwebs.proxool.ProxoolDataSource.getConnection(ProxoolDataSource.java:97)
at quickfix.JdbcLog.insert(JdbcLog.java:147)
at quickfix.JdbcLog.onEvent(JdbcLog.java:119)
at quickfix.CompositeLog.onEvent(CompositeLog.java:79)
at quickfix.Session.<init>(Session.java:348)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:159)
at quickfix.mina.acceptor.AbstractSocketAcceptor.createSessions(AbstractSocketAcceptor.java:254)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:83)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:100)
at quickfix.ThreadedSocketAcceptor.<init>(ThreadedSocketAcceptor.java:32)

Please reply as soon as possible.
Thanks and Regards,
Kanupriya.



 Comments   
Comment by Steve Bate [ 17/Jun/08 ]

There have been a few reports of this in the past, but it's very uncommon. If I remember correctly, it may have been related to a specific JDBC driver, but I'm not sure.





[QFJ-312] DataDictionaryTest does not reset ContextClassLoader when complete - sets to null Created: 27/May/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

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

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP
Java 1.6.0



 Description   

The DataDictionaryTest changes the threads contextClasspath loader to customClassloader. Once the test is complete, it sets the threads contextClassloader to null instead of the previous value.






[QFJ-311] FileUtil open fails if CONTEXT_RESOURCE finds file and CLASSLOADER_RESOURCE does not - no break in switch Created: 13/May/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Michael Franz Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

OSX 10.4.11
Java 1.5



 Description   

The switch statement in the FileUtil.open(...) does not break after matching CONTEXT_RESOURCE. This causes files to not open if they are found by CONTEXT_RESOURCE and not by CLASSLOADER_RESOURCE. This can also return the wrong file if each resource finds a different version of the file.






[QFJ-310] When the sender disk is full, the sender will generate messages with same sequence number. Created: 06/May/08  Updated: 15/Nov/12  Resolved: 18/Jun/08

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

Type: Bug Priority: Default
Reporter: Mike Gu Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

When the sender disk is full, the sender will generate messages with same sequence number. The reason for is in the sendRaw() method
try{
...
.....
......

if (num == 0) {
int msgSeqNum = header.getInt(MsgSeqNum.FIELD);
if (persistMessages)

{ state.set(msgSeqNum, messageString); }

state.incrNextSenderMsgSeqNum();
}
return result;
} catch (IOException e)

{ logThrowable(getLog(), "Error Reading/Writing in MessageStore", e); return false; }

When the sender disk is full, state.set(msgSeqNum, messageString) will throw an IOException.So it will return false but does not increase SenderMsgSeqNum.So next time calling sendRaw() will generate message with same sequence number.



 Comments   
Comment by Steve Bate [ 18/Jun/08 ]

This is true, but if you are out of disk space then you should probably be shutting down the engine anyway until the problem is resolved. QFJ behavior is undefined when the message store cannot store messages.





[QFJ-309] There is no need to store the messages in the message Queue when we use infinite range for resend request. Created: 06/May/08  Updated: 19/Dec/13

Status: Open
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.3.1
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Mike Gu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Windows xp, eclipse


Issue Links:
Relates
relates to QFJ-271 StackOverflowError trying to process ... Closed

 Description   

There is no need to store the messages in the message Queue when we use infinite range for resend request. Also there is no need to check the queue in the Session.next(Message) method when we use infinite range for resend request. That may cause the bug QFJ-271.






[QFJ-308] Fieldorder cannot be changed for NewOrderSingle, NewOrderMultiLeg, NewOrderCross Created: 28/Apr/08  Updated: 17/Jun/08

Status: Open
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.3.1
Fix Version/s: Future Releases

Type: Improvement Priority: Default
Reporter: Peter Reinhardt Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

The class NewOrderSingle does not allow to define a custom fieldorder, e.g. the constructor from the superclass Message(int[] fieldOrder) is not exposed.

I have a couple of extra fields my company uses, and currently I cannot change the order for these fields.



 Comments   
Comment by Steve Bate [ 03/May/08 ]

Have you considered creating a custom NewOrderSingle class with your company's field ordering and support for extra fields? You'd still need to add extra fields to the data dictionary for validation purposes. You can also generate all messages to have data dictionary-defined ordering. See the documentation on how to do that.

Comment by Peter Reinhardt [ 06/May/08 ]

Yes, that's possible.

I just have to make a copy of the NewOrderSingle class (and some of the other Order classes like NewOrderMultileg) class to support the additon of 2 custom fields. So I have to duplicate 99% of the code of the NewOrderSingle class to have custom ordering.

I think it would be much easier to expose the constructor.





[QFJ-307] Messages Logged as being sent but never sent over the wire Created: 24/Apr/08  Updated: 15/Nov/12  Resolved: 08/Sep/08

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

Type: Bug Priority: Default
Reporter: Saqib Rasul Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None

Attachments: Java Source File IoSessionResponder.java    
Issue Links:
Relates
is related to QFJ-345 Support configuration for controlling... Closed

 Description   

We had an issue with QuickfixJ where the logs told us that messages were being sent, but were infact never sent over the wire. A network trace and the resulting actions from the counterpart that we were connected to also proved that messages were never sent. What seemed to happen is that after a certain point, no messages were sent to the other party.

the strange things is that this issue only ocured on one of our platforms and we could not reproduce it on any other platform.

After diggind in QuickfixJ code and Mina code, i made several changes: those described in QFJ-296 and some others in the IoSessionResponder.java class. this seemed to resolve this issue. i wanted to get your feedback on these changes and see what you think.



 Comments   
Comment by Saqib Rasul [ 24/Apr/08 ]

the changed IoSessionResponder class. my change is in the send method

Comment by Steve Bate [ 18/Jun/08 ]

Did you determine why MINA was not able to transmit your messages? Were you having network problems? I'm concerned that your proposed change will significantly lower message throughput by effectively disabling asynchronous output.

Comment by Saqib Rasul [ 18/Jun/08 ]

I was not able to find out why mina (or java) was not sending the messages over the network. i can say that there were no network problems. We tried to trace the problem also down the system calls layer and found that the systems calls to do the network-send were not being called even though from the mina and jre perspective they seemed to be sent. from the mina logs we would see that it would not write data to the output stream.

i agree that my change is not optimal. i would be fine with being able to configure waiting for a write via session config. this way we can have the waiting on a user-by-user basis. if you want i can submit a patch for being able to configure this waiting from outside.

Comment by Steve Bate [ 20/Jun/08 ]

Did adding the join on the write cause the data to be transmitted over the wire? Or are you trying to make the app hang before logging a message transmission if it can't send a message? If you're sure it's not the network and MINA has tried to send the message, then that seems to leave a JVM NIO bug as a prime suspect. I'm not confident that adding the join will reliably solve the problem if it is actually a bug in a specific JVM implementation.

Can you leave a comment to document which version of QFJ, JVM (vendor and build), operating system, and hardware platform you were using when this occurred. Although no one else has reported this problem, the information may be useful if someone else does encounter something similar. Thanks.





[QFJ-306] JdbcStore has an incorrect query for the UPDATE, when it wants to update a message whose sequence was already entered... Created: 11/Apr/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Tom Mowad Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Everywhere



 Description   

The problem is in the function with prototype

public boolean set(int sequence, String message)

The mistaken code says:

update.setInt(offset++, sequence);
update.setString(offset, message);

But ought to be:

update.setString(offset++, message);
update.setInt(offset, sequence);

instead.

If we see the place where INSERT_UPDATE_MESSAGE is defined

INSERT_UPDATE_MESSAGE = "UPDATE " + messageTableName + " SET message=? " + "WHERE "
+ idWhereClause + " and msgseqnum=?";

it is clear that the message ought to be stored before the sequence number.



 Comments   
Comment by Dan Mihai Dumitriu [ 03/Jun/08 ]

This is a major bug. How come nobody has looked at it??





[QFJ-305] Improvements to the build process Created: 25/Mar/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Improvement Priority: Default
Reporter: Saqib Rasul Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: XML File build.xml     XML File build.xml     XML File build.xml     XML File build.xml     XML File module.xml    

 Description   

In order to make it easier to know what version of quickfixJ one is running i propose that the jars that are created should have the version of quickfixJ in their name. as in:
quickfixj-core-1.3.1.jar
looks better than
quickfixj-core.jar.

Another improvement i propose is that now that we break up the release jars into core and the fix-version-specific jars, we should also have a all-in-one-jar that contains everything. for deployment situations that dont care about fix versions and want a all-in-one jar they can deploy.

i can make the changes to the build files to implement these but i want to get agreement if this is a good idea or not.



 Comments   
Comment by Saqib Rasul [ 25/Mar/08 ]

for version 1.3.1 here is the module.xml the only change is on line 6 with the addition of this property:

<property name="quickfixj.version" value="1.3.1" />

Comment by Saqib Rasul [ 25/Mar/08 ]

the core/build.xml the changes here are in the jar target

Comment by Jörg Thönnes [ 25/Mar/08 ]

The all-in-one is probably a good idea.

Currently, just picking out one FIX version plus the core does not work since the DefaultMessageFactory
depends on all FIX versions.

Comment by Steve Bate [ 25/Mar/08 ]

I use a lot of open source products and my impression is that it's more common to not have the version numbers in the filename. I personally see advantages and disadvantages to both approaches and I don't have a strong personal preference. However, I probably won't change the current approach unless I'm convinced there is a clear benefit to the renaming.

In case you didn't know, you can determine the version of a quickfix-core.jar by executing it (e.g. "java -jar quickfix-core.jar").

I don't have a problem creating a quickfixj-all.jar.

As Joerg mentioned, there are issues with the message version dependencies. I think the issue DefaultMessageFactory can be solved by doing lazy creation of the version-specific message factories. The MessageCracker is another issue. However, this has been documented in other JIRA issues.

Comment by Saqib Rasul [ 25/Mar/08 ]

i am glad we agree on the all-in-one jar. you can see my creation of the all-in-one jar in the build.xml attached. if you like it, you may use it.

the advantages of the naming that i see are:

  • no extra step before knowing the version
  • the java -jar approach was introduced recently so it wont work for all and it not a 'standard' approach for finding out the version

the disadvantages that i see are:

  • people used to current files names will have to get used to another version
  • the java -jar works only for the quickfixj-core jar and not he message jars
  • if i download 2 versions of quickfixJ, the message-version-specific jars are named similarly and the only difference is an md5hash

i would also like to add that directory that the tar-gz (or zip) that is created from the sourceforge download should also have a version number in it so as to distinguish between version numbers.

Comment by Toli Kuznets [ 26/Mar/08 ]

I'd vote for having a version in the jar file as well.
We actually end up hosting all the QFJ jars on our Maven repository at http://repo.marketcetera.org/maven/quickfixj/ . Maven assumes that the jars have the version in them, so I would think most open-source projects are moving towards the "version-in-name" convention in the future.

Saqib, if you are using Maven, you can access QFJ off the Marketcetera repo if you follow the Maven instructions from http://www.quickfixj.org/quickfixj/usermanual/installation.html#build

Note that the docs are slightly outdated, you can grab versions 1.3.1 from there now.

Comment by Brad Harvey [ 26/Mar/08 ]

+1 for adding version to the jar name. It's a simple way to make version management of dependencies easier.

Comment by Steve Bate [ 26/Mar/08 ]

OK, I'll add the version numbers to the JAR file as well. I've scheduled this for 1.3.2. Thanks for the comments.

Comment by Saqib Rasul [ 26/Mar/08 ]

just want to add that we should also put a version number in the dir that gets un(g)ziped from the sourceforge download. for example

quickfixj-1.3.1-bin.tar.gz should untar/gunzip to a directory called 'quickfixj-1.3.1' and not 'quickfixj'

Comment by Saqib Rasul [ 24/Apr/08 ]

do you want a patch for this for the current trunk version of QuickfixJ? or for any of the branches?

Comment by Steve Bate [ 24/Apr/08 ]

A patch against the trunk or just the modified file (I can diff it myself) would be great. Thanks.

Comment by Saqib Rasul [ 04/Jun/08 ]

my apologies for the delay... i just got some time on hands and i will endeavour to get you the modified files this week.

Comment by Saqib Rasul [ 06/Jun/08 ]

here is a patch against the current trunk for this issue. i hope it is to your satisfaction. the files in question are:

$ svn status
M core/build.xml
M examples/build.xml
M build.xml





[QFJ-304] EST Timezone SessionScheduleTest.testSettingsWithoutStartEndDayWithTimeZoneInTime() Created: 18/Mar/08  Updated: 07/Aug/08  Resolved: 26/Mar/08

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Dustin Vain Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

OS X 10.5.2
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)



 Description   

SessionScheduleTest.testSettingsWithoutStartEndDayWithTimeZoneInTime() uses the timezone "EST" when it sets the Session.SETTING_START_TIME and when it sets the tz for the "current time" in the tests. It uses "US/Central" for the Session.SETTING_END_TIME.

The tests that follow assume that "US/Central" is 1 hour behind "EST". This is not always true. "US/Central" accounts for Daylight Savings and "EST" does not. So, during DST, the difference between these zones is 0 hours.

This causes the following test to fail (line 398 in version 1.3.1), because it relies on the 1 hour timezone difference:
doIsSessionTimeTest(schedule, true, 2003, 5, 5, 15, 59, 0, tz);

I suggest using "US/Eastern" instead of "EST" in this test so that the test passes year round.



 Comments   
Comment by Steve Bate [ 25/Mar/08 ]

Good point. Thanks! I'm make the change for the next release.





[QFJ-303] Remove log4j.properties file from src/main/resources Created: 15/Mar/08  Updated: 07/Aug/08  Resolved: 11/Apr/08

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Comments   
Comment by Steve Bate [ 11/Apr/08 ]

Removed





[QFJ-302] Changing SocketConnectPort or SocketConnectHost does not create new set of FileStorePath temp files Created: 13/Mar/08  Updated: 15/Nov/12  Resolved: 25/Mar/08

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

Type: Bug Priority: Default
Reporter: Emil Crumhorn Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows XP, Eclipse RCP application



 Description   

We have two FIX servers living on the same remote machine (however, this test will work if you have two different machines on different IP's as well). One is on listening port 8811, the other is on 8911. Assuming I have no files in my FileStorePath and I connect with our client to 8811 and do things everything is fine and works as it should. After a while, I decide that now I want to connect to 8911 to test that machine, so I change my quickfix configuration file and update the port number to reflect this and then I restart the client and connect. However, when I then try to log on to the server I now get the following error and the server disconnects me:

MsgSeqNum too low, expecting 173 but received 32

Basically, the "temp" files do not reflect either the server or the port in them, so as it's the same files being used but now a completely different connection, it becomes rather confused and I can no longer connect until I remove the files in the FileStorePath directory and connect again.

The files seem to have the following format: FIX.4.4-XXXX-YYYY.session where the first part is obviously the FIX version, the second is the SenderCompID and the other the TargetCompID.. It seems this problem could easily be fixed by including the host and port in the naming of those files as well.



 Comments   
Comment by Steve Bate [ 25/Mar/08 ]

This is expected behavior. The sequence numbers are associated with a session ID, not a specific host or port. This is consistent with the logical notion of a FIX session as defined in the spec. The physical connection might change (e.g., during failover) but the session state continues. The failover mechanism must ensure that the session sequence numbers continue as expected when failing over to the new host.





[QFJ-301] Sending invalid requests may force Executor into an unstable state Created: 12/Mar/08  Updated: 07/Aug/08  Resolved: 11/Apr/08

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Hiranya Jayathilaka Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Ubuntu 7.10, Java 5



 Description   

Steps to reproduce the faulty state;

1. Start Banzai and Executor
2. In Banzai specify the side to be 'Cross' and send a message (This will give an exception in Executor side)
3. Now send a valid message from Banzai (specifying the side as Buy or Sell)

Doing this will force Executor to an infinite loop giving the following output over and over...

<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, incoming> (8=FIX.4.19=12535=D34=443=Y49=BANZAI52=20080312-03:48:5956=EXEC122=20080312-03:48:5711=120529373765021=138=540=154=155=IBM59=010=103)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, event> (MsgSeqNum too high, expecting 3 but received 4)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, outgoing> (8=FIX.4.19=6435=234=3549=EXEC52=20080312-03:48:5956=BANZAI7=316=99999910=200)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, event> (Sent ResendRequest FROM: 3 TO: 999999)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, incoming> (8=FIX.4.19=12535=D34=343=Y49=BANZAI52=20080312-03:48:5956=EXEC122=20080312-03:48:5411=120529373427321=138=540=154=855=IBM59=010=104)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, event> (ResendRequest for messages FROM 3 TO 3 has been satisfied.)
<20080312-03:48:59, FIX.4.1:EXEC->BANZAI, event> (Invalid order side: 8
java.lang.RuntimeException: Invalid order side: 8
at quickfix.examples.executor.Application.getPrice(Application.java:185)
at quickfix.examples.executor.Application.onMessage(Application.java:204)
at quickfix.fix41.MessageCracker.crack41(MessageCracker.java:205)
at quickfix.MessageCracker.crack(MessageCracker.java:45)
at quickfix.examples.executor.Application.fromApp(Application.java:131)
at quickfix.Session.fromCallback(Session.java:1287)
at quickfix.Session.verify(Session.java:1245)
at quickfix.Session.verify(Session.java:1316)
at quickfix.Session.next(Session.java:727)
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:106)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:595)
)



 Comments   
Comment by Steve Bate [ 11/Apr/08 ]

Modified Executor application to log an error during order processing instead of allowing the exception to propogate and rollback the session sequence number (causes an infinite resend loop between the executor and a client).





[QFJ-300] "BigDecimal" build of QuickFIX/J doesn't preserve precision in quantities Created: 05/Mar/08  Updated: 07/Aug/08  Resolved: 11/Apr/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

ant -Dgenerator.decimal=true


Attachments: Text File DecimalFieldTest.java     Text File qfj-300.patch    

 Description   

When you use a "BigDecimal" build of QuickFIX/J, it should preserve the scale of the number inside a message. For example, if I set the Price field to be "10.3000" I should get that same value (with the trailing zeroes) back from fieldMap.getDecimal(), and similar calls. Included is a simple test.

	public void testQuickFIXAssumptions() throws FieldNotFound, InvalidMessage{
		BigDecimal originalPrice = new BigDecimal("10.3000");
		assertEquals(4, originalPrice.scale());
		Message message = new Message();
		message.setField(new Price(new BigDecimal("10.3000")));
		BigDecimal extractedPrice = message.getDecimal(Price.FIELD);
		assertEquals(4, extractedPrice.scale());
		assertEquals(new BigDecimal("10.3000"), extractedPrice);
		String newOrderString = message.toString();
		Message rehydratedMessage = new Message(newOrderString);
		BigDecimal rehydratedPrice = rehydratedMessage.getDecimal(Price.FIELD);
		assertEquals(new BigDecimal("10.3000"), rehydratedPrice);
		assertEquals(4, rehydratedPrice.scale());
	}


 Comments   
Comment by Toli Kuznets [ 06/Mar/08 ]

So it seems that the culprit is the DecimalConverter.convert(BigDecimal) function.
In the current implementation it's calling through to the DecimalConverter.convert() method that takes the padding like this:
public static String convert(BigDecimal d)

{ return convert(d, 0); }

Underneath that goes into the DoubleConverter.getDecimalFormat(padding).format(d) and causes the incoming BigDecimal to lose its scale since the "padding" (or scale) is set to 0.

The way to fix that would be to use call either send in the d.scale() (which is not the best way since scale may be negative for big decimals) or rewrite the function as such:
public static String convert(BigDecimal d) { return convert(d, 0); }

Ideally, I'd vote to remove the function with "padding" altogether, and just rely on the scale() method in BigDecimal instead.

thoughts?

Comment by Toli Kuznets [ 06/Mar/08 ]

complete unit test for this issue.
Works when you patch DecimalConverter to have this convert() function:

public static String convert(BigDecimal d)

{ return d.toPlainString(); }
Comment by Graham Miller [ 07/Mar/08 ]

That unit test will only compile against a "BigDecimal" build, right? Because it uses a constructor like new Price(new BigDecimal("10.3000"))? If that's the case, we probably can't add it to the core unit tests.

Comment by Toli Kuznets [ 10/Mar/08 ]

Patch with the fix for the bug, and fixes to the sample applications to handle both doubles and BigDecimals by switching internal qty handling to BigDecimals.
Added a unit test that verifies the bug is working if fields are built with BigDecimal support.

Comment by Steve Bate [ 11/Apr/08 ]

I've applied the patches. For some reason, there were a few places where the patch wasn't performed automatically. I think I've applied the patch correctly but can you (Toli) try this out with the big decimal build? Thanks.

Comment by Toli Kuznets [ 06/May/08 ]

Steve, i've made some additional changes to the examples files which weren't part of your changes and checked them in http://quickfixj.svn.sourceforge.net/viewvc/quickfixj?view=rev&revision=804

The examples now work for both regular doubles and BigDecimal builds





[QFJ-299] Determine Data Type of a Field Created: 27/Feb/08  Updated: 10/Jan/10  Resolved: 10/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: None
Fix Version/s: Future Releases

Type: New Feature Priority: Default
Reporter: Hiranya Jayathilaka Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

any



 Description   

If there was a method to retrieve the data type of a given field it would be more convenient.



 Comments   
Comment by Steve Bate [ 18/Jun/08 ]

Which data type do you mean? The Java data type or the FIX data type as specified in the data dictionary? If it's the latter, it's possible to get this from the DataDictionary.getFieldType() method.

Comment by Steve Bate [ 10/Jan/10 ]

Closed due to nonresponse from the feature requestor.





[QFJ-298] Send Binary Data Over Fix Created: 27/Feb/08  Updated: 07/Aug/08  Resolved: 18/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.1
Fix Version/s: 1.3.2

Type: New Feature Priority: Default
Reporter: Hiranya Jayathilaka Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

any


Attachments: File svn_diff.patch    

 Description   

Currently the only way to send binary data over FIX is to get the binary data into a String and then call setString() method on the message object passing the string variable as a parameter. Since putting binary data in strings could be error prone it would be better if there was a method (somethine like setBytes(byte[] b)) to directly set a byte array into a message field.



 Comments   
Comment by Hiranya Jayathilaka [ 27/Feb/08 ]

In fact I think it's best not to allow putting binary data in messages using Strings. Strings are not meant for that kind of work.

Comment by Hiranya Jayathilaka [ 07/Mar/08 ]

Attached herewith is a possible solution for the issue. I added a new class called BytesField extending the Field class to support better handling of binary data and added setField(int field, byte[] value), setField(BytesField field) and getField(BytesField field) methods to the FieldMap API.

Comment by Steve Bate [ 18/Jun/08 ]

I've added this feature. However, be aware that internally the byte arrays are still being converted to strings. Also, the generated message "data" classes will still be based on StringField for compatibility with QuickFIX JNI. When parsing a message the data fields will be parsed into StringFields. For these reasons the BytesFields usefulness is limited somewhat.

The patch has a bug where it was formatting the field using byte[].toString() (in the Field base class) which will not result in a correct FIX message. I've added unit tests that include a test of this functionality.





[QFJ-297] Logout message not received in fromAdmin event, during first failed logon attempt. Created: 25/Feb/08  Updated: 15/Nov/12  Resolved: 19/Aug/08

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

Type: Bug Priority: Default
Reporter: Dominic Cubitt Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

JDK 1.6, Windows, Java



 Description   

Using a quickfix initiator, logging on to another FIX gateway (for the first time), where the logon is rejected for some reason, while the target gateway sends a logout message with 58=The Reason, this is not passed to the fromAdmin method. The connection is simply dropped without any way for the client application to display the reason.

While the onLogout event is called, this of course does not contain the message and therefore no reason can be extracted. Only looking at the fix message logs and examining the fix message can one tell why the logon was rejected.

If a session is previously established, and the target gateway sends a logout message, in this case the message is received on the fromAdmin and the client can display the reason.



 Comments   
Comment by Steve Bate [ 17/Jun/08 ]

Can you be more specific about the scenario where this occurs? Generally, an incoming logout message should always be provided to the fromAdmin callback. Are you sure the counterparty wasn't just dropping the connection?

Comment by Dominic Cubitt [ 17/Jun/08 ]

Specifically, the scenario is logging on for the first time, where the logon is rejected for some reason that is detailed in the logout message in tag 58.

In this case, the fromAdmin callback is not called. The onLogon callback is called.

The response message is sent and can be viewed from logs, and indeed contains the logon rejection reason in tag 58.

This makes it impossible to programmatically display the logon rejection reason.

The counterparty is not just dropping the connection, as the logout message can be viewed in the logs.

Comment by Steve Bate [ 17/Jun/08 ]

I'm trying to determine why a logout message from a "first login" would handled any differently than a logout received for any other reason. Another possibility is that the logout message is not passing validation.

The normal sequence of methods handling the logout message is...

Session.next(message)
Session.nextLogout(message)
Session.verify(message, ...)
Session.fromCallback(..., message, ...)
Application.fromAdmin(message, ...)

The fromAdmin method should always called for a valid logout message. Do you see anything in your logs related to a failed message validation for the logout? Thanks.

Comment by Steve Bate [ 18/Jun/08 ]

Dominic, have you been able to review your log files for errors with the logout verification?

Comment by Dominic Cubitt [ 18/Jun/08 ]

Hi Steve, I have sent you a log file to your ...@quickfixj email address as I did not wish to post it on a public site. Hope this helps.

Comment by Paul-Henri Giraud [ 23/Jun/08 ]

We reproduce exactly the same issue. Thanks for your help.

Comment by Paul-Henri Giraud [ 23/Jun/08 ]

It seems that we do not get the fromAdmin callback when the logout is the result of a timeout:

[11:08:34][INFO][event] FIX.4.3:XXXX->YYYY: Timed out waiting for logon response
[11:08:34][INFO][event] FIX.4.3:XXXX->YYYY: Disconnecting
[11:08:34][INFO][fixInitiator] Session FIX.4.3:XXXX->YYYY logged out.
[11:08:34][INFO][event] FIX.4.3:ZZZZ->YYYY: Timed out waiting for logon response
[11:08:34][INFO][event] FIX.4.3:ZZZZ->YYYY: Disconnecting
[11:08:34][INFO][fixInitiator] Session FIX.4.3:ZZZZ->YYYY logged out.

The fromAdmin is correctly call when the logout is actually incomming from external:

[11:08:46][INFO][outgoing] FIX.4.3:XXXX->YYYY: 8=FIX.4.3 | 9=127 | 35=A | 34=29 | 49=XXXX | 52=20080623-09:08:46.534 | 56=YYYY | 98=0 | 108=30 | 553=btobxpte0130 | 554=_OvD4bPZdyWUi6A8eMBy2IQcQW$SEl | 10=188 |
[11:08:46][INFO][event] FIX.4.3:XXXX->YYYY: Initiated logon request
[11:08:46][INFO][outgoing] FIX.4.3:ZZZZ->YYYY: 8=FIX.4.3 | 9=127 | 35=A | 34=26 | 49=ZZZZ | 52=20080623-09:08:46.550 | 56=YYYY | 98=0 | 108=30 | 553=btobxpte0130 | 554=_OvD4bPZdyWUi6A8eMBy2IQcQW$SEl | 10=192 |
[11:08:46][INFO][event] FIX.4.3:ZZZZ->YYYY: Initiated logon request
[11:08:47][INFO][incoming] FIX.4.3:XXXX->YYYY: 8=FIX.4.3 | 9=81 | 35=5 | 49=YYYY | 56=XXXX | 34=7 | 52=20080623-09:08:39 | 58=Service Unavailable | 10=210 |
[11:08:47][INFO][incoming] FIX.4.3:ZZZZ->YYYY: 8=FIX.4.3 | 9=81 | 35=5 | 49=YYYY | 56=ZZZZ | 34=5 | 52=20080623-09:08:39 | 58=Service Unavailable | 10=217 |
[11:08:47][INFO][fixInitiator] ************** fromAdmin ******************
[11:08:47][INFO][event] FIX.4.3:ZZZZ->YYYY: Received logout request
[11:08:47][INFO][event] FIX.4.3:ZZZZ->YYYY: Disconnecting
[11:08:47][INFO][fixInitiator] Session FIX.4.3:ZZZZ->YYYY logged out.
[11:08:47][INFO][event] FIX.4.3:XXXX->YYYY: Disconnecting
[11:08:47][INFO][fixInitiator] Session FIX.4.3:XXXX->YYYY logged out.

Comment by Steve Bate [ 24/Jun/08 ]

The purpose of the fromAdmin callback is to provide administrative messages from counterparties to a local application. In the case of a logon timeout, there is no corresponding message from the counterparty. Therefore, there's no message to provide to fromAdmin. The onLogout callback is still invoked since it doesn't require a message.





[QFJ-296] Messages logged as being sent even if the Responser is null Created: 06/Feb/08  Updated: 15/Nov/12  Resolved: 18/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Saqib Rasul Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

All



 Description   

In the quickfixj.Session.java class we log that a message is sent even if the Responder for that Session is null:

1770     private boolean send(String messageString) {
1771         getLog().onOutgoing(messageString);
1772         synchronized (responderSync) {
1773         if (!hasResponder()) {
1774             getLog().onEvent("No responder, not sending message");
1775             return false;
1776         }
1777         return getResponder().send(messageString);
1778         }
1779     }

as you can see in line 1771, we log the message as being sent, but we still check that the Resonder can be null and the message may eventually not be sent out



 Comments   
Comment by Saqib Rasul [ 06/Feb/08 ]

i would suggest the following fix:

private boolean send(String messageString) {
synchronized (responderSync) {
if (!hasResponder())

{ getLog().onEvent("No responder, not sending message"); return false; }

boolean messageSent = getResponder().send(messageString);

if(messageSent)
getLog().onOutgoing(messageString);
else
LogUtil.logThrowable(getLog(), "ERROR SENDING!", new Exception());

return messageSent;
}
}

even better would be to log in the Responder if the message was actually sent or not. And return the return value of the IOSession in the Respnder.

Comment by Steve Bate [ 11/Feb/08 ]

It's acceptable to send a message to a QFJ session even if the session is not currently connected. When the session connection is established later, the FIX resend protocol will transmit the message.

However, I do agree the logging could be a little more clear about what's happening. For example, we could log that the message is being stored for later transmission if there is no responder.





[QFJ-295] Extend JdbcStore and JdbcLog to allow non-empty strings as defaults (for Oracle) Created: 04/Feb/08  Updated: 07/Aug/08  Resolved: 03/May/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Oracle treats empty strings as SQL NULLs.



 Comments   
Comment by Jörg Thönnes [ 05/Feb/08 ]

Hi Steve,

I am feeling a bit uncomfortable introducing another parameter. IMHO, if this new parameter for a default null value
would be the empty string "" (not null), this would also for other non-Oracle database. We just act as Oracle and treat
empty strings like null.

In this way, we could use the empty string always and remove the externally settable parameter. This would keep the
interface simple.

Cheers, Jörg

Comment by Steve Bate [ 03/May/08 ]

Unfortunately, I didn't receive a notification about this comment so I just now saw it. I'm not sure I understand what you are suggesting. The issue is that the parameter cannot be null since the columns are part of the primary key. That's why the SessionID object uses empty strings as a default value. The problem is that Oracle has a vendor-specific behavior that treats empty strings as SQL NULLS. Since this is not allowed, some other value (other than an empty string) must be provided to Oracle. The purpose of the configurable parameter is to let the user choose what that special value will be.





[QFJ-294] "Initial Handshake failed" on ssl sessions with 1.3.1 Created: 01/Feb/08  Updated: 10/Jan/10  Resolved: 10/Jan/10

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.3.1
Fix Version/s: Future Releases

Type: Bug Priority: Default
Reporter: Thomas Hügel Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None

Attachments: Zip Archive ssl.zip    

 Description   

Today I exchanged the quickfix/j library in my fixengine in our test environment with the 1.3.1 version(before 1.3.0).
There are many sessions configured in it; all non ssl sessions came up, but the one that has ssl configured doesn´t:

19:30:01,865 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50229
19:30:02,069 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.
19:30:31,954 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50231
19:30:32,040 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.
19:31:02,046 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50232
19:31:02,206 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.
19:31:02,207 | [SocketConnectorIoProcessor-3.0] | INFO fixengine.FIXApplication | Logout: FIX.4.4:DPBTST->TRADEWEBLDN:794 Fri Feb 01 19:31:02 CET 2008 on session 'tradeweb test'
19:31:32,125 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50234
19:31:32,191 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.
19:31:32,192 | [SocketConnectorIoProcessor-3.0] | INFO fixengine.FIXApplication | Logout: FIX.4.4:DPBTST->TRADEWEBLDN:794 Fri Feb 01 19:31:32 CET 2008 on session 'tradeweb test'
19:32:02,229 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50236
19:32:02,313 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.
19:32:32,337 | [SocketConnectorIoProcessor-3.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50237
19:32:32,432 | [SocketConnectorIoProcessor-3.0] | ERROR initiator.InitiatorIoHandler | socket exception (/62.189.50.234:17001): Initial SSL handshake failed.

I switched back to the old library (1.3.0), restarted the fix engine and it works without any problems. the mina core and the ssl-filters havent changed, so it must be something in the quickfix/j core code.
19:35:01,308 | [SocketConnectorIoProcessor-2.0] | INFO initiator.InitiatorIoHandler | MINA session created: /10.252.212.72:50260
19:35:02,484 | [QFJ Message Processor] | INFO fixengine.FIXApplication | Logon: FIX.4.4:DPBTST->TRADEWEBLDN:794 Fri Feb 01 19:35:02 CET 2008 on session 'tradeweb test'

Configuration of the session:
********************************
[DEFAULT]
AutoStart=Y
Description=tradeweb test
ConnectionType=initiator
BeginString=FIX.4.4
UseDataDictionary=Y
FileStorePath=/home/jetty/fixengine/sessionpersistence
FileLogPath=/home/jetty/fixengine/log

[SESSION]
SenderCompID=xxxx
TargetCompID=xxxxx
SessionQualifier=794
StartTime=09:00:00
EndTime=20:30:00
SocketConnectHost=x.x.x.x
SocketConnectPort=17001
HeartBtInt=30
ReconnectInterval=30
TimeZone=Europe/Berlin
SendResetSeqNumFlag=N
DataDictionary=/home/jetty/fixengine/datadicts/initiator1178126847640_datadic.xml
SocketUseSSL=Y
SocketKeyStore=/home/jetty/fixengine/keystores/initiator1178126847640/keystore.ks
SocketKeyStorePassword=password
ResetOnLogout=N
************************************

Regards
Thomas



 Comments   
Comment by Steve Bate [ 02/Feb/08 ]

Not much has changed in this part of the code. The only thing I'm seeing so far that might result in this type of error is a modified strategy for loading the keystore files. It should be backwards compatible. Do you see a warning with the text "keystore not found, using empty keystore" in your application log files? If so, that would indicate there is a file loading problem.

Comment by Thomas Hügel [ 04/Feb/08 ]

i tested again and i did not found any "keystore not found warnings". But the ssl functionality remains still broken. Switching back to 1.3.0 fixed all problems.

Comment by Steve Bate [ 04/Feb/08 ]

Very mysterious. The SecureSocketTest is passing so it's working to some extent.

Can you turn on SSL debugging to see if it gives any more useful information?

http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#Debug

In the meantime, I'll do some experimentation and see if I can reproduce the problem in more complex scenarios than the one being tested in SecureSocketTest.

Steve

Comment by Thomas Hügel [ 07/Aug/08 ]

Steve,

i tested on 1.3.2, but the SSL functionality is still broken. Have to stay at 1.3.0 .

Thomas

Comment by Steve Bate [ 08/Aug/08 ]

Thanks for the report. I'd like to fix this issue but I've never been able to reproduce it. The test of the secure communications has continued to pass and I'm not sure what's different about what you're doing and what the test is doing. If you are able to create a variant of the secure socket unit test that fails it would greatly help me to diagnose and fix the problem.





[QFJ-293] running the acceptance tests will fail using any slow MessageStore Created: 01/Feb/08  Updated: 15/Nov/12  Resolved: 02/Feb/08

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

Type: Improvement Priority: Default
Reporter: Wolfgang Grinfeld Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

Windows XP - dual core Intel



 Description   

In case the acceptance tests are not run with a memoryStore and the messageStore used takes up time to update the sequence numbers (like by using a remote JDBC connection - JdbcStore), the acceptance tests are likely to fail on

6_SendTestRequest.def

This is because the heartbeat gets sent too early to the server.

Possible workaround until a better solution is created:
Slow down the messages in InitiateMessageStep.run()



 Comments   
Comment by Steve Bate [ 01/Feb/08 ]

You can use the "atest.heartbeat" system property to override the heartbeat interval specified in the test. For example, in 6_SendTestRequest, the heartbeat interval is 6 seconds. You could pass -Datest.heartbeat=30 to cause the heartbeat to be sent at 30 seconds instead. Does this solve your issue?





[QFJ-292] On checksum errors, include information on the problem section of the stream Created: 22/Jan/08  Updated: 07/Aug/08  Resolved: 17/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1, 1.3.0, 1.3.1
Fix Version/s: 1.3.2

Type: Improvement Priority: Default
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

If there is a checksum error an error is logged, but it does not include the problem section of stream. This would useful in determining if it was a garble, a problem with the counterparty's software or whatever.

A patch we've tried is to add the following snippet to FIXMessageDecoder.handleError(ByteBuffer, int, String, boolean), right before the "if(disconnect))":

int mark = buffer.position();
try {
StringBuilder sb = new StringBuilder(text);
sb.append("\nBuffer debug info: ").append(getBufferDebugInfo(buffer));
buffer.position(0);
sb.append("\nBuffer contents: ");
try

{ final byte[] array = new byte[buffer.limit()]; for(int i = 0; i < array.length; ++i) array[i] = buffer.get(); sb.append(new String(array, "ISO-8859-1")); }

catch (Exception e)

{ sb.append(buffer.getHexDump()); }

text = sb.toString();
} finally

{ buffer.position(mark); }




[QFJ-291] Problems with initiator reconnect will block heartbeats on other sessions Created: 17/Jan/08  Updated: 07/Jan/20  Resolved: 18/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1, 1.3.0, 1.3.1
Fix Version/s: 1.3.2

Type: Bug Priority: Major
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-555 Problems with heartbeating in one ses... Open

 Description   

The session timer and initiator reconnect tasks run on the same single threaded executor (SessionConnector.scheduledExecutorService). As a result, if there is a problem reconnecting on one session, it will block the heartbeat on other sessions, leading to test requests from the counterparties and, if bad enough, disconnects. We have seen this scenario in production twice and view it as serious. Other similar scenarios are possible.

Suggested fix is to switch to an unbounded pool, i.e.,
scheduledExecutorService = Executors.newScheduledThreadPool(1, new QFTimerThreadFactory());
(There is no obvious reason the tasks cannot execute in parallel.)



 Comments   
Comment by Rhys Yarranton [ 17/Jan/08 ]

One other thing to note. In the event log for the problem initiator, all you'll see is:
xx:xx:xx,xxx INFO [xxxx.Event] FIX.4.2:xxxx->yyyy: null
This is due to IoSessionInitiator.connect() line 136, which shows only the message on the IOException and does not include the stack trace. From a diagnostic point of view, I would suggest logging all exceptions caught in that catch block, and also not unrolling them (lines 132-134). (All line numbers from 1.2.1.)

Comment by Steve Bate [ 17/Jan/08 ]

OK, I understand the issue. I'm not sure I want to use an unbounded thread pool since it may lead to excessive thread construction and destruction, but I'll consider that as a possible solution. I'm thinking that I'll probably modify the ConnectTask to not wait indefinitely for the connection to complete. Instead it will basically periodically poll the ConnectFuture until the connection request completes.

On the exception issue, can you explain more how the stack trace for the IOExceptions would help you? I can understand how adding a prefix to the exception message might help when the IOException has a null message. However, printing the stack traces results in a large amounts of useless stack traces in the log files during normal reconnect scenarios.

Comment by Rhys Yarranton [ 22/Jan/08 ]

That sounds like it should work for the initiator task. The heartbeat task normally shouldn't block for long as the send is asynchronous. otoh, it could include application toAdmin() code over which the engine has no control. There is the option of a bounded pool with bound > 1, which would not fully isolate each session but would allow for a handful of problem sessions.

I'm not sure how to explain on the stack trace thing. It would include the exception type and message for all the messages in the chain, so you would likely get more info than just "null". It would make it easier to find where in the code it came from (I had to go code surfing to find log statements that might output "null"). And often we find useful info by seeing where something died in a third party library as it might point us to a botched config, a known bug or whatever. In this case hopefully it would allow us to say "This is a socket timeout," as opposed to "This might be a socket timeout, or it could be a pause followed by a disconnect or ..."

Personally I would prefer to see stack traces unless the cause is definitely identified. e.g., if you can see the exception is a "connection reset by peer" and want to be brief, that makes sense, but if it's mystery error number five I want to see all the gory details. QF is extremely terse in this regard. e.g., if there is a checksum error you get a warning, but it doesn't show you the problem section of stream. (Have a patch for that, will enter a JIRA.)

Comment by Christoph John [ 07/Jan/20 ]

This will be improved with https://github.com/quickfix-j/quickfixj/issues/254.





[QFJ-290] FileStore.messageIndex is not cleared on reset Created: 15/Jan/08  Updated: 07/Aug/08  Resolved: 01/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1, 1.3.0
Fix Version/s: 1.3.2

Type: Bug Priority: Minor
Reporter: Rhys Yarranton Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-321 PersistMessages config parameter defa... Closed

 Description   

FileStore.messageIndex is not cleared on reset. As a result, get(int, int, Collection) may include "junk" entries for sequence numbers that used to be known to the store but are no longer. You can usually work around this by being careful not to peek beyond the current sequence number.

Suggested fix would be to add
messageIndex.clear()
to the top of initializeMessageIndex()

tx






[QFJ-289] ListenerSupport proxy creation uses self's classloader Created: 12/Jan/08  Updated: 15/Jan/08  Resolved: 12/Jan/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

It previously used the thread's context class loader






[QFJ-288] Data dictionary supports flexible (open-ended) enum value definitions Created: 12/Jan/08  Updated: 15/Jan/08  Resolved: 12/Jan/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None





[QFJ-287] Provide hook for manually closing FileLog files Created: 11/Jan/08  Updated: 05/Apr/10  Resolved: 11/Jan/08

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-350 Sessions do not cleanup after themsel... Closed
is related to QFJ-224 Automatically close logs and message ... Closed

 Description   

This issue represents a portion of the linked issue. This issue will be included in 1.3.1, but the remaining functionality described in the linked issue will be implemented in a later release. See the linked issue for the SVN commits (they were committed before splitting the issue).






[QFJ-286] Sequence number not correct after ResendRequest when PersistMessages=N (ATServer configuration) Created: 10/Jan/08  Updated: 15/Nov/12  Resolved: 18/Feb/09

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.5.0

Type: Bug Priority: Default
Reporter: Peter Eriksson Assignee: Steve Bate
Resolution: Fixed Votes: 1
Labels: None
Environment:

WinXP x64



 Description   

Case 8_OnlyAminMessages.def faild.

Suggestion for solution in Session.java:

private void nextResendRequest(Message resendRequest) throws IOException, RejectLogon,
FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType,
InvalidMessage {
if (!verify(resendRequest, false, false))

{ return; }

int beginSeqNo = resendRequest.getInt(BeginSeqNo.FIELD);
int endSeqNo = resendRequest.getInt(EndSeqNo.FIELD);

getLog().onEvent("Received ResendRequest FROM: " + beginSeqNo + " TO: " + endSeqNo);

String beginString = sessionID.getBeginString();
int expectedSenderNum = getExpectedSenderNum();
if (beginString.compareTo(FixVersions.BEGINSTRING_FIX42) >= 0 && endSeqNo == 0

beginString.compareTo(FixVersions.BEGINSTRING_FIX42) <= 0 && endSeqNo == 999999
endSeqNo >= expectedSenderNum) { endSeqNo = expectedSenderNum - 1; }

if (!persistMessages) {
endSeqNo += 1;
int next = state.getNextSenderMsgSeqNum();
if (endSeqNo > next)

{ endSeqNo = next; }

generateSequenceReset(beginSeqNo, endSeqNo);

}
else {
ArrayList<String> messages = new ArrayList<String>();
state.get(beginSeqNo, endSeqNo, messages);

int msgSeqNum = 0;
int begin = 0;
int current = beginSeqNo;

for (String message : messages) {
Message msg = parseMessage((String) message);
msgSeqNum = msg.getHeader().getInt(MsgSeqNum.FIELD);
String msgType = msg.getHeader().getString(MsgType.FIELD);

if ((current != msgSeqNum) && begin == 0)

{ begin = current; }

if (msgType.length() == 1 && "0A12345".indexOf(msgType) != -1) {
if (begin == 0)

{ begin = msgSeqNum; }

} else {
if (resend(msg)) {
if (begin != 0)

{ generateSequenceReset(begin, msgSeqNum); }

send(msg.toString());
getLog().onEvent("Resending Message: " + msgSeqNum);
begin = 0;
} else

{ if (begin == 0) begin = msgSeqNum; }

}
current = msgSeqNum + 1;
}

if (begin != 0)

{ generateSequenceReset(begin, msgSeqNum + 1); }

if (endSeqNo > msgSeqNum)

{ endSeqNo = endSeqNo + 1; int next = state.getNextSenderMsgSeqNum(); if (endSeqNo > next) endSeqNo = next; generateSequenceReset(beginSeqNo, endSeqNo); }

}

int tMsgSeqNum = resendRequest.getHeader().getInt(MsgSeqNum.FIELD);
if (!isTargetTooHigh(tMsgSeqNum) && !isTargetTooLow(tMsgSeqNum))

{ state.incrNextTargetMsgSeqNum(); }

}



 Comments   
Comment by Staffan Ulfberg [ 06/Feb/08 ]

I found this when googling for this issue since I discovered it in the C++ version a few hours ago. The fix above is the equivalent to what I would suggest for the C++ code. I checked the bug tracker for the quickfix (not j) project but could not find anything about this.

Comment by Jason Aubrey [ 15/Jan/09 ]

Just to summarize a bit (since the indenting is a bit lost), the key parts of this code are:
1) The removal of the 'return' after the first occurrence of 'generateSequenceReset'
2) The addition of the 'else' block immediately after the removed 'return'
3) Since there's no return (due to 1) the code skips over the else (due to 2) when !persistMessages and does the incrNextTargetMsgSeqNum

Any other changes I see here seem superfluous in my local revision (899).





[QFJ-285] Proxy Support for Initiator connections Created: 09/Jan/08  Updated: 13/Dec/16  Resolved: 13/Dec/16

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

Type: Improvement Priority: Default
Reporter: James Furness Assignee: Christoph John
Resolution: Fixed Votes: 3
Labels: None

Attachments: Text File actual_patch_v01.txt     Text File quickfixj-proxy-initial.patch    
Issue Links:
Requires
requires QFJ-664 Upgrade MINA from 1.1.8 to 2.0.x Closed

 Description   

QuickFIX/J doesn't seem to currently support initiator connections via a proxy. MINA may support proxies in the future, but does not at present:

http://issues.apache.org/jira/browse/DIRMINA-415

In the meantime it might be good to implement a workaround in IoSessionInitiator similar to this:

http://www.nabble.com/Proxy-filter-tp10997336s16868p11056766.html

Are there currently any plans for proxy support in QuickFIX/J? If not and the above solution sounds reasonable I would be happy to attempt this and contribute a patch if I can find the time to do so.

Thanks,
James



 Comments   
Comment by Toli Kuznets [ 09/Jun/09 ]

the corresponding MINA RFE that tracked the underlying proxy support feature just got closed - which means proxy support will be available in the 2.0 MINA release.

Do we have plans for testing/incorporating the 2.0 MINA into QFJ?

Comment by oliver jehle [ 24/Jan/12 ]

attached v0.1 of my work to use mina2.0.4 with quickfix/j.

i saw different messages about 2.0 mina in 2008, but no patches. so i did it myself.

the unit and accepance tests run successfully, so i hope i understand the differences
with mina 1.

the patch is against svn trunk and can be applied by patch -p0. you have to replace
the mina 1.1.8 libs with the 2.0.4 libs

Comment by Jörg Thönnes [ 25/Jan/12 ]

Please create sub-ticket to upgrade MINA from 1.1.8 to 2.0.4 as suggested in the mailing list.

Comment by oliver jehle [ 25/Jan/12 ]

open issue QFJ-664 for the upgrade to mina 2.0.4. the issue is the baseline for solve this issue

Comment by oliver jehle [ 13/Mar/12 ]

posted the hopefully "final" patch for QFJ-664 upgrade the mina framework. i prepared already the first sources for proxy support. the problem i have now is to simulate a proxy locally for the ant tests, if somebody has a hint or know a good small http proxy on java base, please give feedback.

Comment by oliver jehle [ 21/Apr/15 ]

as the mina is now merged, i rebased the patches for proxy. i'm still searching a possbility to test with a proxy. i found jsocks.jar , but for http proxy i still need a possiblity to test it somehow..

Comment by oliver jehle [ 21/Apr/15 ]

not tested rebased changes to head

Comment by Christoph John [ 22/Apr/15 ]

Hi Oliver, are you able to open a pull request for this or don't you have a github account? But either way, thanks for the patch.

Cheers,
Chris.

Comment by DaniG [ 23/Feb/16 ]

Hi,

I've tested the solution against a proxy and doesn't work. The ioHandler on IoSession initiation must be an instance of org.apache.mina.proxy.AbstractProxyIoHandler to connect with a proxy.

Best regard.

Comment by Christoph John [ 23/Feb/16 ]

Hi, you are saying that you patched the current version with the attached quickfixj-proxy-initial.patch and it didn't work?

Comment by DaniG [ 23/Feb/16 ]

Hi Christoph,

Yes, I've patched the code and doesn't work, I've tested it with proxy.

Comment by Christoph John [ 23/Feb/16 ]

Hi Dani, are you able to fix this or provide a new patch?

Comment by Christoph John [ 13/Dec/16 ]

Will be integrated based on PR https://github.com/quickfix-j/quickfixj/pull/91





[QFJ-284] Misspelling in configuration setting FileLogHeartbeats Created: 04/Jan/08  Updated: 15/Jan/08  Resolved: 10/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: david koo Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

There is a misspelling in the value assigned for SETTING_LOG_HEARTBEATS constant field in FileLogFactory.java

It is assigned a constant value of "FileLogHeatbeats" when it should be "FileLogHeartbeats". It is causing the documented configuration setting to be ignored.






[QFJ-283] quickfix fail to send reject when the message parsing fails due to invalid data Created: 28/Dec/07  Updated: 15/Nov/12  Resolved: 12/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.0, 1.2.1, 1.3.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: sarath Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

This issue arise when the group data is set incorrectly by users. Sometimes users leave the group tags empty(mainly the group count) with no value.

Below is the case where the test fail with NullPointerException. The exception is not caught in AbstractIOHandler.java and is never sent to client app causing the error to be ignored.

We should catch the exception and send reject to clients.

  1. @testcase 14i
  2. @Receive a message with repeating groups in which the "count" field value for a repeating group is incorrect.

iCONNECT

  1. logon message and response
    I8=FIX.4.235=A34=149=TW52=<TIME>56=ISLD98=0108=2
    E8=FIX.4.29=6035=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=210=0

#------------------------

  1. begin message exchange
    #------------------------

#New order message with incorrect repeating group "count". NoTradingSessions (386)
I8=FIX.4.235=D34=249=TW52=<TIME>56=ISLD11=ID21=140=154=138=200.0055=INTC386=336=PRE-OPEN336=AFTER-HOURS60=<TIME>

  1. expect a reject
    E8=FIX.4.29=11835=334=249=ISLD52=00000000-00:00:00.00056=TW45=258=Incorrect NumInGroup count for repeating group371=386372=D10=0


 Comments   
Comment by Steve Bate [ 08/Jan/08 ]

Can you attach the test case so that the field delimeters are not lost? Thanks.

I'm curious what's causing the NullPointerException, but this is not exactly a case of an incorrect NumInGroup value. A missing group count tag might appear similar, but it has significantly different implications. Without a group count tag, the repeating groups effectively do not exist from a parsing perspective.

Comment by Steve Bate [ 12/Jan/08 ]

When I modify test 14i to remove the group count field, I receive a reject saying "Tag not defined for this message type:336". This is what I would expect since tag 336 would appear to be included in the main message body (which would be invalid). I saw no NullPointerException. Was this possibly coming from your application code?





[QFJ-282] FIXMessageEncoder#encode() may throws java.nio.BufferOverflowException if message contains Chinese characters Created: 27/Dec/07  Updated: 02/Apr/15  Resolved: 09/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.6.0

Type: Bug Priority: Default
Reporter: CaiQi Assignee: amichair
Resolution: Duplicate Votes: 0
Labels: encoding

Issue Links:
Duplicate
duplicates QFJ-666 FIXMessageEncoder got BufferOverflowE... Closed
Relates
relates to QFJ-382 Foreign Language Support - Multibyte ... Closed

 Description   

FIXMessageEncoder#encode() may throws protocol handler exception: java.nio.BufferOverflowException, if message contains Chinese characters.

we use "UTF-8" as default charset instead of "ISO-8859-1". So charsetEncoding = "UTF-8".

FIXMessageEncoder#encode() :
ByteBuffer buffer = ByteBuffer.allocate(fixMessageString.length());
try

{ buffer.put(fixMessageString.getBytes(charsetEncoding)); }

catch (UnsupportedEncodingException e)

{ throw new ProtocolCodecException(e); }

if message contains Chinese characters, fixMessageString.length() will not equal to fixMessageString.getBytes(charsetEncoding).length. Because A Chinese character will use "three" Bytes in "UTF-8". But in String, it's length is still "1".

we let: byte[] src = fixMessageString.getBytes(charsetEncoding);
when a message contains "one" Chinese character,
if fixMessageString.length() = 190, then src.length = 192, buffer.capacity() = 256. So buffer.put(src) will not throw java.nio.BufferOverflowException;
if fixMessageString.length() = 255, then src.length = 257, buffer.capacity() = 256. At this time, buffer.put(src) will throw java.nio.BufferOverflowException;

solution:
use "fixMessageString.getBytes(charsetEncoding).length" to allocate buffer space instead of "fixMessageString.length()".

ByteBuffer buffer;
try

{ byte[] src = fixMessageString.getBytes(charsetEncoding); buffer = ByteBuffer.allocate(src.length); buffer.put(src); }

catch (UnsupportedEncodingException e)

{ throw new ProtocolCodecException(e); }

 Comments   
Comment by Jan Amoyo [ 29/Apr/08 ]

One can also use the CharsetEncoder in java.nio.charset:

Charset charset = Charset.forName("UTF-8");
CharsetEncoder encoder = charset.newEncoder();

CharBuffer cb = CharBuffer.wrap("fixMessageString");
ByteBuffer buffer = encoder.encode(cb);

Comment by Jay Walters [ 03/Feb/09 ]

See QFJ-382 for the patches to resolve this issue.





[QFJ-281] Read "LogoutTimeout" Parameter bug Created: 24/Dec/07  Updated: 15/Jan/08  Resolved: 10/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: Mike Gu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

all situations


Issue Links:
Relates
is related to QFJ-268 LogoutTimeout configuration not proce... Closed

 Description   

in DefaultSessionFactory.java:
When it reads "logoutTimeout" parameter from sessionSettings, it actually reads "LogonTimeout". It's a terrible small bug.

code:
int logoutTimeout = getSetting(settings, sessionID,
Session.SETTING_LOGON_TIMEOUT, 2);

should change as :
int logoutTimeout = getSetting(settings, sessionID,
Session.SETTING_LOGOUT_TIMEOUT, 2);






[QFJ-280] Improve behavior of parsing out-of-order fields Created: 24/Dec/07  Updated: 15/Jan/08  Resolved: 12/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Improvement Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The order of fromString() is parseHeader(),parseBody(dd),parseTrailer(dd).
Problem 1:
When extracting header, if a body/trailer's field appears in header, the field will be pushed to body and the extraction end up. This field will be considered
as the first field of the body. This will cause Other fields followed dropped.

Problem 2:
When extracting body, if a trailer's field appers in it, it's the same as problem 1.

Problem 3:
When extracting body, if a header's field appers in it, it will be set back into the header. In this case, the header's field could be set in the body which cannot be validated.
e.g. This message can be received.
8=IMIX.1.09=15335=D11=00034=84049=ICBC50=operator00152=20071207-
10:06:38.50556=XXX11=12344=148=asd54=155=WAKEN354=7355=12\001493=711=99989=memory10=XXX

Solution :

In parseBody():
If headerfield is set in body or bodyfield is set in header, throw exception.
If the field has been set in head, throw exception.

In parseTrailer():
If the field has been set in head/body, throw exception.
If trailerfield is set in header/body; or header/body field is set in trailer, throw exception.



 Comments   
Comment by Steve Bate [ 12/Jan/08 ]

I've slightly modified the parsing and added some additional test cases. The cases you mention will parse without an exception but the message will be marked as having an invalid structure. If the first 3 headers fields are not correct, that will still result in an immediate exception.





[QFJ-279] Fields in groups will not be checked. Created: 24/Dec/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-168 Add repeating group validation in mes... Closed

 Description   

If there are repeating groups or fields in a group, they will not be verified when received.

1. When verify the field in a fieldMap, fields in groups must be vevified.
DataDictionary.iterate(FieldMap map, String msgType) is the method to verify fields. It could be invoked in recursion.

Add this into DataDictionary:
// Check the fields and groups in groups.
if (isGroup(msgType, field.getField())) {
checkGroupCount(field, map, msgType);
List groupMembers = map.getGroups(field.getField());
Group originalGroup = (Group) groupMembers.get(0);

for (int i = 0; i < groupMembers.size(); i++)

{ originalGroup = (Group) groupMembers.get(i); GroupInfo rg = getGroup(msgType, field.getField()); DataDictionary group_dataDictionary = rg.getDataDictionary(); group_dataDictionary.hasVersion = this.hasVersion; group_dataDictionary.beginString = this.beginString; group_dataDictionary.fieldValues = this.fieldValues; group_dataDictionary.fieldTypes = this.fieldTypes; group_dataDictionary.iterate(originalGroup, msgType); }

}

2. Groups must be added into memory from *.xml.
Add this into DataDictionary.addXMLGroup():
groupDD.addMsgField(msgtype, field);



 Comments   
Comment by CaiQi [ 24/Dec/07 ]

Initiator:send a message which the NoGroup is wrong.
Acceptor:different problems occur.

For example, such are parts of some messages. 802:Number of group.
802=156 523=777 803=1. The acceptor cannot find the CheckSum. The message will be dropped on the bottom when decoded.
802=1 523=777 803=1. This will be well received.
802=20 523=777 803=1. The acceptor will consider the CheckSum is wrong and reject it.
802=156 . No 523 or 803. This will be received.

This is because fields in groups and groups in groups are not verified when received. We must verify them (In QFJ-279).

Comment by Steve Bate [ 03/Feb/08 ]

I'm not sure if this was fixed as a side-effect of other changes, but I can't reproduce these errors with the code in the SVN trunk. I've added a test in RepeatingGroupTest to specifically test for high and incorrect group counts in the message.





[QFJ-278] method extractField(Group group, DataDictionary dataDictionary, FieldMap fields) don't check The length of "sohOffset" Created: 24/Dec/07  Updated: 01/Feb/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

In the class Message, method extractField(Group group, DataDictionary dataDictionary, FieldMap fields): The length of "sohOffset" is not checked. This will bring about full range of the message received as Message string out of range.

For all the field, if it is dataField, its length must be calculated by the former Field(Except for Tag 89/93). Because the data may contain a SOH.
For example, field 355 is dataField. Its length is in Field 354.
We must check the offset of the dataField is shorter than length of the message, and the offset's next char is SOH.

Add this code into Message.extractField():

//Judge if sohOffset's next char is '\001'.
if(messageData.indexOf('\001', sohOffset) != sohOffset)
throw new InvalidMessage("Wrong length of data field.");
//Judge if sohOffset is shorter than fields.
if(sohOffset > messageData.length())
throw new InvalidMessage("Wrong length of data field.");



 Comments   
Comment by CaiQi [ 24/Dec/07 ]

Initiator:send a message which is not comply with the protocol.
Acceptor:different problems occur.

For example, the dependances of fields. 354: the length of 355
354=10 355=123. The accptor will consider it that String out of range.
354=3 355=123. This is right.





[QFJ-277] if set "\001" in the StringField, it cause lots of problems Created: 24/Dec/07  Updated: 12/Jan/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

If "\001" is set in the string field by users, it can't be validated before sending. The field is considered as user expected. But it could be validated when received. There are three cases:

(1)Error incorrect format when Agent receives.
e.g. newOrderSingle.set(new Symbol("\001WAKEN"));
8=FIX.4.4_9=142_35=D_34=346_49=ICBC_50=operator001_52=20071128-03:03:37.140_56=XXX_212=346_11=123_38=1_40=2_44=1_54=1_55=WAKEN_60=20071128-11:03:37.125_10=XXX
Agent: [ERROR] quickfix.mina.acceptor.AcceptorIoHandler - Invalid message: bad tag format: For input string: "WAKEN_60"

e.g. newOrderSingle.set(new Symbol("WAK\001EN"));
8=FIX.4.4_9=142_35=D_34=329_49=ICBC_50=operator001_52=20071128-
03:00:50.875_56=XXX_212=329_11=123_38=1_40=2_44=1_54=1_55=WAK_EN_60=20071128-11:00:50.875_10=XXX_
Agent: [ERROR] quickfix.mina.acceptor.AcceptorIoHandler - Invalid message: bad tag format: For input string: "EN_60"

e.g. newOrderSingle.set(new Symbol("WAKEN\001"));
8=iMIX.1.0_9=142_35=D_34=365_49=ICBC_50=operator001_52=20071128-
03:06:13.671_56=XXX_212=365_11=123_38=1_40=2_44=1_54=1_55=WAKEN_60=20071128-11:06:13.671_10=XXX
Agent: [ERROR] quickfix.mina.acceptor.AcceptorIoHandler - Invalid message: bad tag format: For input string: "_60"

e.g. newOrderSingle.set(new Symbol("WAK\001=EN"));
8=iMIX.1.0_9=143_35=D_34=312_49=ICBC_50=operator001_52=20071128-
02:56:44.578_56=XXX_212=312_11=123_38=1_40=2_44=1_54=1_55=WAK_=EN_60=20071128-
10:56:44.562_10=XXX_
Agent:[ERROR] quickfix.mina.acceptor.AcceptorIoHandler - Invalid message: bad tag format: For input string: ""

(2)The message is rejected as expected.

e.g. newOrderSingle.set(new Symbol("WAK\001123=EN"));
8=iMIX.1.0_9=146_35=D_34=269_49=ICBC_50=operator001_52=20071128-
02:50:38.406_56=XXX_212=269_11=123_38=1_40=2_44=1_54=1_55=WAK_123=EN_60=20071128-
10:50:38.406_10=XXX_
Incorrect data format for value

e.g. newOrderSingle.set(new Symbol("\001123=EN"));
8=iMIX.1.0_9=143_35=D_34=248_49=ICBC_50=operator001_52=20071128-
02:49:02.406_56=XXX_212=248_11=123_38=1_40=2_44=1_54=1_55=_123=EN_60=20071128-
10:49:02.406_10=XXX_
Tag specified without a value

e.g. newOrderSingle.set(new Symbol("WAKEN\001123="));
8=iMIX.1.0_9=146_35=D_34=383_49=ICBC_50=operator001_52=20071128-
03:12:25.546_56=XXX_212=383_11=123_38=1_40=2_44=1_54=1_55=WAKEN_123=_60=20071128-
11:12:25.531_10=XXX_
Tag specified without a value

(3)The message is received successfully, but it is wrong. The result is critical. It will be used to attack the Server. This mustn't absolutely happen.
e.g. newOrderSingle.set(new Symbol("WAKEN\00110048=2"));
8=iMIX.1.0_9=149_35=D_34=449_49=ICBC_50=operator001_52=20071128-
03:21:47.031_56=XXX_212=449_11=123_38=1_40=2_44=1_54=1_55=WAKEN_10048=2_60=20071128-
11:21:47.015_10=XXX_

Solution 1
Encode the StringField at the Client, and decode at the Server. The encode and decode can be implemented in class StringField.
Fault:
In the FieldType "DATA", "\001" is permited. Its length is defined by the former field rather than by the position of "\001". So it is not affected by "\001". When encoded, its length will be changed. So the former field's value must be modified. To avoid this, a new class must be added instead of StringField. Make all
the "DATA" type extend StringField.

Solution 2
In the FIX protocol, the String field is not permit to be set as '\001'. So we can throw Exception directly or replace '\001' with ' ' in the StringField.
This can be implemented in class stringField. When construct a StringField except DATA fieldType, if find "\001", throw Exception directly or replace '\001' with ' '.
I think the solution 2 is better. The concisest method is to judge the DataField by tags. Now there are at least 3 pairs of DataField: 93/89, 95/96, 354/355.
Hard code is written:
if(field == 89||field == 96||field == 355)



 Comments   
Comment by Steve Bate [ 08/Jan/08 ]

If I understand your concern correctly, this is more of a FIX protocol issue than a QuickFIX/J issue.On the QFJ side, we can validate
that a value of a String field doesn't contain a "\001". However, this doesn't stop the possibility of "server attacks". From the perspective
of the receiving engine, a "\001" is a field delimeter and the message will be parsed accordingly. Even if we validate the StringFields, your
counterparty can send whatever FIX message string they want with whatever fields they want so you must validate those anyway in your application
code.

Comment by Steve Bate [ 11/Jan/08 ]

This is more involved than I thought it would be. The data fields are based on StringField so I need to think more about to provide validation for String versus data fields.





[QFJ-276] Specify order of signature-related trailer fields Created: 24/Dec/07  Updated: 15/Jan/08  Resolved: 11/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Using JVM 1.5 on WindowsXP.



 Description   

Field 93 is SignatureLength, Field 89 is Signature. The fields 89 and 93 are in the trailer. 89 is DataField. 93 is the length of 89. When receives a message containing field 89, accptor will extract every field in order. 89 is extracted earlier. Acceptor cannot find the length of it(93) at this time. So exception occurs.

A effective method is to change the order of message. Put the field 93 former to the field 89. Thus, the field 93 is extracted earlier than 89. Use this method:
Message.Trailer.calculateString():
super.calculateString( buffer, new int[]

{ SignatureLength.FIELD }

, new int[]

{CheckSum.FIELD }

);






[QFJ-275] Make validation of fields optional in an incoming message when using a DataDictionary Created: 19/Dec/07  Updated: 07/Aug/08  Resolved: 17/Jun/08

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

Type: New Feature Priority: Default
Reporter: Hemant Bhatia Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Unix / Windows



 Description   

Currently, when using a DataDictionary, Quickifx only allows preventing validation of user defined fields in an incoming message for fields with tags greater than or equals 5000, by setting ValidateUserDefinedFields property to N.

It would be nice to have a way to be able to prevent Quickfix from validating any user defined fields (not defined in the DataDictionary for the Message Type) in the incoming message.



 Comments   
Comment by Steve Bate [ 02/Feb/08 ]

Nonstandard fields with a tag < 5000 are not called "user defined fields", but are just invalid fields (relative to the spec and/or data dictionary). I changed the name of the issue to avoid confusion.

I'll call the option something like ValidateUnknownFields or AllowUnknownFields.





[QFJ-274] Accessibility of methods in FieldMap for getting Groups from default to public Created: 19/Dec/07  Updated: 15/Jan/08  Resolved: 10/Jan/08

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

Type: Improvement Priority: Default
Reporter: Hemant Bhatia Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Unix / Windows



 Description   

Can the accessiblity of the follwing methods in FieldMap class be changed from Default to Public ?

/* package */
List<Group> getGroups(int field) {
List<Group> groupList = groups.get(field);
if (groupList == null)

{ groupList = new ArrayList<Group>(); groups.put(field, groupList); }

return groupList;
}

int getGroupCount(int tag)

{ return getGroups(tag).size(); }

Map<Integer,List<Group>> getGroups()

{ return groups; }

It will be really helpful in order to iterate through the groups in the message generically.



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

I'll make the getGroupCount() method public. I'm not going to expose the other two methods because they are not type safe and I'd have to copy all the groups to be sure they weren't modified outside the FieldMap.





[QFJ-273] Catch any application callback exceptions and log them. Created: 19/Dec/07  Updated: 15/Jan/08  Resolved: 21/Dec/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Do not allow application callback exceptions to effect the engine operation.



 Comments   
Comment by Steve Bate [ 21/Dec/07 ]

Catching exceptiions for all callbacks except incoming message callbacks (fromApp, fromAdmin). Those exceptions will propagate and result in subsequent resend activity.





[QFJ-272] Support additional ID fields in SessionID Created: 12/Dec/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add support for subID and locationID. This is mostly backward compatible, but will change the database schemas.



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

Added support for the additional fields. This means that data stores (e.g. JDBC) will no longer be compatible since they now include additional columns. The documentation has also been updated.





[QFJ-271] StackOverflowError trying to process queued SequenceReset Created: 11/Dec/07  Updated: 23/Dec/13  Resolved: 23/Dec/13

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Steve Bate
Resolution: Fixed Votes: 2
Labels: None

Attachments: Text File Session.java    
Issue Links:
Duplicate
is duplicated by QFJ-409 Stack overflow when processing a larg... Closed
Relates
is related to QFJ-309 There is no need to store the message... Open

 Description   

While testing out of order messages, we ran into the stack overflow at bottom. We are using 1.2.1. I believe this also affects 1.3.0.

Scenario: Counterparty sends messages through 41 OK, then sends 50 and 51 out of sequence. QF queues these and issues a resend request. Messages 42 through 49 arrive, QF processes 50 from the queue OK then cacks on 51. Message 51 is:
16:13:27,627 INFO [GATEWAYS.FWST.Incoming] FIX.4.2:BIDS->FWST: 8=FIX.4.2^A9=60^A35=4^A49=FWST^A56=BIDS^A34=51^A52=20071210-21:13:26^A123=Y^A36=51^A10=215^A

The problem appears to be that message 51 is asking QF to set the next sequence number to 51. QF obediently leaves the sequence number at 51, resulting in an infinite loop, and due to the use of recursion, a stack overflow.

The FIX 4.2 spec didn't seem too clear to me whether one should issue a reject or ignore the message. Whatever the case, I guess we have to make sure the nasty message gets removed from the buffer.

Don't know if there are other types of pathological messages. This buffer stuff is kind of tricky, and coupled with the recursion makes me nervous. e.g., you can get an overflow simply because someone sends you a massive plug of out-of-order data.

java.lang.StackOverflowError
at java.lang.Exception.<init>(Exception.java:77)
at java.lang.reflect.InvocationTargetException.<init>(InvocationTargetException.java:54)
at sun.reflect.GeneratedMethodAccessor63.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:917)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1339)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:391)
at org.apache.log4j.spi.LoggingEvent.writeObject(LoggingEvent.java:407)
at sun.reflect.GeneratedMethodAccessor100.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:917)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1339)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
at org.apache.log4j.net.SocketAppender.append(SocketAppender.java:232)
at com.amsl.common.util.QuietSocketAppender.append(QuietSocketAppender.java:79)
at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230)
at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65)
at org.apache.log4j.Category.callAppenders(Category.java:203)
at org.apache.log4j.Category.forcedLog(Category.java:388)
at org.apache.log4j.Category.warn(Category.java:1008)
at com.amsl.bids3.fixgw.session.FIXGateway.validateMessageForLatency(FIXGateway.java:777)
at com.amsl.bids3.fixgw.session.FIXGateway.fromAdmin(FIXGateway.java:671)
at quickfix.Session.fromCallback(Session.java:1227)
at quickfix.Session.verify(Session.java:1190)
at quickfix.Session.nextSequenceReset(Session.java:939)
at quickfix.Session.next(Session.java:688)
at quickfix.Session.next(Session.java:1487)
at quickfix.Session.nextQueued(Session.java:1477)
at quickfix.Session.nextQueued(Session.java:1461)
at quickfix.Session.next(Session.java:750)
at quickfix.Session.next(Session.java:1487)



 Comments   
Comment by Rhys Yarranton [ 12/Dec/07 ]

On further digging, it looks like there could also be a problem when NewSeqNo < MsgSeqNum on a queued message. QF issues a reject, but leaves the message in the queue and does not increment the sequence number.

So, perhaps an underlying problem is that SessionState.dequeue() is using Map.get() instead of Map.remove(). The queue will never have anything removed until disconnect when SessionState.clearQueue() is called, which is itself a memory leak. If remove() were used, the case NewSeqNo == MsgSeqNum would result in essentially a no-op.

Comment by Biswaranjan Das [ 18/Jan/13 ]

Looks this requires some refactoring. This stack overflow is a genuine problem. Following refactoring should fix it without any business logic impact. I am referring it based on 1.4 code base.


    /**
     * (Internal use only)
     */
    public void next(Message message) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
            IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage {
    	
    	if(!processMessage(message)){
    		return;
    	}

        nextQueued();
        if (isLoggedOn()) {
            next();
        }
    }
    
    private boolean processMessage(Message message) throws FieldNotFound, RejectLogon, IncorrectDataFormat,
    IncorrectTagValue, UnsupportedMessageType, IOException, InvalidMessage {

        if (!checkSessionTime()) {
            reset();
            return false;
        }

        Header header = message.getHeader();
        String msgType = header.getString(MsgType.FIELD);

        try {

            String beginString = header.getString(BeginString.FIELD);

            if (!beginString.equals(sessionID.getBeginString())) {
                throw new UnsupportedVersion();
            }

            if (msgType.equals(MsgType.LOGON)) {
                if (sessionID.isFIXT()) {
                    targetDefaultApplVerID.set(new ApplVerID(message.getString(DefaultApplVerID.FIELD)));

                } else {
                    targetDefaultApplVerID.set(MessageUtils.toApplVerID(beginString));
                }
            }

            if (dataDictionaryProvider != null) {
                DataDictionary sessionDataDictionary = dataDictionaryProvider
                        .getSessionDataDictionary(beginString);
    
                String customApplVerID = header.isSetField(CstmApplVerID.FIELD) ? header
                        .getString(CstmApplVerID.FIELD) : null;
    
                ApplVerID applVerID = header.isSetField(ApplVerID.FIELD) ? new ApplVerID(header
                        .getString(ApplVerID.FIELD)) : targetDefaultApplVerID.get();
    
                DataDictionary applicationDataDictionary = isAdminMessage(msgType)
                        ? dataDictionaryProvider.getSessionDataDictionary(beginString)
                        : dataDictionaryProvider.getApplicationDataDictionary(applVerID,
                                customApplVerID);
                
                DataDictionary.validate(message, sessionDataDictionary, applicationDataDictionary);
            }
            
            if (msgType.equals(MsgType.LOGON)) {
                nextLogon(message);
            } else if (msgType.equals(MsgType.HEARTBEAT)) {
                nextHeartBeat(message);
            } else if (msgType.equals(MsgType.TEST_REQUEST)) {
                nextTestRequest(message);
            } else if (msgType.equals(MsgType.SEQUENCE_RESET)) {
                nextSequenceReset(message);
            } else if (msgType.equals(MsgType.LOGOUT)) {
                nextLogout(message);
            } else if (msgType.equals(MsgType.RESEND_REQUEST)) {
                nextResendRequest(message);
            } else if (msgType.equals(MsgType.REJECT)) {
                nextReject(message);
            } else {
                if (!verify(message)) {
                    return false;
                }
                state.incrNextTargetMsgSeqNum();
            }
        } catch (FieldException e) {
            generateReject(message, e.getSessionRejectReason(), e.getField());
        } catch (FieldNotFound e) {
            if (sessionID.getBeginString().compareTo(FixVersions.BEGINSTRING_FIX42) >= 0
                    && message.isApp()) {
                generateBusinessReject(message,
                        BusinessRejectReason.CONDITIONALLY_REQUIRED_FIELD_MISSING, e.field);
            } else {
                if (msgType.equals(MsgType.LOGON)) {
                    getLog().onEvent("Required field missing from logon");
                    disconnect();
                } else {
                    generateReject(message, SessionRejectReason.REQUIRED_TAG_MISSING, e.field);
                }
            }
        } catch (IncorrectDataFormat e) {
            generateReject(message, SessionRejectReason.INCORRECT_DATA_FORMAT_FOR_VALUE, e.field);
        } catch (IncorrectTagValue e) {
            generateReject(message, SessionRejectReason.VALUE_IS_INCORRECT, e.field);
        } catch (InvalidMessage e) {
            getLog().onEvent("Skipping invalid message: " + e.getMessage());
        } catch (RejectLogon e) {
            String rejectMessage = e.getMessage() != null ? (": " + e.getMessage()) : "";
            getLog().onEvent("Logon rejected" + rejectMessage);
            if (e.isLogoutBeforeDisconnect()) {
                generateLogout(e.getMessage());
            }
            state.incrNextTargetMsgSeqNum();
            disconnect();
        } catch (UnsupportedMessageType e) {
            if (sessionID.getBeginString().compareTo(FixVersions.BEGINSTRING_FIX42) >= 0) {
                generateBusinessReject(message, BusinessRejectReason.UNSUPPORTED_MESSAGE_TYPE, 0);
            } else {
                generateReject(message, "Unsupported message type");
            }
        } catch (UnsupportedVersion e) {
            if (msgType.equals(MsgType.LOGOUT)) {
                nextLogout(message);
            } else {
                generateLogout("Incorrect BeginString");
                state.incrNextTargetMsgSeqNum();
                // 1d_InvalidLogonWrongBeginString.def appears to require
                // a disconnect although the C++ didn't appear to be doing it.
                // ???
                disconnect();
            }
        } catch (IOException e) {
            LogUtil.logThrowable(sessionID, "error processing message", e);
        }
        return true;
    }

    private void next(String msg) throws InvalidMessage, FieldNotFound, RejectLogon,
            IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType, IOException {
        try {
            processMessage(parseMessage(msg));
        } catch (InvalidMessage e) {
            String message = e.getMessage();
            getLog().onEvent(message);
            if (MsgType.LOGON.equals(MessageUtils.getMessageType(msg))) {
                getLog().onEvent("Logon message is not valid");
                disconnect();
            }
            throw e;
        }
    }
Comment by Biswaranjan Das [ 18/Jan/13 ]

Patch on 1.4 Code Base.

Comment by Jörg Thönnes [ 15/Mar/13 ]

The current version is QF/J 1.5.3 so why providing patches based on 1.4?

If the issue still applies to the current version, please comment accordingly.

Otherwise, I would like to close this as "Cannot Reproduce".

Comment by Jörg Thönnes [ 15/Mar/13 ]

Sorry, closed this by accident. But actually I want to take your findings honestly and wait for a test with the current version.

Comment by Christoph John [ 19/Dec/13 ]

Will investigate if this still is a problem. I am pretty sure that map.remove is used in current versions of QFJ.

Comment by Christoph John [ 23/Dec/13 ]

Turned out that the map.remove is present in the code since QFJ 1.3.1 and QFJ-271 should hence be no problem for current versions. Added unit test now to ensure expected behaviour.

http://sourceforge.net/p/quickfixj/code/1130/





[QFJ-270] conditionally required field missing message uninformative Created: 10/Dec/07  Updated: 07/Aug/08  Resolved: 18/Jun/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.3.2

Type: Improvement Priority: Minor
Reporter: John Coleman Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

JVM 1.5 on WindowsXP.



 Description   

When messages with conditionally required fields missing are submitted, the rejection message does not specify the tag number of the missing field. This probably needs to be somewhere in tag 58, as tag 371 is not a FIX standard tag for message rejections.



 Comments   
Comment by Steve Bate [ 03/Feb/08 ]

Can you add some more detail on this issue? At least in the Session implementation, conditionally-required field rejects do include the tag number. For FIX 4.2 and above it is put into tag 371. For older versions, it is included in the Text (58) field.

Is this an issue with the Banzai example program?

Comment by John Coleman [ 04/Feb/08 ]

I amended the following code in Session.java to resolve the issue:

public synchronized void next(Message message) throws FieldNotFound, RejectLogon,
...
if (sessionID.getBeginString().compareTo(FixVersions.BEGINSTRING_FIX42) >= 0
&& message.isApp())

{ generateBusinessReject(message, BusinessRejectReason.CONDITIONALLY_REQUIRED_FIELD_MISSING, e.field); }

else {
generateReject(message, SessionRejectReason.REQUIRED_TAG_MISSING, e.field);
if (msgType.equals(MsgType.LOGON))

{ getLog().onEvent("Required field missing from logon"); disconnect(); }

}
...

private void generateBusinessReject(Message message, int err, int field) throws FieldNotFound, IOException

{ Message reject = messageFactory.create(sessionID.getBeginString(), MsgType.BUSINESS_MESSAGE_REJECT); initializeHeader(reject.getHeader()); String msgType = message.getHeader().getString(MsgType.FIELD); String msgSeqNum = message.getHeader().getString(MsgSeqNum.FIELD); reject.setString(RefMsgType.FIELD, msgType); reject.setString(RefSeqNum.FIELD, msgSeqNum); reject.setInt(BusinessRejectReason.FIELD, err); state.incrNextTargetMsgSeqNum(); String reason = BusinessRejectReasonText.getMessage(err) + " " + field; populateRejectReason(reject, reason); sendRaw(reject, 0); getLog().onEvent("Message " + msgSeqNum + " Rejected: " + reason); }




[QFJ-269] validate method in DataDictionary does not validate group fields Created: 10/Dec/07  Updated: 31/Aug/08  Resolved: 03/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4, 1.2.1
Fix Version/s: 1.3.2

Type: Bug Priority: Major
Reporter: John Coleman Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Using JVM 1.5 on WindowsXP.


Issue Links:
Duplicate
duplicates QFJ-169 Message parsing fails on messages wit... Closed

 Description   

It is possible for QFJ to accept messages with invalid field values as defined in the data dictionary xml file enumerations. This can result in code built on QFJ crashing due to acceptance of messages with invalid fields, and thus developer must enforce validation using hard-coding to avoid this.

The DataDictionary.validate method only checks values on the top level of the message and does not walk the group field trees.

It is necessary to add code at the end of the method similar to following:

Map groups = map.getGroups();
if (groups.size() > 0) {
Iterator groupIter = groups.entrySet().iterator();
while (groupIter.hasNext()) {
Map.Entry entry = (Map.Entry) groupIter.next();
List groupInstances = ((List) entry.getValue());
for (int i = 0; i < groupInstances.size(); i++)

{ FieldMap groupFields = (FieldMap) groupInstances.get(i); iterate(groupFields, msgType); }

}
}

[NB: Some of the validate method calls do not work with above suggestion.]

A generic tree walking technique would be handy in many places.



 Comments   
Comment by Toli Kuznets [ 10/Dec/07 ]

I think this is a duplicate of QFJ-169





[QFJ-268] LogoutTimeout configuration not processed correctly Created: 06/Dec/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: Rudy Fasouliotis Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux


Issue Links:
Relates
relates to QFJ-281 Read "LogoutTimeout" Parameter bug Closed

 Description   

I am trying to set LogoutTimeout=10 in my quickfixj conf file.

I have tried this in both the DEFAULT and SESSION sections, but it doesn't seem to be working.

I still get a timeout after about 4 seconds (even though default is 2)

<20071206-17:10:03, FIX.4.2:5J0004N->XXXX, outgoing> (8=FIX.4.29=10035=034=249=XXXXXXX52=20071206-17:10:03.58356=XXXX50=XXXX57=G112=1196960966326142=XXXX10=116)
<20071206-17:10:15, FIX.4.2:5J0004N->XXXX, event> (Initiated logout request)
<20071206-17:10:15, FIX.4.2:5J0004N->XXXX, outgoing> (8=FIX.4.29=10035=534=349=5J0004N52=20071206-17:10:15.60756=XXXX50=XXXX57=G58=user requested142=OptionsCity10=084)
<20071206-17:10:18, FIX.4.2:5J0004N->CME, event> (Timed out waiting for logout response)
<20071206-17:10:18, FIX.4.2:5J0004N->CME, event> (Disconnecting)

I have replaced some stuff with "XXXX", but you get the picture

Am I doing something wrong, or is this a bug?



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

The LogoutTimeout was not being processed correctly.





[QFJ-267] Method SocketAcceptor.stop() does not unblock SocketAcceptor.block() Created: 27/Nov/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

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

Type: Bug Priority: Default
Reporter: Eduardo Ostertag Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP SP2 (Spanish), Java JDK 1.6



 Description   

Method SocketAcceptor.stop() does not unblock method SocketAcceptor.block(). As far as I can tell, the reason is that stop() does not call eventHandlingStrategy.stopHandlingMessages(), so private variable "isStopped" continues "false", and eventHandlingStrategy.block() stays blocked.

By contrast, SocketInitiator.stop() calls eventHandlingStrategy.stopHandlingMessages(), and everything works OK.






[QFJ-266] Initiator can't reconnect if there was no network during startup. Created: 22/Nov/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.2.1, 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: Bartosz Lawniczek Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP



 Description   

IoSessionInitiator.connect() method throws UnresolvedAddressException if there is no network connection. After connection is reestablished it is not able to recover and still throws UnresolvedAddressException.

This is because InetSocketAddress is created only ones during startup. If it was not resolved then it will never be resolved.

Workaround is to create new InetSocketAddress each time the Initiator tries to reconnect and the address is unresolved. Modification of IoSessionInitiator.getNextSocketAddress() that fixed the problem for me:

private SocketAddress getNextSocketAddress() {
SocketAddress socketAddress = socketAddresses[nextSocketAddressIndex];

if (socketAddress instanceof InetSocketAddress) {
InetSocketAddress inetAddr = (InetSocketAddress) socketAddress;
if (inetAddr.isUnresolved())

{ socketAddress = new InetSocketAddress(inetAddr.getHostName(), inetAddr.getPort()); socketAddresses[nextSocketAddressIndex] = socketAddress; }

}

nextSocketAddressIndex = (nextSocketAddressIndex + 1) % socketAddresses.length;
return socketAddress;
}



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

Added the patch. Thanks.





[QFJ-265] Log4j or commons-logging integration for the FileLog Created: 21/Nov/07  Updated: 15/Nov/12  Resolved: 22/Dec/07

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

Type: Improvement Priority: Default
Reporter: André Malenfant Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

I am not sure this is part of 1.3 but I don't think so.

It would be nice if the FileStore class uses commons-logging, log4j or slf4j for outputing the message log to a file. This way we could manage the log files the same way we manage our application logs. For example, it would be interesting in a production environment to be able to use a DailyRollingFileAppender to prevent the file from growing too much. We would also benefit from all formatting options such as timestamps in the platform timezone that are easier to read than the time in the header of the message (which may be in a different timezone depending on the other party).



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

The file store needs to efficiently access it's data when message resends are requested. A regular log file does not provide good support for this type of usage. A rolling log file is a problem because all the messages for the current session must be available in the message store for resend purposes. The message store is truncated at the end of a daily or weekly session.

Comment by André Malenfant [ 23/Dec/07 ]

Sorry, I think I confused quickfix.Log with FileStore when wrtting my issue. My suggestion was to be able to send events and messages logs to commons-loggin or log4j, not to alter the message store functionnality.

I have experimented by writting my own LogFactory that creates a Log instance that outputs to log4j and it works perfectly fine. I did not touch the store files. The only problem (and it is why I submitted this post in the first place) is that the Log interface only has one method that only receives one String parameter, thus cannot distinguish error messages from informational and debug messages nor accept a Throwable object.

It is now common practive at least in Java to use libraries like log4j that gives the flexibility to filter the output to the log based on the originating code or priority level of the message. An offer a variety of output formats. Most importantly, it allows to report a complete stack trace to the log when an error occurs. I think t is unacceptable to only see a message such as: NullPointerException in a log file without the stack trace and some sort of indication of the source of the error. In fact all major open source products or packages use a similar pattern for logging and it has become a criteria of quality that QuickFIX/J would certainly benifit, especially in the type of business it is trying to succeed in.

Comment by Steve Bate [ 23/Dec/07 ]

QuickFIX/J includes an SLF4JLogFactory (see http://www.slf4j.org/) that supports a variety of logging providers, including Log4J. It also has a bridge to Commons Logging. To use a Log4J rolling file appender with QFJ, you just include slf4j-log4j12-1.3.0.jar in your classpath instead of the default slf4j-jdk14-1.3.0.jar and then configure Log4J as you normally would.

The issue with logging levels is a limitation of the QuickFIX JNI API which QFJ is based upon. I agree it would be nice to be able to specify a logging level.

I'm not sure I understand the issue about stack traces. Your application log anything it would like directly to your logging provider of choice. However, this would typically be a separate log file than the session log file. If you specifically want to log a stack trace to the session log file then you can use the quickfix.LogUtil.logThrowable() methods to format a stacktrace and write it to the QFJ Log implementation.

The SLF4JLogFactory also allows you specify category patterns that can have session id-related placeholders. This allows separate categories for each FIX session which would support sending different sessions to different files or specifying different pattern layouts for fix versions or specific counterparties, for example.

Comment by André Malenfant [ 23/Dec/07 ]

I will experiment with the SLF4JLogFactory. It does not fix the level issue but still helpfull.

The stack trace issue is for exceptions thrown from quickfixj code, not applications. For example, when an error occurs, the only indication in the event log is the error message of the underlying exception like: NullPointerException. A lot of developers like myself are now expecting to see a full stack trace of where the error was thrown. A stack trace is a great debugging tool. I agree that with bug free code one can rely on the error message only but bug free code is not something I have come accross very often.

As for JNI, do you think quickfixj will eventually branch from quickfix. What is the benefit of keeping compatibility with quickfix. I imagine you have good reasones but from my perspective it is only creating issues: the log level issue, the fix message packaging issue (as noted by Francis Lalonde), the static session issue (I know I should open another issue on this topic).

Comment by Steve Bate [ 23/Dec/07 ]

Stack traces are logged for several exceptions that internal to the engine. I generally only log a stack trace if the exception is probably caused by a coding error. For example, logging a stack trace for an exception caused by a corrupt incoming FIX message isn't really helpful since the corruption generally occurs in the network or in the counterparty's code.

However, if you have specific places where an exception is logged that would be more useful with a stack trace, let me know. I've added a few more recently and I've started catching all exceptions originating from an Application implementation exception and logging stack traces for those (although the application developer should really be doing it). This is in the trunk, not 1.3.0.

On the branching issue, I don't know if you are a subscriber to the mailing list but someone asked about that recently and I've requested some community discussion about it. So far, nobody has followed up on the topic. If you wanted to share your opinions there that would be great. Thanks.

Comment by André Malenfant [ 23/Dec/07 ]

In my developement team, we have taken the habit of systematically log all exceptions in our application code using log4j. Any exception cached are logged along with a message (except a few irrelevant ones like null pointers that are catched to return a default value for example) . This habbit is simple to take when you use log4j (and other libraries as well) because the log methods all take a throwable as a parameter. An administrator of our applications can then choose not to display them in the logs but at least the possibility is there. I don't understand why quickfixj wraps logging with it's own logging classes where slf4j or comons-logging or log4j have already everything required.

I agree that in some instances the stack trace does not give much more information but in a lot of cases it does and especially with an open source product where one can browse the code imself and try to fix the issue or at least investigate. Considering that it is not more effort that simply writting a message in a log (additional parameter to pass to the logging method), I think it is not a luxury and that it can definitely improve troubleshooting.

I will look for the posts regarding the possibility of branching quickfixj and participate if I have some more data to put into it.

Comment by Steve Bate [ 23/Dec/07 ]

André,

Thanks for your comments. Again, if you have a specific place where a stack trace would have been useful to debug your application or to track down problems in QFJ and it wasn't provided, I'll most likely add the stack trace. However, I won't add stack traces for every exception. I've explained why some of these stack traces are not useful. This would only add needless noise to the log file. The fact that's it's so easy to add this noise is more of a problem than a feature, in my opinion.

Where did you see the NullPointerException without the stack trace? Did the exception arise in QFJ or in your application callbacks?

As you know, the logging approach in QFJ is based on the logging API of the QuickFIX JNI code which was obviously not based on Log4J or any other Java logging provider. If I were writing a Java FIX engine from the ground up I wouldn't use the same design. I also still wouldn't use Log4J directly since various libraries use different logging providers. I'd base it on something like SLF4J or Commons Logging.





[QFJ-264] Should be TimeZone.getTimeZone("GMT") instead of TimeZone.getTimeZone("UTC") Created: 14/Nov/07  Updated: 15/Nov/07  Resolved: 15/Nov/07

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

Type: Improvement Priority: Default
Reporter: Eduardo Ostertag Assignee: Unassigned
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows XP SP2, JDK 1.6.0_03 and J2SDK1.4.2_16



 Description   

You are calling the method "TimeZone.getTimeZone" with argument "UTC" to obtain the "GMT" timezone . According to the documentation, you should be calling this method with argument "GMT", instead. The call TimeZone.getTimeZone("UTC") is working because it has fallback logic that defaults to "GMT" when the requested timezone (in this case, "UTC") is not found. As far as I can tell, the following QuickFIX/J files are affected by this issue:

DateField.java
JdbcStore.java
SessionSchedule.java
SystemTime.java
FieldConvertersTest.java
SessionScheduleTest.java
AbstractDateTimeConverter.java



 Comments   
Comment by Steve Bate [ 14/Nov/07 ]

In my environment...

java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b06)
Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)

"UTC" is a valid time zone ID. Are you seeing otherwise? "UTC" and "GMT" are slightly different.

Comment by Eduardo Ostertag [ 15/Nov/07 ]

The directory "<java_home>/lib/zi" contains the names (and definitions) of the time zones distributed with a standard Java JRE/JDK. This directory contains the definition of a time zone (file) called "GMT", but the definition (file) for time zone "UTC" is found in the subdirectory "Etc/UTC". So I guess what I'm saying is that the correct value for the argument of "TimeZone.getTimeZone" should be "Etc/UTC" and not just plain "UTC".

As I said before, calling TimeZone.getTimeZone("UTC") works because "getTimeZone" has logic that defaults to "UTC" in case it doesn't find the requested time zone. This is OK, but when I debug an application built with QuickFIX/J, my "eclipse 3.3" IDE stops inside the JDK code showing the place where a "FileInputStream" throws a "FileNotFoundException" when trying to open a file "UTC" in the directory "<java_home>/lib/zi".

Comment by Steve Bate [ 15/Nov/07 ]

I think I understood your original message. The TimeZone.getTimeZone("UTC") does actually return a UTC timezone object (not GMT) with my version of Java. The TimeZone.getAvailableIDs() method returns both "UTC" and "Etc/UTC" as valid identifiers. Is that the case with your Java environment?

Comment by Eduardo Ostertag [ 15/Nov/07 ]

I checked, and my Java environment returns both "UTC" and "Etc/UTC" as valid identifiers. I also double-checked what I said about the fall back code returning "GMT" time zone, and I was wrong. Calling TimeZone.getTimeZone("UTC") worked OK, and no fallback code was executed. My apologies, your code is OK.

Comment by Steve Bate [ 15/Nov/07 ]

No problem. I didn't realize the TimeZone had a fallback of GMT, which seems a little dangerous, so I had to double check the code to be sure I hadn't imagined a UTC timezone (it's been awhile ). Have a good day.





[QFJ-263] ConfigError when trying to setup SessionSettings from code by filling out Dictionary object Created: 04/Nov/07  Updated: 01/Feb/08  Resolved: 01/Feb/08

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

Type: Other Priority: Major
Reporter: Ionel Roman Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None
Environment:

Windows XP Professional with JRE 1.6.0.03 running Eclipse 3.3.1.1 and QuickFix/J 1.3.0



 Description   

I`m new to Java but I hope my stupidness regarding this environment is not the case of this issue I`m having.

I`m trying to have a QuickFix/J application running. I`m using the same method used in C# with QuickFix.NET: I`m creating the SessionSettings and its configuration Dictionary manually from code. Anyway, the thing is that when I try to assign the Dictionary object to SessionSettings Eclipse tells me I have a ConfigError. I tried different schematics, I even tried with sample config files, still ConfigError. Here is my code:

import quickfix.ConfigError;
import quickfix.Message;
import quickfix.SessionID;

public class QFApplication extends quickfix.MessageCracker implements quickfix.Application {

public QFApplication() {
quickfix.SessionSettings settings = new quickfix.SessionSettings();

quickfix.Dictionary dictionary = new quickfix.Dictionary("session");
dictionary.setLong(quickfix.Session.SETTING_HEARTBTINT, 600);
dictionary.setLong(quickfix.Initiator.SETTING_RECONNECT_INTERVAL, 1);
dictionary.setString(quickfix.FileStoreFactory.SETTING_FILE_STORE_PATH, "c:/qfstore");
dictionary.setString(quickfix.FileLogFactory.SETTING_FILE_LOG_PATH, "c:/qfstore/log");
dictionary.setString(quickfix.Session.SETTING_START_TIME, "00:00:00");
dictionary.setString(quickfix.Session.SETTING_END_TIME, "00:00:00");
dictionary.setBool(quickfix.Session.SETTING_USE_DATA_DICTIONARY, true);
dictionary.setString(quickfix.Session.SETTING_DATA_DICTIONARY, "c:/qfstore/dictionaries/FIX42.xml");
dictionary.setString("BeginString", quickfix.FixVersions.BEGINSTRING_FIX42);
dictionary.setString(quickfix.SessionSettings.SENDERCOMPID, "sender");
dictionary.setString(quickfix.SessionSettings.TARGETCOMPID, "receiver");
dictionary.setString(quickfix.SessionFactory.SETTING_CONNECTION_TYPE, quickfix.SessionFactory.INITIATOR_CONNECTION_TYPE);
dictionary.setBool(quickfix.Session.SETTING_RESET_ON_LOGON, false);
dictionary.setBool(quickfix.Session.SETTING_RESET_ON_LOGOUT, true);
dictionary.setBool(quickfix.Session.SETTING_RESET_ON_DISCONNECT, true);
dictionary.setString(quickfix.Initiator.SETTING_SOCKET_CONNECT_HOST, "127.0.0.1");
dictionary.setLong(quickfix.Initiator.SETTING_SOCKET_CONNECT_PORT, 1025);
dictionary.setBool(quickfix.Session.SETTING_PERSIST_MESSAGES, true);

/*
so I`m setting up the dictionary all ready to be added to session, I need to create a new session with the BeginString identical with the one from Dictionary otherwise QuickFix will not let me add the dictionary to the sessionid and that "settings.set(session, dictionary);" throws exception in the IDE, I can`t get to the source of it though and when the try / catch is there it will not enter the catch part like it did not crash
*/

quickfix.SessionID session = new quickfix.SessionID(
new quickfix.field.BeginString("FIX.4.2"),
new quickfix.field.SenderCompID("sender"),
new quickfix.field.TargetCompID("receiver")
);
try

{ settings.set(session, dictionary); }

catch (ConfigError e)

{ e.printStackTrace(System.out); }

quickfix.FileLogFactory logger = new quickfix.FileLogFactory(settings);
quickfix.FileStoreFactory storer = new quickfix.FileStoreFactory(settings);
quickfix.MessageFactory messages = new quickfix.DefaultMessageFactory();
try

{ quickfix.SocketInitiator initiator = new quickfix.SocketInitiator(this, storer, settings, logger, messages); }

catch (ConfigError e)

{ // TODO Auto-generated catch block e.printStackTrace(System.out); }

}

public void onCreate(SessionID sessionID) {}

public void onLogon(SessionID sessionID) {}

public void onLogout(SessionID sessionID) {}

public void toAdmin(Message message, SessionID sessionID) {}

public void fromAdmin(Message message, SessionID sessionID)
throws quickfix.FieldNotFound, quickfix.IncorrectDataFormat, quickfix.IncorrectTagValue, quickfix.RejectLogon {}

public void toApp(Message message, SessionID sessionID)
throws quickfix.DoNotSend {}

public void fromApp(Message message, SessionID sessionID)
throws quickfix.FieldNotFound, quickfix.IncorrectDataFormat, quickfix.IncorrectTagValue, quickfix.UnsupportedMessageType

{ crack(message, sessionID); }

}

all the best and I hope I did not upset any Java gurus out there with my stupid newbie code,
thank you, my respects to you all,
Ionel Roman






[QFJ-262] Quickfix resend problems after recovering from network failure Created: 30/Oct/07  Updated: 15/Jan/08  Resolved: 12/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.2.1, 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Critical
Reporter: Tim Wright Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None
Environment:

Linux Centos 4 \ Sun JDK 1.6_02


Attachments: Text File FIX Issue.txt     Text File QuickFixLog.txt    

 Description   

We have seen an incident occur twice in our quickfix code where the fix engine seems to send spurious resend requests, and processes FIX messages incorrectly - including handing duplicate messages to the application.

On both occasions, this has happened following a network failure where the FIX engine seemed to behave correctly, recovering missed messages, and correctly handling the re-establishment of the proper sequence numbers. Following (what we assume) is the triggering incident things start to seem to go wrong.

I have attached a file with the full details from out log files which a walk through commentary



 Comments   
Comment by Tim Wright [ 30/Oct/07 ]

This document contains the log files and full details of the issue I have seen.

Comment by Michael Briganti [ 17/Nov/07 ]

We have experienced the same issue while running with 1.3.0. We have not been able to say for certain whether our network experienced an "interruption" but on at lease on distinct occasion we observed the same "runaway" and unrequited resend request. Any help on this issue, or work-around, would be very useful.

Comment by Michael Briganti [ 21/Nov/07 ]

We attempted to investigate further, but unfortunately we cannot provide a log with any conclusive information. What we can say is that we believe there is a network level issue with the mina jar's found in 1.3.0. After migrating to 1.3.0 our application began dropping messages causing the fix engine to send resend requests. We found this behavior to be intermittent, sporadic, and only manifesting during very high load conditions (algorithmic based trading). Prior to "upgrading" to 1.3.0 our application had run for over six months with quickfix 12.1 without ever "glitching." Since this is a production issue for us, and since we were not successful duplicating the issue in our QA environment our solution was to roll-back to quickfix 1.2.1, afterwhich everything became calm again.

We are submitting only to provide a record should others experience unexplained issues with "dirty sockets."

Comment by Steve Bate [ 21/Nov/07 ]

Thanks for the additional information. Is there something specific making you think it is MINA versus a threading issue?

Comment by Michael Briganti [ 21/Nov/07 ]

Our apologies. We hope we aren't sounding too alarmist by assigning the issue to MINA, and in truth, even if MINA is the culprit, it is most likely a threading issue anyway--albeit for MINA to solve.

Our assessment is based on indirect observation which admittedly, must be held circumspect. What we observed is that we can most definitely confirm from logs that our sending engine (in4Reach) sent sequence numbers 10, 11, 12 to the QuickFix 1.3.0 engine and we received 10, and 12. The engine rightfully requests a resend, but what caused the missed message?

Network disconnect on either side is ruled out-both QuickFix 1.3.0 (MINA) and the connecting engine (in4Reach) would have registered a network exception, as in the case of this current issue (QFJ-262)-the reason for the initial thread.

Also, both the connecting engine (in4Reach) and the QuickFix 1.3.1 engine is running internally, on our LAN, indeed on the same subnet. Network topology, and message loss is always a possibility, but not likely since QuickFix 1.2.1 ran for months without ever a single resend request, under similar loads and under the same network topology no less.

Based on our limited analysis, the only issues we have left to investigate is the differences between the QuickFix versions (1.3.1 vs. 1.2.1). When we compared the Session.java modules from the two versions we couldn't be certain, but it appeared that most of the changes are of the "plain vanilla type" and were initiated in order to move from jdk1.4 to jdk1.5 although of course, you would be in a better position then we are to know what exactly is going on in that module. Furthermore, if the issue was at the QuickFix level, we would expect the MINA modules to have logged the incoming messages and for the messages to make it through the MessageDecoders--which to the best that we can tell, is not the case.

We've used MINA for other purposes, and while our experiences have been positive, we have always been concerned about stability of new releases, but this may be a simple prejudice rather then a something to be considered a hard fact.

A little more about our installations. You already know the network topology. From the hardware perspective, we are running on MS Window 2003 multi-processor (2 dual core) server machines. On the QuickFix side we are using the SleepycatStore which initially we had some concerns about because there was some synchronization in the SleepycatStore module that we didn't quite understand. We hypothesized that the SleepycatStore module may have no extensive field experience to speak of and that this module could be mucking up sequence numbers, but again, the QuickFix based MINA modules would have logged the incoming messages, after which things would have gotten a little chaotic within the engine itself.

That is all we have to offer. I wish our report could provide more conclusive evidence with regard to the issues genesis. Of course, if messages are not being reliably delivered, we can expect that this thread would start to load up pretty quickly.

Comment by Tim Wright [ 22/Nov/07 ]

Hi all,

Firstly, I do have to apologize for throwing in a bit of a red herring in. I double checked the versions of quickfix we were running when the incidents occurred and it was 1.2.1 and not 1.3.0. It seems looking for the issue we have experience will not be found in a code change between 1.2.1 and 1.3.0.

We have only ever seen the issue following an "ungraceful fail over" of a switch connected to our firewall (thru which the FIX connection passes).To date, we have not done much investigation into the code since a restart the process is quite painless, the issue is rare and the problematic switch has now been fixed!

Michael, it seems possible you have a different or related issue?

It's doe seems likely that the issue we experience were triggered by a problem in Mina. In on example quickfix reports that a messages was dropped and starts the resend process even though the message is clearly output in the log. It's seems possible that problems in Mina could cause this - but not sure how.

When we get some time, we will try and reproduce the problem and do a little more investigation.

Tim

Comment by Michael Briganti [ 23/Nov/07 ]

We are attaching a file of a recent session running with QuickFix 1.3.0. Our installation receives a message type 35=Q, DK message with sequence number 1285. The message is received and logged to the JDBC logger so we know this message made it to our quickfix 1.3.0 installation. The engine then complains that it hasn't received 1285, apparently claiming it is receiving 1286, even though 1286 does not appear until quite a few milliseconds later (and in the form of a 35=4 the sequence reset protocal). The engine requests a resend, and apparently gets the resend, and we see that no matter what happens, the 1285 message does not get satisfied.

Comment by Michael Briganti [ 23/Nov/07 ]

Incidentally, the last post, and attached logging information, plus some additional investigations we did with the MINA community seems to rule-out MINA as the culprit, at least for the issues we are experiencing.

Comment by Steve Bate [ 24/Nov/07 ]

The log file definitely indicates some strange behavior. My current theory is that it's some type of thread-related issue. The resend processing hasn't changed in quite some time. Just for additional information, what message store and session connector implementations are you using? Have you created custom implementations or modified the QFJ bundled implementations? Again, I'm not saying you're doing anything to cause this problem but I'm trying to eliminate that possibility.

Comment by Michael Briganti [ 24/Nov/07 ]

We are running quite a few QuickFix installations around here--to you and your team credit. Of course, when a "problem" was uncovered in one installation, our development team became hyper-vigilent and that is how the second problem was uncovered. For the particular implementation that coincides with our log attachment, we are using the standard ThreadedSocketAcceptor/Initiators that comes "out of the box."

I'm glad you asked about the message store. Originally I was under the impression that we were using the supplied JdbcStore, but after closer inspection for this implementation we are using a slightly "tweaked" JdbcStore, and for the first implementation, the implementation where the original problem was observed, we are using the SleepycatStore.

In closer inspection of the "tweaked" version of the JdbcStore, I can see we have slightly modified the reset() method, and this very well could be the reason for the issue and the strange behavior exhibited in the log file we supplied. Our reason for modifying reset() escapes me at the moment. For this installation we are planning to revert to the standard JdbcStore and to also instrument that installation with SLF4J engine level logging. That installation is a large one (for us) with over 30 separate connections, some initiators and some acceptors. Generally it behaves very well and should a problem develop, we will have increased visibility within the logs and better assurances that we are using a out-of-box configuration.

Going forward, we still have the SleepycatStore installation to contend with. This installation is used in Algorithmic trading and must contend with large burst of many orders that happen in very quick succession. Like the other installation, this component is using standard ThreadedSocketAcceptor/Initiators and is currently fully instrumented for engine level logging through SLF4J. This installation works fine with 1.2.1 but begins to fritz with the upgrade to 1.3.0. Originally we suspected MINA, but after having discussions on the MINA boards, and upon closer inspections we are backing away from that assessment.

Kindly weigh in on your assessment of the SleepycatStore. We are considering sacrificing some through-put and convert to the JdbcStore for the aforementioned installation since we are concerned that the SleepycatStore may have little or no experience in actual production situations.

In reviewing our contributions to this thread, I am realizing that we have supplied you with a lot of words but no conclusive material that can assist in saying for certain if there is a problem in 1.3.0 or not. We will continue to monitor our installations and will provide additional information as it becomes available to us.

In the meantime thanks for your timely support.

Comment by Steve Bate [ 12/Jan/08 ]

I think this may have been an issue with the way the session state resend queue was being managed. I have made some modifications and done some load testing with lots of corrupted messages, random disconnects, and so on and everything appears to be working well. If you continue to have these problems after 1.3.1, then please reopen the issue.





[QFJ-261] Date/time field constructors use current time by default Created: 26/Oct/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.1

Type: Improvement Priority: Default
Reporter: Qiyan Li Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

The TransactionTime() constructor in version 1.2.1 used to return a TransactionTime with the current system time in it, and this has changed in the 1.3.0 where the time of the first call to this constructor is returned. Is this intentional? There's no Javadocs, so I can't tell for sure.

If this is not intentional, the problem lies with the createDate() method of quickfix.DateField.java:

private static Date createDate() {
synchronized (calendar)

{ return calendar.getTime(); }

}

where calendar is also static.



 Comments   
Comment by Toli Kuznets [ 26/Oct/07 ]

Qiyan

I think that this is a bug as well - i brought it up in an email thread http://www.nabble.com/No-arg-constructor-for-DateFields-tf4577998.html#a13068511 , but then ended up coding around it and, unfortunately, never followed up.

Essentially, due to teh fact that the calendar in DateField is static, the times are cached so code like this ends up getting the same time value for both fields:
Message msg = new Message();
msg.setField(new TransactTime());
sleep(20 seconds)
msg.setField(new SendingTime());

Comment by Qiyan Li [ 26/Oct/07 ]

I have worked around the problem, but the real problem is that the semantics of the default constructor changed between releases. This can cause problems to code relying on backward compatibility.

Comment by Steve Bate [ 22/Dec/07 ]

Modified the default constructor of the DateField object to use new Date().





[QFJ-260] onLogout event Created: 19/Oct/07  Updated: 01/Feb/08  Resolved: 01/Feb/08

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

Type: Other Priority: Default
Reporter: André Malenfant Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Is the onLogout event called when the heartbeat is not received within the configured interval?



 Comments   
Comment by Toli Kuznets [ 20/Oct/07 ]

Andre,
To answer your question - yes, onLogout is called when the session is "timed out" - ie when the time from last received message is greater than some multiplier of heartbeat interval.

It's also called from a few other places, such as wrong versions, fields missing from logon, etc

Comment by André Malenfant [ 23/Oct/07 ]

Thanks for your quick response.

Is the multiplier configurable?

How does one differentiate a "gracefull" logout from a timed out session or other error from the listener?





[QFJ-259] DoNotSend constructors Created: 18/Oct/07  Updated: 22/Dec/07  Resolved: 22/Dec/07

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

Type: Improvement Priority: Default
Reporter: Danilo Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

quickfix.DoNotSend should implement all four java.lang.Exception constructors.

DoNotSend();
DoNotSend(String);
DoNotSend(String, Throwable);
DoNotSend(Throwable);



 Comments   
Comment by Steve Bate [ 22/Dec/07 ]

The DoNotSend exception is only used to override the sending of messages in certain scenarios. It is not logged or rethrown to any code that could make use of the exception message text.





[QFJ-258] MINA acceptor unbind closes sockets before logout Created: 17/Oct/07  Updated: 15/Jan/08  Resolved: 12/Jan/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.1

Type: Bug Priority: Major
Reporter: Mike Gu Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Wndows XP, Eclipse 3.2.1, Jdk1.5



 Description   

SocketAcceptor ,ThreadSocketAcceptor stop mechanism can't work.

In the version 1.2.1, in the sample, after the banzai and the executor have run, I press <enter> in the executor console. It turns out only one session has been disconnected in my computer and other four sessions still run.
In the version 1.3.0, in the sample, after the banzai and the executor have run, I press <enter> in the executor console. It turns out all five sessions have been disconnected(not logout). In my opinion, after we call SocketAcceptor \ ThreadSocketAcceptor stop method, what we really want to do is to initiate the logout procedure, not initiate the discnonnect procedure. Am I right?

Thanks
Mike Gu



 Comments   
Comment by Mike Gu [ 17/Oct/07 ]

I have confirmed that the reaseon that version 1.2.1 acts differently to version 1.3.0 is they using different versions of mina jar.

Comment by Mike Gu [ 17/Oct/07 ]

I have found the bug reason. In the SocketAcceptor\ThreadSocketAcceptor stop() mehod, it firstly call the stopAcceptingConnections(). And in the stopAcceptingConnections() method, there is an operation: ioAcceptor.unbind(acceptorSocketAddress); It will unbind and also close the io connnection.





[QFJ-257] Error Reading/Writing in MessageStore Created: 16/Oct/07  Updated: 12/Dec/07  Resolved: 12/Dec/07

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

Type: Other Priority: Default
Reporter: Parag Mehta Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux.



 Description   

Hi,

Was receiving this message without any stack trace or details on initialization of the quickfixj engine.

2007-10-15 15:52:53,394 [QFJ Timer] INFO quickfixj.event - FIX.4.2:SENDER->TARGET: Error Reading/Writing in MessageStore

The subsequent incoming seqnum does not get updated in the db though outgoing does, causing the engines to stop talking to each other. I believe I had to delete entries in the messages table to get rid of the error. Unfortunately, I forgot to capture the offending data in messages table.

Q:

  • Is there a way to get more information about 'Error Reading/Writing in MessageStore' message to make the cause more apparent (like a strack trace, or data that failed to be read/written)?
  • Is the behavior expected (unable to write incoming seqnum once the error has occurred )?
  • Is there a way to make the engine throw an exception on initialization when the error occurs so that the process can be stopped instead of allowed to continue? The error itself is logged at INFO level.

Thanks a lot for your help.



 Comments   
Comment by Parag Mehta [ 16/Oct/07 ]

More info:

The issue seems to happen when:

  • There are existing messages in the db.
  • Seq numbers are rolled back or reset without removing the existing messages which would clash seq numbers when the engine starts.

While writing a message with the same id exists in the table, hence the error probably.

The resolution of course is that if seq reset is required, the messages table needs cleanup.





[QFJ-256] SSLContextFactory doesn't support custom trust stores Created: 02/Oct/07  Updated: 29/May/17  Resolved: 29/May/17

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.3.0
Fix Version/s: 1.6.3

Type: Improvement Priority: Default
Reporter: James Furness Assignee: Marcin L
Resolution: Duplicate Votes: 1
Labels: None
Environment:

WinXP SP2, jdk1.5.0_11, QuickFIXJ 1.3.0


Issue Links:
Duplicate
duplicates QFJ-821 Quickfix/J Server should validate SSL... Closed

 Description   

SSLContextFactory is able to load a custom keystore into the KeyManagerFactory to send a certificate to the other party. However, it is not able to load a custom truststore into the TrustManagerFactory, instead it uses SimpleTrustManagerFactory which accepts any certificate sent by the other party.

This has no impact on the ability to connect since all connections will be accepted, however it seems to leave the connection open to a man-in-the-middle attack.

Although the chances of this happening are remote, it would be good to be able to specify a custom truststore.

This could be achieved by using TrustManagerFactory.getInstance(...) instead of SimpleTrustManagerFactory.X509_MANAGERS and specifying the trust store using system properties (As mentioned here http://www.nabble.com/SSL-with-QuickFIX-J-1.1.0-t3758073.html).

Alternatively, possibly better would be to use the existing configuration files, and load a configured trust store into the TrustManagerFactory something like this:

----------------
// initialise the TrustManagerFactory and load our keystore into it
trustManagerFactory = TrustManagerFactory.getInstance(trustAlgorithm);

FileInputStream trustInputStream = new FileInputStream(trustFile);
KeyStore keystore = KeyStore.getInstance("jks");
keystore.load(trustInputStream, trustPass.toCharArray());
trustInputStream.close();

// Initialise TrustManagerFactory with this KeyStore
trustManagerFactory.init(keystore);
----------------

This can then be passed to SSLContext.init() instead of SimpleTrustManagerFactory.X509_MANAGERS.

Thanks,
James






[QFJ-255] Remove dependencies between different FIX version jarfiles Created: 02/Oct/07  Updated: 01/Apr/14  Resolved: 01/Apr/14

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

Type: Improvement Priority: Default
Reporter: Francis Lalonde Assignee: Unassigned
Resolution: Fixed Votes: 2
Labels: None
Environment:

windows / eclipse using FIX 4.3 initiator


Attachments: File DefaultMessageFactory.java     File DefaultMessageFactory.java     File DefaultMessageFactory.java     File MessageCracker.java     XML File MessageCracker.xsl    

 Description   

Since QFJ v1.2, the QFJ lib consists of 5 jarfile. Programs depending on QFJ need to import all five files for it to work because of internal circular dependencies.

The submitted improvement breaks these dependencies and allows client application to import only the jarfiles of the FIX version that they use. For example, a client application conversing only with FIX 4.3 servers, could import only quickfixj-core.jarfile and quickfixj-msg-fix43.jar. The space savings could be useful in constrained remote deployment situations, and generally helps to reduce bloat.

The first code transforms tries to to keep the original MessageCracker pattern intact, without breaking existing code. MessageCrackers no longer extend each other from one version to the next; instead they all derive from the core MessageCracker, which uses introspection used to load the appropriate MessageCracker classes for each FIX version that needs to be cracked. The version-specific MessageCracker instances are stored in a cache.

crack() calls to the core (generic) MessageCracker method are routed to a modified crack() method in the appropriate version-specific MessageCracker, which takes the orignal instance as parameter in order to be able to callback the appropriate overloaded onMessage() method once the message class is determined. The core MessageCracker defines utility methods to enable introspection based onMessage() calls and handling of MessageType default cases.

Exisiting code using classes extending the versionned MessageCracker classes should see no impact, since the call pattern did not change at all in that case.

Existing classes deriving from the core (generic) MessageCracker will break on compilation if they were calling super() in their onMessage() methods, since the generic MessageCracker no longer derives from the fix44 MessageCracker, it no longer defines these methods. However, their onMessage methods will still be called correctly, although through Introspection rather than overloading.

Although not tested, it is quite probable that using introspection will somewhat reduce performance when using the generic MessageCracker, although not enough to show any impact in low to moderate message volumes. A second level per-instance method-cache could be added to reduce onMessage() method lookup time. If performance is an absolute concern, using version-specific MessageCrackers should be considered.

The second code transform is of a more benign nature and only affects the DefaultMessageFactory class. Like the message cracker, it uses dynamic classloading to identify which version-specific MessageFactories are available. Once loaded, create() methods are called directly, without Introspection.

Errors in dynamic classloading and introspection mechanisms result in RuntimeExceptions. An application expecting version specific behavior should break if the appropriate jarfile is not on the classpath. Generic handling of message without an onMessage() method will throw UnsupportedMessageType. Where needed, InvocationTargetExceptions are unwrapped and rethrown bare to preserve the application's ability to handle special cases (UnsupportedMessageType, FieldNotFound, IncorrectTagValue).



 Comments   
Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\MessageCracker.java

Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\codegen\MessageCracker.xsl

Comment by Francis Lalonde [ 02/Oct/07 ]

replaces quickfixj-1.3.0-src\quickfixj\core\src\main\java\quickfix\DefaultMessageFactory.java

Comment by Francis Lalonde [ 02/Oct/07 ]

This replaces the first uploaded version. Better loading performance, better error reporting.

Comment by Scott Harrington [ 28/Mar/08 ]

Francis: I found your contribution very useful.

There is a typo at DefaultMessageFactory.java:124, in that line you need to change BEGINSTRING_FIX43 to BEGINSTRING_FIX42.

Comment by Francis Lalonde [ 09/Apr/08 ]

Fixed the BEGINSTRING_FIX43- > 42 at line 124 issue reported by Scott (thanks).

Also, note that the proposed modifications do not pass the unit tests, as the harness expects some classes to be derived from others, which is the thing this fix specifically intends to break, while preserving full compatibility with existing client code. So either the test cases should be loosened (can we do that?), or this change be confined to an experimental branch.

Comment by Christoph John [ 22/Aug/12 ]

I'm not 100% sure, but wasn't this addressed in QFJ 1.5.1 and the cracker uses introspection since then?

Comment by Christoph John [ 01/Apr/14 ]

I think this has been solved in http://sourceforge.net/p/quickfixj/code/1005





[QFJ-254] SSLContextFactory doesn't load a SocketKeyStore configured as a file path Created: 01/Oct/07  Updated: 15/Jan/08  Resolved: 13/Dec/07

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

Type: Improvement Priority: Default
Reporter: James Furness Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

WinXP SP2, jdk1.5.0_11, QuickFIXJ 1.3.0



 Description   

The initializeKeyStore() method of SSLContextFactory uses SSLContextFactory.class.getResourceAsStream() followed by SSLContextFactory.class.getClassLoader().getResourceAsStream() to locate the configured SocketKeyStore. Both of these seem to return null if SocketKeyStore is a local path.

The Configuring QuickFIX/J section of the user manual states valid values for SocketKeyStore are "File path", so I assume this isn't intentional.

Applying the patch below to SSLContextFactory.java fixes the issue for me:

75a84,89
> if (in == null) {
> try

{ > in = new FileInputStream(keyStoreName); > }

catch (FileNotFoundException ex)

{ > }

> }

I've attached the abridged output from running a test app with -Djavax.net.debug=ssl:handshake, this shows the SSL handshake is failing due to an empty certificate chain, and that a keystore hasn't been loaded.

Before:

-----------------
<20071001-17:33:32, FIX.4.4:SOURCE->TARGET, event> (Session FIX.4.4:SOURCE->TARGET schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC))
<20071001-17:33:32, FIX.4.4:SOURCE->TARGET, event> (Created session: FIX.4.4:SOURCE->TARGET)
trigger seeding of SecureRandom
done seeding SecureRandom
Using SSLEngineImpl.
%% No cached client session

      • ClientHello, TLSv1
        RandomCookie: ...
        Session ID: {}
        Cipher Suites: ...
        Compression Methods: { 0 }
        ***
        SocketConnector-0, WRITE: TLSv1 Handshake, length = 73
        SocketConnector-0, WRITE: SSLv2 client hello message, length = 98
        SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 1425
        *** ServerHello, TLSv1
        RandomCookie: ...
        Session ID: ...
        Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
        Compression Method: 0
        ***
        %% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
        ** SSL_RSA_WITH_RC4_128_MD5
        *** Certificate chain
        chain [0] = [
        [
        Version: V1
        Subject: ...
        Signature Algorithm: ...

        Key: Sun RSA public key, 1024 bits
        modulus: ...
        public exponent: ...
        Validity: [From: Tue Jun 07 19:13:15 BST 2005,
        To: Fri Jun 05 19:13:15 BST 2015]
        Issuer: ...
        SerialNumber: ...

        ]
        Algorithm: [MD5withRSA]
        Signature: ...

        ]
        ***
        *** CertificateRequest
        Cert Types: RSA, DSS,
        Cert Authorities:
        ...
        *** ServerHelloDone
        *** Certificate chain
        ***
        *** ClientKeyExchange, RSA PreMasterSecret, TLSv1
        Random Secret: ...
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 141
        SESSION KEYGEN:
        ...
        CONNECTION KEYGEN:
        Client Nonce:
        ...
        Server Nonce:
        ...
        Master Secret:
        ...
        Client MAC write Secret:
        ...
        Server MAC write Secret:
        ...
        Client write key:
        ...
        Server write key:
        ...
        ... no IV for cipher
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Change Cipher Spec, length = 1
        *** Finished
        verify_data: ...
        ***
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 32
        SocketConnectorIoProcessor-0.0, READ: TLSv1 Alert, length = 2
        SocketConnectorIoProcessor-0.0, RECV TLSv1 ALERT: fatal, bad_certificate
        SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: bad_certificate
        SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Received fatal alert: bad_certificate
        <20071001-17:33:37, FIX.4.4:SOURCE->TARGET, event> (Disconnecting)
        SocketConnectorIoProcessor-0.0, called closeOutbound()
        SocketConnectorIoProcessor-0.0, closeOutboundInternal()
        SocketConnectorIoProcessor-0.0, SEND TLSv1 ALERT: warning, description = close_notify
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Alert, length = 18
        SocketConnectorIoProcessor-0.0, called closeInbound()
        SocketConnectorIoProcessor-0.0, fatal: engine already closed. Rethrowing javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
        SocketConnectorIoProcessor-0.0, called closeOutbound()
        SocketConnectorIoProcessor-0.0, closeOutboundInternal()
        -----------------

        After:
        -----------------
        <20071001-17:34:17, FIX.4.4:SOURCE->TARGET, event> (Session FIX.4.4:SOURCE->TARGET schedule is daily, 00:00:00 UTC - 00:00:00 UTC (daily, 00:00:00 UTC - 00:00:00 UTC))
        <20071001-17:34:17, FIX.4.4:SOURCE->TARGET, event> (Created session: FIX.4.4:SOURCE->TARGET)
        ***
        found key for : TARGET
        chain [0] = [
        [
        Version: V1
        Subject: ...
        Signature Algorithm: ...

        Key: Sun RSA public key, 1024 bits
        modulus: ...
        public exponent: ...
        Validity: [From: Wed Jun 06 16:51:56 BST 2007,
        To: Sat Jun 03 16:51:56 BST 2017]
        Issuer: ...
        SerialNumber: ...

        ]
        Algorithm: [MD5withRSA]
        Signature:
        ...

        ]
        ***
        trigger seeding of SecureRandom
        done seeding SecureRandom
        Using SSLEngineImpl.
        %% No cached client session
        *** ClientHello, TLSv1
        RandomCookie: ...
        Session ID: {}
        Cipher Suites: ...
        Compression Methods: { 0 }

        ***
        SocketConnector-0, WRITE: TLSv1 Handshake, length = 73
        SocketConnector-0, WRITE: SSLv2 client hello message, length = 98
        SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 1425

      • ServerHello, TLSv1
        RandomCookie: ...
        Session ID: ...
        Cipher Suite: SSL_RSA_WITH_RC4_128_MD5
        Compression Method: 0
        ***
        %% Created: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
    • SSL_RSA_WITH_RC4_128_MD5
      • Certificate chain
        chain [0] = [
        [
        Version: V1
        Subject: ...
        Signature Algorithm: ...

Key: Sun RSA public key, 1024 bits
modulus: ...
public exponent: ...
Validity: [From: Tue Jun 07 19:13:15 BST 2005,
To: Fri Jun 05 19:13:15 BST 2015]
Issuer: ...
SerialNumber: ...

]
Algorithm: [MD5withRSA]
Signature:
...

]
***

      • CertificateRequest
        Cert Types: RSA, DSS,
        Cert Authorities:
        ...
      • ServerHelloDone
        matching alias: TARGET
      • Certificate chain
        chain [0] = [
        [
        Version: V1
        Subject: ...
        Signature Algorithm: ...

Key: Sun RSA public key, 1024 bits
modulus: ...
public exponent: ...
Validity: [From: Wed Jun 06 16:51:56 BST 2007,
To: Sat Jun 03 16:51:56 BST 2017]
Issuer: ...
SerialNumber: ...

]
Algorithm: [MD5withRSA]
Signature:
...

]
***

      • ClientKeyExchange, RSA PreMasterSecret, TLSv1
        Random Secret: ...
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 604
        SESSION KEYGEN:
        PreMaster Secret:
        ...
        CONNECTION KEYGEN:
        Client Nonce:
        ...
        Server Nonce:
        ...
        Master Secret:
        ...
        Client MAC write Secret:
        ...
        Server MAC write Secret:
        ...
        Client write key:
        ...
        Server write key:
        ...
        ... no IV for cipher
      • CertificateVerify
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 134
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Change Cipher Spec, length = 1
      • Finished
        verify_data: ...
        ***
        SocketConnectorIoProcessor-0.0, WRITE: TLSv1 Handshake, length = 32
        SocketConnectorIoProcessor-0.0, READ: TLSv1 Change Cipher Spec, length = 1
        SocketConnectorIoProcessor-0.0, READ: TLSv1 Handshake, length = 32
      • Finished
        verify_data: ...
        ***
        %% Cached client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5]
        QFJ Timer, WRITE: TLSv1 Application Data, length = 156
        <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Initiated logon request)
        <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Logon contains ResetSeqNumFlag=Y, resetting sequence numbers to 1)
        <20071001-17:34:21, FIX.4.4:SOURCE->TARGET, event> (Received logon response)
        -----------------

Thanks,
James



 Comments   
Comment by Steve Bate [ 13/Dec/07 ]

I added the file system search. Thanks.





[QFJ-253] CLONE -First login attempt of initiator afterStartTime is responded with logout Created: 01/Oct/07  Updated: 01/Feb/08  Resolved: 01/Feb/08

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

Type: Other Priority: Default
Reporter: Michael Briganti Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

2003



 Description   

Hi Steve, it's been quite a while.
We are experiencing the bug detailed below.
Do you have a specific patch for this for 1.2.1, or is 1.3.0 stable enough
for production.

This could be related to a open bug about the timer events not being
processed in an acceptor while it's disconnected (QFJ-218). This would
cause the logout with the old sequence number to be sent the first time
someone connects. Subsequent connections should be ok and should use the
new session's sequence numbers. If we can complete the 1.3 release soon,
I'll have the fix in there. Otherwise, I'll patch 1.2.1 and release a
new version of that branch.

A temporary workaround is to call reset manually on the message
store before the new session start time.

Regards,

Steve



 Comments   
Comment by Michael Briganti [ 01/Oct/07 ]

Hi Steve. We tried with version 1.3.0 and it appears this issue has not been fixed.

Comment by Steve Bate [ 01/Oct/07 ]

This is apparently a different issue. Does the logout message have a text field in it? If so, what does it say? I assume you've looked in the log files to see if there is anything interesting there.

Comment by Davide Tedesco [ 21/Jan/08 ]

Hi,

I got the same problem and I tried either ver. 1.3.0 and 1.3.1; they seems to carry the same bug.
I see that on EndTime the Initiator sends the logout and disconnect, without waiting for the ack from the Acceptor.
As a workaround I tried to set LogoutTimeOut = 10 sec, but the Initiator drop the connection at EndTime, without waiting 10 sec.
As a consequence at next StartTime the Initiator sends a logout first, problably because it didn't receive the ack to the logout at the last Endtime.
So the 2 bugs seems to be realated.

Regards,

Davide





[QFJ-252] Quickfix/J stops sending tag 141 on logon Created: 27/Sep/07  Updated: 09/Jan/08  Resolved: 22/Dec/07

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

Type: Bug Priority: Default
Reporter: André Malenfant Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

After several logon attemps, quickfix/J stops sending tag 141 and starts increasing the sequence number which has for effect to received a msg sequence error when the logon is eventually responded. See the log excerpt below and note that there are numerous logon attemps before and after it:

8=FIX.4.39=8035=A34=149=cgiwl352=20070905-10:12:44.51056=bofaCgiwlTest98=0108=30141=Y10=154
8=FIX.4.39=8035=A34=149=cgiwl352=20070905-10:12:55.50956=bofaCgiwlTest98=0108=30141=Y10=164
8=FIX.4.39=8035=A34=149=cgiwl352=20070905-10:13:06.54056=bofaCgiwlTest98=0108=30141=Y10=156
8=FIX.4.39=7435=A34=249=cgiwl352=20070905-10:13:18.52356=bofaCgiwlTest98=0108=3010=119
8=FIX.4.39=7435=A34=349=cgiwl352=20070905-10:13:29.52356=bofaCgiwlTest98=0108=3010=122
8=FIX.4.39=7435=A34=449=cgiwl352=20070905-10:13:40.52256=bofaCgiwlTest98=0108=3010=115
8=FIX.4.39=7435=A34=549=cgiwl352=20070905-10:13:51.52156=bofaCgiwlTest98=0108=3010=117



 Comments   
Comment by Toli Kuznets [ 27/Sep/07 ]

Andre,
can you attach your quickfixj.cfg file to this?
The values of ResetOnLogout/ResetOnDisconnect/ResetOnLogin all contribute to whether or not tag 141 gets sent.

Comment by André Malenfant [ 27/Sep/07 ]

ResetOnLogout not specified (N)
ResetOnDisconnect not specified (N)
ResetOnLogin not specified (N)
SendResetSeqNumFlag=Y

Comment by André Malenfant [ 27/Sep/07 ]

Sorry,

ResetOnDisconnect=Y

Comment by Steve Bate [ 06/Oct/07 ]

This won't be enough information for me to effectively diagnose the issue. If you start the Banzai example program with a similar configuration and with no corresponding acceptor program, do you see the same behavior?

Comment by André Malenfant [ 08/Jan/08 ]

We can reproduce this problem almost systematically on a production environment and this is a big problem for us as we cannot rely on automatic reconnection if connections are dropped. Most of the time, the flag is not sent for a period of time and then, all of the suden, it is sent. Sometimes it can take serveral minutes and close to an hour for the flag to be sent.

I understand that you don't have enough info to troubleshoot but can you give us ideas on what data to collect (I was about to say debugging level to help investigate?

Comment by Steve Bate [ 08/Jan/08 ]

André,

Well, I did make a suggestion back in October.

This doesn't appear to be a reconnect problem. You can't send a logon message if you aren't connected. Apparently, the reconnect is working fine.

For the sequence reset, QFJ will only sent send 141=Y when the expected sequence numbers are 1 for both sender and target. Notice that in your original log example the 141=Y stopped being sent when the sequence number was greater than 1.

The ResetOnDisconnect flag resets the sequence numbers every time there is a disconnect and this should cause the 141=Y to be sent. Are the logon attempts timing out? That should cause a disconnect, but I'm curious. In any case, it's seems /very/ strange to be doing a sequence reset on disconnect in a production environment. Are you doing anything in your code related to logon messages (for example, explicitly initiated them or modifying them in some way)?

Comment by André Malenfant [ 08/Jan/08 ]

Steve, I did not try your suggestion in October because I cannot reproduce the problem in my development environment with my app. I can only reproduce in prod. The only difference beeing that the remote application is different and I have no control over it.

Sorry for the confusion I meant when a logout occurs (whether scheduled or because of a connection drop) quickfixj will eventually start to issue logon messages (after the connection is reestablished, of course) and will not send the flag in all cases. I cannot find any pattern that could help understand the conditions for it.

In my original log, quickfixj sends the flag 3 times and then, all of the suden, starts incrementing the sequence number and stops sending the flag. Why is this so? Why would it start incrementing the sequence number without having received a logon response from the other party? Nothing happens in between except quickfixj retrying a logon every mintue.

The other case we see is the opposite. Quickfixj does not send the sequence reset flag even tough the sequence number has been reset on disconnect. Which obviously creates an issue and the other party denies the login because of the numbers beeing desynchronized. Eventually, after some time, quickfixj resets the number and starts to send the flag. Sometimes, to speed up the process I restart my app until this occurs without having done anything else than restarting.

The reason that we want to reset is because the data that is transmitted is transent and thus cannot be resent. There is no point in recovering lost messages and we simply want to reset the sequence numbers when we disconnect.

We are not doing anything special with regard to the login. We let quickfixj handle that. The only message we create and send explicitely are application level messages.

This is a real life production issue, and it is problematic for us.

Comment by Steve Bate [ 08/Jan/08 ]

> In my original log, quickfixj sends the flag 3 times and then, all of the suden, starts incrementing the
> sequence number and stops sending the flag. Why is this so?

Like I said, QFJ will only send the sequence resets when the sender/target sequence numbers are 1. The fourth and subsequent messages in your attached log has a sequence number greater than 1.

Which message store are you using? Are you using the PersistMessages=N session option? This might eliminate the need to hack the sequence numbers when no messages should ever be resent (like with market data).

Can you create a timeline that includes both the logon message events and connect/disconnect events? This might give some clues.

Comment by André Malenfant [ 08/Jan/08 ]

Agreed but why did quickfixj started incrementing the sequence between too logon attempt? The sender was never involved in the log above.

I will document more clearly an occurance of the problem and get back to you.

Here is my config (I scrambled some sensitive data...):

[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60

[SESSION]
BeginString=FIX.4.3
SenderCompID=SomeCompID
TargetCompID=TargetCompID
StartTime=00:00:00
EndTime=00:00:00
HeartBtInt=30
SocketConnectPort=9999
SocketConnectHost=MyHost
UseDataDictionary=N
SessionQualifier=MySession
SendResetSeqNumFlag=N
ResetOnDisconnect=Y
DataDictionary=...\config\schemas\quickfix\FIX43.xml
JdbcDriver=net.sourceforge.jtds.jdbc.Driver
JdbcURL=jdbc:jtds:sqlserver:server:port
JdbcUser=andre
JdbcPassword=password
JdbcStoreMessagesTableName=quickfixMessages
JdbcStoreSessionsTableName=quickfixSessions

Thanks

Comment by André Malenfant [ 09/Jan/08 ]

Steve, the config I sent previously is not valid, this was a test config I used to try different settings.

You should read:

SendResetSeqNumFlag=Y
ResetOnDisconnect=N

We had the issue on 17 apps yesterday night. Here is an example: (timestamps in Europe\London)

1- It starts with a scheduled logout coming from the other party which I changed here to DEF
2- We respond to the logout successfully
3- Quickfix then starts to try to reconnect and keeps the sequence number even thoug we have have SendResetSeqNumFlag=Y . Not a big deal since the other party in not responding yet.
4- At the 7th retry, quickfix reset the sequence to 1 but does NOT send the flag
5- The other party returns an error, a valid one since we did not ask him to reset the sequence.
6- This goes on over an hour until the flag is sent after numerous restarts.
7- Notice the last lines where, finally, quickfix sends the flag.

We know have set ResetOnDisconnect=Y since it reduces the number of restarts we need to do to correct the situation to one.
We recognise that there is something strange in the fact that the other party returns an error in the first place. It is expecting a sequence number that is higher than everything we ever sent. I will try to get this explain. But the sequence reset problem remains valid to me.

8=FIX.4.39=8335=549=DEF56=ABC34=288152=20080108-22:04:5958=Scheduled logout10=107
8=FIX.4.39=6735=534=266549=ABC52=20080108-22:04:59.99656=DEF10=077
8=FIX.4.39=7935=A34=266649=ABC52=20080108-22:05:00.71556=DEF98=0108=3010=094
8=FIX.4.39=7935=A34=266749=ABC52=20080108-22:06:01.71556=DEF98=0108=3010=097
8=FIX.4.39=7935=A34=266849=ABC52=20080108-22:07:02.73156=DEF98=0108=3010=098
8=FIX.4.39=7935=A34=266949=ABC52=20080108-22:08:02.73156=DEF98=0108=3010=100
8=FIX.4.39=7935=A34=267049=ABC52=20080108-22:09:03.74756=DEF98=0108=3010=101
8=FIX.4.39=7935=A34=267149=ABC52=20080108-22:10:03.76356=DEF98=0108=3010=092
8=FIX.4.39=7235=A49=DEF56=ABC34=152=20080108-22:10:04108=3098=010=233
8=FIX.4.39=11935=534=267249=ABC52=20080108-22:10:04.92056=DEF58=MsgSeqNum too low, expecting 2882 but received 110=152
8=FIX.4.39=7935=A34=267349=ABC52=20080108-22:11:04.76456=DEF98=0108=3010=097
8=FIX.4.39=7235=A49=DEF56=ABC34=352=20080108-22:11:05108=3098=010=237
8=FIX.4.39=11935=534=267449=ABC52=20080108-22:11:05.48356=DEF58=MsgSeqNum too low, expecting 2882 but received 310=162
8=FIX.4.39=7935=A34=267549=ABC52=20080108-22:12:05.78056=DEF98=0108=3010=099
8=FIX.4.39=7235=A49=DEF56=ABC34=552=20080108-22:12:05108=3098=010=240
8=FIX.4.39=11935=534=267649=ABC52=20080108-22:12:06.46756=DEF58=MsgSeqNum too low, expecting 2882 but received 510=170

... around an hour later ...

8=FIX.4.39=12135=534=281249=ABC52=20080108-23:16:45.88356=DEF58=MsgSeqNum too low, expecting 2882 but received 13510=009
8=FIX.4.39=8235=A34=149=ABC52=20080108-23:17:45.77456=DEF98=0108=30141=Y10=244
8=FIX.4.39=7835=A49=DEF56=ABC34=152=20080108-23:17:46108=30141=Y98=010=042

Comment by André Malenfant [ 09/Jan/08 ]

Here is a working logout/login sequence coming from the same app with the same config:

8=FIX.4.39=8235=549=DEF56=ABC34=37052=20071120-22:04:5958=Scheduled logout10=043
8=FIX.4.39=6635=534=37049=ABC52=20071120-22:05:00.04256=DEF10=238
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:05:00.66756=DEF98=0108=30141=Y10=226
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:06:01.68356=DEF98=0108=30141=Y10=226
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:07:02.70056=DEF98=0108=30141=Y10=218
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:08:02.71656=DEF98=0108=30141=Y10=226
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:09:03.71756=DEF98=0108=30141=Y10=229
8=FIX.4.39=8235=A34=149=ABC52=20071120-22:10:04.73356=DEF98=0108=30141=Y10=220
8=FIX.4.39=7835=A49=DEF56=ABC34=152=20071120-22:10:05108=30141=Y98=010=023

Comment by Steve Bate [ 09/Jan/08 ]

First, I assume that you are using QFJ 1.2.1, given the "affects version". Please tell me if that's not correct.

For future comments, please replace the SOH character in the FIX message log records with a delimiter (like '|'). The delimeters are currently being lost and it makes it much more difficult and time consuming to interpret the log entries.

The SendResetSeqNumFlag has no effect in QFJ 1.2.1. It remained in the documentation from an earlier version but it should not have been in the 1.2.1 documentation. I didn't mention this earlier because you were also using ResetOnDisconnect and I didn't want to confuse the issue. I recommend you remove SendResetSeqNumFlag from your configuration file to avoid any further confusion.

You also did not give me the timeline of logon messages and connection events. The logs of logon messages alone do not provide enough information to diagnose the problem since I don't know when the connection is established and broken. For example, I'm not sure if there is a disconnect between
each logon attempt or the connection is established and the counterparty is just not responding for some reason which would cause the logons to timeout. By not providing the relevant events from the event log (again, a merged timeline of messages and events would be most helpful) it makes it much more difficult for me to help you effectively.

Please keep in mind that free support on QFJ depends on the availability of my spare time. There are organizations that can provide commercial support for QFJ and they are listed on the web site. A few of these are in Europe.





[QFJ-251] Reprocessing missed FIX messages - application side. Created: 27/Sep/07  Updated: 15/Nov/12  Resolved: 28/Sep/07

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

Type: Other Priority: Default
Reporter: Parag Mehta Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

all



 Description   

Wondering if application has missed processing some FIX messages (e.g. due to exceptions in other code), is it possible to use any quickfixj API point to get a range of messages to be send back to the application from FIX? I.e. the messages are still in the db, they just want to be resend to the callback.

Also how many messages are stored in the messages table, when would this table be truncated (when session resets?).

Thanks.
Parag



 Comments   
Comment by Steve Bate [ 28/Sep/07 ]

The resend capability of FIX (and QFJ) is intended to be used for recovery from communication errors between counterparties. It only stores /sent/ messages in case they need to be sent again later. It sounds like you would need received messages if there is an local application error. The message log can provide this capability but there is no API for accessing the log. However, if you use a JdbcLog then you could write ad hoc queries against the incoming message table. You could even modify the schema to add a column that indicates whether the application has completed processing a specific message.

Also be aware that if an application message processing callback throws an exception (it would have to be an unchecked exception), the session's incoming message sequence number is not incremented. This means that when the next message arrives, the session will request a resent from the counterparty. This can have a similar effect to what you are wanting.





[QFJ-250] Expiry Time UTC Conversion. Created: 27/Sep/07  Updated: 06/Oct/07  Resolved: 06/Oct/07

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

Type: Other Priority: Default
Reporter: Parag Mehta Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

all



 Description   

Question about expiry time problem. We set it to UTC (today: 00:00:00) and pass it down to ExpiryTime constructor.

Date date = (09-26-2007: 00:00:00);
// If UTC formatter is used this will print today 00:00:00 UTC
ExpiryTime expiryTime = new ExpiryTime(date);

The problem is when it's send over to FIX, the time zone diff is somehow added to the converted string, e.g.: 22:00 below and the main problem: today becomes today-1 (9/26 becomes 9/25).
126=20070925-22:00:00

Is this correct? From all the documentation I read, it seems if UTC is passed, no conversion should happen and the date to string conversion should keep it 09-26:00:00 all along.

It would also possibly help to have another ExpiryTime(String) constructor; since FIX UTC timestamp is eventually a string.

Thanks.
Parag



 Comments   
Comment by Steve Bate [ 28/Sep/07 ]

Are you sure you are creating the date in the correct time zone?

The following unit tests passes...

public void testUtcFieldFormatting()

{ Calendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC")); c.set(2008, Calendar.JANUARY, 1, 0, 0, 0); c.set(Calendar.MILLISECOND, 0); ExpireTime expireTime = new ExpireTime(c.getTime()); Message m = new Message(); m.setField(expireTime); assertEquals("9=26126=20080101-00:00:00.00010=193", m.toString()); }

As for your question about passing a String. You can create a StringField directly and use that
to set the field. Just be sure to format the string correctly.





[QFJ-249] Message Generation does not generate header repeating groups correctly Created: 24/Sep/07  Updated: 15/Jan/08  Resolved: 22/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

winXP SP2, JDK1.5.0.12, Eclipse 3.3



 Description   

After Message Generation, we can't find the class "public static class NoHops extends Group"; at QFJ, and so, we can use this header repeating group like other repeating group.
Maybe, we can generate some codes like this, at quickfix.fix44.message.java or quickfix.fix44.message.Header :

public static class NoHops extends Group {
public NoHops() {
super(627,628,
new int[]

{628,629,630,0 }

); }
public void set(quickfix.field.HopCompID value)

{ setField(value); }
public quickfix.field.HopCompID get(quickfix.field.HopCompID value) throws FieldNotFound
{ getField(value); return value; }
public quickfix.field.HopCompID getHopCompID() throws FieldNotFound
{ quickfix.field.HopCompID value = new quickfix.field.HopCompID(); getField(value); return value; }
public boolean isSet(quickfix.field.HopCompID field)
{ return isSetField(field); }
public boolean isSetHopCompID()
{ return isSetField(628); }
public void set(quickfix.field.HopSendingTime value)
{ setField(value); }

public quickfix.field.HopSendingTime get(quickfix.field.HopSendingTime value)
throws FieldNotFound

{ getField(value); return value; }
public quickfix.field.HopSendingTime getHopSendingTime() throws FieldNotFound
{ quickfix.field.HopSendingTime value = new quickfix.field.HopSendingTime(); getField(value); return value; }
public boolean isSet(quickfix.field.HopSendingTime field)
{ return isSetField(field); }
public boolean isSetHopSendingTime()
{ return isSetField(629); }
public void set(quickfix.field.HopRefID value)
{ setField(value); }
public quickfix.field.HopRefID get(quickfix.field.HopRefID value)
throws FieldNotFound
{ getField(value); return value; }

public quickfix.field.HopRefID getHopRefID() throws FieldNotFound

{ quickfix.field.HopRefID value = new quickfix.field.HopRefID(); getField(value); return value; }

public boolean isSet(quickfix.field.HopRefID field)

{ return isSetField(field); }

public boolean isSetHopRefID()

{ return isSetField(630); }

}



 Comments   
Comment by Steve Bate [ 21/Dec/07 ]

I've looked at the quickfix.fix44.Message$Header object and it does contain the NoHops support. It's a nested class in the Message$Header class. If I didn't understand the issue, please reopen it.

Comment by Steve Bate [ 22/Dec/07 ]

I see that although the group counter field is generated, the actual group is not. Therefore, I'm reopening this issue.

Comment by Steve Bate [ 22/Dec/07 ]

Modified XSLT to generate repeating groups correctly for the message headers. Added parser test to MessageTest.





[QFJ-248] Data dictionary does not parse header repeating groups correctly Created: 24/Sep/07  Updated: 31/Aug/08  Resolved: 22/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: CaiQi Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

winXP SP2, JDK1.5.0.12, Eclipse 3.3



 Description   

In QFJ_1.2.1, I can't use the repeating group "NoHops"and the fiels 628,629,630. I only can use field 627.

Because repeating group "NoHops" is the only group at messageHeader, so in many places, we may ignore it! For example, at DataDictionary.java,

private void load(InputStream inputStream) throws ConfigError {
.......

// HEADER
NodeList headerNode = documentElement.getElementsByTagName("header");
if (headerNode.getLength() == 0)

{ throw new ConfigError("<header> section not found in data dictionary"); }

NodeList headerFieldNodes = headerNode.item(0).getChildNodes();
if (headerFieldNodes.getLength() == 0)

{ throw new ConfigError("No header fields defined"); }

for (int i = 0; i < headerFieldNodes.getLength(); i++) {
Node headerFieldNode = headerFieldNodes.item;
String nodeName = headerFieldNode.getNodeName();
if (nodeName.equals("field") || nodeName.equals("group")) {
String name = getAttribute(headerFieldNode, "name");
if (name == null)

{ throw new ConfigError("<" + nodeName + "> does not have a name attribute"); }

String required = getAttribute(headerFieldNode, "required", NO);
if (required == null)

{ throw new ConfigError("<" + headerFieldNode.getNodeName() + "> does not have a 'required' attribute"); }

addHeaderField(lookupXMLFieldNumber(document, name), required.equalsIgnoreCase("Y"));
}
........
}

It only load <group name="NoHops" required="N"> from fix44.xml, but can't load <field name="HopCompID" required="N"/>Unable to render embedded object: File ("<field name="HopSendingTime" required="N"/>) not found."<field name="HopRefID" required="N"/> which are in the group.

So, maybe, we should add:

if (nodeName.equals("group")) {
String required = getAttribute(headerFieldNode, "required");
if (required == null)

{ throw new ConfigError("<group> does not have a 'required' attribute"); }

addHeaderXMLGroup(document, headerFieldNode, this, required
.equalsIgnoreCase("Y"));
}
}

there, I used a new function:addHeaderXMLGroup(),coming from addXMLGroup().

This question may relate to addXMLComponentFields(), addXMLGroup(), addGroup(), isGroup(), getGroup(), checkGroupCount(), iterate() at DataDictionary.java; and parseGroup(), parseHeader() at Message.java; where ignore the only group at messageHeader, "NoHops".



 Comments   
Comment by CaiQi [ 24/Sep/07 ]

Sorry, I want to change "Component/s" to be "Metadata/Specs", it is better than "Engine ".

Comment by Steve Bate [ 22/Dec/07 ]

Modified DataDictionary to parse header repeating group information. Added tests to DataDictionarTest and MessageTest that use the changes.





[QFJ-247] Allow for dynamic session addition in AbstractSocketInitiator Created: 22/Sep/07  Updated: 12/Nov/18  Resolved: 12/Nov/18

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

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Andy Flury
Resolution: Fixed Votes: 4
Labels: None

Attachments: Text File AbstractSocketInitiator.java.patch    

 Description   

Right now you can have multiple sessions in same SocketInitiator only when you configure them at startup.
Would be nice to have a programmatic way to add new sessions to socket initiator dynamically, either via code an application level or via some JMX adapter.

It's possible to work around this by creating a new SocketIntiator, but that may create threading issues for people using single-threaded strategies and having single-threaded assumptions in their application code.

Not sure if the right way is to provide a AbstractSocketInitiator.addSession() (and removeSession) function, or if there's a better approach.



 Comments   
Comment by Danilo [ 06/May/08 ]

I need this too. Is there any other way to work around this while it's not implemented the way you propose?

Comment by Toli Kuznets [ 06/May/08 ]

Danilo, we've been working on the code to implement this but haven't had the time to polish it yet so we haven't checked it in. But i'm hoping to have that ready in a few weeks.

Comment by Steve Bate [ 10/Jan/10 ]

Hi Toli. Any updated status on this feature?

Comment by Toli Kuznets [ 15/Jan/10 ]

Steve,
Unfortunately, we never ended up implementing this, so it's still in RFE stage...

Comment by Cesar Kamoy [ 27/Jul/11 ]

I fully agree with Steve

Comment by Evan Ross [ 24/May/12 ]

Has this made any progress? I need the ability to create and destroy initiators at runtime.

Comment by Andy Flury [ 01/Oct/12 ]

Would like invest some time in this and come up with a solution and potential patch. Can somebody provide a hint how to approach this?

Comment by Andy Flury [ 01/Oct/12 ]

Ok, this is my first try.

I added a method createDynamicSession which takes a SessionID (that can be retriebed from settings). It will create the session and create the corresponding initiator.

Also, I added a new session level boolean setting "Inactive", that can be added to settings that should not start automatically when starting QuickFix. So this session can be started on demand with above new method. The constant SETTING_INACTIVE_SESSION would probably have to be moved somewhere else.

This might not be the proper way to do this, but it seems to be working.

Any comments are welcome

Andy





[QFJ-246] First login attempt of initiator afterStartTime is responded with logout Created: 22/Sep/07  Updated: 15/Nov/12  Resolved: 28/Sep/07

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

Type: Other Priority: Default
Reporter: Michael Briganti Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

2003



 Description   

Hi Steve, it's been quite a while.
We are experiencing the bug detailed below.
Do you have a specific patch for this for 1.2.1, or is 1.3.0 stable enough
for production.

This could be related to a open bug about the timer events not being
processed in an acceptor while it's disconnected (QFJ-218). This would
cause the logout with the old sequence number to be sent the first time
someone connects. Subsequent connections should be ok and should use the
new session's sequence numbers. If we can complete the 1.3 release soon,
I'll have the fix in there. Otherwise, I'll patch 1.2.1 and release a
new version of that branch.

A temporary workaround is to call reset manually on the message
store before the new session start time.

Regards,

Steve



 Comments   
Comment by Steve Bate [ 28/Sep/07 ]

Please let me if the 1.3.0 release resolves your issues.





[QFJ-245] Classpath file is out of date on latest sourceforge build 1.3.0 Created: 21/Sep/07  Updated: 11/Feb/09  Resolved: 24/Sep/07

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.3.0
Fix Version/s: 1.3.0

Type: Bug Priority: Default
Reporter: Matt Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The binary download was missing some paths and had wrong version numbers for some includes,
Also- it doesn't state anywhere I could see that you need to add environment variable QFJ_HOME, although it's obvious when you open the classpath.bat.
This worked for me:

set CP="%CLASSPATH%"
set CP=%CP%;"%QFJ_HOME%/core/target/quickfixj.jar"
rem For Eclipse build
set CP=%CP%;"%QFJ_HOME%/classes"
rem For binary release
set CP=%CP%;"%QFJ_HOME%/quickfixj.jar"
set CP=%CP%;"%QFJ_HOME%/quickfixj-msg-fix40.jar"
set CP=%CP%;"%QFJ_HOME%/quickfixj-msg-fix41.jar"
set CP=%CP%;"%QFJ_HOME%/quickfixj-msg-fix42.jar"
set CP=%CP%;"%QFJ_HOME%/quickfixj-msg-fix43.jar"
set CP=%CP%;"%QFJ_HOME%/quickfixj-msg-fix44.jar"

rem For build environment
set CP=%CP%;"%QFJ_HOME%/core/src/main/lib/mina-core-1.0.1.jar"
set CP=%CP%;"%QFJ_HOME%/core/src/main/lib/backport-util-concurrent-2.1.jar"
set CP=%CP%;"%QFJ_HOME%/core/src/main/lib/slf4j-api-1.3.jar"
set CP=%CP%;"%QFJ_HOME%/core/src/main/lib/slf4j-jdk14-1.3.jar"

rem For binary release
set CP=%CP%;"%QFJ_HOME%/lib/mina-core-1.0.1.jar"
set CP=%CP%;"%QFJ_HOME%/lib/backport-util-concurrent-2.1.jar"
set CP=%CP%;"%QFJ_HOME%/lib/slf4j-api-1.3.0.jar"
set CP=%CP%;"%QFJ_HOME%/lib/slf4j-jdk14-1.3.0.jar"






[QFJ-244] problem with single SocketIOProcessor shared across multiple users and one user has a n/w problem Created: 19/Sep/07  Updated: 28/Dec/07  Resolved: 06/Oct/07

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

Type: Bug Priority: Default
Reporter: sarath Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

test



 Description   

I am using 1.0.5 and apache MINA 1.1 and if I use single SocketIOProcessor on MINA and then connect from 2 users.
1) i unplug one of the users n/w
2) second user stopped getting rates
3) once the first user is disconnected, the second user started getting rates



 Comments   
Comment by rohit [ 27/Sep/07 ]

Steve - Did anyone noticed this problem? Thanks for your help in advance.

Comment by Steve Bate [ 06/Oct/07 ]

Hello,

I recommend upgrading to the latest version of QFJ. I don't actively support 1.0.5 any more.

Regards,

Steve

Comment by sarath [ 28/Dec/07 ]

This issue is due to the SOLINGER option. If we set to non-zero, then the dispatcher thread waits until the SoLinger timeout is compete.





[QFJ-243] SessionState.isWithinHeartBeat never seems to be modified or initliazed Created: 19/Sep/07  Updated: 15/Nov/12  Resolved: 28/Sep/07

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

Type: Other Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm looking at the code in SessionState.isWithinHeartBeat() function, and it references a variable that's never initialized or modified.
The whole function seems to be a no-op, since the value is always 'false'.

Is it an oversight and it needs to be modified? or maybe we can just take it out altogether to make sure we don't cause confusion?



 Comments   
Comment by Steve Bate [ 28/Sep/07 ]

It appears to be a leftover from prior refactorings. Thanks for cleaning this up.

Comment by Erb [ 31/Aug/09 ]

This was not fixed





[QFJ-242] Check for presence of conditionally required fields (OpenFIX) Created: 19/Sep/07  Updated: 02/Feb/08

Status: Open
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: New Feature Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We are filing this because of a failing OpenFIX test, but we actually believe that the test itself is broken, so I won't describe the interaction here.

It would be nice if QuickFIX/J could check for the presence of conditionally required fields in messages when doing validation with a data dictionary. An example: In an execution report, we have the following description of ExpireDate and ExpireTime:

432 ExpireDate C Conditionally required if TimeInForce (59) = GTD and ExpireTime (126) is not specified.
126 ExpireTime C Conditionally required if TimeInForce (59) = GTD and ExpireDate (432) is not specified.

QuickFIX/J should reject a message if 59=6 but the message is missing both 432 and 126.

Other than that, this request is pretty open-ended. Clearly there would need to be some language for expressing these conditional requirements in the data dictionary, but we would have to think about what that would look like.






[QFJ-240] Reject not sent with "bad tag format" (OpenFIX) Created: 19/Sep/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-239 Reject not sent when repeating group ... Closed

 Description   

This is a failing OpenFIX test. The test sends a message with an SOH character in a field specifier (see 500^A40 below). QuickFIX/J does not send a reject.

Here is what OpenFIX has to say about the test:
==========
This tests your ability to handle a field that includes an SOH character. We will send you a message with the SOH character embedded in the OrderQty value.

Expected flow:

  • Send Reject (session-level) referencing field identifier (tag number) with embedded SOH
  • Increment inbound MsgSeqNum
  • Generate an "error" condition in test output

The details of these session-level tests can be found in the FIX 4.3 Specification, Volume 2.
==========

I get this message in my QuickFIX/J log, but no reject message:

13:49:49,765 ERROR [SocketConnectorIoProcessor-0.0] mina.initiator.InitiatorIoHa
ndler (AbstractIoHandler.java:117) - Invalid message: bad tag format: For input
string: "500
40"

Here is the message they sent:

FIX.4.2:XXX->OPENFIX: 8=FIX.4.2
9=177
35=8
49=OPENFIX
56=XXX
52=20070918-20:49:50
34=113
37=1190148549048-3
11=11901485490482
20=0
55=T
54=2
38=1
500^A40=1
17=1190148549048-4
32=0
31=0
14=0
6=0
151=3000
39=0
150=0
10=157



 Comments   
Comment by Toli Kuznets [ 21/Sep/07 ]

This bug has a similar codepath as QFJ-238.
The exception is thrown "too early" - it's in AbstractIoHandler, so the message is skipped out-right but no reject message is sent back.
The fix for this wil be very similar (if not the same) as for QFJ-238.





[QFJ-239] Reject not sent when repeating group out of order (OpenFIX) Created: 19/Sep/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

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

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-240 Reject not sent with "bad tag format"... Closed

 Description   

This is a failing OpenFIX test. Here's what OpenFIX has to say about it:

===========
This tests your ability to handle a message with a repeating group whose fields are out of order. We will send you an Allocation message with two repeating groups, each of which has its fields in the incorrect order.

Expected flow:

  • Send Reject (session-level) referencing the repeating group with the incorrect field ordering
  • Increment inbound MsgSeqNum
  • Generate an "error" condition in test output

The details of these session-level tests can be found in the FIX 4.3 Specification, Volume 2.
===========

I get this message in the error log, but no reject message:

13:45:51,000 ERROR [SocketConnectorIoProcessor-0.0] mina.initiator.InitiatorIoHa
ndler (AbstractIoHandler.java:117) - Invalid message: Repeating group 78 is out
of order: first field should be 79, but was 80.

Here is the message they send:

FIX.4.2:XXX->OPENFIX:
8=FIX.4.2
9=170
35=J
49=OPENFIX
56=XXX
52=20070918-20:45:51
34=103
70=11901479545313
71=0
73=1
11=11901479545314
54=2
55=T
53=3000
6=27
75=20011004
78=2
80=2900
79=1234
80=100
79=2345
10=190



 Comments   
Comment by Toli Kuznets [ 21/Sep/07 ]

Same problem as QFJ-238 and QFJ-240. Message parsing causes an exception that doesn't generate a reject message.





[QFJ-238] No reject sent for message with duplicate field (OpenFIX) Created: 19/Sep/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.2

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File qfj-238.patch    

 Description   

This is a failing OpenFIX certification test. It will test that the FIX engine sends a reject when it receives a message with two of the same field (non-repeating group fields). In this case, it sends a message with OrderQty(38) set twice. Here is what openFIX has to say about the test:

============
This tests your ability to handle a field that appears more than once in a message. We will send you a message with OrderQty set twice.

Expected flow:

  • Send Reject (session-level) referencing duplicate field identifier (tag number)
  • Increment inbound MsgSeqNum
  • Generate an "error" condition in test output

The details of these session-level tests can be found in the FIX 4.3 Specification, Volume 2.
=============

This is the message that they send.

FIX.4.2:XXX->OPENFIX:
8=FIX.4.2
9=192
35=8
49=OPENFIX
56=XXX
52=20070918-20:34:33
34=85
37=1190147432328-19
11=119014743232810
20=0
55=T
54=1
38=3000
40=2
44=27
17=1190147432328-20
32=0
31=0
14=0
6=0
151=3000
39=0
150=0
38=3100
10=094



 Comments   
Comment by Graham Miller [ 19/Sep/07 ]

Sorry, I forgot to mention that quickfix does not send the reject message. Therein lies the bug.

Comment by Toli Kuznets [ 20/Sep/07 ]

So this is actually fairly easy to detect - see the attached patch. There was another variation where we can collect all the dupes and then throw the error at the end, showing all the dupes. i chose the first one, but we can easily go back to case 2.

Regardless, the behaviour required by OpenFIX certifiation error is much harder to achieve.
They send a message with a dupe in it, and they expect a session-level Reject back.

However, the way this works is that a message comes in to AbstractIoHandler, MessageUtils.parse gets called which calls Message.fromString which will throw an InvalidMessage exception, prints a log error and that's it - this is too low-level a point to send out a session-level reject.

The rejects are sent form Session code itself, and we never get to that point.
If we "ignore" the dupes in the initial parse of the message in AbstracdtIoHandler entrypoint, we lose the fact that we had dupes since we just end up setting the field twice (and losing the previous value). This was the behaviour i was seeing when i was just collecting the dupes into a list, and trying to validate it later (by having another dupeDetection boolean).

So not sure how to handle this case best - if we throw an exception before we get into Session message processing code, we don't send a reject. If we wait until Session code, we've already lost the dupe.

We can, of course, send a reject in the case the message doesn't parse correctly in AbstractIoHandler.messageReceived but i'm not sure of how easy it is to do that since we don't have access to any Session.generateReject code.

thoughts?

Comment by Steve Bate [ 20/Sep/07 ]

I understand the issues. We probably need to wait until after the 1.3.0 release for this one. I'd like some more time to consider the options. Is that ok with you?

Comment by Toli Kuznets [ 20/Sep/07 ]

Yes, i agree, it's too much of a change to introduce right now.

It's possible to create a "duplicate fields" list that's part of the parsed message, and only validate that it's empty when the codepath is in Session.next() code.
However, even in Session.next(Message msg) function catching an InvalidMessage exception right now only prints a log error and doesn't reject the message, so that'll need to be changed as well.





[QFJ-237] Provide a way to send a sequence reset (via JMX operation?) Created: 18/Sep/07  Updated: 11/Feb/09  Resolved: 19/Sep/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: New Feature Priority: Default
Reporter: Graham Miller Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Attachments: JPEG File .jpg    

 Description   

the OpenFIX testing suite requires the ability for the FIX engine to send a sequence reset at an arbitrary point in the testing process (see attached screenshot). I don't think QuickFIX can do this currently.

It seems to me that this might be an easy thing to add to the set of operations available on SessionAdminMBean (which is then exported via the JMX interface). In order to satisfy the test the user would need to be able to specify one int argument to the operation (not sure if this is possible).

Also, provided the JMX interface is the right entry point, what is the correct way to send the sequence reset? Can I just construct a message and call Session.sendToTarget?



 Comments   
Comment by Graham Miller [ 18/Sep/07 ]

The point in the OpenFIX certification that requires a sequence reset message. (note the specific request for the reset to use the "next" sequence number 28

Comment by Steve Bate [ 18/Sep/07 ]

Yes, I your suggestion is correct. To send an explicit sequence reset message, you could add a JMX operation that would construct and send the message like a normal message.

Comment by Toli Kuznets [ 19/Sep/07 ]

fix for this checked in rev 739.

Added a new resetSequence() function to SessionAdminMBean that sends a Sequence Reset mesagge with the specified sequence number.





[QFJ-236] Make the time interval when Test Request being sent configurable Created: 12/Sep/07  Updated: 11/Feb/09  Resolved: 19/Sep/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: New Feature Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File qfj-236.patch     Text File qfj-236.patch    

 Description   

We've been going through a certification process with TransactTools (http://www.openfix.net/), and encountered a different expected behaviour with sending Test Requests.

In the TransactTools test, they skip a heartbeat message and expect our quickfix engine (Ie QFJ) to send a test request:
"We suppressed our last heartbeat message.
In response we expected to receive a test request message from you within 9 seconds (30% of the HeartBeatInt field) but did not."

Seems like they expect it to be sent within HeartBeatInt+9secs. Looking at the code in SessionState.isTestRequestNeeded(), it calculates the Test Request delay as 1.5 * (HeartBeatInt + numTestRequestsSent + 1), which translates into HeartBeatInt * 1.5 (for first request) = 30 + 15secs, which is over the +9 seconds that's expected.

Is there a known spec for this formula or was it something "reasonable" but not necessarily standard? Maybe it's something we need to make configurable to satisfy different expectations form counterparties?



 Comments   
Comment by Toli Kuznets [ 19/Sep/07 ]

Moved this from a question to an RFE

will make the time interval configurable.

Comment by Toli Kuznets [ 19/Sep/07 ]

Patch for this bug.
I removed a few unused/unreferenced parameters that were passed into Session, and instead added a new testRequestDelayMultiplier parameter. It's coming from SessionSettings.

added unit tests to verify that the parameter is passed in correctly, and that it's being used correctly as well.

Comment by Toli Kuznets [ 19/Sep/07 ]

oh, and i forgot to add changes to documentation - will definitely do that before i submit it.

Comment by Toli Kuznets [ 19/Sep/07 ]

updated patch with documentation change

Comment by Toli Kuznets [ 19/Sep/07 ]

fix checked in rev 740





[QFJ-235] FIX44 validation doesn't handle valid value for SymbolSfx field Created: 11/Sep/07  Updated: 15/Jan/08  Resolved: 13/Dec/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.2.1
Fix Version/s: 1.3.1

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

This is similar to QFJ-40.
Starting with FIX44, the SymbolSfx field has 2 hard-coded constants - "WI" and "CD". in the FIX44.xml file we have them called out explicitly with
<field number="65" name="SymbolSfx" type="STRING">
<value enum="WI" description="WHEN_ISSUED"/>
<value enum="CD" description="A_EUCP_WITH_LUMP_SUM_INTEREST"/>
</field>

All the other files have the field being empty (ie no pre-canned values).

The FIX spec says: "Valid values: As defined in the NYSE Stock and bond Symbol Directory and in the AMEX Fitch Directory.", plus in FIX44 you get the 2 hardcoded values.
As a result, when you have a message with SymbolSfx="A" in FIX40-4.3 it passes validation since there is no set of valid values in the DataDictionary.
However, with FIX4.4 you have the 2 hard-coded values, your message has something else and as a result it fails validation.

Not sure what the best solution is, aside from doing the same approach as QFJ-40: commenting out the valid constants in FIX4.4. but that leads to usability loss.

Perhaps we can create some token that takes in a RegEx pattern as a set of other valid values?
or maybe a marker saying that "all other strings are valid"?



 Comments   
Comment by Steve Bate [ 13/Dec/07 ]

I've added a feature to allow field enums to be partially specified. For example,

<field number="65" name="SymbolSfx" type="STRING" allowOtherValues="true">
<value enum="WI" description="WHEN_ISSUED"/>
<value enum="CD" description="A_EUCP_WITH_LUMP_SUM_INTEREST"/>
</field>

Notice the allowOtherValues attribute on the field node. This will allow other fields
but still provide the code generator with information for generating the constants for
the defined values. So far, I've only changed the FIX44.xml data dictionary for this
field. Feel free to make similar changes to other fields and FIX versions where this
is a problem.





[QFJ-234] Add documetation to kinds of SSL certs supported for SSL connectivity Created: 31/Aug/07  Updated: 06/Oct/07

Status: Open
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: Task Priority: Default
Reporter: Toli Kuznets Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Need to add more documentation specifying the exact format of SSL certs that are necessary to be in the keystore for SSL connectivity to work.

Seems like the PKCS#12 is the format that needs to be in the keystore, but perhaps there are others.



 Comments   
Comment by Gregg Freeman [ 31/Aug/07 ]

I believe that the keystore is it's own "special" java format, and easily accepts DER encoded certificates/keys. However, PKCS#12, which is the only format that windows supports for private key encoded certificates, isn't readable by the standard java keytool utility.

The following worked for me to use a private key PKCS12 certificate:
Import the root certificate into a keystore using the java keytool utility (keytool -import -file xxxx -keystore xxxxx)
Import the intermediate certificate (if you have one) just as you did the root certificate (using the same keystore file).
For PKCS#12 certificates, the easiest thing to do is to download the jwsdwp 2.0 (as of Sept 07) and use the pkcs12import.bat utility to import the PKCS#12 certificate into the same keystore.

Make the keystore file available on the classpath.
Change the SSL settings in the session.properties to include the keystore, keystore password, and SSL setting = on.

For connections that can use a self-signed certificate, it's much easier.
Use the keytool to generate a key using the following command:
keytool -genkey -alias <anything> -keystore <keystorefilename>

Follow the prompts, change your session.properties, and make the keystore available on the classpath & you're all good.





[QFJ-233] SendResetSeqNumFlag shows up in documentation but is not queried anywhere in the code Created: 30/Aug/07  Updated: 07/Apr/09  Resolved: 02/Sep/07

Status: Closed
Project: QuickFIX/J
Component/s: Documentation, Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

the configuration.html file contains an entry for the SendResetSeqNumFlag:
SendResetSeqNumFlag Send a sequence number reset when initiating a logon.

However, i'm not seeing any references to it in the QFJ code it self - the setting is now showing up in the Session.java nor is there a corresponding flag for it and it's not used in Session.isResetNeeded() function.

are the docs out of date? and what's the appropriate way to ensure that a reset (ie 141=Y) is not being sent in the first Logon message?



 Comments   
Comment by Steve Bate [ 02/Sep/07 ]

This is a strange one. I see it was added to the documentation over two years ago, but I don't see it ever being used in the session factory in any past file versions. Unless you have another suggestion, I'm going to just delete it from the documentation.

Comment by Toli Kuznets [ 02/Sep/07 ]

Deleting it is fine. You can achieve the same behaviour of not sending a resetSeqNum in the first logon by just turning off all the ResetOnDisconnect/ResetOnLogin/ResetOnLogout flags to N.

Comment by Mihai Sardarescu [ 07/Apr/09 ]

The flag SendResetSeqNumFlag still appears in the QuickfixJ configuration: http://www.quickfixj.org/quickfixj/usermanual/usage/configuration.html.
SendResetSeqNumFlag - Send a sequence number reset when initiating a logon.

I have searched the source code for version 1.4.0 and it seems that it is never used.





[QFJ-232] Transact time - What is the time zone? Created: 30/Aug/07  Updated: 02/Sep/07  Resolved: 02/Sep/07

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

Type: Other Priority: Default
Reporter: Parag Mehta Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Steve, anyone,

What exactly is the timezone of the date (long) parsed out of the Transact time. Seems to me it is local, and if a UTC time is required, a conversion is necessary. Pls note: this is not a display (format) question, only what timezone is the long value represented in.

Cheers.
Parag



 Comments   
Comment by Toli Kuznets [ 30/Aug/07 ]

Parag,

There are two different constructors of TransactTime - one that takes a Date (in which case it's up to you what timezone it's in).

Otherwise, if you are just using the default QFJ behaviour, since the TransactTime inherits from the DateField object, all the newly created TransactTime fields are done in UTC timezone.

See the DateField.createDate() function: http://quickfixj.svn.sourceforge.net/viewvc/quickfixj/trunk/core/src/main/java/quickfix/DateField.java?view=markup

DateField use a default Calendar that's set to a UTC timezone.

Comment by Parag Mehta [ 30/Aug/07 ]

My question was from the perspective of getting a filled transact time out of an ExecutionReport or Allocation message. Which method will it use in this case.

I.e., in this case:

long time = allocation.getField(new TransactTime()).getValue().getTime();
// What is timezone for 'time'?
Comment by Steve Bate [ 31/Aug/07 ]

The long value is "the number of milliseconds since January 1, 1970, 00:00:00 GMT" (per the java.util.Date docs). Are you asking what timezone is used to parse the string from the FIX message field? If so, UTC is used to parse the timestamp string into a java.util.Date. What causes you to think you are getting a local time?





[QFJ-231] During the logou process, sometimes in the initiator side's log file there is an unsend logon message. Created: 28/Aug/07  Updated: 11/Feb/09  Resolved: 02/Sep/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Bug Priority: Major
Reporter: Mike Gu Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

windows 2000 professional. eclipse3.2


Issue Links:
Relates
is related to QFJ-218 Session time not checked while sessio... Closed

 Description   

Recently, I notice that during the logou process there is a strage behaveior: sometimes in the initiator side's log file there is an unsend logon message. I think the cause is: when the initiator receive an logout from acceptor, it will call disconnect method. In the disconnect method, it will setResponder(null), then set sessionstate as the initial state and it ends. Between it sets sessionstate as the initial state and it ends. Another thread session timer thread happenedly executes at
if (!state.isLogonReceived()) {
if (state.isLogonSendNeeded())
then, it will send a logon message, but it will not succeed because the Iosession has been closed.
My solution is if (!state.isLogonReceived()&&hasResponder()) {
if (state.isLogonSendNeeded()) {






[QFJ-230] Update classpaths in example scripts Created: 25/Aug/07  Updated: 11/Feb/09  Resolved: 01/Sep/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

If possible, let's automate this.

Must set classpath for...

Source distribution
Binary/Java5 distribution
Binary/Java4 distribution






[QFJ-229] FIX engine stuck in unrecoverable state when trying to connect under poor network conditions Created: 24/Aug/07  Updated: 15/Nov/12  Resolved: 24/Aug/07

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

Type: Bug Priority: Major
Reporter: Qiyan Li Assignee: Steve Bate
Resolution: Duplicate Votes: 0
Labels: None
Environment:

Linux and Solaris


Issue Links:
Duplicate
duplicates QFJ-150 Calling toString() on an empty Messag... Closed

 Description   

If the FIX engine tries to connect to a remote engine under little or no network connectivity, it tends to be stuck in a unrecoverable state and cannot reconnect automatically when the connectivity restores. This appears to be caused by a NPE in the quickfix.mina.initiator.IoSessionInitiator$ConnectTask.connect() line: 136

quickfixSession.getLog().onEvent(e.getMessage());

where e.getMessage() is a null pointer, which causes quickfix.FileLog.writeMessage(java.io.FileOutputStream, java.lang.String, boolean) line: 104

stream.write(message.getBytes(CharsetSupport.getCharset()));

to throw a null pointer exception, which in turn puts the engine into an unrecoverable state. The event log looks something like this:

20070820-08:59:02: Sent test request TEST
20070820-08:59:06: Timed out waiting for heartbeat
20070820-08:59:06: Disconnecting
20070820-09:00:08: <------- stuck here

The implication is that if the network connectivity is poor enough to force the engine to disconnect, and if the condition lasts during the first reconnect attempt, the engine will be stuck and never recover even if the network condition gets better.

All line numbers are from 1.2.1 version of the source code. Java 1.5 was used.



 Comments   
Comment by Toli Kuznets [ 24/Aug/07 ]

If i'm not mistaken, this is a dupe of QFJ-223 and was fixed in http://quickfixj.svn.sourceforge.net/viewvc/quickfixj/trunk/core/src/main/java/quickfix/mina/initiator/IoSessionInitiator.java?r1=721&r2=720&pathrev=721

Qiyan, would it be possible for you to verify this fix with the latest code from SVN?

Comment by Steve Bate [ 25/Aug/07 ]

I think this is a duplicate of another recent bug report. If so, it's been fixed in the trunk and will be released soon in 1.3.0. Can you verify if this is actually a duplicate? Thanks.

Comment by Qiyan Li [ 26/Oct/07 ]

Just tried out the 1.3.0 release, and the problem has gone away.





[QFJ-228] Weekly session schedule calculates wrong day for non-GMT timezone Created: 24/Aug/07  Updated: 11/Feb/09  Resolved: 25/Aug/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.3.0

Type: Bug Priority: Critical
Reporter: Christian Braeuner Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any. Bug is happening on various Unix and Windows JREs



 Description   

This Friday morning our production system stopped at 00:30:00, rather than tomorrow, Saturday at 00:30:00, which caused a lot of trouble.

We have changed the time zone of our session scheduling in the production system from GMT to America/Chicago to switch correctly for the US Daylight saving later this year. We have adjusted the start end end time accordingly to accomodate the new time zone. The setting is the following now:
TZ=America/Chicago
End Day=Friday
End Time=19:30:00

This equates to the same settings in GMT, which we had previously:
End Day=Saturday
End Time=00:30:00

So QF should have shut down tomorrow morning and not today on Friday morning.

I've had a look into the QF source code and found that the start and end time do not wrap the day when the TZ offset is applied, because schedule days and times are treated separately.
The result is that if the start or end time in the target timezone is not on the same day than on GMT then QF gets it wrong.

I have done the following temporary fix to correct this:

SessionSchedule::SessionSchedule(...)
{
...
Calendar localTime = SystemTime.getUtcCalendar();
localTime.setTimeZone(sessionTimeZone);
localTime.set(Calendar.MILLISECOND, 0);
localTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(matcher.group(1)));
localTime.set(Calendar.MINUTE, Integer.parseInt(matcher.group(2)));
localTime.set(Calendar.SECOND, Integer.parseInt(matcher.group(3)));
< //moved down: Calendar startTime = SystemTime.getUtcCalendar();
< //moved down: startTime.setTime(localTime.getTime());
int startDay = -1;
if (weeklySession)

{ startDay = getDay(settings, sessionID, Session.SETTING_START_DAY, -1); > localTime.set(Calendar.DAY_OF_WEEK,startDay); //set weekday in start calendar }

> Calendar startTime = SystemTime.getUtcCalendar();
> startTime.setTime(localTime.getTime());

matcher = TIME_PATTERN.matcher(endTimeString);
if (!matcher.find())

{ throw new ConfigError("Session " + sessionID + ": could not parse end time '" + endTimeString + "'."); }

localTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(matcher.group(1)));
localTime.set(Calendar.MINUTE, Integer.parseInt(matcher.group(2)));
localTime.set(Calendar.SECOND, Integer.parseInt(matcher.group(3)));
< //moved down :Calendar endTime = SystemTime.getUtcCalendar();
< //moved down :endTime.setTime(localTime.getTime());
int endDay = -1;
if (weeklySession)

{ endDay = getDay(settings, sessionID, Session.SETTING_END_DAY, -1); > localTime.set(Calendar.DAY_OF_WEEK,endDay); //set week day in end calendar }

> Calendar endTime = SystemTime.getUtcCalendar();
> endTime.setTime(localTime.getTime());

  • this.startTime = new TimeEndPoint(startTime); //removed weekday parameter
  • this.endTime = new TimeEndPoint(endTime); //removed weekday parameter
    }
  • TimeEndPoint::TimeEndPoint(Calendar c) //removed weekday parameter { * this( c.get(Calendar.DAY_OF_WEEK) , c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND)); //use calendar's weekday instead of separate weekday }


 Comments   
Comment by Steve Bate [ 24/Aug/07 ]

Added unit test and modified code to handle this situation properly. Thanks for the report.





[QFJ-227] Login Reject (possible SessionReject) Created: 21/Aug/07  Updated: 15/Nov/12  Resolved: 25/Aug/07

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

Type: Other Priority: Major
Reporter: Ulvi Ugur Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any



 Description   

Hi,

When the acceptor gets the login message (35=A), certain verifications are being performed by the QuickFIX engine like SenderCompID, TargetCompId, CurrentTimes, SeqNum, etc. If one or many of these verifications fail, the issue is logged on the acceptor side but no messages are send to the initiator.

Is it possible to configure/program QuickFIX so that it sends a Reject-session-level (35=3) message with a SessionRejectReason (373) with the rejection reason ? Or is there any other mechanism which would inform the initiator about the problem ?

Thanks in advance,

Ulvi



 Comments   
Comment by Steve Bate [ 25/Aug/07 ]

We do send rejects for these types of problems if the message is not a login message. The spec recommends the behavior we've implemented for login messages. IIRC, this is at least partly a security issue to make it harder for a hacker to get feedback when trying to gain access to the engine. Currently, there is no configuration to override this behavior for login messages.

Comment by Ulvi Ugur [ 26/Aug/07 ]

Hi Steve,

Thanks for the feedback. I can understand and appreciate that QuickFIX is not responding to a failed login attempt with an explanatory message wizth security concerns. However, I still think that this mode should be configurable and can be combined with an SSL certificate implementation. After all this is the normal mode of operation for many internet based transaction applications which use their own non-FIX based implementation which might be easily a growing space for FIX (or QuickFIX if you want to see it that way).

Given that, do you think if it would be possible to add this request as a future release candidate functionality ?

Regards,

Ulvi





[QFJ-226] MDEntryTime/Date fields aren't parsed correctly when Daylight Savings time is in effect Created: 21/Aug/07  Updated: 27/Mar/08  Resolved: 06/Oct/07

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

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

FIX.4.4 protocol has MDEntryTime (273) and MDEntryDate (272) to specify the time/date of market data entries.

When you are trying to parse a market data incremental refresh (MsgType=X), and you have a MDEntryTime of "13:30:00" it will parse it using the UtcTimeOnlyConverter, but it'll parse the time relative to the January 1, 1970 date. As a result, in the summer you'll end up with times being off-by-one, bc January is not during DST.

The real way to parse the MDEntryTime is to combine it with the MDEntryDate, so that if the other field is present it should use it and then it'll have the right date and will have the DST value calculated correctly.

The workaround, for now, is to of course parse the entire date/time combined string together.

Here's the example portion of a message that'll break this (see fields 272/273):
8=FIX.4.4
35=X
...
268=1950
279=0
269=5
55=YHOO
270=23.6400
272=20070820
273=13:30:00.000
279=0
....



 Comments   
Comment by Steve Bate [ 24/Aug/07 ]

This is an interesting problem. In general, combining FIX fields to parse times would require some nontrivial extensions to the message metadata (data dictionary). Another option would be to always use the current UTC date to parse the times. It seems reasonable to interpret a time-only field in that way, although their may be other fields in the message that could specify a different date.

Comment by Steve Bate [ 31/Aug/07 ]

Does UTC have a DST adjustment? I tried googling for it but had trouble finding the answer.

Comment by Toli Kuznets [ 20/Sep/07 ]

I don't think that UTC has any provisions for DST adjustments at all - it's just meant to be an absolute.
From wikipedia:
The definition for time zones can be written in short form as UTC±n (or GMT±n), where n is the offset in hours. These examples give the local time at various locations at 12:00 UTC when daylight saving time (or summer time, etc.) is not in effect:

So it's explicitly not counting DST. another quote: "a location observing UTC+10 during standard time is at UTC+11 during DST".

i think using using current UTC date to parse time may be a reasonable approach, but then again, i'm sure there'll be situations under which that breaks if we are parsing some historical quotes, for example.

It's quite possible that this is bad design on the part of FIX and we'll just need to have special cases in the application code itself. QFJ may not have enough context to parse everything correctly.

Comment by Toli Kuznets [ 20/Sep/07 ]

UTC article: http://en.wikipedia.org/wiki/Time_zone#Standard_time_zones
DST article: http://en.wikipedia.org/wiki/Daylight_saving_time#Observance_practices

Comment by Steve Bate [ 06/Oct/07 ]

I agree that the FIX approach of having separate date and time fields is questionable. I'm going the leave the current implementation the way it is for now.

Comment by Toli Kuznets [ 27/Mar/08 ]

We ended up finding a workflow that works around this fairly cleanly.

We needed to display incoming times from a message in market data refresh with this code:

SimpleDateFormat simpleDateFortmat = new SimpleDateFormat("HH:mm");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
simpleDateFormat.format(msg.getUTCTimeOnly(MDEntryTime.FIELD))

Since QFJ uses the UTC timezone to parse the time value, this works out just fine.





[QFJ-225] Enhance JMX support to include notifications of login/logout Created: 17/Aug/07  Updated: 23/Jul/12  Resolved: 31/Aug/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Placeholder for an RFE to add additional functionality to current QFJ JMX support.
Would be great to have a notification model, where listeners could register to receive JMX notifications of logins/logouts, and of potentially MINA events.
Would be great to have capacity to add new sessions/destinations via JMX, both for acceptor and initiator sessions.



 Comments   
Comment by Steve Bate [ 17/Aug/07 ]

Hi Toli,

I've been investigating this. The only callbacks from the Session are currently to the Application implementation. This is clearly restrictive but is based on the QF design. I've been brainstorming on some options to add the notifications.

I could add a new callback capability directly on the Session – something like a SessionStateListener could be attached directly to the session. This listener would provide callbacks for logon, logoff, connect, disconnect and maybe other events like missed heartbeat and so on.

The JMX exporter would attach a listener to each session and generate the appropriate JMX notification. (BTW, I just realized the JMX exporter currently cannot export dynamically created acceptor sessions.)

This callback could be used for other purposes as well and could be registered by a user from the Application.onCreate call.

I'm thinking the callbacks should probably come directly from the SessionState object rather than the Session itself.

Thoughts?

Comment by Toli Kuznets [ 17/Aug/07 ]

We can test it out on static sessions, and then extend it to dynamically created sessions at a later time once the feature set/requirements are more stable if it's easier that away.

Having the callbacks come form SessionState seems to make sense too. I'm assuming you'll just add them into SessionState.setLogoutReceived()/setLoginReceived(), right?

This sounds like a solid approach to me.

Comment by Saneesh Kumar [ 23/Jul/12 ]

Dear Mr. Steve,

I am trying to achieve something similar, I need to implement the SessionStateListener in the Initiator.

Firstly, I defined my Initiator to Implement SessionStateListener, Then I added the listener by:

Session.lookupSession(quickfixSessionID).addStateListener(fixInitiator);

and now trying to receive following callbacks to check if the network is down:
@Override
public void onMissedHeartBeat()

{ System.out.println("######onMissedHeartBeat"); }

@Override
public void onHeartBeatTimeout()

{ System.out.println("######Heartbeat time out"); }

But the onMissedHeartBeat() and OnHeartbeatTimeout() methods are called only once the network connection is reestablished. I need to understand when the network went down and when it came back.

Please send me if you have any solution for the above to [email protected]





[QFJ-224] Automatically close logs and message stores when session connector is closed. Created: 14/Aug/07  Updated: 15/Nov/12  Resolved: 20/May/11

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.2.1
Fix Version/s: 1.5.1

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux


Issue Links:
Duplicate
is duplicated by QFJ-350 Sessions do not cleanup after themsel... Closed
is duplicated by QFJ-406 No way for FileStore to be closed Closed
Relates
relates to QFJ-287 Provide hook for manually closing Fil... Closed

 Description   

When you use a FileStoreFactory as a MessageFactory for "Acceptor" QFJ applications, it does not seem to close or delete files associated with a particular session.

For example, when i connect to my acceptor (running on Linux) with a new dynamic session, i can see the new set of files being created for it.
I can run 'lsof +p <pid> ' and see the files being open for the session.

When i kill my initiator and force a disconnect, the files still remain open - i can still see them in the output of lsof command.

So after a long running time and lots of incoming connections the acceptor application ends up running out of file descriptors.

I stepped through the code and it looks like the files are being closed in the Session.disconnect() --> FileStore.reset() call, but somehow the file descriptors still show up in use.



 Comments   
Comment by Steve Bate [ 14/Aug/07 ]

The acceptor does no management of the message stores.

To implement this feature, we'd need to create some type of new or extended interface that some of the message stores could implement that would allow them to clean up their resources based on specific session events.

As a workaround, you could access the session's state in the Application onLogout callback, cast it to a FileStore and then call deleteFiles() on it.

Comment by Toli Kuznets [ 15/Aug/07 ]

The above workaround works for me, as long I have the following vars setup:
ResetOnLogin=Y
ResetOnDisconnect=N
ResetOnLogout=N

Since Session.disconnect() calls into application.onLogout() before it does the check/reinitalization on disconnect, i had to set ResetOnDisconnect=N.

My quickfix.Application.onLogout() code:
public void onLogout(SessionID sessionId) {
FileStore store = (FileStore) Session.lookupSession(sessionId).getStore();
try {
store.closeFiles();
store.deleteFiles();
if(LoggerAdapter.isDebugEnabled(this))

{ LoggerAdapter.debug("Closed and deleted files for session "+sessionId, this); }

} catch (IOException e)

{ LoggerAdapter.error(e.getMessage(), e, this); }

}

Comment by Steve Bate [ 06/Oct/07 ]

We have the listener interface to implement this feature now. I think it should be configurable (default to off) since the FileStore loads all sent messages when it initializes. This could cause a significant delay during counterparty login. However, closing the files and clearing the caches makes a lot of sense for other applications, like simulators.

Comment by André Malenfant [ 21/Nov/07 ]

The same applies to the quickfix.Log class but the workaround cannot be used since the close() method is protected.

Comment by André Malenfant [ 21/Nov/07 ]

Sorry, It is atually package scope.

Comment by André Malenfant [ 21/Nov/07 ]

Sorry fro the multiple comments in a row...

To be more precise, I don't talk specifically about deleting the files. This can be a nice developement feature but you definitely don't want that in a prod environment. What is most important is that the store AND the logger close their files if the initiatior or acceptor is stopped. This way, if a web application gracefully responds to a stop event from the container, it can stop all connections opened in quickfixj and expect the files to be unlocked.

Comment by André Malenfant [ 21/Nov/07 ]

And B.T.W. (sorry again) to close the files on logout is not enough because the session may not be logged on at all at the time the initiator or acceptor is closed. This should be done also or at least on close.

Comment by Steve Bate [ 11/Jan/08 ]

I split this into a separate issue for 1.3.1 to expose hooks for manually closing FileLog files. See the related issue.

Comment by Steve Bate [ 06/Apr/10 ]

Added support to Session for disposable message stores and logs. However, we need to think more about how to support these in the current file-based implementations. There are still potential issues with the FileStore if it's required to load it's caches on every session connect event. FileLogs might be a little easier to handle.

Comment by Steve Bate [ 26/Apr/11 ]

Modified the title to more accurately reflect the feature request. One approach for this is to check in the session connector (initiator or acceptor) whether the message log and/or store implements the java.io.Closeable interface. If so, the connector will call close on the log or store.

Comment by Steve Bate [ 20/May/11 ]

This issue has become confusing over the last four years. I'm think that we want to close the file-based resources when a connector is stopped. When a connector is stopped, the Sessions are unregistered. If we "close" the sessions at this point then we can release resources if the plugins (store, log) support it. Let me know if anyone else has a different interpretation.

Comment by Steve Bate [ 20/May/11 ]

If a MessageStore or Log implementation implements the java.io.Closeable interface then the Session will close them (the connector tells the session to close them after unregistering the session). The FileLog and FileStore have been modified to implement the Closeable interface.

Comment by Mate Varga [ 08/Aug/12 ]

Am I right thinking that (initiator means SocketInitiator in the following)

  • an initiator creates the sessions in start() -> initialize() -> createSessionInitiators()
  • if an initiator is stopped, then the sessions will be unregistered
  • if an initialized initiator is started, then it only re-registers the sessions, and does not recreate them (see initialize())
  • a Session closes it's Log if it's closeable (see Session -> unregisterSessions() -> close() -> closeIfCloseable(getLog())
  • a FileLog only opens it's streams in clear() and in it's constructor

— therefore, if SocketInitiator using a FileLog is stopped, then next time it gets started it will throw exceptions as the underlying file handle is closed.

Opinions?

Comment by Mate Varga [ 08/Aug/12 ]

By the way, this is in 1.5.2.





[QFJ-223] IoSessionInitiator sometimes tries to log null messages in case of IOExceptions Created: 10/Aug/07  Updated: 11/Feb/09  Resolved: 14/Aug/07

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

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

If there's an IOException in IoSessionInitator that's actually a java.net.ConnectionException, sometimes QFJ gets in a situation when it's trying to log an exception with NULL message.
If you have JDBC log configured you end up having with JDBC errors since the log tables aren't nullable.

This usually happens when you pull a network plug out from the server, and the intiator can't connect to it.

Stack trace:
com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Column 'text' cannot be null
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:931)
<snip>
at quickfix.JdbcLog.insert(JdbcLog.java:90)
at quickfix.JdbcLog.onEvent(JdbcLog.java:52)
at quickfix.CompositeLog.onEvent(CompositeLog.java:79)
at quickfix.mina.initiator.IoSessionInitiator$ConnectTask.connect(IoSessionInitiator.java:136)



 Comments   
Comment by Toli Kuznets [ 10/Aug/07 ]

i checked in a fix for this in rev 721
However, not sure how best to test this case since the class it's implemented in is private and there's no easy way to force this codepath.





[QFJ-222] public SessionJmxExporter.createSessionName Created: 07/Aug/07  Updated: 11/Feb/09  Resolved: 14/Aug/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Danilo Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm writing a monitoring web application using JMX and it would be very useful if SessionJmxExporter.createSessionName is made public.






[QFJ-221] Extend dynamic creation of sessions to have template IDs for each FIX version Created: 07/Aug/07  Updated: 11/Feb/09  Resolved: 16/Aug/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.3.0
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-165 Allow for dynamic definition of sessions Closed

 Description   

This is an extension to QFJ-165.
Currently the way to allow for dynamic sessions is to use and specify a set of session settings and a template SessionID that will drive the creation of new sessions dynamically.

That works great as long as all the new sessions are of same FIX version and need the same data dictionary file.

However, if you want to support different FIX versions coming across the same acceptor connection this paradigm breaks down, since only the data dictionary of the template session will be used.

The simple solution is to use a Map of templateIDs --> SessionSettings, with different settings for each corresponding session id. Then you look up the appropriate template ID based on the incoming FIX version and use the corresponding settings.

Not sure if this simple approach has a similar (but yet undiscovered) future drawback....

Workaround:
In client code, you can subclass from DynamicAcceptorSessionProvider and override the getSession() method to overwrite the value of Data dictionary path to be the right version.



 Comments   
Comment by Steve Bate [ 08/Aug/07 ]

You could also create a template for each FIX version and bind them to separate acceptor ports. Clients would connect to a specific port depending on the version of FIX they wanted to use.

Comment by Toli Kuznets [ 08/Aug/07 ]

Good point - I guess we can have multiple SocketAcceptors and as a result multiple DynamicAcceptorSessionProviders.
that's a good workaround.

however, ideally i think it'd be good to have an option of being able to multiple different FIX version over the same port connection.





[QFJ-220] QFJ hangs in IoSessionResponder.disconnect() while waiting for scheduled messages to be written Created: 06/Aug/07  Updated: 11/Feb/09  Resolved: 14/Aug/07

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

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

HEAD revision of QFJ (actually, rev 710)


Attachments: Text File responder.patch     Text File socket_state.txt     Text File trace.txt    
Issue Links:
Relates
relates to QFJ-215 QFJ deadlocks in Session.disconnect()... Closed

 Description   

This is a continuation of QFJ-215.
I'm now seeing a new hang that happens in IoSessionResponder.disconnect() on the waitForScheduleMessagesToBeWritten() line.

Seems that one of the connecting sockets gets the underlying MINA framework in a "bad state" and the IoSessionResonder.waitForScheduleMessagesToBeWritten() function never gets out of the loop that's waiting for the messages to be written.

I have 2 acceptor sessions running with MINA 1.1.0, and both end up in this state after a few days of being up.
See the attached logs for the full stack dump, and the output of netstat command (on Ubuntu Linux).

The relevant portion of the stack trace is:
"SocketAcceptorIoProcessor-0.0" prio=1 tid=0x082427c0 nid=0x546e sleeping[0xb0c71000..0xb0c71f60]
at java.lang.Thread.sleep(Native Method)
at quickfix.mina.IoSessionResponder.waitForScheduleMessagesToBeWritten(IoSessionResponder.java:55)
at quickfix.mina.IoSessionResponder.disconnect(IoSessionResponder.java:43)
at quickfix.Session.disconnect(Session.java:1370)
at quickfix.mina.AbstractIoHandler.exceptionCaught(AbstractIoHandler.java:82)

Seems that the waitForScheduledMessagesToBeWritten() call that was added in rev 698 (http://quickfixj.svn.sourceforge.net/viewvc/quickfixj/trunk/core/src/main/java/quickfix/mina/IoSessionResponder.java?view=diff&r1=697&r2=698) is the crux.



 Comments   
Comment by Toli Kuznets [ 06/Aug/07 ]

Output of 'netstat an|grep 7001" (our acceptor socket) command on Linux.
The main 7001 socket is established, but all the incoming connections are hung.

Comment by Toli Kuznets [ 06/Aug/07 ]

Full Java stack trace at time of hang

Comment by Steve Bate [ 07/Aug/07 ]

Damn. The reason the wait functionality is there is because disconnect would frequently complete before the logout message was sent. We could just wait once for a short time (say 50ms) and then do the close. That should generally be enough time for the logout to be sent. If it's not send, it's not a critical problem, but it's polite behavior to send the message.

Comment by Toli Kuznets [ 07/Aug/07 ]

Steve, what can we be doing differently in QFJ than others aren't with MINA?
From the stack trace, it looks like the problem originates in SocketIoProcessor.read (line 227, i had been using MINA 1.1.1)
It's sitting in the catch(Throwable) inside the read loop - so can it be that there's an error on the socket, it fires an exception, and then we end up waiting for the socket to send out some messages while the socket-related code has already essentially "panicked"?

as a result, we can't send any outgoing Logout messages out and end up hanging.

Is this possible? where's the code path that tries to send something out? Or does that mean we just have some "outstanding" messages waiting to go out when the socket code panics, and that it's not necessarily a logout we are waiting to send out?

Comment by Steve Bate [ 07/Aug/07 ]

I think your analysis probably correct, but without digging into MINA deeply I'm not sure how to verify it. My guess is that a message send has been initiated, there is a socket error, and the pending write count is never decremented (although strictly speaking, there are no more pending writes).

I'm not sure we are doing anything differently in checking the written message count. However, we can't call close().join() (the related problem) because we use a manual thread model. MINA is typically used with some type of thread pool executor. QF manages the threads in the Connector implementations and I didn't want another thread handoff between MINA and the Connectors. In the long term, I'd like to eliminate the thread management in the Connectors and use a more typical MINA threading architecture. The only sticky issue is that messages must be delivered to Sessions in the order they were received.

Comment by Toli Kuznets [ 07/Aug/07 ]

What if we overload the Session.disconnect() call to take a boolean specifying whether or not to try and wait for messages to be cleared?

in that case, when we call Session.disconnect() from AbstractIoHandler.exceptionCaught() we tell it to skip waiting for messages to be written, and let it do the waiting in all the other cases?

Then, if our theory is correct, that should probably fix the problem. What kind of message are we expecting to be sent out? A log out?

I can try this modification on the Marketcetera Exchange simulator and ask the users to pound the exchange and see what happens.
Is there any way to exercise this? I thin it may be triggered by having many incoming simultaneous connections on different SessionIDs.

Comment by Toli Kuznets [ 11/Aug/07 ]

Patch for the propagating a boolean on whether or not to wait for all messages to be written out.
This is not the most elegant solution, as it adds another function call to Responder API that duplicates the existing one.

If we choose to go with this solution, i'd vote to modify the Responder API to remove the overloaded call, and only have 1 with the boolean.

I'll update the bug in a few days after this code runs long enough behind the outward-facing Marketcetera Exchange Simulator (http://exchange.marketcetera.com/marketDisplay) to show there are no other lingering issues with dynamic acceptor sessions

Comment by Steve Bate [ 14/Aug/07 ]

We'll only wait for a limited about of time (up to 50ms) for messages to be written. This should eliminate the hang.





[QFJ-219] Maven artifacts dependencies Created: 01/Aug/07  Updated: 06/Apr/10  Resolved: 06/Apr/10

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: Bug Priority: Default
Reporter: Danilo Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None

Attachments: File quickfixj-core-1.3.1-java4.pom     File quickfixj-msg-fix40-1.3.1-java4.pom     File quickfixj-msg-fix41-1.3.1-java4.pom     File quickfixj-msg-fix42-1.3.1-java4.pom     File quickfixj-msg-fix43-1.3.1-java4.pom     File quickfixj-msg-fix44-1.3.1-java4.pom    

 Description   

The generated pom's for each quickfixj maven artifact should include the correct dependencies.
Core should depend on backport-util-concurrent and mina.
Message version artifacts should depend on the previous version, i.e. 4.1 depend on 4.0, 4.2 depend on 4.1 and 4.0, and so on.



 Comments   
Comment by Toli Kuznets [ 01/Aug/07 ]

Danilo, this is going to be a silly question, but what commands do you use to generate the POM?

are you doing this through the ant target? Eclipse? Through IntelliJ?

Comment by Danilo [ 09/Aug/07 ]

I'm not generating the POM.
I said "generated pom" because I thought it was being generated by an ant task or whatever, instead of manually written.

Comment by Toli Kuznets [ 21/Sep/07 ]

Danilo,
Are you talking about the POMs on http://repo.marketcetera.org/maven/quickfixj/ ?
We do generate those (essentially) by hand, so I can make sure to try and add dependencies to them as well.

Do you have a copy of the "right" POM that you can attach to this bug so that we can make sure that we create the right POMs?

Comment by Danilo [ 21/Sep/07 ]

Toli,
I don't have the correct pom's.
I included the dependencies in my project pom.

– Danilo

Comment by Christian Bach [ 14/Mar/08 ]

Hey guys

I put together a set of POMs with conclusive transitive hulls for quickfixj-1.3.1-java4. Check out the attachments and enjoy .

– Christian.





[QFJ-218] Session time not checked while session is disconnected Created: 27/Jul/07  Updated: 11/Feb/09  Resolved: 02/Sep/07

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

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-231 During the logou process, sometimes ... Closed
is related to QFJ-212 Query behaviour on first Logon messag... Closed

 Description   

The session time should be monitored whether the session is connected (has a responder) or not.






[QFJ-217] Update documentation for Java 5 / JDK 1.4 compilation and usage (and new MINA libraries) Created: 27/Jul/07  Updated: 11/Feb/09  Resolved: 02/Sep/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-216] Support recursive custom group definitions in the code generator Created: 27/Jul/07  Updated: 27/Apr/11

Status: Open
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.2.1
Fix Version/s: Future Releases

Type: New Feature Priority: Default
Reporter: Lev Grevnin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Environment:

windows XP/java 1.5_06



 Description   

Suppose I have the following xml message definition

<message name="FirmPrice" msgtype="UN020" msgcat="app">
<field name="Symbol" required="Y"/>
<field name="Size" required="Y"/>
<group name="NoPriceEntries" required="Y">
<component name="PriceComponent" required="Y"/>
</group>
<group name="NoLegEntries" required="N">
<component name="LegComponent" required="N"/>
</group>
</message>

...

<component name="LegComponent">
<field name="Size" required="Y"/>
<field name="Symbol" required="Y"/>
<group name="NoPriceEntries" required="Y">
<component name="PriceComponent" required="Y"/>
</group>
</component>

The message generation creates a MessageFactory.java which has the following snippet of code in it:

if("UN020".equals(msgType)) {
switch(correspondingFieldID)

{ case liquidity.quickfix.fields.NoPriceEntries.FIELD: return new liquidity.quickfix.messages.FirmPrice.NoPriceEntries(); case liquidity.quickfix.fields.NoLegEntries.FIELD: return new liquidity.quickfix.messages.FirmPrice.NoLegEntries(); case liquidity.quickfix.fields.NoPriceEntries.FIELD: return new liquidity.quickfix.messages.FirmPrice.NoLegEntries.NoPriceEntries(); }

}

This cannot compile, obviously, as it has a duplicate case label. So, it seems like the usage of a field in both, the enclosing message and the nested component is not handled properly by the generated code.

Looks like this is due to "NoPriceEntries" appearing twice: once in the main body of the message, and once in the subcomponent "LegComponent".



 Comments   
Comment by Steve Bate [ 16/Aug/07 ]

Toli, any ideas on what we should do about this issue? The only idea I have is to have a second group generation method that accepts a list of message and group fields to identify the specific nested group to create.

Comment by Toli Kuznets [ 17/Aug/07 ]

Steve,

This bug is a case of a group appearing twice in a message, once inside a "top-level" and then once again in a nested subgroup.

If QFJ were to support this case, it'll probably make sense to make it available for any deep level of nesting, right?
That becomes a much more complicated problem, right? For every level of nesting you need to keep passing some additional arguments in to be able to reconstruct how all of this is related, correct?

What does the FIX spec say about that? Can you have same groups showing up multiple times in different nested subgroups? I couldn't see the spec specifically disallowing it, so my guess is that this is allowed and we need to support it?

A message specification is a hierarchical tree, with different fields appearing in different locations. Are the group fieldIDs treated as unique IDs that specify their location? (kind of like the <id> tag in HTML?)
Looks like we are trying to flatten out a hierarchical structure that has is indexed by field names/ids. We are only specifying a fieldID per field, and it seems that it follows a built-in assumption that having only 1 fieldID is enough to specify the position of the field inside the hierarchy of the message specification.
If you have a message with repeating field names at different level of nesting, then they'll cause a collision when flattened out - which is what we are seeing with this bug.

Sounds like we may need to pass all the information/context about the level of nesting into the factory message in order to able to create the groups at the right level of nesting...

A workaround would certainly be to create more specific field types or change the name of some sub-group. Maybe create a NoPriceEntriesPerLeg ? This would be a straight-forward short-term workaround.

Comment by Lev Grevnin [ 27/Nov/07 ]

Hi. Did anyone manage to have a look at this? Is it still an issue?

Comment by Lev Grevnin [ 20/Dec/07 ]

Yes, indeed, it appears the quickfix 1.3.0 still suffers from this problem. It would be really nice to correct it.

Comment by Steve Bate [ 26/Apr/11 ]

I don't know if the specification prohibits it, but apparently there are no standard FIX group definitions that contain a repeating group of the same type (recursive group definition). Therefore, I changed this from a bug to a feature request and dropped the priority. I'm curious about whether the message parser will handle the recursive groups.

Comment by Eric Deshayes [ 27/Apr/11 ]

As it is a new feature that would have some impact on the generated classes (and therefore not be backward compatible), it is descoped from the 1.5.1 release.





[QFJ-215] QFJ deadlocks in Session.disconnect() code when a Windows client disconnects from Linux or Mac server Created: 26/Jul/07  Updated: 11/Feb/09  Resolved: 27/Jul/07

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

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

rev 709


Issue Links:
Relates
is related to QFJ-220 QFJ hangs in IoSessionResponder.disco... Closed

 Description   

I'm encountering a situation (in the HEAD code) where I get a deadlock when i disconnect from a QFJ acceptor running on Linux or Mac OS X from a Windows machine.
I can reproduce this using the sample executor/banai applications, so i don't think that it has anything to do with my application code.

Repro:
Run the executor app on a Mac machine
Setup Banzai to connect from a Windows machine to the acceptor on a Mac or a Linux box. this has to be a separate box, not localhost. VMWare Windows -> Linux host works.

The first time the connection will go through successfully. Now, press Ctrl-C to disconnect the Banzai process - the "acceptor" side registers the disconnect messages:
<20070726-02:30:40, FIX.4.0:EXEC->BANZAI, event> (Responding to logon request)
Jul 25, 2007 7:30:43 PM quickfix.mina.AbstractIoHandler exceptionCaught
SEVERE: socket exception (/10.1.9.204:1747): Connection reset by peer
<20070726-02:30:43, FIX.4.4:EXEC->BANZAI, event> (Disconnecting)

Now, try connecting Banzai again. on the Banzai side, you see the logon initiation messages:
<20070726-02:33:10, FIX.4.1:BANZAI->EXEC, event> (Initiated logon request)
<20070726-02:33:10, FIX.4.4:BANZAI->EXEC, outgoing> (8=FIX.4.4☺9=66☺35=A☺34=14☺4
9=BANZAI☺52=20070726-02:33:10.312☺56=EXEC☺98=0☺108=30☺10=007☺)

On the 2nd try, when you see Banzai trying to log on, there are no messages showing up on the Executor side. Doing a Ctrl-\ to get a stack trace yields the following:

"SocketAcceptorIoProcessor-0.0" prio=10 tid=0x905e1800 nid=0x2e7f in Object.wait() [0x8ffad000..0x8ffadf30]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0xb1de2338> (a org.apache.mina.common.support.DefaultCloseFuture)
        at java.lang.Object.wait(Object.java:485)
        at org.apache.mina.common.support.DefaultIoFuture.join(DefaultIoFuture.java:86)
        - locked <0xb1de2338> (a org.apache.mina.common.support.DefaultCloseFuture)
        at quickfix.mina.IoSessionResponder.disconnect(IoSessionResponder.java:44)
        at quickfix.Session.disconnect(Session.java:1369)
        at quickfix.mina.AbstractIoHandler.exceptionCaught(AbstractIoHandler.java:82)
        at org.apache.mina.common.support.AbstractIoFilterChain$TailFilter.exceptionCaught(AbstractIoFilterChain.java:695)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextExceptionCaught(AbstractIoFilterChain.java:423)
        at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:54)
        at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.exceptionCaught(AbstractIoFilterChain.java:794)
        at org.apache.mina.common.IoFilterAdapter.exceptionCaught(IoFilterAdapter.java:78)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextExceptionCaught(AbstractIoFilterChain.java:423)
        at org.apache.mina.common.support.AbstractIoFilterChain.access$1100(AbstractIoFilterChain.java:54)
        at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.exceptionCaught(AbstractIoFilterChain.java:794)
        at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.exceptionCaught(AbstractIoFilterChain.java:611)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextExceptionCaught(AbstractIoFilterChain.java:423)
        at org.apache.mina.common.support.AbstractIoFilterChain.fireExceptionCaught(AbstractIoFilterChain.java:407)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:293)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:563)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:619)

When you run this on a vanilla Quickfix/J-1.2.1 distribution everything works. However, it starts breaking using the head (as of 709) revision.
Linux->Mac and Linux->linux works, it seems that only when you enter Windows into the equation it starts to misbehave.

I'm inclined to think this is a QFJ and not a MINA issue, since it works fine with 1.2.1 but not with SVN revision.
Also, i've tried various versions of MINA - 1.0.3, 1.0.4 and 1.1.1, and the app still deadlocks in the same way.

I've looked at the code, and it seems that there are 2 different code paths that happen.
When a non-Windows initiator disconnects, the xxx.mina.xxx.DefaultCloseFuture.setValue() is hit, after which we get into the quickfix.mina.IoSessionResponder.disconnect() and sail right through the close().join() code.
However, with a Windows iniatiator, we go straight into the IoSessionResponder, and it seems that the close0() function is never hit so we never mark the future as closing and hang as a result.

I saw something related in https://issues.apache.org/jira/browse/DIRMINA-261 but since we are not specifying SO_LINGER (or SocketLinger) i don't think it applies. i tried setting SocketLinger to be 0, but that didn't change the behaviour.

I can reproduce this consistently, so would like any advice on how to go about further debugging or fixing this.



 Comments   
Comment by Steve Bate [ 27/Jul/07 ]

I've removed the CloseFuture.close() call. That shouldn't have been there because the threading model we are using will cause MINA to not be able to process the close completion event (and complete the join()).





[QFJ-214] Does SLF4J/Log4J combo ignore changes to the log4j.properties file? Created: 21/Jul/07  Updated: 27/Jul/07  Resolved: 27/Jul/07

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

Type: Other Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I have an app that's using SLF4JLogFactory and i have the slf4j-logj4 jar in the path, so in the end it's using log4j to print log messages.

The entries in the log4j.properties file are parsed and used when the app starts up, so whatever i have setup drives the filtering of the output.
However, if i modify the log4j file after the app starts up, the changes never take effect - the same messages get printed, regardless of whether or not i turn certain categories on/off.

Anybody else seeing something similar? I couldn't trace through in the QFJ code where that would make a difference - seems that SLF4J/Log4J would handle that on their own.

Just wondering if maybe we are not setting SLF4J/Log4J up correctly.



 Comments   
Comment by Jörg Thönnes [ 21/Jul/07 ]

Toli, I think this behaviour is standard. We use plain log4j in our processes and log4j reads
the config once at startup.

On the other hand, e.g. the JBoss app server refreshes properties regularly.

Actually, this depends how log4j is used programmatically. I remember some methods / classes in the API
to support this, but at moment I forgot where they are...

So I guess this should be handled inside the SL4J adapter code. Did you check whether they support some
config do enable this?

Cheers, Jörg

Comment by Brad Harvey [ 23/Jul/07 ]

Jörg is correct. I think you need to use http://logging.apache.org/log4j/docs/api/org/apache/log4j/PropertyConfigurator.html#configureAndWatch(java.lang.String) to make it reread the property file. I suspect you can just do this first thing in your application.

It should not be QFJ that does this though unless it is optional - otherwise other environments that already do this (eg, JBoss) might not behave as expected.

Cheers,
Brad.

Comment by Steve Bate [ 27/Jul/07 ]

Toli, I agree with Brad's comments. Does that approach sound OK to you?

Comment by Toli Kuznets [ 27/Jul/07 ]

Hmm, i think we are using conifgureAndWatch in our app ourselves (we use Log4J directly): http://trac.marketcetera.org/trac.fcgi/browser/platform/trunk/core/src/main/java/org/marketcetera/core/LoggerAdapter.java#L41

but it's been over a year since i've touched or looked at the logging code, so maybe there's some weird interplay of how we start the log4j and how QFJ does the same through SLF4J.

but it does sound like something is incorrect in our own setup. i'll investigate a bit more and let you guys know. thanks for the advice.





[QFJ-213] MessageStore should refresh immediately before connector start or logon Created: 19/Jul/07  Updated: 06/Oct/07  Resolved: 06/Oct/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0, 1.2.0, 1.2.1
Fix Version/s: None

Type: Improvement Priority: Default
Reporter: Jörg Thönnes Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

In a failover setup, two instances with QuickFIX/J engines are running on different nodes. They connect to the same database using Jdbc. One engine is started and persists its session state into the database.

The other instance is stopped. If a failover occurs (instance crashes etc.), the second instance takes over and the engine is started. But the session state is not refreshed from the database. It has been loaded when the instance started and the QF connector (acceptor or initiator) has been constructed. In the meanwhile, the other instance has updated the session state.

I would expect that the second instance picks up the new session state on connector.start() or even better immediately before the Logon is sent / processed.

RefreshOnLogon already does this for acceptors. Maybe this is a good place to add this for initiators.

In summary, a general MessageStore.refresh() is required at connector.start(). If possible, immediately before the Logon (network connection already established) would be great.



 Comments   
Comment by Steve Bate [ 16/Aug/07 ]

Did you try using RefreshOnLogon with the initiators? From looking at the code, this will refresh the state for initiators before sending the logon message. It sounds like the behavior you want.

I'm curious, how are you signalling the backup initiator to become active and logon?

Comment by Steve Bate [ 06/Oct/07 ]

AFAIK, the current code should exhibit the desired behavior.





[QFJ-212] Query behaviour on first Logon message from initiator when disconnected during session expiry Created: 13/Jul/07  Updated: 27/Jul/07  Resolved: 27/Jul/07

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

Type: Other Priority: Default
Reporter: Rob Gilliam Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Sun JVM 1.4


Issue Links:
Relates
relates to QFJ-218 Session time not checked while sessio... Closed

 Description   

[I searched to see if this had come up before, but couldn't find it - many apologies if this is a duplicate]

We have an issue when an acceptor receives the a Logon(A) message to start a new session from an initiator which was not connected at the time that the old session expired.

The Logon(A) message has 34=1 and 141=Y, so I would expect the acceptor to just go ahead with the new session. Unfortunately the logon message is being passed to Session.next(Message), which is getting false from a call to checkSessionTime() and so just calls Reset(), which sends a Logout(5) message (without having reset the sequence number) and disconnects (without even waiting for a Logout(5) response).

Our applicaiton is based on a slightly-customized version of QuickFIX/J (currently based on 1.0.4), so upgrading to a later version to see if this is resolved is not a quick and simple task, hence I thought I'd just ask a) if this is/was a known problem, and b) whether upgrading will resolve it before I investigate further next week.



 Comments   
Comment by Steve Bate [ 13/Jul/07 ]

The acceptor session checks the session time once per second regardless of whether there is a connection or not at the time. When it detects a session start time the session is reset and checkSessionTime will return true until the next session time interval. Do you have any idea why checkSessionTime is returning false when the logon arrives?

Comment by Rob Gilliam [ 16/Jul/07 ]

SessionTimerTask.run() (in 1.2.1 and 1.0.4) has the following:

if (session.hasResponder())

{ session.next(); }

which suggest to me that sessions which are not connected (i.e. have no socket connection established) will not have their session time checked (as Session.next() won't be called); this would match the behaviour we're seeing.

Or have I missed something somewhere?

Comment by Steve Bate [ 27/Jul/07 ]

I'll look into it more and let you know what I find out.

Comment by Steve Bate [ 27/Jul/07 ]

After looking at the code, guarding the session.next() based on the responder is not correct (because, as you've seen, the session time is not monitored). I've created a bug report (see the link in this issue). Thanks for reporting and investigating this issue.

Comment by Steve Bate [ 27/Jul/07 ]

See linked bug report for further information.





[QFJ-211] Race Condition/NPE on Session.disconnect() Created: 13/Jul/07  Updated: 11/Feb/09  Resolved: 27/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I'm seeing the following show up when i kill the connection to my FIX destination:
<20070713-01:24:51, FIX.4.4:test-quote-asker->test-exchange, event> (Forcibly disconnecting session)
<20070713-01:24:51, FIX.4.4:test-quote-asker->test-exchange, event> (Disconnecting)
<20070713-01:24:51, FIX.4.4:test-quote-asker->test-exchange, event> (Disconnecting)
18:24:51,172 ERROR [SocketConnectorIoProcessor-1.0] mina.initiator.InitiatorIoHandler (AbstractIoHandler.java:77) - protocol handler exception
jjava.lang.NullPointerException
at quickfix.Session.disconnect(Session.java:1369)
at quickfix.mina.AbstractIoHandler.sessionClosed(AbstractIoHandler.java:99)

This happens in Session.disconnect(), where we have the following code:
if (hasResponder()) {
getLog().onEvent("Disconnecting");
NPE>>>> getResponder().disconnect();

both hasResponder() and getResponder() are protected with synchronized(responderSync), but it seems that we have a situation where the responder itself disappears between the call to hasResponder() and when it's being used.

Perhaps we need to put a bigger lock around the whole test/get/use structure?



 Comments   
Comment by Steve Bate [ 27/Jul/07 ]

Modified Session.disconnect to eliminate the race condition.





[QFJ-210] Change ANT testing targets to test both Java 5 and JDK 1.4 releases. Created: 12/Jul/07  Updated: 11/Feb/09  Resolved: 14/Aug/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-209] Port QFJ to Java 5+ Created: 07/Jul/07  Updated: 11/Feb/09  Resolved: 11/Jul/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

Update code to Java 5+. Use retrotranslator to provide JDK 1.4 compatibility. Extend tests to test both Java 5 and JDK 1.4 versions of the libraries (this may be split into a separate task).



 Comments   
Comment by Laurent Danesi [ 11/Jul/07 ]

We will open different task for other points.





[QFJ-208] example bin scripts are broken Created: 07/Jul/07  Updated: 11/Feb/09  Resolved: 27/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.2.1
Fix Version/s: 1.3.0

Type: Bug Priority: Default
Reporter: Danilo Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

windows



 Description   

.bat script are broken due to 1.2.x release, which separates the libraries.



 Comments   
Comment by Steve Bate [ 27/Jul/07 ]

Tolio, thanks for the fix.





[QFJ-207] Session Qualifier for acceptor sessions Created: 06/Jul/07  Updated: 19/Jul/07  Resolved: 13/Jul/07

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

Type: Improvement Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

Hello,

i think, it would be a good idear, to have a session qualifier for acceptor sessions (ConnectionType=acceptor).
If you try to configure two acceptors in separate configuration files (Same fix-version, SenderCompId, TargetCompID) and the only difference is the port number, the configuration will not work if the Message store is in the same directory. They will both use the same message and eventlog files.

Regards
Thomas Hügel



 Comments   
Comment by Steve Bate [ 07/Jul/07 ]

Can you explain this further? Are you saying you have two configurations accepting the same sessions running simultaneously?

Comment by Thomas Hügel [ 10/Jul/07 ]

Steve,

i got your point. This configuration would describe the same session. Please ignore it.

Thanks
Thomas

Comment by Jörg Thönnes [ 19/Jul/07 ]

As a side note: We would need the SessionQualifier for Oracle based JdbcStore. An empty qualifier would be treated as NULL by Oracle and this is not allowed inside the primary key.

Setting SessionQualifier to some other value would help here.





[QFJ-206] Some XSLT templates weren't handling custom packaging correctly Created: 04/Jul/07  Updated: 11/Feb/09  Resolved: 06/Jul/07

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

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-205] Heartbeat Timeouts in 1.2.0 Created: 03/Jul/07  Updated: 04/Jul/07  Resolved: 04/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.2.0
Fix Version/s: 1.2.1

Type: Bug Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

1.2.0, linux


Attachments: Text File threaddump.log    

 Description   

Hello,

after exchanging the 1.1.0 libraries with the 1.2.0 ones all of my connected FIX Session counterparties complain "stale connection" or "hearbeat timeout". The session does not disconnect, but seems somehow to have a problem. The session now look like:
0 Tue Jul 03 17:34:35 GMT 2007 Heartbeat admin outbound
1 Tue Jul 03 17:34:39 GMT 2007 TestRequest admin inbound
2 Tue Jul 03 17:34:34 GMT 2007 Heartbeat admin inbound
3 Tue Jul 03 17:34:00 GMT 2007 Heartbeat admin outbound
4 Tue Jul 03 17:34:04 GMT 2007 TestRequest admin inbound
5 Tue Jul 03 17:33:59 GMT 2007 Heartbeat admin inbound
6 Tue Jul 03 17:33:25 GMT 2007 Heartbeat admin outbound
7 Tue Jul 03 17:33:29 GMT 2007 TestRequest admin inbound
8 Tue Jul 03 17:33:24 GMT 2007 Heartbeat admin inbound
9 Tue Jul 03 17:32:49 GMT 2007 Heartbeat admin outbound

inbound: 8=FIX.4.2|9=65|35=0|34=1426|49=xxx|52=20070703-17:39:15|56=xxx|369=1396|10=137|
outbound: 8=FIX.4.2|9=83|35=0|34=1397|49=xxx|52=20070703-17:38:40.395|56=xxx|112=HeartBtExt Timeout|10=093|
inbound: 8=FIX.4.2|9=88|35=1|34=1425|49=xxx|52=20070703-17:38:45|56=xxx|369=1395|112=HeartBtExt Timeout|10=067|

When i changed back to the old libraries, the problem disappears.

Best Regards
Thomas Hügel



 Comments   
Comment by Steve Bate [ 03/Jul/07 ]

Can you provide a thread dump to show what's happening after the missed heartbeat? It sounds like it might be a thread synchronization issue. Synchronization changed a lot in 1.2 so that might be related to the different behavior.

Comment by Steve Bate [ 04/Jul/07 ]

Thanks Thomas. I found the problem. One of the heartbeat values was not being set properly in the SessionState (only for initiators). Thanks again for reporting the problem so quickly.





[QFJ-204] Support interpolation during parsing of session settings Created: 03/Jul/07  Updated: 11/Feb/09  Resolved: 07/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Parag Mehta Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

All.



 Description   

Interpolation in 1.1.0 does not work with SenderCompID in default section, though it works elsewhere. Also possibly does not work with the other two fields used to generate session id.

Often interpolation is required for SenderCompID since this should be different in dev, UAT and Production.

Related to http://www.quickfixj.org/jira/browse/QFJ-114

Thanks.



 Comments   
Comment by Steve Bate [ 07/Jul/07 ]

The problem is actually not directly related to the default section. The settings are parsed and the interpolation previously only occurred when a variable was accessed. This means the session ID fields would not be interpolated before the internal session ID keys were created. This would have occurred whether or not the interpolated ID field was in the default section. I've modified the parser to interpolate variables during parsing. I've also added a new unit test to test the behavior.





[QFJ-203] Update documentation for new features Created: 30/Jun/07  Updated: 04/Jul/07  Resolved: 30/Jun/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-202] The method quickfix.Session.sendToTarget(amessage,getSessionId(aDecoder)); hangs. Created: 27/Jun/07  Updated: 12/Jul/07  Resolved: 12/Jul/07

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

Type: Bug Priority: Default
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Win32 and Linux



 Description   

I just upgraded to 1.1.0, when I run now the method call sendToTaget hangs.



 Comments   
Comment by Toli Kuznets [ 28/Jun/07 ]

Richard,

Is it possible for you to provide more information?
For example, can you do a Ctrl-\ or kill -QUIT on your process to generate the stacktrace?

I'd really help if we had a stacktrace to see what locks the session is waiting for.

Comment by Steve Bate [ 07/Jul/07 ]

Richard, do you have any more information on this issue?





[QFJ-201] Potential null pointer in DataDictionary.isMsgField Created: 20/Jun/07  Updated: 11/Feb/09  Resolved: 20/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.1.0
Fix Version/s: 1.2.1

Type: Bug Priority: Trivial
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

isMsgField uses single & after a null check - since & doesn't short circuit it throws null pointer if fields is null.

Change from:

public boolean isMsgField(String msgType, int field)

{ Set fields = (Set) messageFields.get(msgType); return fields != null & fields.contains(new Integer(field)); }

to

public boolean isMsgField(String msgType, int field)

{ Set fields = (Set) messageFields.get(msgType); return fields != null && fields.contains(new Integer(field)); }

Unit test - add the following to DataDictionaryTest.testDictionary()

assertFalse(dd.isMsgField("UNKNOWN_TYPE", 1));



 Comments   
Comment by Toli Kuznets [ 20/Jun/07 ]

Great catch, Brad!
fixed in rev 684

Comment by Brad Harvey [ 21/Jun/07 ]

Credit for the catch goes to IntelliJ IDEA's code analysis





[QFJ-200] Session.enabled is accessed in both synchronized and unsynchronized contexts. Created: 20/Jun/07  Updated: 04/Jul/07  Resolved: 28/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Minor
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Access to Session.enabled is synchronized on Session everywhere except next() in the trunk. Is this intended?

In 1.1.x branch it appears that next() itself is synchronized.

I also notice that there's a synchronized (this) in Session's constructor. I think this is redundant?



 Comments   
Comment by Steve Bate [ 20/Jun/07 ]

Thanks, I'll change the "enabled" access to use isEnabled() instead. The idea behind synchronizing the nonfinal, nonvolatile variable set in the Session constructor is that even with the variable read synchronized, the variable value may not be visible to other threads if the set is not synchronized. I could also just call logon() which is synchronized and does effectively the same thing as setting enabled = true. Can you explain more why you thought the synchronization was redundant?

Comment by Brad Harvey [ 20/Jun/07 ]

Sorry you're absolutely correct, it does need the sync in the constructor. I was wondering how another thread could get a reference to an instance variable of an object yet to be constructed, but I forgot about it needing to flush back to main memory.

Comment by Brad Harvey [ 21/Jun/07 ]

... and on closer inspection, I see that Session registers itself in the static session map in the constructor, so that is how another thread could get a reference to it!

I was doing some reading to try and improve my understanding of issues like this and came across http://www.ibm.com/developerworks/java/library/j-jtp0618.html. It recommends not publishing 'this' references during a constructor. It would be possible to make adding to the session map the SessionFactory's responsibility, but that might break any user SessionFactory implementations. Maybe 2.0?

Comment by Steve Bate [ 21/Jun/07 ]

Yeah, the registration-in-constructor behavior is from the C++ port. I know it's not considered good practice. I like your suggestion about doing it in the factory, but I have the same concerns about altered behavior.

These are tricky issues. Like you mentioned, even without leaking "this" in the constructor, there is an issue of field visibility on multiprocessor machines. I like using test-driven techniques for software development, but many concurrency issues still seem to require visual inspection and analysis. I definitely appreciate another set of eyes to watch for these types of problems.

Comment by Brad Harvey [ 24/Jun/07 ]

In this case it was automated code analysis that picked up the problem. I had it look for threading issues since I was having some problems with some of the acceptance tests, but I see you've recently fixed those (locking around sequence number updates). It flagged a few other things, but this was the only one I thought could cause problems.





[QFJ-199] Add support for Oracle databases Created: 15/Jun/07  Updated: 28/Nov/07  Resolved: 28/Jun/07

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

Type: Improvement Priority: Critical
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None
Environment:

JDBC



 Description   

If the SessionQualifier is not used, it is left as an empty string.

Some database, e.g. Oracle, treat the empty string as a null value which is not allowed for the SessionQualifier column.

Therefore, I suggest to use a string with exactly one space instead of an empty string if the SessionQualifier is not set.

Steve, what do you think?



 Comments   
Comment by Steve Bate [ 15/Jun/07 ]

We currently don't have any Oracle SQL files for QFJ. Why can't we create those and allow null values for qualifier column? Are there other issues?

Comment by Jörg Thönnes [ 15/Jun/07 ]

(In reply to comment #1)
> We currently don't have any Oracle SQL files for QFJ.

Actually, I plan to add them soon. We now have an Oracle 10g Express installation here.

> Why can't we create those
> and allow null values for qualifier column? Are there other issues?

If the qualifier column is part of the primary key, the non-null constraint is automatically set.

Comment by Jörg Thönnes [ 15/Jun/07 ]

To summarize: If you confirm that the session qualifier is not needed as part of the primary key,
we can allow null values here. Then I would like to change the primary key definition for all supported
databases.

Is there any specific reason why the session qualifier must be part of the primary key?

Comment by Steve Bate [ 15/Jun/07 ]

Technically, it is part of the primary key. That's probably why the QF SessionID has "" instead of null for the default values. I think we should document this limitation of Oracle (treating "" as NULL) and suggest always using a session qualifier with Oracle rather than changing code related to all the other databases.

Comment by Jörg Thönnes [ 16/Jun/07 ]

OK, I will add a comment to configuration.html.

Comment by Wolfgang Grinfeld [ 28/Nov/07 ]

On version 1.3.0, the application still has trouble with Oracle JDBC Store: It crashes with the error:

java.lang.RuntimeException: java.sql.SQLException: ORA-01400: cannot insert NULL into ("WLGRINFELD"
."SESSIONS"."SESSION_QUALIFIER")

A workaround I thought possible follows:

drop index I_Messages;
drop table Messages;
CREATE TABLE Messages (
beginstring VARCHAR2(8) NOT NULL,
sendercompid VARCHAR2(64) NOT NULL,
targetcompid VARCHAR2(64) NOT NULL,
session_qualifier VARCHAR2(64) ,
msgseqnum INTEGER NOT NULL,
message VARCHAR2(4000) NOT NULL
);
create unique index I_Messages on Messages (beginstring, sendercompid, targetcompid, session_qualifier, msgseqnum);

drop index I_Sessions;
drop table Sessions;
CREATE TABLE Sessions (
beginstring VARCHAR2(8) NOT NULL,
sendercompid VARCHAR2(64) NOT NULL,
targetcompid VARCHAR2(64) NOT NULL,
session_qualifier VARCHAR2(64) ,
creation_time TIMESTAMP NOT NULL,
incoming_seqnum INTEGER NOT NULL,
outgoing_seqnum INTEGER NOT NULL
);
create unique index I_Sessions on Sessions (beginstring, sendercompid, targetcompid, session_qualifier);





[QFJ-198] Comment line ending file creates infinite loop in Session Settings Created: 15/Jun/07  Updated: 04/Jul/07  Resolved: 15/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Nick Fortescue Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None


 Description   

If you create a configuration properties file which ends with a comment line with no carriage return, SessionSettings will go into an infinite loop when it tries to read it. This is because of the comment line handing code in lines 502-510 in SessionSettings. A change could either be made to isNewLineCharacter(), (which might have unintended side effects with the other places it is called) or in the condition on the while loop.



 Comments   
Comment by Jörg Thönnes [ 15/Jun/07 ]

Yes, the check for end-of-file is missing.

isNewLineCharacter() is also used here:

private boolean isValueCharacter(char ch)

{ return !isEndOfStream(ch) && !isNewLineCharacter(ch); }

This is the only other occurence. But look! This is the condition we need!

So replacing the condition by isValueCharacter(ch) would solve this issue:

} else if (ch == '#') {
do

{ ch = nextCharacter(reader); }

while (isValueCharacter(ch));
return getToken(reader);
}

Comment by Jörg Thönnes [ 15/Jun/07 ]

Added unit test to verify the changed condition.





[QFJ-197] Provide option to disable the usage of the Proxool connection pooling Created: 15/Jun/07  Updated: 30/Jun/07  Resolved: 30/Jun/07

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

Type: Improvement Priority: Critical
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None
Environment:

JDBC



 Description   

It seems that Proxool can have issues with some JDBC implementations. E.g. Oracle does not play well with Proxool.

Therefore, I suggest to add an configuration option to disable the underlying Proxool connection pool.

This should be straightforward to implement

How do you think about this, Steve?



 Comments   
Comment by Steve Bate [ 15/Jun/07 ]

There is a setDataSource method on the JdbcLogFactory and JdbcMessageStoreFactory. If the data source is set explicitly (e.g. to the Oracle data source) then Proxool is not used. This was added because of the problems between Proxool and Oracle. Does that satisfy your needs?

Comment by Jörg Thönnes [ 15/Jun/07 ]

Basically, yes. But I also prefer to have an configurable option to do so.

Would that be very difficult?

Comment by Steve Bate [ 15/Jun/07 ]

I see a several issues with the configurable option. One is that the data sources often need special vendor-specific configurations. For example, the Oracle data source supports configurable prepared statement caching. This would be messy to support with the QF session settings file format. Another issue is that the factories are already created programatically so it seems natural to set the data source at that time. The last issue is that the data source might be created directly or it might be loaded from JNDI (in an application server context) or using some other technique (e.g., Spring injection). Again, the current settings file is not well suited for supporting these options.

We could add an option just to disable Proxool independent of whether a data source has been specified. However, I don't think this is the behavior most people will want since performance will suffer greatly without the connection pooling capabilities provided by most JDBC data sources.

Comment by Jörg Thönnes [ 15/Jun/07 ]

OK, Steve. We finally found the issue: If you use CHAR with Oracle, you should always fill up with spaces
up to the full length.

Other way round: If you define all character columns in the tables (specifically beginstring) as VARCHAR2, then it works fine.
(If you avoid to have empty session qualifiers.)

So I will close this issues.





[QFJ-196] SessionNotFound error during an active session Created: 13/Jun/07  Updated: 28/Jun/07  Resolved: 28/Jun/07

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

Type: Other Priority: Default
Reporter: Robert Jen Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NetBeans 5.5 JDK 1.6



 Description   

Hi,
I am new to this and I am doing something very simple, I think.

2 separate threads in the same class. In the 1st thread messages can be sent & received without any problem.
In the 2nd thread it throws a SessionNotFound error when calling sendToTarget();
The session is active, as my counterpart at the other end of the session confirmed.
Same class; same session; 2 separate threads.

I tried defining a separate initiator in the 2nd thread. That got a Config error

Thanks in advance for any help,
Robert



 Comments   
Comment by Robert Jen [ 14/Jun/07 ]

I changed the message from Message type to quickfix.fix42.NewOrderSingle type, and the error went away.
It seems SessionNotFound is the outbound error equivalent of inbound UnsupportedMessageType, at least in this case.





[QFJ-195] For an initiator to CME, fromAdmin() callback is not activated for seq-num too low on logon Created: 11/Jun/07  Updated: 28/Jun/07  Resolved: 28/Jun/07

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

Type: Other Priority: Default
Reporter: stacey ramsay Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello,

i tested my fixengine by creating an acceptor and an initiator session on the same machine. the initiator is configured to login to the acceptor session. They had different sequence numbers, so the logout() callback from initiator session is getting called. But the fromAdmin() callback is never activated. That´s confusing, because when initiating a session to an remote fix engine this works, I use to catch the fromAdmin() callback and reset the sequencenumbers by reading the remote message sequencenumber; internally it does not work. Why ?.

Regards
Thomas Hügel



 Comments   
Comment by stacey ramsay [ 11/Jun/07 ]

I "cloned" this issue, because I have the same issue, only when trying to have my initiator logon to CME. I get the following response from CME:

<20070611-14:16:03, FIX.4.2:P50187N->CME, incoming> (8=FIX.4.29=16735=534=76369=152=20070611-14:18:22.03049=CME50=G56=P50187N57=18758=Sequence number received lower than expected. Expected [2] Received 1. Logout forced.789=210=057)

Yet, my "fromAdmin(...)" method is never called. That is, I gave logging in all of my callback methods, but all I see is:

2007-06-11 14:14:14,626 DEBUG [sm_cme_dev100] [QFJ Timer] [CMEFIXConnection] - To-Admin, message (8=FIX.4.29=6535=A34=149=P50187N52=20070611-14:14:14.62656=CME98=0108=3010=117) received for session (quickfix.Session@eafb71)!
2007-06-11 14:14:15,538 DEBUG [sm_cme_dev100] [QFJ Message Processor] [CMEFIXConnection] - Logged-Out from session (quickfix.Session@eafb71)!

Any help is greatly appreciated. I am new to FIX in general, so apologies if I am missing something obvious.

Regeards,

  • Stacey
Comment by Steve Bate [ 11/Jun/07 ]

To use FIX effectively, it's very important to understand the how the protocol uses sequence numbers. For some reason, your session is expecting a sequence number of 2 and you are receiving a message with sequence number of 1 (and it's not flagged as a possible duplicate). This is a serious problem. The most common cause is that your session state is inconsistent with the counterparty state. This often happens during debugging sessions. You may need to reset the sequence numbers to synchronize your state with the counterparty. There are various ways to do this depending on the type of message store implementation you are using and the session configuration you have defined (for example, reset on logout behavior). A "reset" means the sequence numbers are set back to 1 for incoming and outgoing messages and any stored messages are cleared (no error recovery will be possible for earlier messages).

In your case, the CME is telling you it expected a sequence number of 2 and you are giving a sequence of 1. This means that you may have done a reset and the reset itself is why you are out of sync with the CME. You must adjust those sequence numbers to get back in sync.

As far as I can tell, the CME may have done a "log out" by just closing the connection. This isn't recommended by the spec, but it's not uncommon. You will receive the onLogout callback but no fromAdmin callback if the logout was not sent or possibly because the connection was closed before the logout was received (if it was actually sent).

Comment by stacey ramsay [ 12/Jun/07 ]

I have resolved this issue. I do understand everything commented on above (knock on wood and my concern was that the "fromAdmin(...)" method was not being invoked so that I could resolve the issue programmatically per the ECN's specs. However, the comments above regarding "reset(...)" made me realize that some recovery code was erroneously calling the "reset(...)" method which must have been clearing the event queues internally. Once I removed this erroneous code, I was able to recover from the condition just as the ECN specified.





[QFJ-194] Allow timezones in start/end time in session specification Created: 10/Jun/07  Updated: 04/Jul/07  Resolved: 10/Jun/07

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-193] Make code generation more flexible Created: 09/Jun/07  Updated: 04/Jul/07  Resolved: 10/Jun/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-192] Format generated message source code to adhere to Java indentation standards Created: 06/Jun/07  Updated: 04/Jul/07  Resolved: 11/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

Currently, the XSLT generating the quickfix.fix4x messages doesn't distinguish between inner classes and regular "outer" class when generating the getter/setter methods.

as a result, they are all indented the same way, making it harder to distinguish where a particular method lives.
See the thread for more info: http://www.nabble.com/QuoteRequest.set%28QuoteRequestType%29-and-various-other-set-methods-missing--tf3876614.html

Since the same XSLT template is used to generate getter/setter methods for outer and nested classes, it's not that easy to fix this in XSLT itself.

May be easier to fix it in the build directly, via a post-generation ANT task (something like Jalopy: http://jalopy.sourceforge.net/existing/plugin-ant.html).

Let me know if you know of any other code-formatting tools we can use instead, or if there may be a better way to achieve this, and i'll implement this in the build file.



 Comments   
Comment by Steve Bate [ 09/Jun/07 ]

Jalopy sounds like a good choice to me. I haven't used it myself but the documentation looks good.

Comment by Toli Kuznets [ 11/Jun/07 ]

Jalopy requires its own jar to do the ant task.
is there a particular place in the source tree where we can put it, or do we need to define that as an external dependency for the build to work? Not sure if you already have a special directory for jars that are needed for the build only, but not for QFJ operation itself.

Comment by Toli Kuznets [ 11/Jun/07 ]

Fix checked in revision 674.
added Jalopy formatting to the src-code generation phase
Upgraded the log4j from 1.2.4 to 1.2.14 (needed by Jalopy)
Added a src/main/lib/build subfolder for build-related libs
Currently, the Jalopy task is very minimal - we accept all defaults so we are
only getting basic formatting done.

Comment by Toli Kuznets [ 30/Jun/07 ]

Steve,

I am thinking we should do some more work on this. this step takes about 4-5 minutes, so i wonder if it'd be better if we added a flag to this that disables it.

or make it be run only when you do the "final final" release build. that way it wouldn't slow down the "ant clean test" cycles as much as it does now.

what do you think?





[QFJ-191] Add transactional behaviour to fromApp() callback Created: 06/Jun/07  Updated: 13/Aug/07  Resolved: 13/Aug/07

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

Type: Improvement Priority: Default
Reporter: Jörg Thönnes Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

Currently, if the fromApp() callback returns, ie the application message has been forwarded to the application layer,
the next expected sequence number of incoming message will be incremented.

If the Java application crashes inside the fromApp() callback, the sequence number stays as is, and after the next logon
the incoming sequence number is too low. Therefore, the message being processed in the fromApp() callback during
the crash will be refetched using a ResendRequest.

On the other hand, if some exception occurs inside the fromApp() callback (e.g. due to fatal processing errors in the application
layer) it would make sense to rollback the processed message by not incrementing the incoming sequence number.
This will cause the message to be redelivered using a ResendRequest.

To accomplish this the fromApp() callback should catch any exceptions (or at least some specific ones) and abstain from incrementing
the incoming sequence number.

As a sub-task prior to this issue I would see to separate the verify processing from the fromApp processing.

Further improvements would include full JTA (Java Transaction API) support (create another JIRA issue for this).



 Comments   
Comment by Steve Bate [ 10/Jun/07 ]

Hello,

I've investigated this issue and it appears the code already has the behavior you describe, at least for unchecked exceptions. An unchecked exception will propagate up to the communication layer, which will then discard the message. However, the sequence numbers will never have been incremented so the message will be resent when the next message arrives and a sequence gap is detected.

Is this the behavior you wanted? What problem were you having?

Thanks,

Steve

Comment by Jörg Thönnes [ 10/Jun/07 ]

Our application does some sort of message processing directly in the fromApp() callback.
If that fails due to an exception, I would like to have some sort of rollback.

If this already works for unchecked exceptions, I may just wrap any exception into a RuntimeException.
Would this work?

Cheers, Jörg

Comment by Steve Bate [ 10/Jun/07 ]

What type of exception was being thrown when the application failed? There are some checked/declared exceptions on the interface. If those are thrown, it depends on the type of message whether the expected sequence number is incremented or not.

Comment by Jörg Thönnes [ 11/Jun/07 ]

Now we implemented something like:

fromApp( ... ) {

try

{ processMessage( ... ); }

catch ( e )

{ throw new RuntimeException( text, e ); }

}

and it works as expected. Possibly a dedicated QF/J exception instead of the general RuntimeException
would be nicer.

Thanks a lot, Jörg

Comment by Steve Bate [ 27/Jul/07 ]

As I commented earlier, I believe the code has the desired behavior for RuntimExceptions. Can we close this issue?





[QFJ-190] User manual refers to Settings rather than SessionSettings Created: 05/Jun/07  Updated: 04/Jul/07  Resolved: 10/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Task Priority: Default
Reporter: Nick Fortescue Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None


 Description   

On the web page and downloaded docs, on page http://www.quickfixj.org/quickfixj/usermanual/usage/application.html
in the user manual the sample code at the bottom of the page refers to "Settings" when it should be "SessionSettings"






[QFJ-189] How to fix "Unsupported Message Type" error Created: 05/Jun/07  Updated: 08/Feb/12  Resolved: 09/Jun/07

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

Type: Other Priority: Default
Reporter: Robert Jen Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NetBeans 5.5 JDK 1.6.0



 Description   

Hi,

I am relatively new at this.

In FIX 4.2, after (1) defining a new tag in java codes and (2) adding the definition to the data dictionary, I now get "Unsupported Message Type" error (instead of "Tag Not Found" error - so I think I made progress

So now how do I solve the "Unsupported Message Type" error ?

Really appreciate any help at all.

Thanks



 Comments   
Comment by Steve Bate [ 06/Jun/07 ]

Hi Robert,

This is usually caused if you are using a MessageCracker and not overriding the method for handling the message you are receiving. The default implementation of all the message cracker methods throws an Unsupported Message Type exception.

Steve

Comment by Robert Jen [ 08/Jun/07 ]

Thanks Steve.
That seemed to have taken care of it.
Much appreciated.

Comment by nanaji [ 22/Feb/11 ]

Hi Steve,

You are awesome. You made my day. It works for me.

Thanks
Jonnadula Nanaji.

Comment by Pradeepkumar [ 08/Feb/12 ]

INITIATOR MESSAGE:
Initiator ToApplication Message:8=FIXT.1.19=9935=BE34=249=CLIENT52=20120208-04:32:57.74456=PLATFORM369=1553=Chilla554=S923=DT12345924=110=148 SessionID:FIXT.1.1:CLIENT->PLATFORM
<20120208-04:32:57, FIXT.1.1:CLIENT->PLATFORM, outgoing> (8=FIXT.1.19=9935=BE34=249=CLIENT52=20120208-04:32:57.74456=PLATFORM369=1553=oooooo554=******923=DT12345924=110=148)
<20120208-04:32:57, FIXT.1.1:CLIENT->PLATFORM, incoming> (8=FIXT.1.19=10935=j34=249=PLATFORM52=20120208-04:32:57.74456=CLIENT369=245=258=Unsupported Message Type372=BE380=310=009).

ACCEPTOR MESSAGE:

Acceptor FromApp8=FIXT.1.19=9935=BE34=249=CLIENT52=20120208-04:32:57.74456=PLATFORM369=1553=Chilla554=S923=DT12345924=110=148
<20120208-04:32:57, FIXT.1.1:PLATFORM->CLIENT, error> (Rejecting invalid message: quickfix.UnsupportedMessageType: 8=FIXT.1.19=9935=BE34=249=CLIENT52=20120208-04:32:57.74456=PLATFORM369=1553=oooooo554=******923=DT12345924=110=148)
<20120208-04:32:57, FIXT.1.1:PLATFORM->CLIENT, error> (Reject sent for Message 2: Unsupported Message Type)

Yes i agreed Mr.Robert
Is there any way to solve the problem.
Thanks
PradeepKumar





[QFJ-188] SSL connections don't support sending a certifcate to outgoing connections Created: 02/Jun/07  Updated: 04/Jul/07  Resolved: 16/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File ssl-rev666.patch     Text File ssl.patch    

 Description   

Some brokers require to send SSL certificates for outgoing connections (ie from QFJ client to SSL FIX destination on the server side)

Currently, as of 1.1.0, QFJ only supports sending certs on the "accepting" side of a connection, but not on a intiating side.

I'm attachinga patch that allows for the initiating connection to send out certs as well, ie to specify a keystore name/password for the initating SSL context.



 Comments   
Comment by Toli Kuznets [ 02/Jun/07 ]

proposed patch with changes to be applied in core.
Combines both AcceptorSSLContextFactory and InitiatorSSLContextFactory into an SSLContextFactory that's used for both acceptor/initator connections.

Comment by Toli Kuznets [ 08/Jun/07 ]

First patch is a diff to 1.1.0 codebase
current one is based off the trunk, rev666

Comment by Toli Kuznets [ 11/Jun/07 ]

Initial set of code checked in with rev 675. need to add more acceptance tests

Comment by Jörg Thönnes [ 15/Jun/07 ]

Toli, did you made any progress with your acceptance tests?

Cheers, Jörg

Comment by Jörg Thönnes [ 15/Jun/07 ]

Toli, did you made any progress with your acceptance tests?

Cheers, Jörg

Comment by Toli Kuznets [ 15/Jun/07 ]

not yet, sorry, got sidetracked by things at work.
will try to have them ready soon.

Comment by Jörg Thönnes [ 15/Jun/07 ]

never mind, toli. Actually I get always "sidetracked" by things at work.
But this is our job.

Since I need some of the planned 1.1.1 feature for a customer installation, I am eager to see it released.

Cheers, Jörg

Comment by Toli Kuznets [ 16/Jun/07 ]

So i think it's not an acceptance test that we need but another testcase in quickfix.mina.ssl.SecureSocketTest that verifies that the "client" initiator also sets up a valid SSL context that has the specified keystore/pwd.

the SecureSocketTest does go through the new code i've written. the major change to fix this bug was to have the initiator code to create an SSLContext with the keyManager instead of null as before, and the SecureSocketTest goes through this code.

The test i ended up writing is a bit of an anti-test. There's no easy to get into the data structures of the client initiator code to verify that the right SSL context is created.

so instead, i supply a bogus password that causes an error during the client initiator start since the SSL context can't be initialized. That verifies that the code goes through the same codepath of using/initializing the keystoreManagers when creating the SSL context (which was the change) so i think that may be enough.

Steve, let me know if you can think of better ways to test this.

checked in rev

Comment by Toli Kuznets [ 16/Jun/07 ]

unit test checked in rev 679





[QFJ-187] Invalid constant values in ExecType class Created: 01/Jun/07  Updated: 15/Nov/12  Resolved: 02/Jun/07

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

Type: Bug Priority: Minor
Reporter: Tommy Hannon Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

QuickFix/J 1.1.0



 Description   

The following values are incorrectly defined (according to FIX spec.) for ExecType (150)...

public static final char PARTIAL_FILL = '1';
public static final char FILL = '2';

These values need to be removed.



 Comments   
Comment by Steve Bate [ 02/Jun/07 ]

In the current QF/QFJ design, the same field objects are used for all versions of FIX. Even though the enums you mentioned were replaced in FIX 4.4, they need to remain in the data dictionary for earlier versions of the spec (all versions use the FIX 4.4 fields).





[QFJ-186] Session.isLogoutTimedOut() calls SessionState.isLogonTimedOut() Created: 30/May/07  Updated: 04/Jul/07  Resolved: 01/Jun/07

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

Type: Bug Priority: Default
Reporter: Chris Audley Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The method isLogoutTimedOut() in Session calls isLogonTimedOut() instead of isLogoutTimedOut() on SessionState






[QFJ-185] Improper use of synchronized keyword Created: 30/May/07  Updated: 04/Jul/07  Resolved: 01/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Major
Reporter: Qiyan Li Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

All



 Description   

In the quickfix.SocketInitiator class, lines [77, 84] are as follows (version 1.1.0 source code):

private void initialize() throws ConfigError {
synchronized (isStarted) {
if (isStarted == Boolean.FALSE)

{ initiateSessions(eventHandlingStrategy); }

isStarted = Boolean.TRUE;
}
}

which incorrectly uses the synchronized keyword because Java locks on objects not variables. In other words, threads would lock on Boolean.TRUE and Boolean.FALSE, which could in turn cause deadlocks.



 Comments   
Comment by Steve Bate [ 30/May/07 ]

Good catch. That's been there for about 1.5 years now. I don't even remember why it was done. It looks like a normal synchronization method would be fine. I'll make the changes in 1.1.1.





[QFJ-184] Improvement to session settings (multibyte) Created: 24/May/07  Updated: 04/Jul/07  Resolved: 07/Jun/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: File quickfixj110.patch    

 Description   

Hi all!

I work as an engineer in a local trading software company in Taiwan.
In our solution for outbound trading, we use QuickFIX/J for
communication with FIX gateways. It works fine for us most of the time,
thanks for the great work, developers!

I find some problems with weekly session in QuickFIX/J in our test
environment these days though:

1. I can't confiure a weekly session using SessionSettings with
an InputStream object (in my case, a FileInputStream object),
because SessionSettings doesn't work well with multibyte characters,
and the name of weekdays in our locale (zh-TW) is in multibyte
characters. Therefore I change the code to use InputStreamReader to read
characters instead.

2. When parsing name of weekdays in class DayConverter, only the leading
two characters are used for comparison, maybe for easier configuration.
But the leading two characters in our locale is all the same for the
7 weekdays, thus it always match the first one (Sunday).
I would suggest not just using the leading two characters for
comparison, it will still work fine for people using only two characters
to confiure.

3. Weekdays (StartDay, EndDay) is always in UTC, even when I set
TimeZone to our local one. For example:

TimeZone=Asia/Taipei
StartTime=06:45:00
EndTime=06:44:59

If I set both StartDay and EndDay to Wednesday (the equivalent,
localized one, in multibyte characters, of course
it would be a weekly session of from Wednesday 22:45:00 UTC
to Wednesday 22:44:59 UTC,
instead of from Tuesday 22:45:00 UTC to Tuesdasy 22:44:59 UTC.
(Note: Wednesday 06:45:00 in Taipei is Tuesday 22:45:00 UTC)

I made some changes to solve the 3 problems above in my own way,
the patch is attached with this mail.
Hope it can be adoped by our developers or help somebody else

Regards,
yongjhen


Yong-Jhen Hong ([email protected])
Senior Software Engineer
Financial Solution Dept.
ICE Technology Corp.
Taiwan



 Comments   
Comment by Steve Bate [ 07/Jun/07 ]

I was able to patch the settings to support multibyte. However, the session schedule patch was too different from the trunk to patch reliably. I've asked the requestor for a patch against the trunk but I haven't received a response. I'm going to resolve this issue and if the session schedule patch is submitted, we'll create a new RFE for that.





[QFJ-183] All incoming messages fromApp are being rejected Created: 24/May/07  Updated: 07/Jun/07  Resolved: 07/Jun/07

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

Type: Other Priority: Major
Reporter: Robert Jen Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NetBeans 5.5
jdk 1.6



 Description   

Thanks for the wonderful quickfixj, and thanks in advance for shedding any light on this.

When receiving incoming messages which conform to spec, my engine rejects all of them. It's the same problem with two similar but separate projects (a 4.2 & a 4.3) with errors like these:

(Message 3 Rejected: Tag not defined for this message type:64)
(Message 46 Rejected: Tag not defined for this message type:55)
(Message 32 Rejected: Tag not defined for this message type:647)
(Message 5 Rejected: Unsupported Message Type)

I have user-defined these problem tags, still same error. My user-defined tags work as per messages I send out.
I get the "tag not defined" or "unsupported message type" or "tag not found" errors depending on how I tweak the data dictionary, but always an error.

Again many thanks in advance,



 Comments   
Comment by Steve Bate [ 25/May/07 ]

Just for clarification, you've defined the problem tags but have you added them to definitions of the messages that will use them?

Comment by Robert Jen [ 28/May/07 ]

On the 4.3 project, the "problem tags" are clearly on spec & defined in data dictionary & require no user definition. So I am puzzled by the error.

On the 4.2 project, the initial error is: Tag Not Found, even after (1) adding the user definition in the body of the java codes. On top of that I manually added the "problem tag" to the data dictionary (2) in the numerical tag definition, then I got a Tag Not Defined error. Then I also added the "problem tag" to the data dictionary (3) in the message definition sesion, which gave me an Unsupported Message Type error.

Thanks again in advance





[QFJ-182] JMX Connector object names are not unique Created: 22/May/07  Updated: 04/Jul/07  Resolved: 25/May/07

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

Type: Bug Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello,

the current implementation of ConnectorJMXExporter.java does only work if you dont use a second connector. The name "type=Connector,role=Initiator" is to generic because the second connector has allways the same name, the error would look like the following:

22.05.2007 17:49:24 org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter export
SCHWERWIEGEND: Failed to export connector MBean
javax.management.InstanceAlreadyExistsException: org.quickfixj:type=Connector,role=Initiator
at com.sun.jmx.mbeanserver.RepositorySupport.addMBean(RepositorySupport.java:452)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.internal_addObject(DefaultMBeanServerInterceptor.java:1410)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:936)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:337)
at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:497)
at org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter.export(ConnectorJmxExporter.java:56)
at org.quickfixj.jmx.JmxExporter.export(JmxExporter.java:60)

My approach was to add the name of the configFile in the JMXExporter.export() function, this is probably to simple in case that the configfiles are not in the same directory. Must be a better way.

****
public void export(MBeanServer mbeanServer, SessionConnector connector, String configFileName) {
try {
ConnectorAdmin connectorAdmin;
if (connector instanceof AbstractSocketAcceptor)

{ connectorAdmin = new SocketAcceptorAdmin((AbstractSocketAcceptor) connector, sessionExporter); }

else if (connector instanceof AbstractSocketInitiator)

{ connectorAdmin = new SocketInitiatorAdmin((AbstractSocketInitiator) connector, sessionExporter); }

else

{ throw new QFJException("Unknown connector type: " + connector.getClass().getName()); }

//changed: ObjectName connectorName = getConnectorName(connector);
ObjectName connectorName = getConnectorName(connector, configFileName);

mbeanServer.registerMBean(connectorAdmin, connectorName);
ArrayList sessionIDs = connector.getSessions();
for (int i = 0; i < sessionIDs.size(); i++)

{ SessionID sessionID = (SessionID) sessionIDs.get(i); sessionExporter.export(mbeanServer, Session.lookupSession(sessionID), connectorName, connector.getSettings()); }

} catch (Exception e)

{ log.error("Failed to export connector MBean", e); }

}
//private ObjectName getConnectorName(SessionConnector connector)
private ObjectName getConnectorName(SessionConnector connector, String configFileName)
throws MalformedObjectNameException

{ ObjectNameFactory nameFactory = new ObjectNameFactory(); nameFactory.addProperty("type", "Connector"); nameFactory.addProperty("role", connector instanceof Acceptor ? "Acceptor" : "Initiator"); //changed nameFactory.addProperty("configFileName", configFileName); return nameFactory.createName(); }

***

The jmx export im my code looks like

jmxExporter = new JmxExporter(ManagementFactory.getPlatformMBeanServer());
jmxExporter.export(acceptor, this.getConfigFile());

instead of

jmxExporter = new JmxExporter(ManagementFactory.getPlatformMBeanServer());
jmxExporter.export(acceptor);

I checked with jconsole, works.

Regards
Thomas Hügel






[QFJ-181] Problem with multiple qualifier settings in JMX object name Created: 22/May/07  Updated: 04/Jul/07  Resolved: 25/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello,
when exporting an jmx session with an session qualifier, the code in SessionJmxExporter.java, sets the property "qualifier" twice which causes the following exception:

22.05.2007 16:21:52 org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter export
SCHWERWIEGEND: Failed to export connector MBean
javax.management.MalformedObjectNameException: key `qualifier' already defined
at javax.management.ObjectName.addProperty(ObjectName.java:664)
at javax.management.ObjectName.construct(ObjectName.java:559)
at javax.management.ObjectName.<init>(ObjectName.java:1304)
at javax.management.ObjectName.getInstance(ObjectName.java:1187)
at org.quickfixj.jmx.mbean.ObjectNameFactory.createName(ObjectNameFactory.java:37)
at org.quickfixj.jmx.mbean.session.SessionJmxExporter.createSessionName(SessionJmxExporter.java:50)
at org.quickfixj.jmx.mbean.session.SessionJmxExporter.export(SessionJmxExporter.java:24)
at org.quickfixj.jmx.mbean.connector.ConnectorJmxExporter.export(ConnectorJmxExporter.java:60)
at org.quickfixj.jmx.JmxExporter.export(JmxExporter.java:60)

I changed the code in SessionJMXExporter.java to

private void addSessionIdProperties(SessionID sessionID, ObjectNameFactory nameFactory)

{ nameFactory.addProperty("beginString", sessionID.getBeginString()); nameFactory.addProperty("senderCompID", sessionID.getSenderCompID()); nameFactory.addProperty("targetCompID", sessionID.getTargetCompID()); //wrong: nameFactory.addProperty("qualifier", sessionID.getSessionQualifier()); nameFactory.addProperty("qualifiersess", sessionID.getSessionQualifier()); }

and the exporting works.

Regards
Thomas Hügel



 Comments   
Comment by Steve Bate [ 22/May/07 ]

Thanks for the report.





[QFJ-180] acceptor and initiator on localhost; fromAdmin() callback is not activated Created: 21/May/07  Updated: 07/Jun/07  Resolved: 07/Jun/07

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

Type: Other Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hello,

i tested my fixengine by creating an acceptor and an initiator session on the same machine. the initiator is configured to login to the acceptor session. They had different sequence numbers, so the logout() callback from initiator session is getting called. But the fromAdmin() callback is never activated. That´s confusing, because when initiating a session to an remote fix engine this works, I use to catch the fromAdmin() callback and reset the sequencenumbers by reading the remote message sequencenumber; internally it does not work. Why ?.

Regards
Thomas Hügel



 Comments   
Comment by Steve Bate [ 25/May/07 ]

I don't know of any reason why this would behave differently if the initiator and acceptor are on the same machine, or even in the same JVM. I assume the automatic logout is caused by the incoming sequence number being too low. The doTargetTooLow() method in the Session generates the logout. The logout is sent using the sendRaw() method which performs the callback. Is there any possibility you are seeing a thread deadlock? You could look at a thread dump to find out. Java 6 will automatically identify deadlocks in the thread dump.





[QFJ-179] Improve session thread synchronization Created: 19/May/07  Updated: 04/Jul/07  Resolved: 19/May/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current approach is safe, but too prone to deadlocks.



 Comments   
Comment by Steve Bate [ 19/May/07 ]

I've redesigned the thread synchronization in the session. The session state is now fully synchronized using the session intrinsic lock. I've added tests to ensure that no locks are held during quickfix.Application callbacks. I also do not hold a lock when invoking MINA for output operations. This should eliminate many potential sources of deadlock between MINA, the quickfix.Session, and application threads.

I've also made the dictionary in the session final. This creates a minor functional incompatibility with QF C++. If someone has a use case for modifying the Session's data dictionary after the session is created then I'm open to suggestions.





[QFJ-178] Session scheduling/Start of day operation Created: 18/May/07  Updated: 24/May/07  Resolved: 24/May/07

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

Type: Other Priority: Default
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Linux



 Description   

Hello,

i played a bit around with the session scheduling feature; the settings "StartTime", "EndTime". I discovered (in the message logs), that Quickfix only suddenly stops the session when "EndTime" is reached, but does not send an logout to the remote FIX Engine.
When starting the session, quickfix initiates an login which is denied because the remote quickfix engine has reset the sequence numbers and sends me the message "Your session needs Start-of-day". I could set the ResetOnLogon flag, but this is not really an "start of day" operation; if i would logout during the day it would reset the sequence-numbers as well.
Why does quickfix don´t send an logout when the "EndTime" is reached ?. Ho would i implement a "Start-of-day" operation, only reset sequence numbers on "StartTime" ?.

Regards
Thomas



 Comments   
Comment by Steve Bate [ 19/May/07 ]

QFJ is designed to send a logout, if possible. When you say the session "stops", do you mean the connection is closed? One possibility is that the counterparty closed their connection at the same time and so the logout cannot be sent.

FIX sessions are usually either daily or weekly. The "start of day" is really start of session. I don't recognize the specific message you describe above, so I assume it's coming from the C++ QuickFIX. When configuring your session schedule, do not set the start and end day if you want daily sessions. Only set the start and end time (UTC time zone). If you set the start and end day, the session is a weekly session and startDay/startTime and endDay/endTime are used together to define the weekly schedule.





[QFJ-177] Provide support classes for inserting authentication information in logon messages Created: 14/May/07  Updated: 17/Jun/20  Resolved: 14/May/20

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

Type: Improvement Priority: Minor
Reporter: Toli Kuznets Assignee: Christoph John
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File logon.patch    

 Description   

What do you think of modifying the logic for sending Logon messages to optionally include the username/password?

While it's possible use QFJ to construct our own Logon message and send it out in the application logic, it's rather non-trivial to do so.

I propose to add 2 new parameters to SessionSettings (username/password) that, if exist (and if DataDictionary has these fields for the given FIX version) would include the username/password in the logon message.

See the attached patch. I couldn't figure out how to create the acceptance tests for it. I also realize that we may want to add extra logic to make sure debug messages don't print the password fields, and maybe a better way to encrypt/obfuscate the password.



 Comments   
Comment by Steve Bate [ 19/May/07 ]

What do you think about doing this at the application level? Typically someone would do it in an application callback:

http://www.quickfixj.org/confluence/display/qfj/Implementing+Custom+Logons

However, we could create an AuthenticatingApplication implementation to implement this behavior or create some type of utility class that can be used with another concrete Application to easily implement the behavior.

Comment by Toli Kuznets [ 21/May/07 ]

Steve, i see you point.
I was originally thinking that it would make sense to do it in the Session since the values (username/password) may be coming from the same config file as the rest of the session descriptor.
However,that may not be the case, as people may not want to store the password in a plain-text config file.

So i'm actually ambivalent about this now - I can easily be convinced that this feature is better left up to individual implementors to be done in the toAdmin() callback.

Having an abstract AuthenticatingApplication is a good idea, it could be something that has to implement a getUser() and getPassword() function and would know how to implement the logon correctly.
Then we take care of doing the logon logic, and the user is still required to implement getPassword() which will enable them to do it in a secure way.

I'm leaving the decision up to you - we can close it as "won't fix" and leave as-is, or we can change it to create the AuthenticatingApplication instead.

Comment by Steve Bate [ 21/May/07 ]

The user could provide the SessionSettings to the authenticated application implementation or extract the user name and password from the SessionSettings and inject them into the application. I like the idea of having some ready-to-go capabilities at the application level. At the same time, I'd like to keep the Session itself as lean and simple as possible.

Comment by Toli Kuznets [ 21/May/07 ]

I agree. So let's brand this as an RFE to create an easy-to-use out-of-the-box AuthenticatingApplication subclass.

Comment by Christoph John [ 14/May/20 ]

Closing this due to https://github.com/quickfix-j/quickfixj/pull/285
Not quite an AuthenticatingApplication but given the fact that no-one implemented this in all these years we've aimed for a simple solution. Users requiring a more sophisticated approach could still do this in their toAdmin() method.





[QFJ-176] BenchmarkSecurityIDSource valid value constants missing Created: 11/May/07  Updated: 04/Jul/07  Resolved: 25/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Improvement Priority: Minor
Reporter: Tommy Hannon Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

BenchmarkSecurityIDSource needs constants for valid values like SecurityIDSource has. Thanks.






[QFJ-175] need help Created: 11/May/07  Updated: 19/May/07  Resolved: 19/May/07

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

Type: Other Priority: Default
Reporter: paritosh pandey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi All
This is with regards to Steve's article on http://www.quickfixj.org/confluence/display/qfj/Using+Message+Metadata.

Actaully i just want to know one thing.Whenever i pass a message to QuickFix and the message is returned as a field map,the sequence is not the original one as i have sended , rather it is arranged according to the increasing order of tag numbers.Say for eg --in ur article the message which is used contains the tag 38=9..which is a field.It is positioned at the end of body in the message but by using the code given ...it gets printed according to the position of the ascending order of tag number.
Does position doesn't matters in quickFix or is there any code to get the sysout in the same sequence in which the mesage was supplied.
Any info on this will be of great help as i am new to this FIX world.
Waiting for ur response

Thanks and Regards
Paritosh Pandey



 Comments   
Comment by Steve Bate [ 19/May/07 ]

Hello,

The FIX specification only requires ordered fields in repeating groups (and a few header fields). The body fields are unordered. The internal data structures used by QFJ do not preserve the order that the fields were set in the body of the message.

Steve





[QFJ-174] App Callback, toXML(Dictionary) function does not contain repeating groups Created: 10/May/07  Updated: 04/Jul/07  Resolved: 19/May/07

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

Type: Bug Priority: Major
Reporter: Thomas Hügel Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Linux, OSX



 Description   

When getting a message from fromApp() Callback, it seems, that the message does not contain the repeating groups. I´m using the toXML(Dictionary) function and have added some debug statements to the core library. The message.toString() function does not show up the repeating groups as well. If i read the message back from MessageStore, then the message.toXML(Dictionary) does list the repeating groups. To get the full message i have to reread the message from MessageStore (in my case a FileStorage).



 Comments   
Comment by Steve Bate [ 10/May/07 ]

If the repeating groups are not present in message.toString() then they probably don't exist in the message. The toString() method is used for all message formatting and it's very heavily tested. The typical cause of the groups missing from a parsed message is that a data dictionary was not used when parsing the message. This could be because a data dictionary was not specified for message construction (if the message is constructed directly from a string) or because no data dictionary was specified for a session configuration.

If you are sure you are using a data dictionary in your session configuration or when parsing a message directly, can you include a small example program that demonstrates the problem you are seeing?

Thanks,

Steve

Comment by Thomas Hügel [ 10/May/07 ]

Steve,

well the flag UseDataDictionary was set to "N" because the ICAP Provider uses some Values not supported in FIX 4.4. But the message Store has the groups, why do they not show up in the message directly.

If i set UseDataDictionary to Y, the messages are getting rejected and i do not receive them in the fromApp() callback. What do you recommend ?. Should i edit a custom FIX44.xml file or is there any other way ?.

Regards
Thomas Hügel

Comment by Steve Bate [ 10/May/07 ]

The raw message strings are put into the message store. The message objects passed to the application are generated by parsing the raw message strings and the groups will not be parsed correctly without a data dictionary.

If your counterparty uses nonstandard fields, you can modify the FIX44.xml to include the additional fields. For example, you can copy the FIX44.xml, modify it for ICAP (e.g. ICAP_FIX44.xml) and use that in the session.

Comment by Steve Bate [ 19/May/07 ]

I've improved the XML formatting a bit. Remember, this is primarily to be used for simple debugging or diagnostic purposes. It's not FIXML.





[QFJ-173] SessionID constructor Created: 09/May/07  Updated: 04/Jul/07  Resolved: 10/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Improvement Priority: Minor
Reporter: Tommy Hannon Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Define new constructor(s) for SessionID that will accept a SessionID "string" as a parameter.



 Comments   
Comment by Steve Bate [ 10/May/07 ]

The constructor has been added.





[QFJ-172] SessionID.fromString(...) not setting 'id' property Created: 09/May/07  Updated: 04/Jul/07  Resolved: 10/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Major
Reporter: Tommy Hannon Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

'fromString' method did not completely work as the 'id' property is not set. I confirmed this by looking at the source code. IMHO, fromString(...) should be a static method returning a new SessionID object.



 Comments   
Comment by Tommy Hannon [ 09/May/07 ]

I have confirmed this workaround...

SessionID sessionID = new SessionID();
sessionID.fromString(sessionIDString);
sessionID = new SessionID(sessionID.getBeginString(), sessionID.getSenderCompID(), sessionID.getTargetCompID());

Comment by Steve Bate [ 10/May/07 ]

I added some unit tests and fixed the problem. Thanks for the report.





[QFJ-171] MessageFactory cannot create certain groups Created: 01/May/07  Updated: 04/Jul/07  Resolved: 01/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.1.0
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Naresh Bhatia Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows


Issue Links:
Relates
is related to QFJ-154 Modify MessageFactory interface to ad... Closed

 Description   

MessageFactory returns a null from the following signature for certain groups:

public Group create(String beginString, String msgType, int correspondingFieldID);

For example,

messageFactory("FIX.4.4", MsgType.ORDER_SINGLE, NoPartyIDs.FIELD);

returns a null.

I think the problem is with the code generation of message factories. For example, the relavant code in quickfix.fix44.MessageFactory does not include a check for NoPartyIDs.FIELD, although this is a group defined for the NewOrderSingle message type.

if("D".equals(msgType)) {
switch(correspondingFieldID)

{ case quickfix.field.NoAllocs.FIELD: return new quickfix.fix44.NewOrderSingle.NoAllocs(); case quickfix.field.NoTradingSessions.FIELD: return new quickfix.fix44.NewOrderSingle.NoTradingSessions(); case quickfix.field.NoUnderlyings.FIELD: return new quickfix.fix44.NewOrderSingle.NoUnderlyings(); }

}

It is possible that this code is not generated because NoPartyIDs is part of the "Parties" component defined within the NewOrderSingle message.



 Comments   
Comment by Steve Bate [ 10/May/07 ]

Toli, have you had any time to look at this issue?





[QFJ-170] Repeating group not parsed correctly Created: 01/May/07  Updated: 10/May/07  Resolved: 10/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: 1.1.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Naresh Bhatia Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows


Attachments: File FixMessageFactoryTest.java    

 Description   

The attached program creates a NewOrderSingle message with a NoAllocs group repeating twice. It converts the message to a string and then parses the string back to a message. Unfortunately one instance of the repeating group is lost, only one instance shows up when the parsed message is converted back to a string. I really hope that I am overlooking something!



 Comments   
Comment by Naresh Bhatia [ 01/May/07 ]

BTW, here's the output from the sample program. The two message strings should be equal, but they are not:

Message1: 8=FIX.4.49=14135=D34=10049=COOLTRD52=20070501-00:17:2556=MA11=ORDER_3091738=100.540=154=155=IBM60=20070501-00:17:2578=279=Account179=Account210=205

Message2: 8=FIX.4.49=12935=D34=10049=COOLTRD52=20070501-00:17:2556=MA11=ORDER_3091738=100.540=154=155=IBM60=20070501-00:17:2578=279=Account210=039

Note that Account1 is missing from Message2.

Comment by Steve Bate [ 10/May/07 ]

To parse a message with a repeating group, you must include a data dictionary. The data dictionary provides metadata to know which fields are part of repeating groups. Your test program did not use a DD when parsing the message. After adding the DD argument to the message constructor, the test worked correctly.

Comment by Steve Bate [ 10/May/07 ]

By the way, thanks for the test case.

Comment by Naresh Bhatia [ 10/May/07 ]

Thanks Steve. It works beautifully after adding the data dictionary. Perhaps this would be a useful tip to add to the docs.





[QFJ-169] Message parsing fails on messages with invalid fields in repeating groups with non-obvious errors Created: 28/Apr/07  Updated: 27/Jul/17  Resolved: 05/Apr/17

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.6.4

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Christoph John
Resolution: Fixed Votes: 2
Labels: None

Attachments: Text File qfj169.patch    
Issue Links:
Duplicate
is duplicated by QFJ-269 validate method in DataDictionary doe... Closed
is duplicated by QFJ-909 Unexpected Behaviour for ValidateInco... Closed
Relates
relates to QFJ-168 Add repeating group validation in mes... Closed
is related to QFJ-791 An unexpected field in a repeating gr... Closed

 Description   

When you create a Message from incoming string that has invalid fields in the repeating group, the message parsing code will fail with a non-obvious (and not helpful) error. This works when you have 2 or more groups and never on just 1 group.

Create a message and add a group to it, and add an invalid field to the first group.
Add group to the message
Add another (valid or invalid) group to the message.

Then try to "roundtrip" (ie do new Message(origMessage.toString(), dictionary)) and create a new message from the old one.
The creation will fail, and the error you get is "Tag not defined for this message" - but the tag you get is the first tag after the invalid one in the repeating group, not the actual tag that's invalid.

What happens is that in Message.parseGroup() function when are in a repeating group, when we find the first invalid field we essentially "pushback" the invalid field and get out of the group parse, skipping any other group fields.

another Bug: we report back the initially calculated group count, not the # of groups we actually parsed

We then add the pushed-back field to the new message, and try to inspect the next field - which belongs in the repeating group and not in message itself.
So the parser throws an exception in that case, saying that field is invalid, while it really should've given an error about the previous field.

See the attached patch for unit test.

The fix is non-trivial - you have to know whether the repeating groups are over and you just got the next "real message" field, or if it's just an invalid field for the repeating group.
Also, you can't just check if the pushed-back field doesn't belong to the parent message, since it may, but you may still have repeating groups coming up.

Perhaps the best way to fix it is to check if the "offending" field is a field in the parent's message type, and if it's not then report an error. You'd do it before pushing the field back. May need to pass the parent's message type through to parseGroup, in case we have groups nested inside other groups.



 Comments   
Comment by Toli Kuznets [ 28/Apr/07 ]

validation may catch this earlier

Comment by Toli Kuznets [ 02/May/07 ]

Patch containing the unit test exhibiting the failure
patch in core/ directory

Comment by Toli Kuznets [ 02/May/07 ]

Removed the code from the bug and added it as a patch attachments, should make the bug cleaner and easier to read.

Comment by Christoph John [ 05/Apr/17 ]
  • extended Message.parseGroup() to accept unknown fields in repeating groups
    • if validation is disabled (either completely or depending on ValidateUserDefinedFields or AllowUnknownMsgFields)
    • if the field encountered is not a trailer or message field
  • moreover, if validation is enabled, the incorrect field will be reported (not the next field that is encountered)
  • added unit tests from QFJ issues
  • removed synchronization from FieldException in Message since it seemed unnecessary




[QFJ-168] Add repeating group validation in messages Created: 28/Apr/07  Updated: 07/Aug/08  Resolved: 03/Feb/08

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

Type: New Feature Priority: Default
Reporter: Toli Kuznets Assignee: Unassigned
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-279 Fields in groups will not be checked. Closed
Relates
is related to QFJ-169 Message parsing fails on messages wit... Closed

 Description   

Seems that Message.validate() method skips the validation of repeating groups. it validates the # of groups, but not the fields inside the group itself.

Would be nice to have the groups be validated.



 Comments   
Comment by Steve Bate [ 10/May/07 ]

To clarify, you want to verify the repeating group field order. Is that right?

Comment by Toli Kuznets [ 10/May/07 ]

Order, and maybe also to make sure that no invalid fields (something that doesn't belong in that particular message group) are present.

Comment by Steve Bate [ 10/May/07 ]

The invalid field issue is a bit tricky because as soon as we see a field that's not part of the group, we assume we are finished with the repeating groups and are starting to parse regular message fields again.

Comment by Toli Kuznets [ 10/May/07 ]

I agree - that's why i linked it to 169, which is exactly what you are describing.
and why i figured that you (steve) would be better equipped to fix both of these since the parsing code is non-trivial





[QFJ-167] SessionNotFound, while connection is still active Created: 27/Apr/07  Updated: 11/Feb/09  Resolved: 11/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.1.0
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Andre Mermegas Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

java 1.5, windows



 Description   

I'm getting this now randomly often, i think the problem is Session migrating from HashMap to WeakHashMap and then losing reference due to weak collection strategy.

2007/04/27 15:39:20:437 EDT [ERROR] TransportSession - <quickfix.SessionNotFound>quickfix.SessionNotFound
at quickfix.Session.sendToTarget(Session.java:421)



 Comments   
Comment by Steve Bate [ 27/Apr/07 ]

I've looked into this and it actually appears the WeakHashMap will not ever release it's references (a different and opposite bug). The connectors and the WeakHashMap have strong references to the sessions and the session references the session ID so the key will never garbage collected. I need to investigate this further but it doesn't appear it would be causing the symptoms you describe.

Comment by Andre Mermegas [ 27/Apr/07 ]

hrm. somehow the session is removed from the map, i stepped into the source and saw it was empty even though heartbeats and connection was still up. thats what led me to weakhashmap idea from my brief look at Session source. I'll mess around some more as well and let you know what i come up with.

have you ever seen this before in your usage?

Comment by Steve Bate [ 10/May/07 ]

Do you have any more information on this issue?

Comment by Andre Mermegas [ 10/May/07 ]

I changed the type in Session.sessions from weakhashmap to hashmap and havent had any problems since.

Comment by Steve Bate [ 11/May/07 ]

Hello Andre,

I've removed the WeakHashMap and instead I'm unregistering sessions when a connector (acceptor or initiator) is stopped. I still don't know how the WeakHashMap would have caused the problem and it's strange no one else has reported it. Still, I think the new implementation is better anyway. Thanks for the report.

Steve

Comment by Andre Mermegas [ 11/May/07 ]

Hey Steve,

Yeah, I'm not completely sure either but in my very quick look at the source i didn't see any other way for it to get taken from the map, i saw no calls to .remove or anything elsewhere.

anyway, sounds good. thanks.

Comment by Ian Paul Johnson [ 12/Jun/07 ]

Just to let you know, last night i had exactly the same problem, whereby i got 2 SessionNotFoundException when the lookup failed - was still heartbeating but no trading activity overnight - the first attempt to send order failed in send. There were no intervening connectivity or other problems. - using 1.1.0. Reconnecting refreshed the session collection and all continued without problems and no java vm restart.





[QFJ-166] Add version information Created: 27/Apr/07  Updated: 04/Jul/07  Resolved: 10/May/07

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

Type: Task Priority: Default
Reporter: Alex McGlashan Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add a command to display the version of QF/J currently installed or add a manifest file to the quickfixj.jar containing version information.



 Comments   
Comment by Steve Bate [ 10/May/07 ]

I added the version information to the manifest file. There is also a Version class that is configured to be the main class of the JAR. You can print the version using the following technique.

java -jar quickfixj.jar

will dump the version specified in the manifest.





[QFJ-165] Allow for dynamic definition of sessions Created: 26/Apr/07  Updated: 11/Feb/09  Resolved: 13/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.1.0
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Graham Miller Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None
Environment:

All


Attachments: Text File dynamicsessions.patch    
Issue Links:
Relates
relates to QFJ-125 session management Closed
is related to QFJ-221 Extend dynamic creation of sessions t... Closed

 Description   

As requested previously (http://www.quickfixj.org/jira/browse/QFJ-125), we have a few compelling use cases where we would like our QuickFIX/J-based server application to be able to update session descriptions on the fly.

I have attached patches to the current SVN HEAD (621), that provide the basic facilities for dynamic session definition in QuickFIX.

  • Replaced the singleton "sessions" map in Session.java with an instance of the new interface ISessionDB
  • Created two implementations of ISessionDB, StaticSessionDB (which provides the same semantics as the original map singleton) and CachingSessionDB which creates a local cache of any session created by a SessionFactory (not sure how useful this is, but it is useful during prototyping and testing)
  • Added a "UseDynamicSessions" boolean configuration variable that can be used in the global scope of the configuration file.
  • Added a "useDynamicSessions" boolean constructor argument to AbstractSocketAcceptor and AbstractIoHandler to correspond to the configuration variable
  • AbstractSocketAcceptor now creates one socket descriptor for 0.0.0.0/0.0.0.0:<port> if there otherwise are none, and UseDynamicSessions is "Y", this makes it possible to have a configuration file with no explicit session sections, only a defaults.
  • If the AcceptorIOHandler does not have a Session in it's local map, it now calls Session.lookupSession() to find it, if useDynamicSessions is true

And some potentially controversial changes:

  • Made the constructors of the Session object public, so that I could provide my own subclass of SessionFactory in my own package.
  • Made the class and constructor of SessionSchedule public, so that I could provide my own subclass of SessionFactory in my own package.
  • Made the DEFAULT_SESSION_ID in SessionSettings.java public, so that I could reuse some code in AbstractSocketAcceptor (see the diffs for AbstractSocketAcceptor.java)

With all of these changes, it is now possible to start up a QuickFIX/J socket acceptor with a .properties file with only a global section, like this:

ConnectionType=acceptor
FileStorePath=output/data/server
HeartBtInt=30
StartTime=00:00:00
EndTime=00:00:00
ReconnectInterval=15
ResetOnLogout=Y
ResetOnDisconnect=Y
SendResetSeqNumFlag=Y
SocketAcceptPort=7001
UseDynamicSessions=Y

In order to make real use of it, you will need to implement your own SessionFactory: in the example below it is called MySessionFactory. I have an implementation of a SessionFactory that accepts all incoming session requests, I don't think it's useful in production, but we could maybe add it to the test code.

MessageFactory messageFactory = new DefaultMessageFactory();
MessageStoreFactory messageStoreFactory = new MemoryStoreFactory();
Application application = new MyApplication();
SessionSettings settings = getSettings();
LogFactory logFactory = new ScreenLogFactory();
SessionFactory sessionFactory = new MySessionFactory(settings, application, messageStoreFactory, messageFactory);
SocketAcceptor acceptor = new SocketAcceptor(sessionFactory, settings);
acceptor.start();

Ultimately it would be nice to have a couple of standard implementations of SessionFactory that read session configuration data out of a DB, or an LDAP server.



 Comments   
Comment by Toli Kuznets [ 26/Apr/07 ]

125 was actually never implemented

Comment by Toli Kuznets [ 26/Apr/07 ]

fixing up markup to try and get it to show up "pretty"





[QFJ-164] Add ability to set data source directly on log/store and remove JNDI property initialization. Created: 23/Apr/07  Updated: 04/Jul/07  Resolved: 31/May/07

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

Type: Improvement Priority: Default
Reporter: Jörg Thönnes Assignee: Jörg Thönnes
Resolution: Fixed Votes: 0
Labels: None
Environment:

JBoss deployed data sources



 Description   

JDBC data sources deployed in JBoss cannot be accessed. The JBoss jndi,properties file contains something like this:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming
java.naming.provider.url=host:port

Actually, only the first and the third properties can be set using the QF/J settings. Accessing the data sources fails.

I suggest to add this and possibly other JNDI properties to JdbcUtils.getDataSource().

If just the data source is defined in the QF/J settings, a JNDI lookup is tried. In that case, all possible JNDI properties are fetched from the settings. If a property cannot be find, this will be ignored.

If there is no other JNDI property set, the default new InitialContext() without arguments is tried. It will pick up its configuration from the resource "jndi.properties" found using the class loader.

Otherwise, the configuration using direct JDBC driver and URL etc. is used.



 Comments   
Comment by Steve Bate [ 11/May/07 ]

I'm wondering if I should go the other direction. When running inside an application server, the initial context should already be configured. So just creating the InitialContext() instance would be enough (with no environment). At least I know this is true for the application servers I've used. I'm not familiar with JBoss. Does it work the same way?

Even if I don't support any JNDI properties directly in the code, they can still be set in various other ways (as you mentioned). At the time I wrote the original code I wasn't sure how it would work in an application server context.

Thoughts?

Comment by Brad Harvey [ 12/May/07 ]

Hi Steve,

JBoss works the same way - you shouldn't need any JNDI context settings if you're connecting within the JVM (and I don't think it makes datasources available outside the JVM, but could be wrong).

Maybe a separate option to pass the DataSource programatically to JdbcxxxFactory and have it pass it directly to JdbcStore/Log would be useful? This way the user can have complete control over how the data source is found (JNDI, commons-dbcp, proxool etc).

Disclaimer: I don't use JDBC with quickfix/j

Cheers,
Brad.

Comment by Steve Bate [ 19/May/07 ]

Thanks, Brad. I don't often use the JDBC plugins either.

Jörg, what do you think about these suggestions? I'd be removing the existing settings-based properties and adding the capability to set the datasource explicitly on the factory. Or you could make the changes, if you'd like.

Comment by Jörg Thönnes [ 21/May/07 ]

I would like to keep JdbcSetting.SETTING_JDBC_DS_NAME.

In addition, if also JdbcSetting.SETTING_JNDI_PROVIDER_URL is set, the InitialContext should be creating using the Hashtable
containing all JNDI properties mentioned in the Context and InitialContext classes. Check every property if it is set and put it
in the Hashtable. I was worried about the incomplete support: If you cannot set any JNDI properties and have to rely on the
InitialContext as it is provided (via application server or jndi.properties), this would be fine.

The ability to set the data source programmatically would be an extra option which makes much sense. But in general, I would
like to see more things to be configurable without extra programming.

My background to use the data source that I have code that should run both in the application server and in a standalone JVM.

Comment by Steve Bate [ 25/May/07 ]

Accidentally resolved the wrong issue.

Comment by Jörg Thönnes [ 30/May/07 ]

JdbcUtil: Removed empty HashMap argument from InitialContext constructor.





[QFJ-163] There is no way to know if a session is timedOut Created: 19/Apr/07  Updated: 15/Nov/12  Resolved: 10/Jun/07

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

Type: Bug Priority: Minor
Reporter: Jeronimo Ginzburg Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

n/a



 Description   

In 1.0.5 in order to see if a given session was timed out you can call getState().isTimedOut()
In 1.1.0 there is no getState() method in Session. So there is no way to know if a session is timedOut.
The getState() function disappeared from Session.java in revision 567.



 Comments   
Comment by Steve Bate [ 07/Jun/07 ]

There is a isLogonTimedout() and isLogoutTimedOut() in the quickfix.Session object. Is this what you need?





[QFJ-162] Weekly session fails on Sundays Created: 19/Apr/07  Updated: 20/Feb/10  Resolved: 20/Feb/10

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.2.0

Type: Bug Priority: Critical
Reporter: Christian Braeuner Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Unix Sun JVM 1.4.2_06 and XP Sun JVM 1.6.0_01


Attachments: File SessionSchedule.java    
Issue Links:
Relates
is related to QFJ-142 Weekday session schedule and default ... Closed

 Description   

When the weekly Session starts on a Sunday, the QF engine resets but does not start at the configured time.
This is quite a serious error for Reuters because the bug has made it into our production system because production has a different Schedule than development. The production system now needs to be started manually with temporary config changes every Sunday evening until we can deploy a fix.

The SessionSchedule class has a bug in TimeInterval.theMostRecentIntervalBefore() when the start or end date is a Sunday. The following code is making the wrong assumptions:
if (startTime.getDay() != -1) {
startCal.set(Calendar.DAY_OF_WEEK, startTime.getDay());
}
This code and the equivalent for endCal assume that the calendar moves backward if startTime is less than the current setting and moves forward if startTime is later than the current setting. I.e. if startCal is Wednesday=4 then the calendar would move back if set to Sunday=1 and forward if set to Friday=5. This is not the always the case and depends on Calendar.getFirstDayOfWeek(). In our case the first day of the week is Monday=2. So for example when the current date is Thu Apr 19 and the session starts on Sunday, then startCal(Calendar.DAY_OF_WEEK, 1) is not moving backwards to Sun 15 Apr, but forwards to Sun 22 Apr, because the week is 2,3,...,6,7,1. This is then returning the wrong interval and prevents the adapter from starting up.

The fix is to insert startCal.setFirstDayOfWeek(1) and endCal.setFirstDayOfWeek(1) at the appropiate lines in this method.

Regards,
Christian



 Comments   
Comment by Steve Bate [ 19/Apr/07 ]

Thanks for the report. Is it possible to provide a patch file? You can attach it to the issue.

Comment by Christian Braeuner [ 19/Apr/07 ]

Added 2 lines to correct scheduling bug:
151:startCal.setFirstDayOfWeek(1);
173:endCal.setFirstDayOfWeek(1);

Comment by Steve Bate [ 19/May/07 ]

I've added tests and, by default, I'm running the unit test in a non-US locale to help catch these problems earlier in the future.

Comment by Steve Bate [ 20/Feb/10 ]

Reopening to remove spam comment





[QFJ-161] FieldType gives the wrong Java type for date-based fields Created: 11/Apr/07  Updated: 11/Feb/09  Resolved: 02/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.2.1

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

The constructors for the singletons for date-based FieldTypes (in FieldType.java) are constructed with the wrong Java datatype (I think). Fields that represent UtcTimeStamps for example, actually return a Date object from getValue().

The offending lines are:

public final static FieldType UtcTimeStamp = new FieldType("UTCTIMESTAMP", Calendar.class);
public final static FieldType UtcDateOnly = new FieldType("UTCDATEONLY", Calendar.class);
public final static FieldType UtcDate = new FieldType("UTCDATEONLY", Calendar.class);
public final static FieldType UtcTimeOnly = new FieldType("UTCTIMEONLY", Calendar.class);

I think the "Calendar.class" should be replaced by "Date.class" at the end of each constructor call.



 Comments   
Comment by Toli Kuznets [ 02/May/07 ]

fixed in revision 622





[QFJ-160] Break up the code base into logical jars Created: 10/Apr/07  Updated: 04/Jul/07  Resolved: 07/Jun/07

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

Type: Improvement Priority: Default
Reporter: Naresh Bhatia Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

All



 Description   

QuickFix/J is currently released as a single 4 MB jar. This jar is extremely large for certain applications. For example, a small FIX client only needs to create FIX messages and send them to a FIX engine. It might make sense to break up the code base in to smaller logical jars, for example quickfixj-core.jar (containing Message, Field, Group, DataDictionary etc.) and quickfixj-engine (containing the remaining classes).



 Comments   
Comment by Steve Bate [ 11/Apr/07 ]

Hello,

We have plans to package the JARs differently but I can't say when that will actually happen. In the meantime, you can easily repackage the JAR yourself and keep only the classes needed by your application. The bulk of the JAR file size are the generated FIX messages for each FIX version. Even within a specific FIX version, a typical application will support only about 10 or so messages (including both application and required session protocol messages).

Steve

Comment by Naresh Bhatia [ 11/Apr/07 ]

Ok, no problem. I will repackage as necessary.

Thanks.
Naresh





[QFJ-159] Add msgTypeName -> msgType mapping to DataDictionary Created: 29/Mar/07  Updated: 12/Apr/07  Resolved: 30/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Improvement Priority: Major
Reporter: Naresh Bhatia Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows, Solaris



 Description   

I need msgTypeName -> msgType mappings in the DataDictionary class. Here's my use case: I have a requirement to be able to change the message metadata dynamically. For example, if a custom field tag value is wrong in a running system, then I should be able to correct it without bouncing the system. Hence message creation and parsing should be completely metadata driven (no hard coding of msgTypes and field tag values is allowed). Looking at the DataDictionary interface, I think message parsing can be completely driven by it, but I am not sure if message creation can be driven by the same metadata. For creating a message, I need to set the MsgTpe. However given a message name (e.g. "NewOrderSingle"), I don't see any way to get the msgType (e.g. "D") . What is needed is a simple method on the DataDictionary that returns a msgType given the message name. For example,

String getMsgType(String msgName);

Thus dd.getMsgType("NewOrderSingle") will return "D".

Is this a convincing use case to add the method to DataDictionary API? Is there another way to solve the issue?



 Comments   
Comment by Steve Bate [ 30/Mar/07 ]

I've committed the changes to the trunk (to be released as 1.1 soon). If you need to use the updated DataDictionary in 1.0.5, it should work, but I can't guarantee it.

Comment by Naresh Bhatia [ 07/Apr/07 ]

Thanks Steve. I have temprorily hard coded the msgType in my code. I will switch over to your new API as soon as 1.1 is released.





[QFJ-158] CxlType field should only show up in FIX40.xml file - it doesn't exist in subsequent FIX versions Created: 23/Mar/07  Updated: 18/Sep/08  Resolved: 20/Aug/08

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.2.1
Fix Version/s: 1.2.1

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

According to the FIX specs at http://www.btobits.com/fixopaedia/, the CxlType (125) field only exists in FIX.4.0
That field is no longer present in anything from 4.1-4.4

However, the field does show up in FIX41-43.xml files, and as a result the CxlType field that is created uses the definition from FIX43.xml file which doesn't contain the 2 constants that the CxlType field should contain (see http://www.btobits.com/fixopaedia/fixdic40/fd0e-125-3132.html).

I propose to remove the CxlType field definition from the FIX41-43.xml files to comply with the spec.

Perhaps there's some other dependency or backwards compatibility issues that i may be missing?

thoughts?



 Comments   
Comment by Toli Kuznets [ 28/Mar/07 ]

fixed in revision 604

Comment by Jörg Thönnes [ 02/Apr/07 ]

Hi Toli,

just checked FPL Fiximate. They confirm this.
So removing is OK, I see no issues except somebody uses this
field where he should not.

Cheers, Jörg





[QFJ-157] duplicate message sending Created: 12/Mar/07  Updated: 24/Mar/07  Resolved: 24/Mar/07

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

Type: Bug Priority: Default
Reporter: rohit Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None


 Description   

When running the acceptor, some times (very rarely) the server is sending same messge again causing the client to disconnect. Not sure where the problem is. Did anyone come across this problem?



 Comments   
Comment by rohit [ 13/Mar/07 ]

Sorry it was due to a bug. Please ignore.





[QFJ-156] Is MINA (using java NIO) good for streaming applications Created: 12/Mar/07  Updated: 10/Apr/07  Resolved: 10/Apr/07

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

Type: Other Priority: Default
Reporter: rohit Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

test



 Description   

Hi Steve,
I have been doing some testing with quickfix and mina 1.0.1 and found it's very inefficient w.r.t the speed/latencies. Any advise would be really appreciated. We have a FIX engine that's implemented using QFJ and want to support 500 users and may be each getting about 250-500 messages per second. All users get the data at the same time as the marekt changes for everyone. When the data changes and as MINA uses "n" number of SocketIOProcessors, I notice delay of couple of mill seconds more on NIO compared to blocking I/O. Any advise of how I can achive more sessions and also less latency?

Thanks for your help.



 Comments   
Comment by rohit [ 12/Mar/07 ]

This is for an acceptor which streams market data.

Comment by Steve Bate [ 13/Mar/07 ]

How are you measuring the relative latency between NIO and blocking IO? Are you setting TCP_NODELAY? Are you wanting to process 25000 msg/sec (500 users x 500 msg/sec) with a single QFJ process? To anything close to that performance, I'd recommend studying the QFJ acceptor implementation and MINA. There are tuning options that might be useful for your application that are currently not directly supported by QFJ (but could be added). Which acceptor implementation are you using (single thread or thread-per-session)?

Comment by rohit [ 13/Mar/07 ]

1) I am running couple of worker clients that initiate 50 fix client sessions per worker and check the delay between current time the fix sending time.
2) I have the nagle algorithm disabled (TcpNoDelay=true)
3) I tried with 1-10 QFJ processors
4) I am using SingleThread as I don't get many messages to the server. It's a streaming server. So, one thread is sufficinet for me.

Could you pls. advise some of the tuning options to achieve better results?

Thanks for the quick response.

Comment by rohit [ 13/Mar/07 ]

Hi Steve,
Also, the throughput on blocked I/O is 5% less compared to non-blocking i/o. But, latency is more important than the throughput for us. The reason for going to non-blocking to avoid delays due to context switching when running 500+ users and our app already uses 2 threads for other purposes.

Comment by Steve Bate [ 10/Apr/07 ]

Hi rohit,

I saw your questions in the MINA list. If I understand them correct, we are doing what they suggested to minimize latency.





[QFJ-155] MINA Filter docs in user guide Created: 10/Mar/07  Updated: 12/Apr/07  Resolved: 25/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Documentation
Affects Version/s: 1.1.0
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: PNG File blacklist filter.png     File blacklist filter.uxf     HTML File mina_filters.html     PNG File protocol codec filter.png     File protocol codec filter.uxf     PNG File whitelist filter.png     File whitelist filter.uxf    

 Description   

Hi,

I've improved (I hope!) the documentation for custom IO Filters which I'll attach to this issue.

It isn't linked on the main documentation index page.

Cheers,
Brad.



 Comments   
Comment by Brad Harvey [ 10/Mar/07 ]

Diagrams were created with umlet 7.1 - http://www.umlet.com/. I've attached the "source" (uxf) in case you want to modify them.

Comment by Steve Bate [ 25/Mar/07 ]

I've updated the docs with your changes. Thanks!





[QFJ-154] Modify MessageFactory interface to add a functionality to create a group based on an enclosing message and group type Created: 10/Mar/07  Updated: 31/May/07  Resolved: 28/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: New Feature Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File createGroup.patch    
Issue Links:
Relates
relates to QFJ-171 MessageFactory cannot create certain ... Closed

 Description   

Currently, the MessageFactory class only exposes functionality to create a Message based on the FIX version and MsgType.

Would be nice to also add a function that would create a group, based on the version, MsgType and the corresponding group type.

Here's the prototype:

    /**
     * Creates a group for the specified parent message type and
     * for the fields with the corresponding field ID
     *
     * Example: to create a {@link quickfix.fix42.MarketDataRequest.NoMDEntryTypes}
     * you need to call
     *       create({@link quickfix.field.MsgType#MARKET_DATA_REQUEST, {@link quickfix.field.NoMDEntryTypes#FIELD})
     *
     * @param msgType   Message type of the enclosing message
     * @param correspondingFieldID  the fieldID of the field in the group
     * @return  group
     */
    public Group create(String beginString, String msgType, int correspondingFieldID);

The change itself is fairly trivial - we just modify the XSLT that creates the MessageFactory classes to add another function.

Any thoughts, requests or other implementation ideas?



 Comments   
Comment by Toli Kuznets [ 10/Mar/07 ]

patch with changes and unit test

Comment by Brad Harvey [ 14/Mar/07 ]

Hi Toli,

I think it's a good idea.

I'd potentially use a convenience method which takes a Message instance instead of beginString and msgType. Which actually makes me wonder, can the generated Message classes have a method to create the groups instead?

/**

  • Creates the group and adds it to the message
  • Example: if you have a Message instance that is a quickfix.fix42.MarketDataRequest and you
  • want to create a {@link quickfix.fix42.MarketDataRequest.NoMDEntryTypes}
  • you need to call
  • createAndAddGroup( {@link quickfix.field.NoMDEntryTypes#FIELD}

    )

  • @param fieldIdOfGroup the field Id of the field in the group.
  • @return the newly added group
    */
    public Group createAndAddGroup(int fieldIdOfGroup);

Message quoteRequest = messageFactory.create("FIX.4.4", MsgType.QUOTE_REQUEST);
Group noRelatedSym = quoteRequest.createAndAddGroup(NoRelatedSym.FIELD);

Unfortunately you'd need a default implementation for Message which throws some type of error, which may be a good reason not to do it this way.

Additionally/alternatively, each message could have a specific createGroup method for its groups. Eg

QuoteRequest quoteRequest = new QuoteRequest();
Group group = quoteRequest.createAndAddGroupNoRelatedSym();

Not sure if adding as well as creating is a good idea, and of course the method names are horrible but you get the picture.

Cheers,
Brad.

Comment by Toli Kuznets [ 19/Mar/07 ]

Brad,

What you are suggesting in the first part is a good idea, to have
Message quoteRequest = messageFactory.create("FIX.4.4", MsgType.QUOTE_REQUEST);
Group noRelatedSym = quoteRequest.createAndAddGroup(NoRelatedSym.FIELD);

think that'd be a pretty convenient method.

I'm not sure about having a create function for each specific group - I think it'd be very unwieldy to have all these special-named functions, it'll quickly get cluttered and confusing.

Steve, any thoughts? It'd definitely making generating each individual Message subclass more complicated, it'd have to know about which groups it has, but it's not impossible. and maybe "cleaner" than enumerating all the possible groups in the factory code.

thoughts?

Comment by Toli Kuznets [ 28/Mar/07 ]

Fix checked in revision 605.
The implementation is the original proposal of having a "create" function that returns a Group:

    /**
     * Creates a group for the specified parent message type and
     * for the fields with the corresponding field ID
     *
     * Example: to create a {@link quickfix.fix42.MarketDataRequest.NoMDEntryTypes}
     * you need to call
     *       create({@link quickfix.field.MsgType#MARKET_DATA_REQUEST, {@link quickfix.field.NoMDEntryTypes#FIELD}) 
     *
     * Function returns null if the group cannot be created.
     * @param beginString
     *            the FIX version (for example, "FIX.4.2")
     * @param msgType   Message type of the enclosing message
     * @param correspondingFieldID  the fieldID of the field in the group
     * @return  group, or null if the group can't be created.
     */
    public Group create(String beginString, String msgType, int correspondingFieldID);




[QFJ-153] tags in a specific order in a FIX packet Created: 08/Mar/07  Updated: 10/Apr/07  Resolved: 10/Apr/07

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

Type: Other Priority: Default
Reporter: Cyril Cohen Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Window / Linux



 Description   

Hello,

I would like to set tags in a FIX packet in a specific order

For instance, in a FIX quote request packet, I need to set the tag38 after the tag303 and quickfixj set it before even if in my source code I set it after:

...
// Instrument
group.set(new Symbol("EUR/USD"));

// Quote request type
group.setInt(303, 2);

// Quote type
group.setInt(537, 2);

// Order Qty
group.setString(38, "1000000");

qr.addGroup(group);
...

Here is the packet it sends: "...146=1 55=EUR/USD 38=1000000 303=2 537=2 ..."
I need to send it like this: "...146=1 55=EUR/USD 303=2 537=2 38=1000000..."

Thank you



 Comments   
Comment by Brad Harvey [ 14/Mar/07 ]

Hi Cyril,

How are you creating the group? The QuoteRequest message class has an inner class - QuoteRequest.NoRelatedSym - that knows what the correct ordering should be. If you just say new Group() it doesn't know.

So I think something like this should work:

QuoteRequest.NoRelatedSym group = new QuoteRequest.NoRelatedSym();

Then set fields as per your example.

Same thing for other groups in other message types - each message type has its own inner classes for groups it contains.

Hope that helps,
Brad.





[QFJ-150] Calling toString() on an empty Message object resutls in a NullPointerException Created: 03/Mar/07  Updated: 25/Aug/07  Resolved: 03/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-229 FIX engine stuck in unrecoverable sta... Closed

 Description   

doing (new quickfix.Message()).toString() results in an NPE.
That's b/c the FieldMap.calculateString() function doesn't guard against fields missing from the pre-canned set of fields.



 Comments   
Comment by Toli Kuznets [ 03/Mar/07 ]

fixed in revision 601





[QFJ-148] FIX42.xml out of sync with QuickFIX equivalent Created: 02/Mar/07  Updated: 12/Apr/07  Resolved: 03/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

All


Attachments: File fx.patch    
Issue Links:
Relates
relates to QFJ-41 AllocLinkType has different descripti... Closed

 Description   

The QuickFIX/J specification file, uses descriptions "F_X_NETTING" and "F_X_SWAP" for the values of field "AllocLinkType", whereas QuickFIX uses "FX_NETTING" and "FX_SWAP", each in the FIX42.xml file.

This could prevent QuickFIX/J from being a true "drop-in replacement" for QuickFIX...



 Comments   
Comment by Graham Miller [ 02/Mar/07 ]

Patch file showing the difference between the QuickFIX FIX42.xml and the QuickFIX/J FIX42.xml

Comment by Steve Bate [ 03/Mar/07 ]

This is the reason for the current mismatch. However, I agree that it's best to keep it consistent with the QuickFIX C++ XML files. For some reason, those files use F_X in some places and FX in others. ???

Comment by Steve Bate [ 03/Mar/07 ]

The previous comment is for the link to the related issue.





[QFJ-147] FIX**.xml missing values for MsgType Created: 02/Mar/07  Updated: 03/Mar/07  Resolved: 03/Mar/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Graham Miller Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None
Environment:

All


Attachments: File msgtype.patch    

 Description   

The fix specification files FIX40.xml, FIX41.xml and FIX42.xml (but not 43 and 44) are missing the values sub elements for the MsgType field definition.

Currently they have:

<field number="35" name="MsgType" type="STRING"/>

But they should have something like:

<field number="35" name="MsgType" type="STRING">
<value enum="0" description="HEARTBEAT" />
<value enum="1" description="TEST_REQUEST" />



 Comments   
Comment by Graham Miller [ 02/Mar/07 ]

Patch to fix MsgType value fields

Comment by Steve Bate [ 03/Mar/07 ]

I'm just curious. Did you post this issue against the C++ QuickFIX also? I noticed Oren made the same changes today.

Comment by Toli Kuznets [ 03/Mar/07 ]

I didn't but Graham did. He noticed the values were missing, checked against the C++ Quickfix and filed a bug in both.
Just means that Oren is faster than me at checking the changes in - i should put it in by the end of the day PST.

Comment by Toli Kuznets [ 03/Mar/07 ]

added the missing values.
fixed checked in in revision 600





[QFJ-146] Subclasses of quickfix.field.UtcTimeStampField don't preserve milliseconds during creation Created: 28/Feb/07  Updated: 01/Mar/07  Resolved: 01/Mar/07

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

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

the UtcTimeStampField has a boolean argument whether or not t preserve the millisecond field from a timestamp.

However, none of the subclasses call that constructor, as a result, the milliseconds are always lost when you round-trip something like
Date aDate = new Date();
assertEquals("rountdrip fails", aDate.getTime(), (new EffectiveTime(aDate)).getValue().getTime());

Message msg = new Message();
msg.setField(new EffectiveTime(aDate));
assertEquals("rountdrip from msg fails", aDate.getTime(), msg.getField(new EffectiveTime()).getValue().getTime());

Fails in the second assert with: rountdrip from msg fails expected:<1172696741599> but was:<1172696741000>

So the milliseconds are lost when a subclass of UtcTimeStampField is retrieved from the message.

The 2nd part is that FieldMap doesn't later use the UtcTimeStampField.showMilliseconds() when it stores the fields in the message.
So the values are lost even at sending (marshaling) time, not just at unmarshaling.

Interestingly, there seems to be a similar error in Quickfix as well: http://www.quickfixengine.org/bugtracker/bug.php?op=show&bugid=1&pos=0



 Comments   
Comment by Toli Kuznets [ 01/Mar/07 ]

Modified the xlslt to call the constructors in UtcTimeStamp/OnlyField classes that preserves milliseconds.
Modified the setter code in FieldMap to use the showMilliseconds() values from Utcxxx fields during conversion.

Comment by Toli Kuznets [ 01/Mar/07 ]

Fix checked in revision 598.





[QFJ-145] Provide a Session.validateMessageBody() method to only validate the body of the message without header or trailer parts. Created: 28/Feb/07  Updated: 25/Sep/08  Resolved: 28/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-143 DataDictionary doesn't preserve the "... Closed

 Description   

What do you think of adding another method to quickfix.Session that allows to check if just the body of the message is valid?

I can see the use cases being where a quickfix message is created (a new order single, a reject, etc) and may need to be validated in the application layer before sending it out on the wire (where it potentially gets validated as well by QFJ itself).

However, it's hard to do that since the header and trailer information are injected into the message by QFJ. And while you can set almost anything, the CheckSum is hard to calculate; and it seems silly to duplicate the effort.

Any thoughts? What do you guys think?



 Comments   
Comment by Toli Kuznets [ 28/Feb/07 ]

Fix for bug 143 means that all the hand-constructed messages that have previously passed validation may no longer do that if they didn't have the header/trailer fields setup.
So now that the DataDictionary code is fixed, having a way to validate just the body becomes more useful.

Comment by Steve Bate [ 28/Feb/07 ]

This sounds like a good idea. Did you want to go ahead and make the changes? Do you have permissions to assign issues? If not, let me know and I'll make the changes to Jira.

Comment by Toli Kuznets [ 28/Feb/07 ]

Overloaded the DadaDictionary.validate() message call to add a boolean to
specify validating just the body of the message.

you can now call dictionary.validate(message, true) to validate just the body

Comment by Toli Kuznets [ 28/Feb/07 ]

checked into SVN in changeset 597





[QFJ-144] What is the intention of the SendResetSeqNumFlag setting? Created: 27/Feb/07  Updated: 03/Mar/07  Resolved: 03/Mar/07

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

Type: Other Priority: Default
Reporter: Rob Gilliam Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

What is the intention of the SendResetSeqNumFlag setting?

The Java constant for this field is Session.SETTING_RESET_WHEN_INITIATING_LOGON and the Configuration section of the QuickFIx/J User Manual has the description "Send a sequence number reset when initiating a logon" and says the default is "N". This implies (to me) that an initiator session with this flag set should always reset its sequence numbers before logging in, sending a Logon(A) request with and 34=1 and 141=Y every time; it's fairly easy to see why such behaviour shouldn't be the default as it risks undelivered messages from the previous session being lost.

However QuickFIX/J actually only seems to use the setting - in Sesson.isResetOnLogonRequested() - to decide whether to set 141=Y in a Logon(A) when the expected sequence numbers for both sides have ALREADY been set to 1, and it has no real effect if ResetOnDisconnect or ResetOnLogout are set, the two most common situations for this, as these cause 141=Y to be set anyway if the sequence numbers have been reset. I would suggest this behaviour IS required in most instances and the default should be "Y".

The only other time I can find the setting being checked is in Session.nextLogon(Message) to avoid rejecting an incoming Logon(A) message with the sequence number higher than we expect; not sure why this is the case, although I've not really thought about it.

So, what is the desired behaviour? Is there a bug in QuickFIX/J (i.e. should this setting really trigger a Session.reset() every time?) or does the documentation maybe need to be made more specific?



 Comments   
Comment by Steve Bate [ 27/Feb/07 ]

This has been cleaned up in the trunk (soon to be version 1.1.0). Can you review that code to be sure it resolves your issues?

Comment by Rob Gilliam [ 27/Feb/07 ]

So the setting will change to "ResetOnLogon" (Session.SETTING_RESET_ON_LOGON) and this'll reset the sequence numbers before logon (and cause the 141=Y flag to be set)?

That looks like what I'm after, thanks.





[QFJ-143] DataDictionary doesn't preserve the "required" attribute of header/trailer fields Created: 24/Feb/07  Updated: 12/Apr/07  Resolved: 24/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-145 Provide a Session.validateMessageBody... Closed

 Description   

DataDictionary.load() method currently hardcodes all the header/trailer fields to be "not required".
As a result, even validating a message without a BeginString or SenderCompID passes, even though those fields are obviously required in the FIX dictionary file.

Source example:
String required = "false";
addHeaderField(lookupXMLFieldNumber(document, name), required.equals("true"));

Need to behave the same as with regular fields.



 Comments   
Comment by Toli Kuznets [ 24/Feb/07 ]

i'll do the copy/paste from the regular message parsing code first and check the fix in.

i'll decomp the code to reuse all the common cases later in a separate check-in.

Comment by Toli Kuznets [ 24/Feb/07 ]

Fixed in checkin 593.





[QFJ-142] Weekday session schedule and default locale == Locale.FRENCH Created: 23/Feb/07  Updated: 04/Jul/07  Resolved: 19/May/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Guillaume Bedard Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP Pro SP2, JDK 1.5.0_01


Issue Links:
Relates
relates to QFJ-162 Weekly session fails on Sundays Closed

 Description   

Whenever we instantiate an Initiator with the following sample session schedule settings, the engine considers that we are out of schedule because internally (in SessionSchedule.theMostRecentIntervalBefore(Calendar)), the interval start date is always after the end date for some reason:

SETTINGS
========
Locale.setDefault(Locale.FRENCH);
String[] WEEKDAYS = new DateFormatSymbols(Locale.getDefault()).getWeekdays();
settings.setString(mySessionID, Session.SETTING_TIMEZONE, "Europe/London");
settings.setString(mySessionID, Session.SETTING_START_DAY, WEEKDAYS[Calendar.SUNDAY]);
settings.setString(mySessionID, Session.SETTING_START_TIME, "22:15:00");
settings.setString(mySessionID, Session.SETTING_END_DAY, WEEKDAYS[Calendar.FRIDAY]);
settings.setString(mySessionID, Session.SETTING_END_TIME, "21:55:00");

LOG OUTPUT
===========
schedule is weekly, DIM 22:15:00 UTC - VEN 21:55:00 UTC (weekly, DIM 22:15:00 GMT - VEN 21:55:00 GMT)
Session state is not current; resetting FIX.4.2:...->...
Created session: FIX.4.2:...->...

As a workaround, temporarily forcing the default locale to Locale.ENGLISH and setting it back after solves the problem, but otherwise, the SessionSchedule.theMostRecentIntervalBefore(Calendar) method seems to have issues.

Furthermore, having to use internationalized week day String values is also a bit awkward (see above example).

Thanking you in advance,

Guillaume



 Comments   
Comment by Steve Bate [ 10/May/07 ]

I'm not sure but this may be related to QFJ-162.

Comment by Steve Bate [ 19/May/07 ]

I've added tests and, by default, I'm running the unit test in a non-US locale to help catch these problems earlier in the future.





[QFJ-141] Provide file-based message extraction utility Created: 12/Feb/07  Updated: 12/Apr/07  Resolved: 12/Feb/07

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The FixMessageDecoder can operate on any ByteBuffer. This utility will take a File and create a memory mapped ByteBuffer for the file. Messages will then be extracted from the memory mapped file. The messages can be returned in an in-memory list or they can be streamed individually. The latter approach allows processing of messages from very large files without consuming excessive memory.






[QFJ-140] Remove MySQL-specific support in favor of JDBC Created: 11/Feb/07  Updated: 12/Apr/07  Resolved: 12/Feb/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Remove MySQL-specific classes, libraries, and documentation. Recommend use of JDBC.






[QFJ-139] Add src.zip to binary release Created: 11/Feb/07  Updated: 12/Apr/07  Resolved: 14/Feb/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-138] Surround calls to log() function with an if statement to avoid costly string concats if the logger is not enabled Created: 10/Feb/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Improvement Priority: Minor
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

This is an obviously low-priority RFE

Would be a nice idea to surround all calls to the logging code with
if(logger.isDebugEnabled(this)) or logger.isInfoEnabled() to avoid the cost of string concats in the case of loggers actually being filtered out.

this is probably only applicable to all the incoming/outgoing FIX message logging, may not be that expensive but probably a good idea.



 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

I'm going to guard the private log() method in the SLF4JLog. Is that what you intended?

Comment by Toli Kuznets [ 11/Feb/07 ]

I think the problem may actually be higher up the chain of call. by the time it makes it to the SLF4J.log() method the strings have already been concatted.

I'm thinking of something like the Session class, where at line 246 we have this:
getLog().onEvent("Session " + sessionID + " schedule is " + sessionSchedule);

by the time that gets down to the particular logger, the String concat has already happened.

so ideally it'd be something like this:

if(getLog().onEventEnabled()) {
getLog().onEvent("Session " + sessionID + " schedule is " + sessionSchedule);
}

May be too hard to do for combined loggers and such.

I was mostly concerned with all the incoming/outgoing FIX messages, but i now realize that these are not constructed form concatenating strings (in Session.send or Log.onOutgoing) - these have already been created, so we are not paying double to create another string to print it.

so this may be a non-issue.





[QFJ-137] SLF4JLog prints itself instead of the actual logging class in the output Created: 10/Feb/07  Updated: 12/Apr/07  Resolved: 07/Apr/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Toli Kuznets
Resolution: Fixed Votes: 0
Labels: None


 Description   

Seems that the SFL4JLog is not setup to correctly show the actual class/line printing the message.
All the messages come out looking like this:
18:30:16,736 INFO [QFJ Timer] quickfixj.msg.outgoing (SLF4JLog.java:90) - FIX.4.2:MRKTC-OMS->MRKTC-EXCH: 8=FIX.4.29=6335=034=2749=MRKTC-OMS52=20070210-02:30:16.73256=MRKTC-EXCH10=114

with (SLF4JLog.java:90) always being the line origin of where the message is coming from.

I know that in Log4J they have a concept of a "wrapper function" name that gets passed in to the log function to make sure the wrapper doesn't get printed:
http://logging.apache.org/log4j/docs/api/org/apache/log4j/Category.html#log(java.lang.String,%20org.apache.log4j.Priority,%20java.lang.Object,%20java.lang.Throwable)

Perhaps there's some similar approach for SLF4J as well?



 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

Is that information being extracted from the stack frames for the function call? If so, there was a similar problem with an earlier version of SL4J where they printed the wrong calling function. I posted a bug about that one and they fixed it. I'm not sure if this is similar, but maybe we should check for a newer version of SLF4J.

Comment by Steve Bate [ 11/Feb/07 ]

I've upgraded to SFL4J 1.2 and this doesn't seem to be a problem any more. Can you confirm and close the issue if you don't see the problem? Thanks.

Comment by Toli Kuznets [ 11/Feb/07 ]

Just tried SLF4J 1.2 and i'm still seeing the same behaviour:
12:22:16,913 INFO [QFJ Timer] quickfixj.msg.outgoing (SLF4JLog.java:90) - FIX.4.2:MRKTC-OMS->MRKTC-EXCH: 8=FIX.4.29=6235=034=549=MRKTC-OMS52=20070211-20:22:16.90556=MRKTC-EXCH10=065

I'll play around with it some more to make sure that i'm not missing something though.

Comment by Steve Bate [ 12/Feb/07 ]

OK, I misunderstood what you wanted. I thought SLF4J was putting one of it's own file names in the log message but I see now that's the QFJ SL4JLog.java file. I haven't seen any capability in SLF4J like you've described, but I haven't looked closely for it. If you find a feature like that in SLF4J, it's fine to add it into the logger. However, remember that it's very expensive to be logging the file name and/or calling class. I know for the calling class they were creating a new Throwable for each logged line so they could process the stack trace. This isn't a QFJ issue per se, but a potential performance issue to remember at the application level.

Comment by Steve Bate [ 24/Feb/07 ]

Any more info on this issue?

Comment by Toli Kuznets [ 25/Feb/07 ]

sorry, haven't had time to look into this yet. I think you are right - if the functionality i'm looking for doesn't come "for free" by calling into some wrapper, it may be too expensive to create an exception to get to teh stack trace every time.

i'll look into this next week.

Comment by Toli Kuznets [ 28/Mar/07 ]

This seems to be related to SLF4J bug 23: http://bugzilla.slf4j.org/show_bug.cgi?id=23
It doesn't look like switching to the latest 1.3.0 version makes any difference, so i'll find out if additional work needs to be done to SLF4J to make the LocationAwareLogger work with LOG4J as well, for example.

Comment by Toli Kuznets [ 03/Apr/07 ]

I cross-posted this on the SLF4J list/bugzilla, and Ceki Gulku suggested an approach to get it work in http://bugzilla.slf4j.org/show_bug.cgi?id=44#c1

Essentially, there's a "LocationAwareLogger" interface in SLF4J, so we need to check if that's what we get back and call through to the function that takes in a location wrapper.

Will work on getting that to work. don't think that it'll add extra overhead, but will need to see how underlying Log4j implementation handles it.

Comment by Toli Kuznets [ 07/Apr/07 ]

Fixed in checkin 612. SLF4JLog now distinguishes between a regular and a LocationAwareLogger.





[QFJ-136] Add capability to filter out Heartbeats to to SLF4JLog and others Created: 10/Feb/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-132 Make JdbcLog configurable to skip hea... Closed

 Description   

ScreenLog is currently the only logger to allow for filtering out of heartbeats.
Idea situation would be to have one unified way to filter out heartbeats for all the loggers.

In slf4j logger, it's trivial to implement by just adding another special logger category that can be filtered out in log4j.properties.

However, since the strings created are pretty large, it may actually be a lot more efficient to intercept it at a higher level and just not print altogether, hopefully saving some string concats along the way.



 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

Are you thinking about a common abstract base class for the QFJ loggers that would provide a configuration option for doing the filtering? If so, that sounds like a reasonable approach.

Comment by Steve Bate [ 11/Feb/07 ]

I added a common base class that includes filtering capabilities.





[QFJ-135] session -> setResponder not thread safe Created: 07/Feb/07  Updated: 11/Feb/09  Resolved: 15/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.0.5

Type: Bug Priority: Minor
Reporter: Christopher Hurst Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows / Unix



 Description   

setResponder is not synchronized (responder not volatile) and called from a different thread to hasResponder.

Although hasResponder is synchronized and will get the latest version from main memory dropping its thread cache , there is no obvious guarantee that the thread calling setResponder has hit a memory barrier and forced its new responder value to main memory so hasResponder method can return an unexpected result as it will get the latest one from memory but not from the other threads cache that may not have been pushed to main memory yet.

change setResponder to be synchronized.

public synchronized void setResponder(Responder responder)






[QFJ-134] Stack overflow when JdbcLog fails to log a message Created: 07/Feb/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File jdbc-oomErrorSessionLookupNPE.patch     Text File out.txt    
Issue Links:
Relates
relates to QFJ-133 Return of bug 89 - session lookup cau... Closed

 Description   

This is a continuation of bug 133 - just breaking out the recursive stack overflow error.

See the (bottom of) attached log - if the JdbcLog fails to insert a message, we end up calling the JdbcLog.insert() recursively until we get a stack overflow.
I think this is b/c of Proxool - it keeps trying to get a connection and log something.

Patch is attached to the bug 133 and here as well.



 Comments   
Comment by Toli Kuznets [ 07/Feb/07 ]

See the bottom of the file for the stack trace that deals with proxool-caused stack overflow

Comment by Toli Kuznets [ 07/Feb/07 ]

patch for both bug 133 and this one





[QFJ-133] Return of bug 89 - session lookup causes an NPE if JdbcLog is miconfigured initially Created: 07/Feb/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File jdbc-oomErrorSessionLookupNPE.patch     Text File out.txt    
Issue Links:
Relates
relates to QFJ-89 sessionID added to global Sessions af... Closed
is related to QFJ-134 Stack overflow when JdbcLog fails to ... Closed

 Description   

I'm able to reproduce the same situation as was in bug 89 initially (http://www.quickfixj.org/jira/browse/QFJ-89)

If you misconfigure the JdbcLog (wrong db name, or just turn off the db altogether), you get into a situation where JdbcLog calls into LogUtil.logThrowable() which tries to lookup the session through Session.lookupSession() which comes back as null and that produces an NPE.

There are actually 2 bugs:
1. When you create a session you try to log session creation.
2. if jdbc log is misconfigured, we get an exception and go into LogUtil.logThrowable() which calls through to Session.lookupSession()
3. since we haven't registered the session yet we get an NPE in LogUtil.logThrowable()

Second bug (this has to do with proxool)
1. When we get the NPE in the above scenario, we try to log it again, which essentially ends up doing this recursively and we run out of memory (see the attached stack trace).

I will create an issue to track the 2nd bug separately as well.

I am submitting a patch that's fixing both bugs:
1. Move the session registration code back from DefaultSessionFactory.create() to the Session() constructor
2. Modify the behaviour of the JdbcLog.insert() to keep track if we are being called recursively and ignore the recursive request in that case. Probably would be a good time to log somewhere else in that case though.



 Comments   
Comment by Toli Kuznets [ 07/Feb/07 ]

Patch containing the fix to both bugs described in this issue
to be applied in core/ subdirectory

Comment by Toli Kuznets [ 07/Feb/07 ]

Stacktrace that shows the NPE for when session is not found if the jdbc logger throws an error due to misconfiguraiton.

also contains the stacktrace for eventual OutOfMemoryException b/c of recursive falied attemps to log an error (when JdbcLog is misconfigured)





[QFJ-132] Make JdbcLog configurable to skip heartbeats Created: 06/Feb/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.5
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File jdbc-heartbeats.patch    
Issue Links:
Relates
is related to QFJ-136 Add capability to filter out Heartbea... Closed

 Description   

I think it'd be very useful to make it configurable whether or not JdbcLog prints heartbeats, just like ScreenLog does.
This may be an addition to issue 75 (to make names of JDBC tables configurable).

We took a stab at making JdbcLog more configurable, i'm attaching the patch file (apply in core/) that contains all the changes and a unit test.

We use Spring to configure our app (and QuickfixJ), and the relevant code to create a JdbcLog is:
<bean id="jdbcLogFactory" class="quickfix.JdbcLogFactory">
<constructor-arg>
<ref bean="sessionSettings"/>
</constructor-arg>
<property name="skipHeartbeats" value="true"/>
</bean>



 Comments   
Comment by Toli Kuznets [ 06/Feb/07 ]

Patch file with all the changes, to be applied in the core/ subdirectory
This is against the revision 576.





[QFJ-131] more than one connection Created: 04/Feb/07  Updated: 11/Feb/07  Resolved: 10/Feb/07

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

Type: Other Priority: Major
Reporter: Raul Alzola Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Tomcat 5.0.28, j2ee 1.4, Windows 2003 Server



 Description   

I have a J2EE web application composed with servlets, jsp's and other components. Within the application must be posible to have two different fix connections avialable, both connecting the same IP but on different ports. Currently I have two different classes implementing Application and extending MessageCracker classes respectly. Although I start their Initialtor objects with their corresponding SettingsConfig, it seems that just the last one is avialable and all the messages sent using Session.sendToTarget(...), are sent by the last connector initated. Is there any way to use different connectors running within the same appliation?



 Comments   
Comment by Steve Bate [ 04/Feb/07 ]

Yes. Multiple connections are supported. Do your sessions have different identifiers (FIX version,target/sender compID, and session qualifier (if any))?

Comment by Raul Alzola [ 04/Feb/07 ]

Both connections have the same BeginString, SenderCompID,TargetCompID. They differs on TargetSubID and SocketConnectPort.

Comment by Steve Bate [ 10/Feb/07 ]

Current, QuickFIX and QuickFIX/J only identify sessions by FIX version and compIDs (acceptors can also use a "qualifier"). I have plans to add the ability to distinguish sessions by subID and locationID as well.

Comment by Raul Alzola [ 11/Feb/07 ]

I got to mantain 2 sessions adding the sessionQualifier field to the .properties configuration file, with a different value for any connector. That's work very well.

Thanks for your help.





[QFJ-130] Accepting new tags (user defined) in responce Created: 01/Feb/07  Updated: 10/Feb/07  Resolved: 10/Feb/07

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

Type: Other Priority: Default
Reporter: Ashish Sharma Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NA


Issue Links:
Duplicate
duplicates QFJ-129 Adding non standard tags in standard ... Closed

 Description   

I have defined a new user defined tag by extending StringField class, as defined in the documentation.

Now I am able to send this tag/value pair by using setField method. Problem is when I get the same tag in response the message is being rejected at server level.

Do I need to add the same in DataDictionary also OR is there another way.

Thanx a ton
Ashish






[QFJ-129] Adding non standard tags in standard response Created: 31/Jan/07  Updated: 10/Feb/07  Resolved: 10/Feb/07

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

Type: Other Priority: Minor
Reporter: Ashish Sharma Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NA


Issue Links:
Duplicate
is duplicated by QFJ-130 Accepting new tags (user defined) in ... Closed

 Description   

As part of FIX spec. Tag 42 is not a part of ExecutionReport (35 = 8).
Currently I have implemented it by modifiying the data dictionary.

Is there a more flexible way of doing it, like adding it to .cfg file.

Thanx a lot



 Comments   
Comment by Steve Bate [ 10/Feb/07 ]

Currently, if you want automated data dictionary-based validation, you need to add the field to the appropriate data dictionary XML file.





[QFJ-128] Review synchronization (based on 1.0.5) Created: 24/Jan/07  Updated: 12/Apr/07  Resolved: 24/Feb/07

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-127] quickfix performance Created: 24/Jan/07  Updated: 10/Feb/07  Resolved: 10/Feb/07

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

Type: Other Priority: Default
Reporter: rohit Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

test



 Description   

Hi Steve,
We are trying to evaluate using QF engine using java api and found new issues. The message creation by just using the data dictionary that comes with FIX.4.2.xml is taking longer than just adding required fields. Our application is very powerful and don't want to add any extra latency. But, when I did some stats, I found QF message creation takes longer time (say for MktdataIncRefresh) if I use groups. I changed the Message.java where I can now do addfield as list and create the message witout using Groups. That's 3 times faster. I understand that the way the java code is written and really superb. But, it affected the performance in big time.

say if I want
1) add desired fields
2) add groups as a list

currently I can't do it with QF. I have to use setField and addgroup methods.

also I found another prb where the send and processmessage methods are synchronized. I guess this is done for sequence numbers. why do we want to lock the object by putting synchronized in the methods?

pls advise. I am anyway going to change as per my requirements.

Thanks for all the great help and support..

Cheers
Rohit



 Comments   
Comment by Steve Bate [ 24/Jan/07 ]

Hello Rohit,

Can you add an issue attachment with your modified version of the Message class and your timing tests for message creation? I'm not sure I understand what you mean by adding fields as a list and why that would be faster. Have you done any profiling to understand the reason for the performance differences?

I assume the processMessage method you are referencing is the one in SingleThreadedEventHandlingStrategy. It's not synchronized, so I'm guessing your concern is about the synchronized Session.next method. If so, you are correct that the synchronization is there to protect session state and ensure is visibility in mulththreaded, multiprocessor applications. What exactly is the problem? Are you having issues with processing high rates of simultaneously incoming and outgoing messages or something else?

Steve

Comment by rohit [ 31/Jan/07 ]

Hi Steve,
Thanks for the info. What I meant was, currently the Message construction (FieldMap) use TreeMap to build the fix message in a proper order(especially for grous). When I tested the message creation times with the default data dictionary, it's taking more time compared to linearly adding fields without worrying about the group order etc. In this case, the user is responsible to add the elements in proper order. The change I made is added "addField()" method which actually maintain an ArrayList and when toString() is called, it will just add in the order. I found the message creation times are 3 times faster than using setField methods. I am talking the times in micro seconds. But, our app creates 1000 of updates in a second. So, it did make a big difference to my app. I will attach the code tomorrow when I am in office.

Thanks as always for the great support. Cheers.

Comment by Sankalp Nayak [ 02/Feb/07 ]

Hi Rohit

Did you also tested the performance while retreiving the different tag-value pairs, ie the "fromString()" method . I guess moving from TreeMap to List may improve the creation performance but may significantly affect the retrieval performance esp if the groups are large in size . It would be interesting to profile that also .

thanks
Sankalp

Comment by Steve Bate [ 10/Feb/07 ]

There have been some performance-related QFJ discussions on the QuickFIX (not QFJ) list.





[QFJ-126] Unhelpful Error message Created: 17/Jan/07  Updated: 15/Nov/12  Resolved: 11/Feb/07

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

Type: Bug Priority: Minor
Reporter: Christopher Hurst Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows \ Quick fix 1.5 (was in 1.4 also)



 Description   

When the mina IO session fails in certain circumstances you get the error message (the simplest way to reproduce is to use incompatiable mina jars but I think I have seen it can on other cartain socket errors, problem was I needed to be in the degugger to catch it before I added the new error message )

Connection failed: null

which isn't very useful in quickfix.mina.initiator.IOSessionInitiator I changed the code

} catch (Throwable e)

{ quickfixSession.getLog().onEvent("Connection failed: " + e.getMessage()); }

to

catch (IncompatibleClassChangeError e) {
quickfixSession.getLog().onEvent("Libs incompatiable check jar/zip versions. " + e);
} catch (Throwable e) {
// CH e.getMessage returns null unfortunately
quickfixSession.getLog().onEvent("Connection failed: " + e);
e.printStackTrace();
}



 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

The connection failures are printed differently in 1.1.0. I'm not planning to patch the 1.0.x branch since 1.1.x will soon replace it. Thanks for the report.





[QFJ-125] session management Created: 11/Jan/07  Updated: 16/Aug/18  Resolved: 11/Jan/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4, 1.0.5
Fix Version/s: None

Type: Other Priority: Default
Reporter: rohit Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

test


Issue Links:
Relates
is related to QFJ-165 Allow for dynamic definition of sessions Closed

 Description   

Currently the default Acceptor implementation expect the sessions to be pre-defined in the config file. Is it possible to dynamically create sessions after the connections are made? My plan is to have some kind of authentication and I want to load session dynamically. Any quick suggestion or example code available somewhere?

My goal is
1) Start aceptor using quickfix SocketAcceptor
2) a way to get the logon message to the message handler
3) the message handler then create the session or start the session

Thanks for the help in advance.



 Comments   
Comment by Steve Bate [ 11/Jan/07 ]

Hello Rohit,

Currently the sessions can only be defined statically. I'd like to support dynamic session creation, but I haven't had time yet.

Steve

Comment by rohit [ 12/Jan/07 ]

Thanks Steve. I iwill mplement my own IOHandler and the Acceptor for this.

Comment by Kedarnath Patil [ 16/Aug/18 ]

Hi Rohit, could you please elaborate more on this as i am having same issue to handle the multiple session.





[QFJ-124] Provide admin callbacks for logon and logoff Created: 09/Jan/07  Updated: 10/Jun/07  Resolved: 10/Jun/07

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

Type: New Feature Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

Linux, netbeans



 Description   

We strongly request that (especially incomming) messages are provided in all application handlers.
e.g. "onLogon" and "onLogout" actually only see the sessionID.
In general, the FIX-Spec allows additional optional message fields also for these messages wich should be accessable for our business logic.
Our problem:
The optional text field from Hotspot - logout message contains the expected sequence number for our logon.

With best regards, Welf



 Comments   
Comment by Steve Bate [ 10/Jun/07 ]

The admin messages like logout and logon are passed to the admin callbacks in the quickfix.Application interface. The logon/logout callbacks can also be used for simple event processing, but are not suitable for general message processing.





[QFJ-123] Add QuickFIX/J releases to the Maven Repository for Maven Users Created: 09/Jan/07  Updated: 12/Jul/07  Resolved: 12/Jul/07

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

Type: New Feature Priority: Default
Reporter: Anthony Whitford Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

For those of us using Maven, it would be very helpful if releases were posted to the Maven Repository. Then, maven users can simply list quickfixj as a project dependency. See http://maven.apache.org/project-faq.html for more details.



 Comments   
Comment by Toli Kuznets [ 27/Feb/07 ]

Anthony,

We are using Maven at Marketcetera, and as a result we end up hosting the QFJ binaries at http://repo.marketcetera.org/maven/quickfixj/

Until Steve starts publishing maven-friendly builds, feel free to just use our repository.
You can get it this way:

            <dependency>
                <groupId>quickfixj</groupId>
                <artifactId>quickfixj</artifactId>
                <version>1.0.5</version>
            </dependency>
{code>
and you'll need to add us to your list of repositories:
{code:xml}
	<repositories>
	  <repository>
        <id>MarketceteraRepo</id>
        <url>http://repo.marketcetera.org/maven</url>
        <releases>
            <enabled>true</enabled>
        </releases>
	  </repository>
	</repositories>

In addition, you can see the example of the pom.xml file

Comment by Toli Kuznets [ 27/Feb/07 ]

Steve,

If you choose to implement this and decide that it may make more sense to convert QFJ to Maven from Ant, I can take care of that task.
I've been using Maven for about a year, and it should be fairly straight-forward to migrate QFJ from Ant to Maven.
We can then have a Maven publish task.

Of course, it's as easy to just create an Ant task to do the same
there's more info at http://maven.apache.org/guides/mini/guide-ibiblio-upload.html

Comment by Steve Bate [ 28/Feb/07 ]

I started to do the conversion and ran into problems with Maven while implementing the QFJ code generation plugin. However, this was a while ago now and Maven has evolved so it may not be a problem any more. I have structured the directories in the trunk to be Maven-friendly. I'd prefer to release 1.1.0 and then if we want, I don't mind moving to a Maven build for a subsequent release.

Comment by Steve Bate [ 10/Jun/07 ]

Until (and if) QFJ is converted to Maven, would you mind having Marketcetera be the official Maven repository for QFJ? If so, we can add some documentation with the instructions. This could be a good way to get some additional publicity for Marketcetera.

Comment by Toli Kuznets [ 13/Jun/07 ]

i checked in changes to doc/usermanual/installation.html file with directions on how to get the QFJ 1.1 to work with Maven, with the jars coming from the Marketcetera repository.

Will need to make appropriate changes to reflect the new jar naming once the jars are posted.

Steve, i can handle the deployment of jars to the repo after the release.





[QFJ-122] Some field access was not fully thread-safe Created: 08/Jan/07  Updated: 08/Jan/07  Resolved: 08/Jan/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.0.5

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The primary message processing paths were safe, but access to session state variables was not fully protected in some places.



 Comments   
Comment by Steve Bate [ 08/Jan/07 ]

Multithreaded access has been reviewed and improved.





[QFJ-121] Duplicate fields and other problem give false body length validation error Created: 04/Jan/07  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Scott Harrington Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: File quickfixj-ValidateMessageStructure.patch    

 Description   

I have encountered a counterparty whose FIX 4.2 Logon message has "98=0" appearing twice. It's clearly wrong, but I couldn't find anywhere in the spec that prohibits it.

We choke on these messages pretty early with the not-too-helpful (see QFJ-65) message "Invalid message: Actual body length=x, Expected body length=x".

The Message.bodyLength() method adds up the lengths of the fields after they've been parsed and grouped as per the DataDictionary, thus the duplicated "98=0" field only gets counted once.

I have added a crude "ValidateMessageStructure=N" work-around for myself which disables the whole bodyLength() validation step (as well as the innocent checkSum and header field order checks). I will attach this hack as a patch against SVN revision 571.

A better solution would be to re-think the bodyLength() validation, could it not just examine the raw (unparsed, ungrouped) message at this point, like checkSum() does?



 Comments   
Comment by Scott Harrington [ 04/Jan/07 ]

This patch is against SVN Revision 571.

Comment by Steve Bate [ 09/Jan/07 ]

I agree it's a good idea to improve the error messages. The FIX specification does prohibit repeated tags except in a repeating group (where the tag can't repeated within a single group). I'll investigate improving the messages for the 1.1.0 release.

Comment by Steve Bate [ 11/Feb/07 ]

I've modified the message to not check for the correct length. As noted, duplicate fields and other problems can cause an apparent body length mismatch even though the raw message has the correct body length. The FIX protocol codec will not pass a message with a bad body length anyway, so I removed that check from the message-level validation. I also added a unit test for the case described in the issue (duplicate 98=0 tags).





[QFJ-120] quickfix acceptor limits Created: 29/Dec/06  Updated: 30/Dec/06  Resolved: 30/Dec/06

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

Type: Other Priority: Major
Reporter: rohit Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux



 Description   

Can anyone tell how many fix users can a FIX acceptor implemented using QFJ can handle? I know that it depends on various factors. But, I just would like to know from your expereinces of using mina io framework.

Assumptions:
Environment: Linux
average outgoing Messagesperuser per second: 50

I am looking to implement a FIX Engine that should handle about 500+ users per FIX server instance.
Any suggestions on the approach for the implementation or useful tips would be really great.



 Comments   
Comment by Steve Bate [ 30/Dec/06 ]

Hello Rohit,

I've used QFJ with 100 or so sessions but I haven't tried it with than many network connections. You might ask the guys on the MINA list, but I'm guessing they would not have any problem with 500 connections. As for the rate, the limiting factor will be message store implementation you use. JDBC will be relatively slow, file system is faster, and memory-based is fastest but has other drawbacks. Using a memory-based message store I've processed messages at a rate of several thousand per second. If you use a file store and a reasonably fast hard drive I wouldn't think that 50 msg/sec would be any problem at all.

Steve





[QFJ-119] No JDBC transactions around storing messages and updating sequence number. Created: 28/Dec/06  Updated: 20/Dec/11  Resolved: 09/Jan/07

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

Type: Other Priority: Default
Reporter: Paul Haefele Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I am curious as to the fact that their is no enclosing transaction around the storing of the messages to the database and the updating of the sequence numbers that happens in Session.sendRaw(). In here, QuickFixJ (if configured for JDBC) updates the database after it has send out the message using:

state.set(msgSeqNum, messageString);
state.incrNextSenderMsgSeqNum();

Both of these update the database, however they don't do it in a single transaction. Doesn't this mean the DB would be in an inconsistent state if the server where to go down between the above two statements.

Indeed I was hoping to be able to hook into this transaction myself to update my own tables so as to ensure that my OMS is always inline with what QuickFix believes it has sent.

I am a relative newbie to QuickFixJ, so please let me know if I am missing the boat entirely.

Many thanks
Paul



 Comments   
Comment by Paul Haefele [ 28/Dec/06 ]

I am curious as to the fact that their is no enclosing transaction around the storing of the messages to the database and the updating of the sequence numbers that happens in Session.sendRaw(). In here, QuickFixJ (if configured for JDBC) updates the database after it has send out the message using:

state.set(msgSeqNum, messageString);
state.incrNextSenderMsgSeqNum();

Both of these update the database, however they don't do it in a single transaction. Doesn't this mean the DB would be in an inconsistent state if the server where to go down between the above two statements.

Indeed I was hoping to be able to hook into this transaction myself to update my own tables so as to ensure that my OMS is always inline with what QuickFix believes it has sent.

I am a relative newbie to QuickFixJ, so please let me know if I am missing the boat entirely.

Many thanks
Paul

Comment by Paul Haefele [ 28/Dec/06 ]

Sorry for the duplicate message above - meant to send an additional comment (below) but ended up re-pasting original...

Looking further at Session.sendRaw() I see that it is doing two things:

a) sending message on network (Session.send() and then
b) logging this message to the database (state.set())

However I'm wondering about the failure semantics here of what would happen if our FixServer went down between (a) and (b). This could mean that the receiving Fix engine could get a message that we don't know about when restart. Wouldn't this lead us to sending a different message with the an already sent MessageID on a restart. I would have expected that (a) and (b) would have been reversed.

Many thanks,
Paul

Comment by Steve Bate [ 09/Jan/07 ]

Hi Paul,

Quickfix and Quickfix/J have no transactional guarantees. This would be an interesting extension. Remember, that most of the messages stores and logs are not themselves transactional. However, the interfaces could be extended to support the potential for this behavior even if it's a no-op for most implementations.

If the rare event (hopefully!) that a server crash happens between the two calls you mention, it may require some manual intervention to patch up sequence numbers or resend messages. I think if the calls are reversed it possibly lead to a dropped message, depending on exactly where the crash occurs. However, I'll look into it further.

Comment by Paul Haefele [ 10/Jan/07 ]

Hi Steve,

Thanks for this reply. In our use of quickfixj, we want to expose the underlying transaction that jdbc will be using. This is so our own DB update can be transactionally guaranteed to occur when quickfix has transactionally committed (i.e. written to its internal store.) I've looked at Session, SessionState and MessageStore (and its implementers) and think I can expose any underlying transaction (assuming there is one) to the Application in a clean and minimal manner.

Indeed I've already implemented this, but want to review (and test) it further. I'm happy to email you the code, and if you feel it will be useful and is implemented correctly, to have this committed to the quickfixj code base.

In terms of the ordering, my sense is that mina is not a guaranteed delivery mechanism, and that FIX itself guarantees this via its message sequence numbers. As such a dropped message is no big issue. If we write to the store and then crash (without sending the message), when we come back up and send another message, the counterparty will simply ask for the missed message which we've stored.

In the case where we send the message first (and let us say it arrives) and then crash before saving to our own store, the next message we send would have the same sequence number, but indeed be a different message. We would not know what message was send prior to the crash. Thus updating our own internal store before sending any message is I believe the preferable way to go.

In any event, thanks for the reply, and most impressed with the way QuickFixJ works - great stuff. I've been working with a commercial OMS that exposes Fix messages, and the quickfixJ implementation is far more consistent and clean.
Thanks again,
Paul

Comment by shaun barker [ 20/Dec/11 ]

Hi
I realise that this is closed, but we recently came upon the same problem, came to the same conclusions and also have the code available. If you want I am happy to ping up the changes? let me know if so. Otherwise - thanks for the great product!





[QFJ-118] javac.debug proprety is not used during java compilation Created: 23/Dec/06  Updated: 10/Jan/07  Resolved: 10/Jan/07

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.0.4
Fix Version/s: 1.1.0

Type: Bug Priority: Minor
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File buildPatch.patch    

 Description   

Seems that the flag on whether or not to compile with debugging turned on is set incorrectly in core/build.xml file

The current value for the javac.debug property is "yes", but it should actually be set to "true" according to ant javac task:

  • <property name="javac.debug" value="yes" />
    + <property name="javac.debug" value="true" />

Subsequently, when it's used later in the do_compile macro it's referenced incorrectly:

  • <javac destdir="@ {output}" debug="@{javac.debug}" memoryMaximumSize="128m" fork="yes">
    + <javac destdir="@{output}

    " debug="$

    {javac.debug}

    " memoryMaximumSize="128m" fork="yes">

Since it's not passed as parameter, shouldn't the property just be accessed directly?

patch file attached.



 Comments   
Comment by Toli Kuznets [ 23/Dec/06 ]

patch file





[QFJ-117] No error message (Null pointer exception thrown) on unexpected message (SingleThreadedEventHandler) (easy to fix) Created: 14/Dec/06  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.1.0

Type: Bug Priority: Minor
Reporter: Christopher Hurst Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows (not hardware specific)



 Description   

(n.b. I only use the SingleThreadedEventHandler)

The problem ...
Basically if the QuickLib gets an unexpected message for a session it throws a null pointer exception (not sure if this has some more serious effects as it progates back up into the mina stuff), rather than display an error log message as the bit that catches the exception generated later then querys the (null) session for log detail but its null ! i.e. the bit that catches the exception causes a new one Changing this to an appropriate error is \would bea big help as initialy I thought this was the issue rather than a symptom of another problem. I've tested this on a Windows XP set.

From SingleThreadEventHandler, the code calling it does not prevent QuickSession = null, this causes a null pointer exception which is caught and an attempt is made to print an error but the catch queries the null object which goes bang again.

try {
if (quickfixSession.getResponder() != null)

{ quickfixSession.next(message); }

} catch (Throwable e)

{ LogUtil.logThrowable(quickfixSession.getSessionID(), e.getMessage(), e); }

Real World Example ...
This can happen in the real world if a test request / heart beat that's late , the session may have given up by the time the 'lost' message makes it, this message is now considered unexpected (which is ok) . Currently you get a null pointer exception later in the process from an exception handler thats hard to trace \ understand when the lost message arrives (it might cause other ill effects but i haven't had a chance to look and its so easy to fix its probably not worth it)

In mina.acceptor.AcceptorioHandler, method processMessage change the last line from ....

eventHandlingStrategy.onMessage(qfSession, message);

to ....

if (qfSession==null)
{
// [CH] this can happen if a late test request arrives after we gave up waiting and closed the session.
log.error("Attempt to process message for non existant or closed session (only legal action for logon messages) this message type was :-"+message.getHeader().getString(MsgType.FIELD));
}
else
{
eventHandlingStrategy.onMessage(qfSession, message);
}



 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

I've added the patch. Thanks!





[QFJ-116] DataDictionary.readFromURL glitch when Java security policy restricts file system access Created: 06/Dec/06  Updated: 10/Jan/07  Resolved: 10/Jan/07

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

Type: Bug Priority: Default
Reporter: Rhys Yarranton Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

JDK 1.5



 Description   

readFromURL() tries the passed value as a file before it tries it as a resource. If there is a Java security policy enabled that restricts access to the file system, new FileInputStream() may throw AccessControlException, as opposed to the FileNotFoundException that is caught.

As a workaround, we converted the resource name to a URL before calling the method. (URL is tried before file.)






[QFJ-115] "isSet" method also for field: LastPx Created: 28/Nov/06  Updated: 15/Nov/12  Resolved: 11/Feb/07

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

Type: New Feature Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

linux netbeans



 Description   

It seems that the Field "quickfix.field.LastPx" is the only field, what does not has the "isSet" methode, so that I need to catch the exception instead of simply:
if (message.isSet(new LastPx()))

{ ... }

 Comments   
Comment by Steve Bate [ 11/Feb/07 ]

I've check a few messages that use the LastPx field (e.g. quickfix.fix42.ExecutionReport) and they have the isSetLastPx() method. If you give me more specifics about the message, I might be able to do more.





[QFJ-114] variables in config-file Created: 25/Nov/06  Updated: 19/Sep/08  Resolved: 09/Jan/07

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

Type: Other Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux, netbeans



 Description   

We are using QFJ within a group and we'd like to use in our config-file an environment variable:
FileStorePath=$HOME/devel/log/fh_test
unfortunately $HOME does not work.

Also we'd like to configure other variables in the session section in our business application like
userID and passwd in the session sections.
How can we do this and how do I get access from my business-application?

Thank you, Welf



 Comments   
Comment by Steve Bate [ 09/Jan/07 ]

The SessionSettings class supports variable interpolation using a configured set of substitution values. By default, the substitution values are JVM system properties. However, you can use setVariableValues() to configure your own set of substitution values. Of course, these in turn can be loaded from a property file and the approach can support simple property inheritance by constructing a chain of java.util.Properties objects (see the Properties constructor options).

The variable syntax is $

{variable}

. For example FileStorePath=logs/$

{user.name}

would substitute the user name into the path using the "user.name" system property as the substitution value.

Comment by Parag Mehta [ 28/Jun/07 ]

Interpolation in 1.1.0 does not work with SenderCompID in default section, though it works elsewhere. Steve, any suggestions?

Thanks.





[QFJ-113] Logon management failures Created: 24/Nov/06  Updated: 10/May/07  Resolved: 10/May/07

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

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux, netbeans, hotspot


Issue Links:
Duplicate
is duplicated by QFJ-112 Logon management failures Closed

 Description   

Situation:
Starting a new hotspot - session after a local reset leads to following problem
local sequence number is reset to "1" but the Hotspot expects any higher number.

Hotspot reacts with a "Logout-Message" or sometimes with a "Reject-Message"
(need to be evaluated why not only logout due to FIX-spec).

No comes the quickfix problem:
conform to the QFJ docu all administrative messages from counterpart (fromAdmin) should pass the
fromAdmin-Handler.
The Reject-Message and not all Logout-Messages will not be passed through the
fromAdmin-Handler
The problem is now fro us, that in the messages are a text string from what we can parse the expected sequence number for another correct Logon-try.

What is also strange is that this problem occurs with quickfixj1.0.4 from download and also with
branches/QFJ_RELEASE_1_0_x.
Surprisingly when using the actual QFJ from trunk:
svn co https://svn.sourceforge.net/svnroot/quickfixj/trunk quickfixj
this version does not have this problem, it seems, that all Logouts and Rejects will be passed through the fromAdmin-Handler. So that we are able to get running sessions.
But:surprisingly the quickfixj-Engine (from trunk) sends "Resend-Messages" without having a Logon from the counterpart, this should not be according to the spec.

My questions:
1. Do you know about this behaviour or is it strange also for you. Do you like to see some Log-Files for better evaluation?
2. Do you have a recommendation how to handle Logon rejects when sequence number is too low
3. What could be the reason that the QFJ-Engines work so different at this point?

In case I can help with logs or more details let me know.
With the trunk our system is running at this point.

Best regards






[QFJ-112] Logon management failures Created: 24/Nov/06  Updated: 08/Jan/07  Resolved: 08/Jan/07

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

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Duplicate Votes: 0
Labels: None
Environment:

linux, netbeans for Hotspot sessions management


Issue Links:
Duplicate
duplicates QFJ-113 Logon management failures Closed

 Description   

Situation:
Starting a new hotspot - session after a local reset leads to following problem
local sequence number is reset to "1" but the Hotspot expects any higher number.

Hotspot reacts with a "Logout-Message" or sometimes with a "Reject-Message"
(need to be evaluated why not only logout due to FIX-spec).

No comes the quickfix problem:
conform to the QFJ docu all administrative messages from counterpart (fromAdmin) should pass the
fromAdmin-Handler.
The Reject-Message and not all Logout-Messages will not be passed through the
fromAdmin-Handler
The problem is now fro us, that in the messages are a text string from what we can parse the expected sequence number for another correct Logon-try.

What is also strange is that this problem occurs with quickfixj1.0.4 from download and also with
branches/QFJ_RELEASE_1_0_x.
Surprisingly when using the actual QFJ from trunk:
svn co https://svn.sourceforge.net/svnroot/quickfixj/trunk quickfixj



 Comments   
Comment by Steve Bate [ 08/Jan/07 ]

This is replaced by the linked issue.





[QFJ-111] Updating QFJ from subversion Created: 22/Nov/06  Updated: 23/Nov/06  Resolved: 23/Nov/06

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

Type: Other Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux, netbeans



 Description   

I have installed QFJ using the source package from sourceforge, it comes up with a structure like:
quickfixj -> src -> quickfix -> ...

to participate on the new changes I have checked out QFJ using subversion, but it comes up with:
core -> src -> main -> java -> quickfix -> ...

the directory test is at a completely other place in the whole structure.
Now I have no idea how to update QFJ

And additionally, when I try to switch to the subversion structure I will loose my netbeans settings for QFJ

My questions:
What can/should I do?
Why QFJ has a completely other structure in svn?

Many thanks, Welf



 Comments   
Comment by Steve Bate [ 23/Nov/06 ]

There is a separate SVN branch from 1.0.x releases. The branch is located in SVN at
/branches/QFJ_RELEASE_1_0_x. I'm guessing you checked out the trunk instead of the
branch. The branch will have the latest code for 1.0.x releases. If you want 1.0.4 specifically
then check out the tagged SVN version /tags/QFJ_RELEASE_1_0_4.

I don't know anything about Netbeans so I can't help with that issue.





[QFJ-110] Truncations / rolling archive of messages log Created: 22/Nov/06  Updated: 15/Apr/15  Resolved: 22/Nov/06

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

Type: Other Priority: Default
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any



 Description   

How can I setup the logs to be truncated (.messages.log) . I would like them truncated / rolled (ie 1..n logs are retained).



 Comments   
Comment by Steve Bate [ 22/Nov/06 ]

Hi Richard,

One option is to the SLF4J log factory with Log4J. The Log4J library has a couple of "appenders" for rolling files. See RollingFileAppender and DailyRollingFileAppender.

http://logging.apache.org/log4j/docs/api/org/apache/log4j/package-summary.html

Regards,

Steve

Comment by Richard Pike [ 24/Nov/06 ]

Can I get a sample of how to configure log4j

Comment by garima gangwar [ 15/Apr/15 ]

I also need a samle of this.. I tried this at my end but didn't work.
I also logged QFJ-834 for it but no luck.





[QFJ-109] Session management endDay calculation is bad (I would say wrong) Created: 16/Nov/06  Updated: 12/Apr/07  Resolved: 17/Nov/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux, netbeans



 Description   

Since session management is important for a good engine (and QFJ is my favourite) I spent the afternoon a little in testing and debugging.
I hope Steve as the maintainer is not too mad on me, that I have decided to create a new bug report.
First the result, I´d like to suggest to change the code in:
SessionSchedule.java: private TimeInterval theMostRecentIntervalBefore(Calendar t)
There are the 2 if constructions adding a day to the end day:
if (endTime.getDay() == -1 && startTime.getHour() >= endTime.getHour())

{ endCal.add(Calendar.DATE, 1); }

if (endTime.getDay() != -1
&& (startTime.getDay() > endTime.getDay() || (startTime.getDay() == endTime
.getDay() && startTime.getHour() >= endTime.getHour())))

{ endCal.add(Calendar.WEEK_OF_YEAR, 1); }

My suggestion is, to make it more precise with:
instead: startTime.getHour() >= endTime.getHour()
startTime.getHour()*3600 +startTime.getMinute()*60+startTime.getSecond() >
endTime.getHour()*3600 +endTime.getMinute()*60+endTime.getSecond()

The important change is the little change ">=" to ">" in both if's

If you are in hurry you can finish reading here .

For most applications this works practically, but there are some problems with the original construction:

1. for testing I have tried to test with small sessions (less than one hour) these sessions were able to start, but did not stop, even if I have put the same startDay and endDay in the config, the endDay was set to the next week.
In case of no startDay and no endDay the endDay is set to tomorrow.
Before I got the reason this was very frustrating.

2. I can not see any good reason for adding on day to the end day only because start and end are in the same hour, but there is a good reason for doing so, when startTime > endTime (thatswhy my suggestion)

3. If you take a look at the code (I mean the whole class SessionSchedule.java, the code is not very nice, no documentation, no clean structure, not effective. To understand what I mean, just take a look at the if-constructions in the method: MostRecentIntervalBefore
3 times the:
if (endTime.getDay() != -1)
and many similiar constructions
Maybe its not time critical at this point, but its also not good readable.

Now the good news:
The methode: public boolean isSessionTime() from Session.java works properly.
So we could program a nice and slim session management like this (and this is my recommendation to do the session management):
After receiving the logout message from the FIX-Engine, we simply check: if (!isSessionTime)
If the session is really over (and not only a logout because of connection problems) we finish the FIX-Engine (according to Steves recommendation), then we clean up our system in a separat thread (archiving and so on) and then we start the FIX-Engine again.

Well this is a recommendation but in some cases for example if you run multiple different sessions with the same engine you can not restart the engine but the session management should work properly like described.

Well, slowly QFJ looks more and more friendly.

Good night from germany, Welf



 Comments   
Comment by Steve Bate [ 17/Nov/06 ]

I've fixed the bug for the very short sessions and did some refactoring and cleanup of the code. I've also added two unit tests (~ 10 test cases) for the bug fix.





[QFJ-108] Session management, especially for Forex (example: Hotspot) Created: 16/Nov/06  Updated: 24/Jan/07  Resolved: 24/Jan/07

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

Type: Improvement Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

linux, netbeans


Issue Links:
Relates
is related to QFJ-107 session management functionality at a... Closed

 Description   

First I have to say sorry, I have really tryed to make it short - but it became longer
Second: Thanks to Steve who patiently answers all the questions (not only mine)

Its all about my problems doing (I think typical) session management with QFJ.

Reffering to my last request "session management at application level" I have additional problems:
Like Steve said its possible to use any external tools or cron jobs, the problem with them is, that they need to be coordinated with the FIX sessions, what is additional (unneccessary) logic.
Now I did this and the following problem occured:
We are running FIX sessions with Hotspot, they are active approx 23 hours per day. In the break of 1 hour we'd like/need to cleanup the system especially we'd like to archive logfiles (approx 700MByte per day).
I did this now using a system functionality (cron), since the two logfiles (event.log and messages.log) were NOT created again from the engine when the new session starts up again we lost a half day of data in the logfiles (database was still written in that period).
Now I assume, that I can not remove the logfiles in a session break, otherwise Im loosing them.
Since I can not find these information in the documentation, its learning by doing ;-(.

My actual conclusion (I might be wrong) is, that when I need to cleanup the system in a session break, I need to restart the entire engine, because otherwise the logfiles are not created.
The problem of session management should be very general for FIX-users, most trading application need some basic functionality:

  • run session from start time till end time (while start time could be later than end time, e.g. Forex)
  • run session from start day till end day (e.g. sunday till friday)
  • do something in the outer session time (e.g. cleaning up the system)
    What I understood, is that actually this is not possible with QFJ, or I was not able to use QFJ correctly at this point.
    The actual solution we are going to implement now is as follows:
    Since we get a logout information (when logout or when disconnect), we implement an own time management logic into our application, what does nothing in case of abnormal disconnect, but cleans up and restarts the engine in case of session break (to recreate the logfiles).

Best regards, Welf



 Comments   
Comment by Welf Wustlich [ 16/Nov/06 ]

Well, after screening some code it seems there is a solution for one problem:
in Class: Session.java is a method:
/**

  • Predicate for determining if the session should be active at the current
  • time.
    *
  • @return true if session should be active, false otherwise.
    */
    public boolean isSessionTime() { return sessionSchedule.isSessionTime(); }

this could be used at application level to determine if the session should run or not.
So: just in case of an logout message, I can check at application level:
if (!isSessionTime()) {
cleanupMySystem();
}
Now there are the following questions left:
a) How can I organize that my QFJ engine generates a new logfile after archiving the old one without a complete engine restart?
b) Why did Steve told me that this functionality is not implemented in QFJ in "session management at application level" a missunderstanding or do I overlook something?
c) How its possible to organize a typical Forex session type (start time is after stop time, start day is sunday, end day is friday)?

If somebody has done this or some good hints available this would help.
Preferably there should be added a small cookbook -like example section in the session management-docu.

Best regards, Welf

Comment by Steve Bate [ 16/Nov/06 ]

I forgot about that method being exposed. It's not intended for application usage, but it might work. Or there might be other side effects. I can't predict the results because I haven't tried it. If I were you, I'd shut down my servers during the break, do my log file management and end of day operations and restart the servers. The log files will still be open when you call cleanupMySystem() so on Windows, for example, the process will still be locking the file. Another option is that you could write your own file-based logger with special behavior if you have problems. Or you could use Log4J as the logger and use one of their rolling file appenders (see the Log4J documentation for more details).

For question c), see the session configuration documentation. Set the start day/time and the end day/time. It's ok for the start time to be after the end time.

For the earlier questions, I'd recommend posting these to the mailing list. Other people may have suggestions based on their own forex implementations.





[QFJ-107] session management functionality at application level Created: 14/Nov/06  Updated: 16/Nov/06  Resolved: 15/Nov/06

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

Type: Other Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux, netbeans


Issue Links:
Relates
relates to QFJ-108 Session management, especially for Fo... Closed

 Description   

Is there an opportunity to use the session management (session schedule or state) to run an own application methode?
What we´d like to do is: to clean up our system (archive log-files and so on) in a session break.
Now we do this with a cron-job, the problem is, that the cronjob and the fix session always need to be coordinated.
Im looking for an additional information when I get a logout, to see that the session has finished regular and Im in a session break and so I can start my cleaning scripts from my application instead of using the cron-job.
Example: Hotspot has a break of one and a half hour per day.

Thanks, Welf



 Comments   
Comment by Steve Bate [ 15/Nov/06 ]

No, that functionality is currently not directly accessible. You could use something like the open source job schedule, Quartz, to schedule end-of-day operations at the correct time. Quartz can be embedded in your application.





[QFJ-106] Bug when parsing repeating groups Created: 13/Nov/06  Updated: 18/Jun/11  Resolved: 09/Jan/07

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

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux netbeans



 Description   

This a bug/feature I have reported some weeks ago, but probably my description was not good understandable (sorry)
In messages with repeating groups, there is a field named NoAllocs (Tag 78)
This field in the message is not used by quickfix. Instead its overwritten by counting the repeating groups themself.
This leads to the problem that a possible mistake can not be detected, for example exception if NoAllocs != countedAllocs would be better.
Maybe this could also lead to cutting of groups like described in my bugreport in log4FIX.

Welf



 Comments   
Comment by Steve Bate [ 14/Nov/06 ]

Can you be more specific (a unit test demonstrating the problem would help greatly)? Are you seeing this behavior during message parsing or formatting?

Comment by Welf Wustlich [ 14/Nov/06 ]

In QFJ: in FieldMap.java is a function:
public void addGroup(Group group)

{ int countTag = group.getFieldTag(); List currentGroups = getGroups(countTag); currentGroups.add(new Group(group)); setGroupCount(countTag, currentGroups.size()); }

this function calls: "setGroupCount(countTag, currentGroups.size());"
and this set the count to the size of the array without checking this
size against the corresponding message field.
The user can not see the original entry in the message anymore.

As you know, I have tryed to pass the openfix tests with quickfix, one
test was if the engine rejects (and requests a new one) a message
(possDup) if the entry in the message how many groups are sent does not
fit to the real number of repeating groups.
QFJ simply ignores the message field by overwriting it with the real
count.

Well, usually this works fine because usually there should not be a
conflict. But when there is something wrong in the message then this is
not so helpful.

Since I have some trouble with the Hotspot Fix4.2 dialect (what is not
100% Fix conform) I affraid, that Im loosing data from the market data
snapshot messages. Also log4FIX what is based on Quickfix is not able to
handle these messages correctly, log4FIX is just cutting of some
repeating groups and I can unfortunately not see a lot of offer prices.
See also my short Bug-Report for log4FIX, where I sent some example
messages from Hotspot. From my point of view these Hotspot messages are
correct and I can not see a reason, why its not parsed correctly.

Best regards, Welf

Comment by Steve Bate [ 15/Nov/06 ]

Look at MessageTest.testMessageGroupCountValidation. It tests that the parser throws an exception when parsing a message with an incorrect group count. This exception should cause a reject message to be sent. Have you analyzed the HOTSPOT FIX messages directly by looking at the tags and determining if the group count is correct or not?

Comment by Miki Abimbola [ 18/Jun/11 ]

#

  1. A fatal error has been detected by the Java Runtime Environment:
    #
  2. EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x28030001, pid=3260, tid=2380
    #
  3. JRE version: 6.0_25-b06
  4. Java VM: Java HotSpot(TM) Client VM (20.0-b11 mixed mode, sharing windows-x86 )
  5. Problematic frame:
  6. C 0x28030001
    #
  7. If you would like to submit a bug report, please visit:
  8. http://java.sun.com/webapps/bugreport/crash.jsp
  9. The crash happened outside the Java Virtual Machine in native code.
  10. See problematic frame for where to report the bug.
    #

--------------- T H R E A D ---------------

Current thread (0x06863400): JavaThread "AWT-Windows" daemon [_thread_in_native, id=2380, stack(0x024c0000,0x025c0000)]

siginfo: ExceptionCode=0xc0000005, reading address 0x28030001

Registers:
EAX=0x0a582ff8, EBX=0x00000001, ECX=0x0b1e1dc8, EDX=0x00000004
ESP=0x025bfaa0, EBP=0x025bfacc, ESI=0x06863528, EDI=0x0b1e1dc8
EIP=0x28030001, EFLAGS=0x00010293

Top of Stack: (sp=0x025bfaa0)
0x025bfaa0: 6d09c720 00000000 6d09c1e0 00000000
0x025bfab0: 025bfb48 00000000 06863528 025bfaa4
0x025bfac0: 025bfb60 6d0c0038 00000001 025bfaf8
0x025bfad0: 75306238 00060310 0000981a 0b1e1dc8
0x025bfae0: 00000000 6d09c1e0 dcbaabcd 00000000
0x025bfaf0: 00000000 6d09c1e0 025bfb70 753068ea
0x025bfb00: 6d09c1e0 00060310 0000981a 0b1e1dc8
0x025bfb10: 00000000 f3aa22bd 025bfc04 025bfbfc

Instructions: (pc=0x28030001)
0x2802ffe1:
[error occurred during error reporting (printing registers, top of stack, instructions near pc), id 0xc0000005]

Register to memory mapping:

EAX=0x0a582ff8 is an unknown value
EBX=0x00000001 is an unknown value
ECX=0x0b1e1dc8 is an unknown value
EDX=0x00000004 is an unknown value
ESP=0x025bfaa0 is pointing into the stack for thread: 0x06863400
EBP=0x025bfacc is pointing into the stack for thread: 0x06863400
ESI=0x06863528 is an unknown value
EDI=0x0b1e1dc8 is an unknown value

Stack: [0x024c0000,0x025c0000], sp=0x025bfaa0, free space=1022k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C 0x28030001
C [USER32.dll+0x16238] gapfnScSendMessage+0x270
C [USER32.dll+0x168ea] gapfnScSendMessage+0x922
C [USER32.dll+0x17d31] LoadStringW+0x11f
C [USER32.dll+0x17dfa] DispatchMessageW+0xf

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j sun.awt.windows.WToolkit.eventLoop()V+0
j sun.awt.windows.WToolkit.run()V+52
v ~StubRoutines::call_stub

--------------- P R O C E S S ---------------

Java Threads: ( => current thread )
0x0afa1000 JavaThread "ITimer" daemon [_thread_blocked, id=4912, stack(0x07ba0000,0x07bf0000)]
0x0af9e400 JavaThread "AsynchRasterManager" daemon [_thread_blocked, id=1016, stack(0x0c560000,0x0c5b0000)]
0x0af9e000 JavaThread "AsynchRasterManager" daemon [_thread_blocked, id=1356, stack(0x0c4d0000,0x0c520000)]
0x0af9d400 JavaThread "ScrollBar" daemon [_thread_blocked, id=5024, stack(0x0c3b0000,0x0c400000)]
0x0698f000 JavaThread "TextField" daemon [_thread_blocked, id=4840, stack(0x0c320000,0x0c370000)]
0x0698e800 JavaThread "ScrollBar" daemon [_thread_blocked, id=4776, stack(0x0c290000,0x0c2e0000)]
0x0698e400 JavaThread "ScrollBar" daemon [_thread_blocked, id=5220, stack(0x0c200000,0x0c250000)]
0x0698dc00 JavaThread "TickTimer" daemon [_thread_blocked, id=2308, stack(0x0c170000,0x0c1c0000)]
0x0698d400 JavaThread "ScrollBar" daemon [_thread_blocked, id=5904, stack(0x0c0e0000,0x0c130000)]
0x0698d000 JavaThread "BadgeStorage" daemon [_thread_blocked, id=5516, stack(0x0c050000,0x0c0a0000)]
0x0698c800 JavaThread "InvalQueue-com.pogo.ui2.awt.ac[PremiumTableGameApplet-ControlPanel,0,0,192x408,invalid]-PremiumTableGameApplet-ControlPanel" daemon [_thread_blocked, id=2196, stack(0x0bfc0000,0x0c010000)]
0x0698c400 JavaThread "SocketConnection" daemon [_thread_blocked, id=2128, stack(0x0bf30000,0x0bf80000)]
0x0698bc00 JavaThread "Applet-EventThread" daemon [_thread_blocked, id=3116, stack(0x0bea0000,0x0bef0000)]
0x0698b800 JavaThread "AsynchRasterManager.avatar" daemon [_thread_blocked, id=1148, stack(0x0be10000,0x0be60000)]
0x0698b000 JavaThread "Thread-38" daemon [_thread_blocked, id=6036, stack(0x0bd80000,0x0bdd0000)]
0x0698a800 JavaThread "Thread-37" daemon [_thread_blocked, id=2264, stack(0x0bcf0000,0x0bd40000)]
0x0698a400 JavaThread "Thread-36" daemon [_thread_blocked, id=1116, stack(0x0bc60000,0x0bcb0000)]
0x06989800 JavaThread "thread applet-com.pogo.game.client2.domino2.DominoApplet-6" [_thread_in_native, id=4820, stack(0x0bb80000,0x0bbd0000)]
0x06870400 JavaThread "SocketConnection" daemon [_thread_in_native, id=3240, stack(0x081b0000,0x08200000)]
0x06871000 JavaThread "Applet-EventThread" daemon [_thread_blocked, id=948, stack(0x071b0000,0x07200000)]
0x06874800 JavaThread "Direct Clip" daemon [_thread_blocked, id=6100, stack(0x09bb0000,0x09c00000)]
0x06874400 JavaThread "Thread-31" daemon [_thread_blocked, id=3324, stack(0x09990000,0x099e0000)]
0x06873c00 JavaThread "Thread-30" daemon [_thread_blocked, id=5200, stack(0x097e0000,0x09830000)]
0x06873800 JavaThread "Thread-29" daemon [_thread_blocked, id=6064, stack(0x09650000,0x096a0000)]
0x06873000 JavaThread "Java Sound Event Dispatcher" daemon [_thread_blocked, id=4760, stack(0x08990000,0x089e0000)]
0x06872400 JavaThread "thread applet-com.pogo.game.client2.table.AutoPlayTableApplet-5" [_thread_blocked, id=1636, stack(0x082d0000,0x08320000)]
0x06871c00 JavaThread "Applet 5 LiveConnect Worker Thread" [_thread_blocked, id=304, stack(0x08240000,0x08290000)]
0x06870c00 JavaThread "thread applet-com.pogo.game.client2.shell.ShellApplet-4" [_thread_blocked, id=3352, stack(0x08000000,0x08050000)]
0x0686d400 JavaThread "AWT-EventQueue-4" [_thread_blocked, id=1428, stack(0x08090000,0x080e0000)]
0x06871800 JavaThread "Applet 4 LiveConnect Worker Thread" [_thread_blocked, id=880, stack(0x07870000,0x078c0000)]
0x0686f000 JavaThread "Browser Side Object Cleanup Thread" [_thread_blocked, id=4992, stack(0x07750000,0x077a0000)]
0x0686e400 JavaThread "Windows Tray Icon Thread" [_thread_in_native, id=4332, stack(0x07510000,0x07560000)]
0x0686e000 JavaThread "CacheCleanUpThread" daemon [_thread_blocked, id=5660, stack(0x07480000,0x074d0000)]
0x0686d800 JavaThread "CacheMemoryCleanUpThread" daemon [_thread_blocked, id=5044, stack(0x073f0000,0x07440000)]
0x02454400 JavaThread "SysExecutionTheadCreator" daemon [_thread_blocked, id=2432, stack(0x06ab0000,0x06b00000)]
0x06866800 JavaThread "AWT-EventQueue-0" [_thread_blocked, id=5704, stack(0x072d0000,0x07320000)]
0x06866000 JavaThread "Java Plug-In Heartbeat Thread" [_thread_blocked, id=2632, stack(0x07240000,0x07290000)]
=>0x06863400 JavaThread "AWT-Windows" daemon [_thread_in_native, id=2380, stack(0x024c0000,0x025c0000)]
0x0685f800 JavaThread "AWT-Shutdown" [_thread_blocked, id=800, stack(0x06e20000,0x06e70000)]
0x0685f000 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=5832, stack(0x06d90000,0x06de0000)]
0x0685a000 JavaThread "Java Plug-In Pipe Worker Thread (Client-Side)" daemon [_thread_in_native, id=4988, stack(0x06b40000,0x06b90000)]
0x02445c00 JavaThread "Timer-0" [_thread_blocked, id=5248, stack(0x06a20000,0x06a70000)]
0x02430000 JavaThread "traceMsgQueueThread" daemon [_thread_blocked, id=6124, stack(0x065e0000,0x06630000)]
0x023f7400 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=5256, stack(0x064c0000,0x06510000)]
0x023e8c00 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=3316, stack(0x06430000,0x06480000)]
0x023e7c00 JavaThread "Attach Listener" daemon [_thread_blocked, id=6060, stack(0x063a0000,0x063f0000)]
0x023e4800 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=4484, stack(0x06310000,0x06360000)]
0x023dc400 JavaThread "Finalizer" daemon [_thread_blocked, id=5304, stack(0x04e30000,0x04e80000)]
0x023db000 JavaThread "Reference Handler" daemon [_thread_blocked, id=5352, stack(0x04da0000,0x04df0000)]
0x024bb000 JavaThread "main" [_thread_blocked, id=5848, stack(0x002c0000,0x00310000)]

Other Threads:
0x0239e400 VMThread [stack: 0x04b70000,0x04bc0000] [id=3276]
0x02400000 WatcherThread [stack: 0x06550000,0x065a0000] [id=220]

VM state:not at safepoint (normal execution)

VM Mutex/Monitor currently owned by a thread: None

Heap
def new generation total 15744K, used 2858K [0x2c550000, 0x2d660000, 0x2eff0000)
eden space 14016K, 17% used [0x2c550000, 0x2c7bcbc8, 0x2d300000)
from space 1728K, 21% used [0x2d300000, 0x2d35de48, 0x2d4b0000)
to space 1728K, 0% used [0x2d4b0000, 0x2d4b0000, 0x2d660000)
tenured generation total 34788K, used 23975K [0x2eff0000, 0x311e9000, 0x34550000)
the space 34788K, 68% used [0x2eff0000, 0x30759cd0, 0x30759e00, 0x311e9000)
compacting perm gen total 12288K, used 5518K [0x34550000, 0x35150000, 0x38550000)
the space 12288K, 44% used [0x34550000, 0x34ab3810, 0x34ab3a00, 0x35150000)
ro space 10240K, 51% used [0x38550000, 0x38a7dc00, 0x38a7dc00, 0x38f50000)
rw space 12288K, 55% used [0x38f50000, 0x395ec300, 0x395ec400, 0x39b50000)

Code Cache [0x02b70000, 0x02e68000, 0x04b70000)
total_blobs=1638 nmethods=1400 adapters=172 free_code_cache=30468928 largest_free_block=320

Dynamic libraries:
0x00400000 - 0x00424000 C:\Program Files (x86)\Java\jre6\bin\java.exe
0x778f0000 - 0x77a70000 C:\Windows\SysWOW64\ntdll.dll
0x75640000 - 0x75740000 C:\Windows\syswow64\kernel32.dll
0x76580000 - 0x765c6000 C:\Windows\syswow64\KERNELBASE.dll
0x764e0000 - 0x76580000 C:\Windows\syswow64\ADVAPI32.dll
0x76810000 - 0x768bc000 C:\Windows\syswow64\msvcrt.dll
0x767f0000 - 0x76809000 C:\Windows\SysWOW64\sechost.dll
0x768c0000 - 0x769b0000 C:\Windows\syswow64\RPCRT4.dll
0x74ff0000 - 0x75050000 C:\Windows\syswow64\SspiCli.dll
0x74fe0000 - 0x74fec000 C:\Windows\syswow64\CRYPTBASE.dll
0x73920000 - 0x7396b000 C:\Windows\system32\apphelp.dll
0x73890000 - 0x7391c000 C:\Windows\AppPatch\AcLayers.DLL
0x752f0000 - 0x753f0000 C:\Windows\syswow64\USER32.dll
0x750b0000 - 0x75140000 C:\Windows\syswow64\GDI32.dll
0x767b0000 - 0x767ba000 C:\Windows\syswow64\LPK.dll
0x76680000 - 0x7671d000 C:\Windows\syswow64\USP10.dll
0x75890000 - 0x764d9000 C:\Windows\syswow64\SHELL32.dll
0x75820000 - 0x75877000 C:\Windows\syswow64\SHLWAPI.dll
0x76c10000 - 0x76d6c000 C:\Windows\syswow64\ole32.dll
0x755b0000 - 0x7563f000 C:\Windows\syswow64\OLEAUT32.dll
0x73980000 - 0x73997000 C:\Windows\system32\USERENV.dll
0x73970000 - 0x7397b000 C:\Windows\system32\profapi.dll
0x73830000 - 0x73881000 C:\Windows\system32\WINSPOOL.DRV
0x73810000 - 0x73822000 C:\Windows\system32\MPR.dll
0x75140000 - 0x751a0000 C:\Windows\system32\IMM32.DLL
0x75750000 - 0x7581c000 C:\Windows\syswow64\MSCTF.dll
0x7c340000 - 0x7c396000 C:\Program Files (x86)\Java\jre6\bin\msvcr71.dll
0x6d7f0000 - 0x6da9f000 C:\Program Files (x86)\Java\jre6\bin\client\jvm.dll
0x712c0000 - 0x712f2000 C:\Windows\system32\WINMM.dll
0x6d7a0000 - 0x6d7ac000 C:\Program Files (x86)\Java\jre6\bin\verify.dll
0x6d320000 - 0x6d33f000 C:\Program Files (x86)\Java\jre6\bin\java.dll
0x6d000000 - 0x6d14b000 C:\Program Files (x86)\Java\jre6\bin\awt.dll
0x735d0000 - 0x7376e000 C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7600.16661_none_420fe3fa2b8113bd\COMCTL32.dll
0x73770000 - 0x737f0000 C:\Windows\system32\uxtheme.dll
0x75740000 - 0x75745000 C:\Windows\syswow64\PSAPI.DLL
0x6acf0000 - 0x6aeb3000 C:\Windows\system32\d3d9.dll
0x737f0000 - 0x737f9000 C:\Windows\system32\VERSION.dll
0x6dda0000 - 0x6dda6000 C:\Windows\system32\d3d8thk.dll
0x734a0000 - 0x734b3000 C:\Windows\system32\dwmapi.dll
0x6a5c0000 - 0x6a9c5000 C:\Windows\system32\atiumdag.dll
0x70940000 - 0x70de4000 C:\Windows\system32\atiumdva.dll
0x63000000 - 0x63037000 C:\Program Files (x86)\Common Files\Motive\McciContextHook_DSR.dll
0x10000000 - 0x10008000 c:\PROGRA~2\mcafee\SITEAD~1\saHook.dll
0x6d7e0000 - 0x6d7ef000 C:\Program Files (x86)\Java\jre6\bin\zip.dll
0x6d420000 - 0x6d426000 C:\Program Files (x86)\Java\jre6\bin\jp2native.dll
0x6d1d0000 - 0x6d1e3000 C:\Program Files (x86)\Java\jre6\bin\deploy.dll
0x76af0000 - 0x76c0c000 C:\Windows\syswow64\CRYPT32.dll
0x752e0000 - 0x752ec000 C:\Windows\syswow64\MSASN1.dll
0x76f10000 - 0x7702a000 C:\Windows\syswow64\WININET.dll
0x778c0000 - 0x778c3000 C:\Windows\syswow64\Normaliz.dll
0x753f0000 - 0x755a6000 C:\Windows\syswow64\iertutil.dll
0x751a0000 - 0x752b0000 C:\Windows\syswow64\urlmon.dll
0x6d6a0000 - 0x6d6e6000 C:\Program Files (x86)\Java\jre6\bin\regutils.dll
0x6d600000 - 0x6d613000 C:\Program Files (x86)\Java\jre6\bin\net.dll
0x76770000 - 0x767a5000 C:\Windows\syswow64\WS2_32.dll
0x75880000 - 0x75886000 C:\Windows\syswow64\NSI.dll
0x72c80000 - 0x72cbc000 C:\Windows\system32\mswsock.dll
0x71140000 - 0x71146000 C:\Windows\System32\wship6.dll
0x6d620000 - 0x6d629000 C:\Program Files (x86)\Java\jre6\bin\nio.dll
0x6d230000 - 0x6d27f000 C:\Program Files (x86)\Java\jre6\bin\fontmanager.dll
0x73060000 - 0x73068000 C:\Windows\system32\Secur32.dll
0x6f020000 - 0x6f064000 C:\Windows\system32\dnsapi.DLL
0x72ea0000 - 0x72ebc000 C:\Windows\system32\iphlpapi.DLL
0x72e90000 - 0x72e97000 C:\Windows\system32\WINNSI.DLL
0x72c70000 - 0x72c75000 C:\Windows\System32\wshtcpip.dll
0x6ef90000 - 0x6efb7000 C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live\WLIDNSP.DLL
0x6ef80000 - 0x6ef86000 C:\Windows\system32\rasadhlp.dll
0x6ef00000 - 0x6ef38000 C:\Windows\System32\fwpuclnt.dll
0x6d510000 - 0x6d534000 C:\Program Files (x86)\Java\jre6\bin\jsound.dll
0x6d540000 - 0x6d548000 C:\Program Files (x86)\Java\jre6\bin\jsoundds.dll
0x6df10000 - 0x6df82000 C:\Windows\system32\DSOUND.dll
0x6e0c0000 - 0x6e0e5000 C:\Windows\system32\POWRPROF.dll
0x76d70000 - 0x76f0d000 C:\Windows\syswow64\SETUPAPI.dll
0x767c0000 - 0x767e7000 C:\Windows\syswow64\CFGMGR32.dll
0x769b0000 - 0x769c2000 C:\Windows\syswow64\DEVOBJ.dll
0x6e080000 - 0x6e0b9000 C:\Windows\system32\MMDevAPI.DLL
0x6ed10000 - 0x6ee05000 C:\Windows\system32\PROPSYS.dll
0x6b4b0000 - 0x6b4e0000 C:\Windows\system32\wdmaud.drv
0x6ecd0000 - 0x6ecd4000 C:\Windows\system32\ksuser.dll
0x6e260000 - 0x6e267000 C:\Windows\system32\AVRT.dll
0x6b290000 - 0x6b2c6000 C:\Windows\system32\AUDIOSES.DLL
0x6e210000 - 0x6e218000 C:\Windows\system32\msacm32.drv
0x6e1b0000 - 0x6e1c4000 C:\Windows\system32\MSACM32.dll
0x6de80000 - 0x6de87000 C:\Windows\system32\midimap.dll
0x769d0000 - 0x76a53000 C:\Windows\syswow64\CLBCatQ.DLL
0x6d440000 - 0x6d465000 C:\Program Files (x86)\Java\jre6\bin\jpeg.dll
0x734d0000 - 0x734e6000 C:\Windows\system32\CRYPTSP.dll
0x73460000 - 0x7349b000 C:\Windows\system32\rsaenh.dll
0x6f010000 - 0x6f020000 C:\Windows\system32\NLAapi.dll
0x74010000 - 0x74018000 C:\Windows\System32\winrnr.dll
0x70810000 - 0x70820000 C:\Windows\system32\napinsp.dll
0x707f0000 - 0x70802000 C:\Windows\system32\pnrpnsp.dll

VM Arguments:
jvm_args: -D_jvm_launched=7526970509 -Xbootclasspath/a:C:\\PROGRA~2\\Java\\jre6\\lib\\deploy.jar;C:\\PROGRA~2\\Java\\jre6\\lib\\javaws.jar;C:\\PROGRA~2\\Java\\jre6\\lib
plugin.jar -Dsun.awt.warmup=true -Xmx128m -Dsun.plugin2.jvm.args=-D
_jvm_launched=7526970509 "-Xbootclasspath/a:C:\\\\PROGRA~2\\\\Java\\\\jre6\\\\lib\\\\deploy.jar;C:\\\\PROGRA~2\\\\Java\\\\jre6\\\\lib\\\\javaws.jar;C:\\\\PROGRA~2\\\\Java\\\\jre6\\\\lib\\\\plugin.jar" "-Djava.class.path=C:\\\\PROGRA~2\\\\Java\\\\jre6\\\\classes" -Dsun.awt.warmup=true — – -Xmx128m
java_command: sun.plugin2.main.client.PluginMain write_pipe_name=jpi2_pid4208_pipe3,read_pipe_name=jpi2_pid4208_pipe2
Launcher Type: SUN_STANDARD

Environment Variables:
PATH=C:\Program Files (x86)\Internet Explorer;;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared
USERNAME=Miki
OS=Windows_NT
PROCESSOR_IDENTIFIER=AMD64 Family 16 Model 4 Stepping 3, AuthenticAMD

--------------- S Y S T E M ---------------

OS: Windows 7 Build 7600

CPU:total 4 (4 cores per cpu, 1 threads per core) family 16 model 4 stepping 3, cmov, cx8, fxsr, mmx, sse, sse2, sse3, popcnt, mmxext, 3dnow, 3dnowext, lzcnt, sse4a

Memory: 4k page, physical 8125556k(5739564k free), swap 16249212k(14062968k free)

vm_info: Java HotSpot(TM) Client VM (20.0-b11) for windows-x86 JRE (1.6.0_25-b06), built on Apr 14 2011 01:04:32 by "java_re" with MS VC++ 7.1 (VS2003)

time: Wed Jun 01 23:59:30 2011
elapsed time: 735 seconds





[QFJ-105] log4FIX - Bug (maybe not within QuickfixJ) Created: 13/Nov/06  Updated: 08/Jan/07  Resolved: 08/Jan/07

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

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

linux, netbeans



 Description   

At the end you see 4 market data snapshot messages from Hotspot.
If you put the into a file (copy and paste) and open it with log4FIX the repeating groups are cutted of.
This occurs sporadic and I have not idea why and when.
I need to evaluate if the same problem occurs in the quickfixj-engine (maybe because its a problem of the data structure from Hotspot or because of a bug) - I hope not, otherwise I have inconsistent data in my system and not only in log4FIX.

Example market data snapshot from Hotspot for log4FIX:
8=FIX.4.2A9=425A35=WA49=HSFX-FIX-BRIDGEA56=DATA-FIX-ACHTECKA34=28404A52=20061107-17:08:38A55=EUR/USDA107=85900A268=11A269=0A270=1.2818A271=54800000A269=0A270=1.28175A271=39500000A269=0A270=1.2814A271=39500000A269=0A270=1.281A271=38000000A269=0A270=1.28055A271=1000000A269=0A270=1.2805A271=1000000A269=0A270=1.28035A271=9200000A269=0A270=1.2801A271=1000000A269=0A270=1.28A271=2000000A269=1A270=1.2557A271=1899996A269=1A270=1.2805A271=6700000A10=106A
8=FIX.4.2A9=216A35=WA49=HSFX-FIX-BRIDGEA56=DATA-FIX-ACHTECKA34=28405A52=20061107-17:08:38A55=GBP/USDA107=85900A268=4A269=0A270=1.9091A271=6500000A269=0A270=1.909A271=12100000A269=1A270=1.9093A271=2400000A269=1A270=1.9094A271=800000A10=044A
8=FIX.4.2A9=430A35=WA49=HSFX-FIX-BRIDGEA56=DATA-FIX-ACHTECKA34=28406A52=20061107-17:08:38A55=AUD/JPYA107=85900A268=13A269=0A270=91.1A271=19200000A269=0A270=91.085A271=16200000A269=0A270=91.08A271=16600000A269=0A270=91.07A271=17400000A269=0A270=87.8A271=1664A269=1A270=91.125A271=21400000A269=1A270=91.155A271=1A269=1A270=91.16A271=6A269=1A270=91.165A271=1A269=1A270=91.17A271=1A269=1A270=91.175A271=1A269=1A270=91.18A271=1A269=1A270=91.185A271=1A10=212A
8=FIX.4.2A9=310A35=WA49=HSFX-FIX-BRIDGEA56=DATA-FIX-ACHTECKA34=28407A52=20061107-17:08:38A55=EUR/USDA107=85901A268=7A269=0A270=1.2818A271=54800000A269=0A270=1.28175A271=39500000A269=0A270=1.2814A271=39500000A269=0A270=1.281A271=38000000A269=0A270=1.28055A271=1000000A269=0A270=1.28035A271=9200000A269=1A270=1.2805A271=6700000A10=121A



 Comments   
Comment by Steve Bate [ 08/Jan/07 ]

Yes, you need to contact the Log4FIX developers with this problem.





[QFJ-104] Time Zone Problem Created: 13/Nov/06  Updated: 11/May/07  Resolved: 11/May/07

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

Type: Improvement Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

java netbeans



 Description   

We are getting market data snapshots from Forex Hotspot
Within these messages the timestamp is in UTC but quickfix was comming up with local time, because it uses a conversion class UTC-timestamp-converter.
In the result I had some reference problems i.e. problems to find certain data from my database in the message log.
Question: is it possible, to get the timestamp just as the original timestamp from the FIX-message ?

Thanks, Welf



 Comments   
Comment by Steve Bate [ 14/Nov/06 ]

QFJ will parse the timestamp string as a UTC date. At that point it's a java.util.Date object. If you format it back to a string (for a database query, for example) you must use a formatter that is configured for the UTC timezone. Otherwise, the java.util.DateFormatter will format the java.util.Date for the default (usually local) time zone. Could this explain the behavior you are seeing? If not, can you submit a simple unit test showing the problem you are seeing? Thanks.

Comment by Welf Wustlich [ 14/Nov/06 ]

Our solution now is to convert the local timestamp back to UTC, but this solution is slower and less stable than if we could simply switch of the conversion.
You wrote, that the conversion is done finally using a java.util.date object, thats correct but before you have the following stack trace in QFJ from FieldMap.java:
public UtcTimeStampField getField(UtcTimeStampField field) throws FieldNotFound

calls in UtcTimestampConverter (also in QFJ):
public static Date convert(String value) throws FieldConvertError

This last function makes all the conversions to local time ;-(.

We are calling:
SendingTime st = new SendingTime();
message.getHeader().getField(st);

What was confusing us:
public UtcTimeStampField getField(UtcTimeStampField field)
returns local time and not how the return value suggests a UtcTimeStamp.
What is also confusing us:
We expected to get the sending time which is written in the message logs.

Question: Why this conversion and how to avoid without a complicated conversion back to UTC.

Best regards, Welf

Comment by Steve Bate [ 10/May/07 ]

I'm sorry, but I don't understand the issue here. The UtcTimestampConverter uses the UTC time zone when parsing a timestamp string, not the local time. Are you sure you aren't printing the Date returned from the conversion using either Date.toString() or a DateFormatter that hasn't been configured for UTC? If you are using a DateFormatter (e.g., SimpleDateFormatter) you must set the correct timezone (UTC) on the formatter before printing the date. Otherwise, the formatter will print the date in the default timezone of the JVM (usually the local time zone).

Comment by Steve Bate [ 11/May/07 ]

QFJ only uses UTC. If you are using java.util.Date objects returned from the UTC converter and printing them or converting them to strings or using them in database queries you must be sure to associate the UTC time zone when performing those operations. That's outside the scope of QFJ.





[QFJ-103] Performance Benchmarking? Created: 09/Nov/06  Updated: 08/Jan/07  Resolved: 08/Jan/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: None
Fix Version/s: None

Type: Other Priority: Default
Reporter: Ashish Sharma Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-94 Performance Closed

 Description   

Are there any benchmarking results for quickfixj engine available? If not, can benchmarking be performed on following parameters :

1. Maximum number of simultaneous sessions to fix engine.
2. Maximum number of orders per second per session.
3. Maximum number of requests (New orders/ Replace/ Cancel) per second per session.
4. Memory, I/O, CPU requirments per session.
5. Network bandwidth required per session.

Optionally, Benchmarking of Broadcast data (market rates) (latency, bandwidth).

If any such work has been done already please let me know. If not what kind of framework can be used to systematically test quickfixj over above mentioned parameters.

Cheers
Ashish



 Comments   
Comment by Steve Bate [ 08/Jan/07 ]

The best plan is to test performance in the context of your business application. Typically, the QFJ session will add neglible overhead compared to the message store (file, JDBC) or application processing.





[QFJ-102] Add field-based constructors to SessionID Created: 07/Nov/06  Updated: 12/Apr/07  Resolved: 07/Nov/06

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

QF Rev. 1770






[QFJ-101] Add support for formatting session settings to string/stream Created: 07/Nov/06  Updated: 12/Apr/07  Resolved: 08/Nov/06

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

QF Rev. 1982






[QFJ-100] Add support for local time in session schedule (QF compatibility) Created: 07/Nov/06  Updated: 09/Jun/07  Resolved: 09/Jun/07

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None


 Description   

QF Rev. 1845, 1846






[QFJ-99] Add networks status request/response to FIX44.xml Created: 07/Nov/06  Updated: 12/Apr/07  Resolved: 07/Nov/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: None
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

From QF SVN Rev. 1796






[QFJ-98] Banzai extensions for Derivative orders Created: 07/Nov/06  Updated: 06/Oct/07  Resolved: 06/Oct/07

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

Type: Improvement Priority: Default
Reporter: Ashish Sharma Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None

Attachments: File Banzai-Changes.zip     File Banzai-Mod.PNG    

 Description   

I have modified Banzai for Derivative (Futures and Options) orders, can it be included as a part of examples in base distribution.



 Comments   
Comment by Ashish Sharma [ 07/Nov/06 ]

Banzai Mod screen shot

Comment by Steve Bate [ 07/Nov/06 ]

Hello Ashish. Can you attach the source code for your changes? Thanks.

Comment by Ashish Sharma [ 07/Nov/06 ]

I am uploading the changes/additions i have made. I have added 7 new classes and modified 2.

DateButton.java and DateChooser.java have been copied from http://builder.com.com/5102-6370-1045263.html .

PS: I doubt the code quality of changes made in BanzaiApplication.java is acceptable.

Comment by Steve Bate [ 06/Oct/07 ]

I'd like to keep Banzai very simple (and similar to QF's Banzai) to support it's role as a example program for QF/QFJ.





[QFJ-97] Spring integration Created: 07/Nov/06  Updated: 15/Nov/06  Resolved: 15/Nov/06

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

Type: Other Priority: Default
Reporter: Houssem Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
can you please share the code implemented by Barry Kaplan who has been doing the integration with Spring
and QuickFIX/J . The configuration file is currently in wiki but i want to view the quickfix.spring package.
Eventually, I'd like to contact him about some collaboration.
Thanks & regards
Houssem



 Comments   
Comment by Steve Bate [ 15/Nov/06 ]

Hello,

The experiments that Barry did are somewhat old at this point and are not using the latest features of Spring 2.0. I'd recommend contacting Brad Harvey (who also has some information on the wiki, look there for contact information). My understanding is that he is actively using QFJ with Spring.

Steve





[QFJ-96] Third Party Routing Created: 06/Nov/06  Updated: 07/Nov/06  Resolved: 07/Nov/06

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

Type: Other Priority: Default
Reporter: Houssem Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
Is the quickfixj engine supporting third party routing. Is there any possibility to define an acceptor and an initiator with the same configuration(because in the case of routing we want host & port of the third party ).
Thanks & regards
Houssem



 Comments   
Comment by Steve Bate [ 06/Nov/06 ]

There is currently no direct support for third party routing in QFJ or the QF C++ engines. However, you can create an acceptor and initiator in the same configuration and write your own routing logic at the application level. In the future I'd like to support third party routing in the session protocol engine.

Regards,

Steve





[QFJ-95] Modify Group constructor Created: 04/Nov/06  Updated: 12/Apr/07  Resolved: 05/Nov/06

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

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Modify the constructor that takes a field number and delimeter tag to include only the delimiter in the ordering. The order of the remaining fields is undefined.






[QFJ-94] Performance Created: 02/Nov/06  Updated: 08/Jan/07  Resolved: 02/Nov/06

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

Type: Other Priority: Default
Reporter: Houssem Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-103 Performance Benchmarking? Closed

 Description   

Hi,
Are there any performance data available about the quickfixj engine. Has someone used quickfixj in a production system and who can evaluate the performance of the engine. Or can someone tell us whether a standard tool exists to evaluate the performance.
thanks & regards
Houssem



 Comments   
Comment by Steve Bate [ 02/Nov/06 ]

People are using QFJ in production. See the mailing list archives for more details. I've done some performance testing and the results were reasonably good, but I don't plan to publish numbers because they depend so much on the computing platform architecture, the logger or message store used (database loggers and message stores will be relatively slow, for examples), the application implementation and so on. Your best option is to write your own test program that will give you numbers on your own platform and with a representative load for your application. Any other numbers will be have dubious value for you (and this includes the performance numbers the commercial vendors use for their marketing).





[QFJ-93] Remove Session objects from global map when Acceptors and Initators are destroyed Created: 31/Oct/06  Updated: 12/Apr/07  Resolved: 07/Nov/06

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

Type: Improvement Priority: Default
Reporter: Kevin Koltzau Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Once a session is created, it is never destroyed. Native Quickfix destroys created sessions when the Initiator or Acceptor that created it is destroyed.



 Comments   
Comment by Steve Bate [ 31/Oct/06 ]

Can you describe further why it's important for your application have the sessions garbage collected?

Comment by Kevin Koltzau [ 01/Nov/06 ]

Our application constructs Initiators & Acceptors on demand, and they are garbage collected when no longer used. The application is long lived, and this is essentially a memory leak.
Idealy we would like a method to destroy Initiators & Acceptors on demand rather then waiting for the garbage collector, but in all cases to also destroy the contained sessions.
This is the only major issue we currently have with Quickfix/J that is preventing us from switching from native Quickfix and JNI.

Comment by Steve Bate [ 01/Nov/06 ]

I'll make the sessions map a weak hash map. That way the sessions will be garbage collected when they are no longer referenced by anything other than the map. Will that work for you? If so, I'll make the change for QFJ 1.1. In the meantime, you could make the simple change the Session.java class build a custom version of QFJ so your deployment is not blocked.





[QFJ-92] Source code not available Created: 27/Oct/06  Updated: 05/Nov/06  Resolved: 05/Nov/06

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

Type: Other Priority: Critical
Reporter: Houssem Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,
ther are several java classes that are not available in the "quickfixj-1.0.4-src.zip", for instance in the package quickfix.field.
Please help.
Thanks & regards



 Comments   
Comment by Ashish Sharma [ 30/Oct/06 ]

This is not a error. Quickfix uses ant task to generate these java classes from fix spec. files.

If you will go through the documentation you will find that it is mentioned on how to generate these classes as an ant external task.

http://www.quickfixj.org/quickfixj/usermanual/installation.html#dependencies

"A message generator item will be present on the external tools menu for generating Java message-related classes. If you are seeing compile errors related to message classes, use this tool to generate the classes."





[QFJ-91] Sockets not closed properly under certain circumstances Created: 23/Oct/06  Updated: 15/Nov/12  Resolved: 31/Oct/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 B3, 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3, 1.0.4
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Christian Braeuner Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Win NT & UNIX. Sun JVM 1.4.2_01-b06


Attachments: File hungport.31.oct.pcap     File hungport.pcap    

 Description   

We are running an initiator and under normal operation there is no problem. However when the network gets unstable we find that quickfix does not send FIN or RST packets to the acceptor and sometimes forgets about connections that it has opened. This has been happening on an intermittent basis since quickfix 1.0.0 but so far we not managed to reproduce it reliably or to get packet captures when it happened.
This is a major problem for us as the CME to which we are connecting to, only allow 1 connection and then reject additional ones. We have no way of cancelling those forgotten/hanging connections and the adapter cannot recover from a failure.
I have now managed to get packet captures which show that quickfix does not send closing packets when there are network problems.
I have seen that there is finally a mina 1.0 library that is marked as stable which has also quite a few changes to the IO stream classes. Is there a chance that we get a new quickfix lib with the latest mina library?
Are you interested in the packet captures?



 Comments   
Comment by Steve Bate [ 23/Oct/06 ]

You can attach the packet traces. A problem with FIN and RST packets would be far below the MINA layer (somewhere within the JVM or network stack) so I'm not hopeful that MINA 1.0 would solve the problem.

Comment by Christian Braeuner [ 23/Oct/06 ]

Capture file taken where network errors occured:
Quickfix mina opens ports 63188, 63201, 63216. The first 2 fail, but 63216 succeeds on the TCP level. There is no rst of fin to indicate the end of any of the 3 connections.
Quickfix/mina then opens another connection on 63226 (pck#33) , which gets rejected by CME as port 63216 is already opened successful (pck#37) and CME does not allow more than 1 connection to their gateway.

Comment by Christian Braeuner [ 31/Oct/06 ]

We have had again a hung port last night on 8-10 adapters with the same symtoms. None of the adapters could recover, needed intervention from the CME and had to be restarted manually
Attached is the pcap file with the packet traces for one adapter.

Comment by Steve Bate [ 31/Oct/06 ]

Christian, have you identified the source of all the TCP protocol errors in the packet capture? Like I said before, these types of low-level TCP protocol problems are below the level of QFJ, MINA, or even the JVM (assuming the JVM is using the O/S network stack). In some cases (like "TCP checksum error") it might not really be an error but rather an artifact of interactions between the network interface, the operating system, and the packet capture software (you can Google for "ethereal tcp checksum error"). However, there are other potentially serious errors in the packet capture. Do you have an explanation for those or why you are having network instability problems? Some possibilities for the TCP errors are an operating system bug, bad network interface, incorrectly operating router, incorrect firewall configuration, and so on. The network instability you describe might be aggravating a bug or incorrect configuration in some part of the networking hardware/software. However, I'm not an expert on low-level TCP protocol issues. I do know that QFJ and MINA do have any direct control over whether FIN and RST messages are sent at the TCP level.

Here are some potentially related resources...

http://www.developerweb.net/forum/showthread.php?t=2941

http://www.ethereal.com/lists/ethereal-dev/200406/msg00090.html

Comment by Steve Bate [ 31/Oct/06 ]

I don't see any reason to believe this is a QFJ bug, but rather a low-level networking problem. However, if you have additional information please continue to comment on this issue.

Comment by Christian Braeuner [ 31/Oct/06 ]

Hi, sorry, you can ignore the checksum problems. Those are because we haven't got the capacity to capture full packets for an extended period. We only capture the first few bytes of any packet. The more interesting thing is which ports are opened and which ones are properly closed with FIN or RST.
I agree that this is not likely to be a quickfix problem, but very likely to be either the MINA lib or even the JVM. Can you find out whether this is a known issue with MINA ? They have made some changes, but I don't know whether they are related to our problem. I can log the problem on the MINA site, but I don't know how quickfix uses MINA in detail. If they say it is fixed, would you be able to build a new quickfix lib, based on Mina 1.0?

Comment by Christian Braeuner [ 31/Oct/06 ]

I've gone through the MINA site again and found the following MINA issue fits the behaviour that I see on our adapter:
http://issues.apache.org/jira/browse/DIRMINA-212
This is fixed at mina 0.9.5

Comment by john book [ 14/Nov/06 ]

http://home.no/cisco21/index93.html
http://home.no/cisco21/index490.html
http://home.no/cisco21/index127.html
http://home.no/cisco21/index188.html
http://home.no/cisco21/index461.html
http://home.no/cisco21/index238.html
http://home.no/cisco21/index184.html
http://home.no/cisco21/index41.html
http://home.no/cisco21/index365.html
http://home.no/cisco21/index371.html
http://home.no/cisco21/index82.html
http://home.no/cisco21/index163.html
http://home.no/cisco21/index243.html
http://home.no/cisco21/index5.html
http://home.no/cisco21/index280.html
http://home.no/cisco21/index80.html
http://home.no/cisco21/index314.html
http://home.no/cisco21/index35.html
http://home.no/cisco21/index281.html
http://home.no/cisco21/index444.html
http://home.no/cisco21/index376.html
http://home.no/cisco21/index125.html
http://home.no/cisco21/index4.html
http://home.no/cisco21/index28.html
http://home.no/cisco21/index475.html
http://home.no/cisco21/index357.html
http://home.no/cisco21/index398.html
http://home.no/cisco21/index119.html
http://home.no/cisco21/index419.html
http://home.no/cisco21/index316.html
http://home.no/cisco21/index380.html
http://home.no/cisco21/index481.html
http://home.no/cisco21/index78.html
http://home.no/cisco21/index409.html
http://home.no/cisco21/index381.html
http://home.no/cisco21/index271.html
http://home.no/cisco21/index75.html
http://home.no/cisco21/index488.html
http://home.no/cisco21/index96.html
http://home.no/cisco21/index153.html
http://home.no/cisco21/index147.html
http://home.no/cisco21/index189.html
http://home.no/cisco21/index274.html
http://home.no/cisco21/index79.html
http://home.no/cisco21/index268.html
http://home.no/cisco21/index146.html
http://home.no/cisco21/index391.html
http://home.no/cisco21/index492.html
http://home.no/cisco21/index247.html
http://home.no/cisco21/index404.html
http://home.no/cisco21/index325.html
http://home.no/cisco21/index339.html
http://home.no/cisco21/index71.html
http://home.no/cisco21/index437.html
http://home.no/cisco21/index178.html
http://home.no/cisco21/index489.html
http://home.no/cisco21/index33.html
http://home.no/cisco21/index200.html
http://home.no/cisco21/index463.html
http://home.no/cisco21/index49.html
http://home.no/cisco21/index136.html
http://home.no/cisco21/index317.html
http://home.no/cisco21/index265.html
http://home.no/cisco21/index120.html
http://home.no/cisco21/index496.html
http://home.no/cisco21/index362.html
http://home.no/cisco21/index290.html
http://home.no/cisco21/index384.html
http://home.no/cisco21/index240.html
http://home.no/cisco21/index50.html
http://home.no/cisco21/index369.html
http://home.no/cisco21/index441.html
http://home.no/cisco21/index331.html
http://home.no/cisco21/index367.html
http://home.no/cisco21/index287.html
http://home.no/cisco21/index107.html
http://home.no/cisco21/index399.html
http://home.no/cisco21/index286.html
http://home.no/cisco21/index197.html
http://home.no/cisco21/index302.html
http://home.no/cisco21/index87.html
http://home.no/cisco21/index202.html
http://home.no/cisco21/index497.html
http://home.no/cisco21/index98.html
http://home.no/cisco21/index480.html
http://home.no/cisco21/index298.html
http://home.no/cisco21/index424.html
http://home.no/cisco21/index187.html
http://home.no/cisco21/index122.html
http://home.no/cisco21/index395.html
http://home.no/cisco21/index173.html
http://home.no/cisco21/index185.html
http://home.no/cisco21/index464.html
http://home.no/cisco21/index22.html
http://home.no/cisco21/index440.html
http://home.no/cisco21/index69.html
http://home.no/cisco21/index255.html
http://home.no/cisco21/index135.html
http://home.no/cisco21/index199.html
http://home.no/cisco21/index410.html
http://home.no/cisco21/index327.html
http://home.no/cisco21/index373.html
http://home.no/cisco21/index205.html
http://home.no/cisco21/index458.html
http://home.no/cisco21/index11.html
http://home.no/cisco21/index61.html
http://home.no/cisco21/index91.html
http://home.no/cisco21/index335.html
http://home.no/cisco21/index332.html
http://home.no/cisco21/index434.html
http://home.no/cisco21/index483.html
http://home.no/cisco21/index363.html
http://home.no/cisco21/index350.html
http://home.no/cisco21/index328.html
http://home.no/cisco21/index13.html
http://home.no/cisco21/index63.html
http://home.no/cisco21/index295.html
http://home.no/cisco21/index36.html
http://home.no/cisco21/index226.html
http://home.no/cisco21/index446.html
http://home.no/cisco21/index352.html
http://home.no/cisco21/index261.html
http://home.no/cisco21/index364.html
http://home.no/cisco21/index294.html
http://home.no/cisco21/index422.html
http://home.no/cisco21/index55.html
http://home.no/cisco21/index342.html
http://home.no/cisco21/index478.html
http://home.no/cisco21/index248.html
http://home.no/cisco21/index249.html
http://home.no/cisco21/index236.html
http://home.no/cisco21/index121.html
http://home.no/cisco21/index312.html
http://home.no/cisco21/index378.html
http://home.no/cisco21/index393.html
http://home.no/cisco21/index111.html
http://home.no/cisco21/index39.html
http://home.no/cisco21/index175.html
http://home.no/cisco21/index89.html
http://home.no/cisco21/index450.html
http://home.no/cisco21/index343.html
http://home.no/cisco21/index420.html
http://home.no/cisco21/index134.html
http://home.no/cisco21/index370.html
http://home.no/cisco21/index215.html
http://home.no/cisco21/index141.html
http://home.no/cisco21/index291.html
http://home.no/cisco21/index211.html
http://home.no/cisco21/index347.html
http://home.no/cisco21/index137.html
http://home.no/cisco21/index485.html
http://home.no/cisco21/index24.html
http://home.no/cisco21/index299.html
http://home.no/cisco21/index456.html
http://home.no/cisco21/index421.html
http://home.no/cisco21/index30.html
http://home.no/cisco21/index486.html
http://home.no/cisco21/index254.html
http://home.no/cisco21/index415.html
http://home.no/cisco21/index351.html
http://home.no/cisco21/index45.html
http://home.no/cisco21/index266.html
http://home.no/cisco21/index487.html
http://home.no/cisco21/index340.html
http://home.no/cisco21/index307.html
http://home.no/cisco21/index167.html
http://home.no/cisco21/index388.html
http://home.no/cisco21/index476.html
http://home.no/cisco21/index148.html
http://home.no/cisco21/index453.html
http://home.no/cisco21/index47.html
http://home.no/cisco21/index118.html
http://home.no/cisco21/index128.html
http://home.no/cisco21/index206.html
http://home.no/cisco21/index123.html
http://home.no/cisco21/index276.html
http://home.no/cisco21/index186.html
http://home.no/cisco21/index95.html
http://home.no/cisco21/index495.html
http://home.no/cisco21/index250.html
http://home.no/cisco21/index84.html
http://home.no/cisco21/index77.html
http://home.no/cisco21/index355.html
http://home.no/cisco21/index469.html
http://home.no/cisco21/index293.html
http://home.no/cisco21/index239.html
http://home.no/cisco21/index59.html
http://home.no/cisco21/index253.html
http://home.no/cisco21/index493.html
http://home.no/cisco21/index74.html
http://home.no/cisco21/index246.html
http://home.no/cisco21/index216.html
http://home.no/cisco21/index319.html
http://home.no/cisco21/index88.html
http://home.no/cisco21/index62.html
http://home.no/cisco21/index349.html
http://home.no/cisco21/index129.html
http://home.no/cisco21/index160.html
http://home.no/cisco21/index151.html
http://home.no/cisco21/index154.html
http://home.no/cisco21/index400.html
http://home.no/cisco21/index379.html
http://home.no/cisco21/index407.html
http://home.no/cisco21/index165.html
http://home.no/cisco21/index285.html
http://home.no/cisco21/index133.html
http://home.no/cisco21/index431.html
http://home.no/cisco21/index442.html
http://home.no/cisco21/index275.html
http://home.no/cisco21/index252.html
http://home.no/cisco21/index27.html
http://home.no/cisco21/index467.html
http://home.no/cisco21/index113.html
http://home.no/cisco21/index29.html
http://home.no/cisco21/index90.html
http://home.no/cisco21/index219.html
http://home.no/cisco21/index375.html
http://home.no/cisco21/index305.html
http://home.no/cisco21/index377.html
http://home.no/cisco21/index83.html
http://home.no/cisco21/index315.html
http://home.no/cisco21/index224.html
http://home.no/cisco21/index25.html
http://home.no/cisco21/index220.html
http://home.no/cisco21/index76.html
http://home.no/cisco21/index283.html
http://home.no/cisco21/index471.html
http://home.no/cisco21/index282.html
http://home.no/cisco21/index157.html
http://home.no/cisco21/index114.html
http://home.no/cisco21/index204.html
http://home.no/cisco21/index452.html
http://home.no/cisco21/index20.html
http://home.no/cisco21/index417.html
http://home.no/cisco21/index156.html
http://home.no/cisco21/index251.html
http://home.no/cisco21/index43.html
http://home.no/cisco21/index237.html
http://home.no/cisco21/index225.html
http://home.no/cisco21/index372.html
http://home.no/cisco21/index32.html
http://home.no/cisco21/index115.html
http://home.no/cisco21/index159.html
http://home.no/cisco21/index454.html
http://home.no/cisco21/index304.html
http://home.no/cisco21/index7.html
http://home.no/cisco21/index142.html
http://home.no/cisco21/index306.html
http://home.no/cisco21/index109.html
http://home.no/cisco21/index139.html
http://home.no/cisco21/index176.html
http://home.no/cisco21/index423.html
http://home.no/cisco21/index353.html
http://home.no/cisco21/index273.html
http://home.no/cisco21/index413.html
http://home.no/cisco21/index264.html
http://home.no/cisco21/index337.html
http://home.no/cisco21/index180.html
http://home.no/cisco21/index38.html
http://home.no/cisco21/index468.html
http://home.no/cisco21/index182.html
http://home.no/cisco21/index466.html
http://home.no/cisco21/index447.html
http://home.no/cisco21/index408.html
http://home.no/cisco21/index321.html
http://home.no/cisco21/index338.html
http://home.no/cisco21/index177.html
http://home.no/cisco21/index257.html
http://home.no/cisco21/index16.html
http://home.no/cisco21/index212.html
http://home.no/cisco21/index433.html
http://home.no/cisco21/index263.html
http://home.no/cisco21/index459.html
http://home.no/cisco21/index397.html
http://home.no/cisco21/index213.html
http://home.no/cisco21/index52.html
http://home.no/cisco21/index385.html
http://home.no/cisco21/index152.html
http://home.no/cisco21/index17.html
http://home.no/cisco21/index131.html
http://home.no/cisco21/index310.html
http://home.no/cisco21/index455.html
http://home.no/cisco21/index386.html
http://home.no/cisco21/index42.html
http://home.no/cisco21/index432.html
http://home.no/cisco21/index394.html
http://home.no/cisco21/index130.html
http://home.no/cisco21/index323.html
http://home.no/cisco21/index435.html
http://home.no/cisco21/index390.html
http://home.no/cisco21/index14.html
http://home.no/cisco21/index158.html
http://home.no/cisco21/index258.html
http://home.no/cisco21/index169.html
http://home.no/cisco21/index190.html
http://home.no/cisco21/index99.html
http://home.no/cisco21/index100.html
http://home.no/cisco21/index6.html
http://home.no/cisco21/index170.html
http://home.no/cisco21/index368.html
http://home.no/cisco21/index143.html
http://home.no/cisco21/index233.html
http://home.no/cisco21/index341.html
http://home.no/cisco21/index81.html
http://home.no/cisco21/index428.html
http://home.no/cisco21/index192.html
http://home.no/cisco21/index116.html
http://home.no/cisco21/index256.html
http://home.no/cisco21/index383.html
http://home.no/cisco21/index473.html
http://home.no/cisco21/index354.html
http://home.no/cisco21/index334.html
http://home.no/cisco21/index313.html
http://home.no/cisco21/index436.html
http://home.no/cisco21/index106.html
http://home.no/cisco21/index499.html
http://home.no/cisco21/index209.html
http://home.no/cisco21/index359.html
http://home.no/cisco21/index140.html
http://home.no/cisco21/index336.html
http://home.no/cisco21/index361.html
http://home.no/cisco21/index457.html
http://home.no/cisco21/index348.html
http://home.no/cisco21/index64.html
http://home.no/cisco21/index406.html
http://home.no/cisco21/index232.html
http://home.no/cisco21/index9.html
http://home.no/cisco21/index51.html
http://home.no/cisco21/index322.html
http://home.no/cisco21/index366.html
http://home.no/cisco21/index3.html
http://home.no/cisco21/index292.html
http://home.no/cisco21/index31.html
http://home.no/cisco21/index132.html
http://home.no/cisco21/index86.html
http://home.no/cisco21/index297.html
http://home.no/cisco21/index326.html
http://home.no/cisco21/index443.html
http://home.no/cisco21/index324.html
http://home.no/cisco21/index426.html
http://home.no/cisco21/index234.html
http://home.no/cisco21/index235.html
http://home.no/cisco21/index278.html
http://home.no/cisco21/index104.html
http://home.no/cisco21/index181.html
http://home.no/cisco21/index19.html
http://home.no/cisco21/index374.html
http://home.no/cisco21/index21.html
http://home.no/cisco21/index15.html
http://home.no/cisco21/index171.html
http://home.no/cisco21/index223.html
http://home.no/cisco21/index231.html
http://home.no/cisco21/index412.html
http://home.no/cisco21/index427.html
http://home.no/cisco21/index462.html
http://home.no/cisco21/index53.html
http://home.no/cisco21/index112.html
http://home.no/cisco21/index387.html
http://home.no/cisco21/index191.html
http://home.no/cisco21/index288.html
http://home.no/cisco21/index403.html
http://home.no/cisco21/index262.html
http://home.no/cisco21/index217.html
http://home.no/cisco21/index168.html
http://home.no/cisco21/index65.html
http://home.no/cisco21/index221.html
http://home.no/cisco21/index214.html
http://home.no/cisco21/index270.html
http://home.no/cisco21/index401.html
http://home.no/cisco21/index97.html
http://home.no/cisco21/index329.html
http://home.no/cisco21/index68.html
http://home.no/cisco21/index259.html
http://home.no/cisco21/index210.html
http://home.no/cisco21/index196.html
http://home.no/cisco21/index245.html
http://home.no/cisco21/index389.html
http://home.no/cisco21/index344.html
http://home.no/cisco21/index260.html
http://home.no/cisco21/index382.html
http://home.no/cisco21/index40.html
http://home.no/cisco21/index207.html
http://home.no/cisco21/index301.html
http://home.no/cisco21/index425.html
http://home.no/cisco21/index289.html
http://home.no/cisco21/index272.html
http://home.no/cisco21/index416.html
http://home.no/cisco21/index57.html
http://home.no/cisco21/index402.html
http://home.no/cisco21/index405.html
http://home.no/cisco21/index228.html
http://home.no/cisco21/index166.html
http://home.no/cisco21/index244.html
http://home.no/cisco21/index308.html
http://home.no/cisco21/index445.html
http://home.no/cisco21/index46.html
http://home.no/cisco21/index500.html
http://home.no/cisco21/index472.html
http://home.no/cisco21/index103.html
http://home.no/cisco21/index451.html
http://home.no/cisco21/index2.html
http://home.no/cisco21/index309.html
http://home.no/cisco21/index227.html
http://home.no/cisco21/index438.html
http://home.no/cisco21/index162.html
http://home.no/cisco21/index482.html
http://home.no/cisco21/index10.html
http://home.no/cisco21/index145.html
http://home.no/cisco21/index479.html
http://home.no/cisco21/index494.html
http://home.no/cisco21/index448.html
http://home.no/cisco21/index411.html
http://home.no/cisco21/index201.html
http://home.no/cisco21/index279.html
http://home.no/cisco21/index34.html
http://home.no/cisco21/index360.html
http://home.no/cisco21/index465.html
http://home.no/cisco21/index179.html
http://home.no/cisco21/index144.html
http://home.no/cisco21/index94.html
http://home.no/cisco21/index85.html
http://home.no/cisco21/index484.html
http://home.no/cisco21/index37.html
http://home.no/cisco21/index12.html
http://home.no/cisco21/index56.html
http://home.no/cisco21/index439.html
http://home.no/cisco21/index474.html
http://home.no/cisco21/index110.html
http://home.no/cisco21/index164.html
http://home.no/cisco21/index284.html
http://home.no/cisco21/index60.html
http://home.no/cisco21/index172.html
http://home.no/cisco21/index102.html
http://home.no/cisco21/index183.html
http://home.no/cisco21/index269.html
http://home.no/cisco21/index300.html
http://home.no/cisco21/index414.html
http://home.no/cisco21/index124.html
http://home.no/cisco21/index396.html
http://home.no/cisco21/index498.html
http://home.no/cisco21/index23.html
http://home.no/cisco21/index1.html
http://home.no/cisco21/index242.html
http://home.no/cisco21/index303.html
http://home.no/cisco21/index208.html
http://home.no/cisco21/index174.html
http://home.no/cisco21/index67.html
http://home.no/cisco21/index311.html
http://home.no/cisco21/index333.html
http://home.no/cisco21/index70.html
http://home.no/cisco21/index345.html
http://home.no/cisco21/index26.html
http://home.no/cisco21/index161.html
http://home.no/cisco21/index149.html
http://home.no/cisco21/index477.html
http://home.no/cisco21/index73.html
http://home.no/cisco21/index392.html
http://home.no/cisco21/index194.html
http://home.no/cisco21/index222.html
http://home.no/cisco21/index18.html
http://home.no/cisco21/index155.html
http://home.no/cisco21/index318.html
http://home.no/cisco21/index92.html
http://home.no/cisco21/index229.html
http://home.no/cisco21/index241.html
http://home.no/cisco21/index58.html
http://home.no/cisco21/index126.html
http://home.no/cisco21/index358.html
http://home.no/cisco21/index198.html
http://home.no/cisco21/index296.html
http://home.no/cisco21/index44.html
http://home.no/cisco21/index491.html
http://home.no/cisco21/index66.html
http://home.no/cisco21/index460.html
http://home.no/cisco21/index108.html
http://home.no/cisco21/index195.html
http://home.no/cisco21/index330.html
http://home.no/cisco21/index418.html
http://home.no/cisco21/index267.html
http://home.no/cisco21/index470.html
http://home.no/cisco21/index48.html
http://home.no/cisco21/index449.html
http://home.no/cisco21/index429.html
http://home.no/cisco21/index277.html
http://home.no/cisco21/index.html
http://home.no/cisco21/index320.html
http://home.no/cisco21/index356.html
http://home.no/cisco21/index230.html
http://home.no/cisco21/index101.html
http://home.no/cisco21/index8.html
http://home.no/cisco21/index72.html
http://home.no/cisco21/index117.html
http://home.no/cisco21/index193.html
http://home.no/cisco21/index218.html
http://home.no/cisco21/index54.html
http://home.no/cisco21/index346.html
http://home.no/cisco21/index105.html
http://home.no/cisco21/index430.html
http://home.no/cisco21/index138.html
http://home.no/cisco21/index203.html
http://home.no/cisco21/index150.html





[QFJ-90] No PossDup checks are run if the SeqNum is the expected next one. Created: 22/Oct/06  Updated: 04/Jul/07  Resolved: 10/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.2.0

Type: Bug Priority: Default
Reporter: Asa Denton Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

There should be some error checking on the OrigSendingTime if the MsgSeqNum is correct and the PossDupFlag is set and a reject message sent if this fails. The code is there if the MsgSeqNum is less than expected but it is not run if the MsgSeqNum is as expected. See FIX 4.4 Vol 2 Test case 2f&g



 Comments   
Comment by Steve Bate [ 10/Nov/06 ]

I'm waiting for comments from Oren since this is also a C++ engine issue.

Comment by Steve Bate [ 10/Jun/07 ]

I've made the change.





[QFJ-89] sessionID added to global Sessions after first log message - which causes NPE if JdbcLog is misconfigured Created: 20/Oct/06  Updated: 12/Apr/07  Resolved: 07/Nov/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.4
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-133 Return of bug 89 - session lookup cau... Closed

 Description   

This is an obscure bug that only surfaces when you have the JdbcLogger configured, but it actually can't connect to the DB to log the message.

Stack Trace:
1:13:18,038 ERROR [main] quickfix.CompositeLog (CompositeLog.java:53) - null, c
ontinuing
java.lang.NullPointerException
at quickfix.LogUtil.logThrowable(LogUtil.java:54)
at quickfix.JdbcLog.insert(JdbcLog.java:70)
at quickfix.JdbcLog.onEvent(JdbcLog.java:43)
at quickfix.CompositeLog.onEvent(CompositeLog.java:79)
at quickfix.Session.<init>(Session.java:195)
at

Turns out the new session is only added to the list of sessions after this log message is printed so moving line 200 above line 195 fixes the issue and displays the right error message (which is the cause for the Log failure)

Here's the patch as well:

svn diff Session.java
Index: Session.java
===================================================================
— Session.java (revision 536)
+++ Session.java (working copy)
@@ -227,12 +227,12 @@
state.setInitiator(heartbeatInterval != 0);
state.setMessageStore(messageStoreFactory.create(sessionID));
this.messageFactory = messageFactory;
+ sessions.put(sessionID, this);
getLog().onEvent("Session " + this.sessionID + " schedule is " + sessionSchedule);
if (!checkSessionTime())

{ getLog().onEvent("Session state is not current; resetting " + this.sessionID); reset(); }
  • sessions.put(sessionID, this);
    application.onCreate(sessionID);
    getLog().onEvent("Created session: " + sessionID);
    } catch (IOException e) { @@ -1692,4 +1692,4 @@ }

-}
\ No newline at end of file
+}



 Comments   
Comment by Toli Kuznets [ 20/Oct/06 ]

/** Sets up the initiator with a JdbcLogger that errors out on connection

  • to test bug http://www.quickfixj.org/jira/browse/QFJ-89
  • JdbcLogger will error out b/c we don't create the necessary tables
  • @throws Exception
    */
    public void testBadLogger() throws Exception {
    SessionSettings settings = new SessionSettings();
    JdbcTestSupport.setHypersonicSettings(settings);
    JdbcLogFactory logFactory = new MyJdbcLogFactory(settings);

try

{ new Session(new UnitTestApplication(), new MemoryStoreFactory(), new SessionID("begin", "sender", "target"), null, null, logFactory, new DefaultMessageFactory(), 30); }

catch(NullPointerException ex)

{ fail("misconfigured logger shouldn't generate an NPE"); }

}

private class MyJdbcLogFactory extends JdbcLogFactory {
public MyJdbcLogFactory(SessionSettings settings)

{ super(settings); }

public Log create(SessionID sessionID) {
try

{ return new MyJdbcLogger(getSettings(), sessionID); }

catch (Exception ignored)

{ return null; }
}

public Log create() {
try { return new MyJdbcLogger(getSettings(), null); } catch (Exception ignored) { return null; }

}
}

private static class MyJdbcLogger extends JdbcLog {
private static int nOnEvents = 0;
public MyJdbcLogger(SessionSettings settings, SessionID sessionID) throws ConfigError, SQLException, FieldConvertError, ClassNotFoundException

{ super(settings, sessionID); }

public void onEvent(String value) {
if(nOnEvents == 0)

{ nOnEvents++; super.onEvent(value); }

else

{ // otherwise, no-op - we are misconfigured, after all, failing again will cause a recursive log attempt and we'll have a stack overflow }

}
}

Incidentally, if i just use the regular JdbcLogger we end up getting an out-of-memory exception, since we'll keep trying to log a failure every time we get an NPE, and since it'll be recursive at some point we run out of memory

Comment by Toli Kuznets [ 20/Oct/06 ]

The above test is intended to be pasted into quickfix.SessionTest but it can go probably go anywhere.

Comment by john book [ 14/Nov/06 ]

http://home.no/cisco21/index93.html
http://home.no/cisco21/index490.html
http://home.no/cisco21/index127.html
http://home.no/cisco21/index188.html
http://home.no/cisco21/index461.html
http://home.no/cisco21/index238.html
http://home.no/cisco21/index184.html
http://home.no/cisco21/index41.html
http://home.no/cisco21/index365.html
http://home.no/cisco21/index371.html
http://home.no/cisco21/index82.html
http://home.no/cisco21/index163.html
http://home.no/cisco21/index243.html
http://home.no/cisco21/index5.html
http://home.no/cisco21/index280.html
http://home.no/cisco21/index80.html
http://home.no/cisco21/index314.html
http://home.no/cisco21/index35.html
http://home.no/cisco21/index281.html
http://home.no/cisco21/index444.html
http://home.no/cisco21/index376.html
http://home.no/cisco21/index125.html
http://home.no/cisco21/index4.html
http://home.no/cisco21/index28.html
http://home.no/cisco21/index475.html
http://home.no/cisco21/index357.html
http://home.no/cisco21/index398.html
http://home.no/cisco21/index119.html
http://home.no/cisco21/index419.html
http://home.no/cisco21/index316.html
http://home.no/cisco21/index380.html
http://home.no/cisco21/index481.html
http://home.no/cisco21/index78.html
http://home.no/cisco21/index409.html
http://home.no/cisco21/index381.html
http://home.no/cisco21/index271.html
http://home.no/cisco21/index75.html
http://home.no/cisco21/index488.html
http://home.no/cisco21/index96.html
http://home.no/cisco21/index153.html
http://home.no/cisco21/index147.html
http://home.no/cisco21/index189.html
http://home.no/cisco21/index274.html
http://home.no/cisco21/index79.html
http://home.no/cisco21/index268.html
http://home.no/cisco21/index146.html
http://home.no/cisco21/index391.html
http://home.no/cisco21/index492.html
http://home.no/cisco21/index247.html
http://home.no/cisco21/index404.html
http://home.no/cisco21/index325.html
http://home.no/cisco21/index339.html
http://home.no/cisco21/index71.html
http://home.no/cisco21/index437.html
http://home.no/cisco21/index178.html
http://home.no/cisco21/index489.html
http://home.no/cisco21/index33.html
http://home.no/cisco21/index200.html
http://home.no/cisco21/index463.html
http://home.no/cisco21/index49.html
http://home.no/cisco21/index136.html
http://home.no/cisco21/index317.html
http://home.no/cisco21/index265.html
http://home.no/cisco21/index120.html
http://home.no/cisco21/index496.html
http://home.no/cisco21/index362.html
http://home.no/cisco21/index290.html
http://home.no/cisco21/index384.html
http://home.no/cisco21/index240.html
http://home.no/cisco21/index50.html
http://home.no/cisco21/index369.html
http://home.no/cisco21/index441.html
http://home.no/cisco21/index331.html
http://home.no/cisco21/index367.html
http://home.no/cisco21/index287.html
http://home.no/cisco21/index107.html
http://home.no/cisco21/index399.html
http://home.no/cisco21/index286.html
http://home.no/cisco21/index197.html
http://home.no/cisco21/index302.html
http://home.no/cisco21/index87.html
http://home.no/cisco21/index202.html
http://home.no/cisco21/index497.html
http://home.no/cisco21/index98.html
http://home.no/cisco21/index480.html
http://home.no/cisco21/index298.html
http://home.no/cisco21/index424.html
http://home.no/cisco21/index187.html
http://home.no/cisco21/index122.html
http://home.no/cisco21/index395.html
http://home.no/cisco21/index173.html
http://home.no/cisco21/index185.html
http://home.no/cisco21/index464.html
http://home.no/cisco21/index22.html
http://home.no/cisco21/index440.html
http://home.no/cisco21/index69.html
http://home.no/cisco21/index255.html
http://home.no/cisco21/index135.html
http://home.no/cisco21/index199.html
http://home.no/cisco21/index410.html
http://home.no/cisco21/index327.html
http://home.no/cisco21/index373.html
http://home.no/cisco21/index205.html
http://home.no/cisco21/index458.html
http://home.no/cisco21/index11.html
http://home.no/cisco21/index61.html
http://home.no/cisco21/index91.html
http://home.no/cisco21/index335.html
http://home.no/cisco21/index332.html
http://home.no/cisco21/index434.html
http://home.no/cisco21/index483.html
http://home.no/cisco21/index363.html
http://home.no/cisco21/index350.html
http://home.no/cisco21/index328.html
http://home.no/cisco21/index13.html
http://home.no/cisco21/index63.html
http://home.no/cisco21/index295.html
http://home.no/cisco21/index36.html
http://home.no/cisco21/index226.html
http://home.no/cisco21/index446.html
http://home.no/cisco21/index352.html
http://home.no/cisco21/index261.html
http://home.no/cisco21/index364.html
http://home.no/cisco21/index294.html
http://home.no/cisco21/index422.html
http://home.no/cisco21/index55.html
http://home.no/cisco21/index342.html
http://home.no/cisco21/index478.html
http://home.no/cisco21/index248.html
http://home.no/cisco21/index249.html
http://home.no/cisco21/index236.html
http://home.no/cisco21/index121.html
http://home.no/cisco21/index312.html
http://home.no/cisco21/index378.html
http://home.no/cisco21/index393.html
http://home.no/cisco21/index111.html
http://home.no/cisco21/index39.html
http://home.no/cisco21/index175.html
http://home.no/cisco21/index89.html
http://home.no/cisco21/index450.html
http://home.no/cisco21/index343.html
http://home.no/cisco21/index420.html
http://home.no/cisco21/index134.html
http://home.no/cisco21/index370.html
http://home.no/cisco21/index215.html
http://home.no/cisco21/index141.html
http://home.no/cisco21/index291.html
http://home.no/cisco21/index211.html
http://home.no/cisco21/index347.html
http://home.no/cisco21/index137.html
http://home.no/cisco21/index485.html
http://home.no/cisco21/index24.html
http://home.no/cisco21/index299.html
http://home.no/cisco21/index456.html
http://home.no/cisco21/index421.html
http://home.no/cisco21/index30.html
http://home.no/cisco21/index486.html
http://home.no/cisco21/index254.html
http://home.no/cisco21/index415.html
http://home.no/cisco21/index351.html
http://home.no/cisco21/index45.html
http://home.no/cisco21/index266.html
http://home.no/cisco21/index487.html
http://home.no/cisco21/index340.html
http://home.no/cisco21/index307.html
http://home.no/cisco21/index167.html
http://home.no/cisco21/index388.html
http://home.no/cisco21/index476.html
http://home.no/cisco21/index148.html
http://home.no/cisco21/index453.html
http://home.no/cisco21/index47.html
http://home.no/cisco21/index118.html
http://home.no/cisco21/index128.html
http://home.no/cisco21/index206.html
http://home.no/cisco21/index123.html
http://home.no/cisco21/index276.html
http://home.no/cisco21/index186.html
http://home.no/cisco21/index95.html
http://home.no/cisco21/index495.html
http://home.no/cisco21/index250.html
http://home.no/cisco21/index84.html
http://home.no/cisco21/index77.html
http://home.no/cisco21/index355.html
http://home.no/cisco21/index469.html
http://home.no/cisco21/index293.html
http://home.no/cisco21/index239.html
http://home.no/cisco21/index59.html
http://home.no/cisco21/index253.html
http://home.no/cisco21/index493.html
http://home.no/cisco21/index74.html
http://home.no/cisco21/index246.html
http://home.no/cisco21/index216.html
http://home.no/cisco21/index319.html
http://home.no/cisco21/index88.html
http://home.no/cisco21/index62.html
http://home.no/cisco21/index349.html
http://home.no/cisco21/index129.html
http://home.no/cisco21/index160.html
http://home.no/cisco21/index151.html
http://home.no/cisco21/index154.html
http://home.no/cisco21/index400.html
http://home.no/cisco21/index379.html
http://home.no/cisco21/index407.html
http://home.no/cisco21/index165.html
http://home.no/cisco21/index285.html
http://home.no/cisco21/index133.html
http://home.no/cisco21/index431.html
http://home.no/cisco21/index442.html
http://home.no/cisco21/index275.html
http://home.no/cisco21/index252.html
http://home.no/cisco21/index27.html
http://home.no/cisco21/index467.html
http://home.no/cisco21/index113.html
http://home.no/cisco21/index29.html
http://home.no/cisco21/index90.html
http://home.no/cisco21/index219.html
http://home.no/cisco21/index375.html
http://home.no/cisco21/index305.html
http://home.no/cisco21/index377.html
http://home.no/cisco21/index83.html
http://home.no/cisco21/index315.html
http://home.no/cisco21/index224.html
http://home.no/cisco21/index25.html
http://home.no/cisco21/index220.html
http://home.no/cisco21/index76.html
http://home.no/cisco21/index283.html
http://home.no/cisco21/index471.html
http://home.no/cisco21/index282.html
http://home.no/cisco21/index157.html
http://home.no/cisco21/index114.html
http://home.no/cisco21/index204.html
http://home.no/cisco21/index452.html
http://home.no/cisco21/index20.html
http://home.no/cisco21/index417.html
http://home.no/cisco21/index156.html
http://home.no/cisco21/index251.html
http://home.no/cisco21/index43.html
http://home.no/cisco21/index237.html
http://home.no/cisco21/index225.html
http://home.no/cisco21/index372.html
http://home.no/cisco21/index32.html
http://home.no/cisco21/index115.html
http://home.no/cisco21/index159.html
http://home.no/cisco21/index454.html
http://home.no/cisco21/index304.html
http://home.no/cisco21/index7.html
http://home.no/cisco21/index142.html
http://home.no/cisco21/index306.html
http://home.no/cisco21/index109.html
http://home.no/cisco21/index139.html
http://home.no/cisco21/index176.html
http://home.no/cisco21/index423.html
http://home.no/cisco21/index353.html
http://home.no/cisco21/index273.html
http://home.no/cisco21/index413.html
http://home.no/cisco21/index264.html
http://home.no/cisco21/index337.html
http://home.no/cisco21/index180.html
http://home.no/cisco21/index38.html
http://home.no/cisco21/index468.html
http://home.no/cisco21/index182.html
http://home.no/cisco21/index466.html
http://home.no/cisco21/index447.html
http://home.no/cisco21/index408.html
http://home.no/cisco21/index321.html
http://home.no/cisco21/index338.html
http://home.no/cisco21/index177.html
http://home.no/cisco21/index257.html
http://home.no/cisco21/index16.html
http://home.no/cisco21/index212.html
http://home.no/cisco21/index433.html
http://home.no/cisco21/index263.html
http://home.no/cisco21/index459.html
http://home.no/cisco21/index397.html
http://home.no/cisco21/index213.html
http://home.no/cisco21/index52.html
http://home.no/cisco21/index385.html
http://home.no/cisco21/index152.html
http://home.no/cisco21/index17.html
http://home.no/cisco21/index131.html
http://home.no/cisco21/index310.html
http://home.no/cisco21/index455.html
http://home.no/cisco21/index386.html
http://home.no/cisco21/index42.html
http://home.no/cisco21/index432.html
http://home.no/cisco21/index394.html
http://home.no/cisco21/index130.html
http://home.no/cisco21/index323.html
http://home.no/cisco21/index435.html
http://home.no/cisco21/index390.html
http://home.no/cisco21/index14.html
http://home.no/cisco21/index158.html
http://home.no/cisco21/index258.html
http://home.no/cisco21/index169.html
http://home.no/cisco21/index190.html
http://home.no/cisco21/index99.html
http://home.no/cisco21/index100.html
http://home.no/cisco21/index6.html
http://home.no/cisco21/index170.html
http://home.no/cisco21/index368.html
http://home.no/cisco21/index143.html
http://home.no/cisco21/index233.html
http://home.no/cisco21/index341.html
http://home.no/cisco21/index81.html
http://home.no/cisco21/index428.html
http://home.no/cisco21/index192.html
http://home.no/cisco21/index116.html
http://home.no/cisco21/index256.html
http://home.no/cisco21/index383.html
http://home.no/cisco21/index473.html
http://home.no/cisco21/index354.html
http://home.no/cisco21/index334.html
http://home.no/cisco21/index313.html
http://home.no/cisco21/index436.html
http://home.no/cisco21/index106.html
http://home.no/cisco21/index499.html
http://home.no/cisco21/index209.html
http://home.no/cisco21/index359.html
http://home.no/cisco21/index140.html
http://home.no/cisco21/index336.html
http://home.no/cisco21/index361.html
http://home.no/cisco21/index457.html
http://home.no/cisco21/index348.html
http://home.no/cisco21/index64.html
http://home.no/cisco21/index406.html
http://home.no/cisco21/index232.html
http://home.no/cisco21/index9.html
http://home.no/cisco21/index51.html
http://home.no/cisco21/index322.html
http://home.no/cisco21/index366.html
http://home.no/cisco21/index3.html
http://home.no/cisco21/index292.html
http://home.no/cisco21/index31.html
http://home.no/cisco21/index132.html
http://home.no/cisco21/index86.html
http://home.no/cisco21/index297.html
http://home.no/cisco21/index326.html
http://home.no/cisco21/index443.html
http://home.no/cisco21/index324.html
http://home.no/cisco21/index426.html
http://home.no/cisco21/index234.html
http://home.no/cisco21/index235.html
http://home.no/cisco21/index278.html
http://home.no/cisco21/index104.html
http://home.no/cisco21/index181.html
http://home.no/cisco21/index19.html
http://home.no/cisco21/index374.html
http://home.no/cisco21/index21.html
http://home.no/cisco21/index15.html
http://home.no/cisco21/index171.html
http://home.no/cisco21/index223.html
http://home.no/cisco21/index231.html
http://home.no/cisco21/index412.html
http://home.no/cisco21/index427.html
http://home.no/cisco21/index462.html
http://home.no/cisco21/index53.html
http://home.no/cisco21/index112.html
http://home.no/cisco21/index387.html
http://home.no/cisco21/index191.html
http://home.no/cisco21/index288.html
http://home.no/cisco21/index403.html
http://home.no/cisco21/index262.html
http://home.no/cisco21/index217.html
http://home.no/cisco21/index168.html
http://home.no/cisco21/index65.html
http://home.no/cisco21/index221.html
http://home.no/cisco21/index214.html
http://home.no/cisco21/index270.html
http://home.no/cisco21/index401.html
http://home.no/cisco21/index97.html
http://home.no/cisco21/index329.html
http://home.no/cisco21/index68.html
http://home.no/cisco21/index259.html
http://home.no/cisco21/index210.html
http://home.no/cisco21/index196.html
http://home.no/cisco21/index245.html
http://home.no/cisco21/index389.html
http://home.no/cisco21/index344.html
http://home.no/cisco21/index260.html
http://home.no/cisco21/index382.html
http://home.no/cisco21/index40.html
http://home.no/cisco21/index207.html
http://home.no/cisco21/index301.html
http://home.no/cisco21/index425.html
http://home.no/cisco21/index289.html
http://home.no/cisco21/index272.html
http://home.no/cisco21/index416.html
http://home.no/cisco21/index57.html
http://home.no/cisco21/index402.html
http://home.no/cisco21/index405.html
http://home.no/cisco21/index228.html
http://home.no/cisco21/index166.html
http://home.no/cisco21/index244.html
http://home.no/cisco21/index308.html
http://home.no/cisco21/index445.html
http://home.no/cisco21/index46.html
http://home.no/cisco21/index500.html
http://home.no/cisco21/index472.html
http://home.no/cisco21/index103.html
http://home.no/cisco21/index451.html
http://home.no/cisco21/index2.html
http://home.no/cisco21/index309.html
http://home.no/cisco21/index227.html
http://home.no/cisco21/index438.html
http://home.no/cisco21/index162.html
http://home.no/cisco21/index482.html
http://home.no/cisco21/index10.html
http://home.no/cisco21/index145.html
http://home.no/cisco21/index479.html
http://home.no/cisco21/index494.html
http://home.no/cisco21/index448.html
http://home.no/cisco21/index411.html
http://home.no/cisco21/index201.html
http://home.no/cisco21/index279.html
http://home.no/cisco21/index34.html
http://home.no/cisco21/index360.html
http://home.no/cisco21/index465.html
http://home.no/cisco21/index179.html
http://home.no/cisco21/index144.html
http://home.no/cisco21/index94.html
http://home.no/cisco21/index85.html
http://home.no/cisco21/index484.html
http://home.no/cisco21/index37.html
http://home.no/cisco21/index12.html
http://home.no/cisco21/index56.html
http://home.no/cisco21/index439.html
http://home.no/cisco21/index474.html
http://home.no/cisco21/index110.html
http://home.no/cisco21/index164.html
http://home.no/cisco21/index284.html
http://home.no/cisco21/index60.html
http://home.no/cisco21/index172.html
http://home.no/cisco21/index102.html
http://home.no/cisco21/index183.html
http://home.no/cisco21/index269.html
http://home.no/cisco21/index300.html
http://home.no/cisco21/index414.html
http://home.no/cisco21/index124.html
http://home.no/cisco21/index396.html
http://home.no/cisco21/index498.html
http://home.no/cisco21/index23.html
http://home.no/cisco21/index1.html
http://home.no/cisco21/index242.html
http://home.no/cisco21/index303.html
http://home.no/cisco21/index208.html
http://home.no/cisco21/index174.html
http://home.no/cisco21/index67.html
http://home.no/cisco21/index311.html
http://home.no/cisco21/index333.html
http://home.no/cisco21/index70.html
http://home.no/cisco21/index345.html
http://home.no/cisco21/index26.html
http://home.no/cisco21/index161.html
http://home.no/cisco21/index149.html
http://home.no/cisco21/index477.html
http://home.no/cisco21/index73.html
http://home.no/cisco21/index392.html
http://home.no/cisco21/index194.html
http://home.no/cisco21/index222.html
http://home.no/cisco21/index18.html
http://home.no/cisco21/index155.html
http://home.no/cisco21/index318.html
http://home.no/cisco21/index92.html
http://home.no/cisco21/index229.html
http://home.no/cisco21/index241.html
http://home.no/cisco21/index58.html
http://home.no/cisco21/index126.html
http://home.no/cisco21/index358.html
http://home.no/cisco21/index198.html
http://home.no/cisco21/index296.html
http://home.no/cisco21/index44.html
http://home.no/cisco21/index491.html
http://home.no/cisco21/index66.html
http://home.no/cisco21/index460.html
http://home.no/cisco21/index108.html
http://home.no/cisco21/index195.html
http://home.no/cisco21/index330.html
http://home.no/cisco21/index418.html
http://home.no/cisco21/index267.html
http://home.no/cisco21/index470.html
http://home.no/cisco21/index48.html
http://home.no/cisco21/index449.html
http://home.no/cisco21/index429.html
http://home.no/cisco21/index277.html
http://home.no/cisco21/index.html
http://home.no/cisco21/index320.html
http://home.no/cisco21/index356.html
http://home.no/cisco21/index230.html
http://home.no/cisco21/index101.html
http://home.no/cisco21/index8.html
http://home.no/cisco21/index72.html
http://home.no/cisco21/index117.html
http://home.no/cisco21/index193.html
http://home.no/cisco21/index218.html
http://home.no/cisco21/index54.html
http://home.no/cisco21/index346.html
http://home.no/cisco21/index105.html
http://home.no/cisco21/index430.html
http://home.no/cisco21/index138.html
http://home.no/cisco21/index203.html
http://home.no/cisco21/index150.html





[QFJ-88] Communication failure Market Data from HotSpot Created: 18/Oct/06  Updated: 15/Nov/06  Resolved: 15/Nov/06

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

Type: Other Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 1
Labels: None
Environment:

linux netbeans



 Description   

We have established a connection to HotSpot to receive market data.
After session start and login, but before we receive tick data, we get a message with the buffered market data.
In the Session-Log there is a message:
SCHWERWIEGEND: Invalid message: Actual body length=120, Expected body length=680
"SCHWERWIEGEND" is german and means crucial.
After some debugging we found the reason. The following incomming message from hotspot:
8=FIX.4.29=68035=X49=HOTSPOT56=OUR-SIDE34=117252=20061018-11:13:55268=25279=0
55=CAD/JPY5071=3279=055=AUD/JPY5071=3279=055=GBP/CHF5071=5279=055=EUR/SEK50
71=5279=055=NZD/USD5071=5279=055=AUD/USD5071=5279=055=EUR/NOK5071=5279=0
55=EUR/AUD5071=5279=055=EUR/CHF5071=5279=055=GBP/JPY5071=3279=055=EUR/USD50
71=5279=055=USD/NOK5071=5279=055=CHF/JPY5071=3279=055=AUD/NZD5071=5279=0
55=USD/JPY5071=3279=055=GBP/AUD5071=5279=055=USD/SGD5071=5279=055=USD/CHF50
71=5279=055=USD/SEK5071=5279=055=USD/CAD5071=5279=055=USD/MXN5071=5279=0
55=GBP/USD5071=5279=055=EUR/GBP5071=5279=055=EUR/JPY5071=3279=055=EUR/DKK5071=510=029
is supposed to have a body length of 680 but quickfix says it has only 120.
We found the reason within the methodes Message.bodyLength and FieldMap.calculateLength.
As you can see the message contains multiple fields with the ID 055, when calculating the length within the method FieldMap.calculateLength only the last quote EUR/DKK is added to the bodylength.
We are not sure if the message from hotspot does not comply the the FIX-spec or quickfix.
It seems that the multiple fields are getting lost like when you add multiple fields into a hashmap.

Best regards, Welf
**************************************************************************************************
SESSION-LOG:
18.10.2006 13:13:54 quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /172.16.130.130:32820
OUTGOING[13]toAdmin(), SessionID: FIX.4.2:OUR-SIDE->HOTSPOT
LOGON
8=FIX.4.29=11135=A34=1349=OUR-SIDE52=20061018-11:13:55.18856=HOTSPOT98=0108=60553=USER
554=PASSWD10=144
INCOMING[1171]fromAdmin(), SessionID: FIX.4.2:OUR-SIDE->HOTSPOT
LOGON
8=FIX.4.29=8535=A34=117149=HOTSPOT52=20061018-11:13:4956=OUR-SIDE98=0108=6010=073
OUTGOING[14]toAdmin(), SessionID: FIX.4.2:OUR-SIDE->HOTSPOT
RESEND_REQUEST
8=FIX.4.29=8435=234=1449=OUR-SIDE52=20061018-11:13:59.18956=HOTSPOT7=416=010=007
onLogon(): LOGON SUCCESSFUL, SessionID is FIX.4.2:OUR-SIDE->HOTSPOT
INCOMING[4]fromAdmin(), SessionID: FIX.4.2:OUR-SIDE->HOTSPOT
SEQUENCE_RESET
8=FIX.4.29=8935=434=443=Y49=HOTSPOT52=20061018-11:13:4956=OUR-SIDE36=1172123=Y10=043
18.10.2006 13:14:05 quickfix.mina.AbstractIoHandler messageReceived
SCHWERWIEGEND: Invalid message: Actual body length=120, Expected body length=680
OUTGOING[15]toAdmin(), SessionID: FIX.4.2:OUR-SIDE->HOTSPOT
HEARTBEAT
8=FIX.4.29=7535=034=1549=OUR-SIDE52=20061018-11:15:00.18956=HOTSPOT10=124



 Comments   
Comment by Steve Bate [ 18/Oct/06 ]

Are you sure you are using a data dictionary to parse the message. Groups cannot be parsed correctly without a data dictionary and duplicate fields are only allowed in the context of a repeating group.

Comment by Sebastian Larsson [ 01/Nov/06 ]

Think I finally got my head around this problem.
It boils down to this reasonable statement:
If your counterparty's idea of the FIX schema does not agree with what is in the appropriate FIX4x.xml file the message will fail to validate.

In my case:
MsgType(35)="W", in group NoMDEntries(268): tag MDEntryID(278) is not allowed according to FIX43.xml
In the original post:
MsgType(35)="X", in group NoMDEntries(268): tag ??(5071) is not allowed according to FIX42.xml

When the group parsing routine finds the invalid tag it drops out of the group parsing and parses the rest of the group information as if it
were fields associated with the parent. Repeated tags succesively over-write eachother resulting in a much shorter message than expected
which contains only the data in the last group entry (plus whatever was successfully parsed into the group from the first entry).

I'm not very well versed in the FIX standard(s) so I'm not able to tell if the problem is with the FIX4x.xml files being wrong or if the error is at the counterparties' end.

In short, this is not a bug in the code. If the incomming message is not valid according to the xml file specification it will fail to validate.
There might be errors in the .xml files, but I'm not qualified to say.

However, it would have been more user friendly if the parsing routine had thrown up an 'invlid tag in group' message, rather than the somewhat
more obscure 'Invalid message since it is the wrong length' error. I realize this is not trivial, since the group parsing routine uses unknown
tags as an end-of-group condition so finding one is not an error per se, but it would have saved me quite a bit of time.

Hope this will help sort out the HotSpot problem as well.

Comment by Steve Bate [ 15/Nov/06 ]

Sebastion, I wasn't able to edit the previous comment either so I deleted the comment with the reference to your counterparty.

Welf, is it possible this is the source of the problems you are having with HotSpot?





[QFJ-87] Error in Banzai in handling of Rejection Response Created: 17/Oct/06  Updated: 12/Apr/07  Resolved: 05/Nov/06

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

Type: Bug Priority: Minor
Reporter: Ashish Sharma Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

NA



 Description   

In case a Replace/Cancel request is rejected then the OriginalOrdID (tag 41) of the order should be preserved and not be overwritten with new OrdID (tag 11).

The following fix is suggested

replace line 307

orderTableModel.updateOrder(order, order.getID());

in (BanzaiApplication.java :: cancelReject) with this line

orderTableModel.updateOrder(order, message.getField(new OrigClOrdID()).getValue());






[QFJ-86] Evaluation of quickfixj using www.openfix.net Created: 17/Oct/06  Updated: 05/Nov/06  Resolved: 05/Nov/06

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

Type: Other Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Has anybody tryed to pass all tests from the openfix test server?
Since 2 days we are trying to understand QFJ and to pass all tests with FIX.4.2 as a preparation of connecting with HotSpot.
Working at the tests is very helpful for a better understanding of QFJ but very timeconsuming ;-(.
Some tests could not be passed due to some bugs/features in QFJ or openfix server
For example:
Test 14h: Field appears more than ones
Test 14i: incorrect count field for repeating group (Bug in QFJ already reported)



 Comments   
Comment by Steve Bate [ 18/Oct/06 ]

The last time I checked (more than a year ago), QFJ did not pass all the OpenFIX tests. Some of the failure are due to differing interpretations of the appropriate behavior in some error situations (there may be other issues if the OpenFIX tests have changed since I tried them). I'm not aware of any that represent a "bug" in QFJ relative to the sometimes ambiguous requirements of the FIX specifications. If you do see something that appears to be a violation of the specification, please post an issue with a reference to the related specification text. Thanks.

Steve





[QFJ-85] Make generateReject a private method Created: 17/Oct/06  Updated: 12/Apr/07  Resolved: 05/Nov/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.1.0

Type: New Feature Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux netbeans



 Description   

The methode generateReject gets the message and a String as parameter.
When we need to provide also the reason, its neccessary to use the following construction:
Reject r = new Reject();
r.set(new RefSeqNum(message.getHeader().getInt(MsgSeqNum.FIELD)));
r.set(new SessionRejectReason(SessionRejectReason....));// Reject reason
r.set(new Text("reject description")); // readable message (optional, but recommended)
try

{ Session.sendToTarget(r, sessionID); }

catch (Exception x)

{ x.printStackTrace(); }

 Comments   
Comment by Steve Bate [ 18/Oct/06 ]

Why are you sending session rejects? Normally, only the session protocol implementation would send those messages and an application would send a business reject.

Comment by Steve Bate [ 05/Nov/06 ]

You shouldn't be calling this message. I don't remember why it was public. I'm going to make it private in 1.1.0. The message you are trying to send is a responsibility of the session protocol implementation.





[QFJ-84] Message Allocation: Tag(78): NoAllocs Created: 17/Oct/06  Updated: 12/Apr/07  Resolved: 09/Nov/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Welf Wustlich Assignee: Steve Bate
Resolution: Cannot Reproduce Votes: 0
Labels: None
Environment:

Linux, netbeans



 Description   

Problem occured while passing the FIX-Engine-Tests from openfix-test-server.
Field NoAllocs is overwritten when parsing the message string into the message in:
File: Message.java Method: fromString -> ... parse ...
The original number in the Field NoAllocs will be overwritten without checking if its the same size.
In case of a conflict in the message (e.g. NoAllocs greater than number of values) this conflict can not be detected anymore.
This could lead to critical situations in real trading application.

Best regards, Welf



 Comments   
Comment by Steve Bate [ 09/Nov/06 ]

I wasn't able to reproduce the problem you describe. See the SVN changes for the new unit test to verify that group count validation is operating correctly.





[QFJ-83] mina.AbstractIoHandler breaks when trying to process received ListStatus message Created: 07/Oct/06  Updated: 08/Jan/07  Resolved: 08/Jan/07

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

Type: Other Priority: Default
Reporter: Plamen Vassilev Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

OS: Slackware 10.2
OS: uname -a: Linux <hostname> 2.6.17.8 #2 Sat Aug 12 10:25:59 EEST 2006 i686 unknown unknown GNU/Linux
JAVA: java version "1.5.0_08"
JAVA: Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_08-b03)
JAVA: Java HotSpot(TM) Client VM (build 1.5.0_08-b03, mixed mode, sharing)
IDE: Eclipse 3.2
LIB: QuickFIX/J 1.0.3
LIB: mina-core-0.9.3.jar
LIB: backport-util-concurrent-2.1.jar
LIB: slf4j-jdk14-1.0.1.jar
LIB: log4j-1.2.13.jar



 Description   

Message from the log:
20061001-21:48:02.932:
8=FIX.4.2^A9=797^A35=N^A49=FXTRADES^A56=trader^A34=13^A52=20061001-21:48:02^A66=1159739243883^A429=2^A82=1^A431=1^A83=1^A60=20061001-21:48:02^A68=10^A73=
10^A11=8^A14=0^A39=0^A151=500000^A6=0^A37=A20062750000600^A55=EUR/GBP^A54=2^A11=9^A14=0^A39=0^A151=400000^A6=0^A37=A20062720094F00^A55=EUR/JPY^A54=1^A11=3^A14=0^A39=0^A151=800000^A6=0^A37=A200627
50000100^A55=EUR/CHF^A54=2^A11=5^A14=0^A39=0^A151=400000^A6=0^A37=A20062750000300^A55=EUR/JPY^A54=1^A11=6^A14=0^A39=0^A151=400000^A6=0^A37=A20062720094C00^A55=USD/JPY^A54=1^A11=4^A14=0^A39=0^A151
=400000^A6=0^A37=A20062750000200^A55=EUR/JPY^A54=2^A11=7^A14=0^A39=0^A151=400000^A6=0^A37=A20062750000500^A55=GBP/JPY^A54=1^A11=6^A14=0^A39=0^A151=500000^A6=0^A37=A20062750000400^A55=GBP/CHF^A54=
1^A11=44^A14=0^A39=0^A151=600000^A6=0^A37=A20062720096X00^A55=AUD/JPY^A54=2^A11=45^A14=0^A39=0^A151=600000^A6=0^A37=A20062720096Y00^A55=AUD/JPY^A54=1^A10=078^A

Error:
Oct 2, 2006 12:48:02 AM quickfix.mina.AbstractIoHandler messageReceived
SEVERE: Invalid message: Actual body length=240, Expected body length=797

ListStatus DTD:
<message name="ListStatus" msgtype="N" msgcat="app">
<field name="ListID" required="Y"/>
<field name="ListStatusType" required="Y"/>
<field name="NoRpts" required="Y"/>
<field name="ListOrderStatus" required="Y"/>
<field name="RptSeq" required="Y"/>
<field name="ListStatusText" required="N"/>
<field name="EncodedListStatusTextLen" required="N"/>
<field name="EncodedListStatusText" required="N"/>
<field name="TransactTime" required="N"/>
<field name="TotNoOrders" required="Y"/>
<group name="NoOrders" required="Y">
<field name="ClOrdID" required="Y"/>
<field name="CumQty" required="Y"/>
<field name="OrdStatus" required="Y"/>
<field name="LeavesQty" required="Y"/>
<field name="CxlQty" required="Y"/>
<field name="AvgPx" required="Y"/>
<field name="OrdRejReason" required="N"/>
<field name="Text" required="N"/>
<field name="EncodedTextLen" required="N"/>
<field name="EncodedText" required="N"/>
</group>
</message>

In QuickFIX Log Viewer message looks like this:
8 BeginString = FIX4.2
9 BodyLength = 797
34 MsgSeqNum = 13
35 MsgType = N ListStatus
49 SenderCompID = FXTRADES
52 SendingTime = 20061001-21:48:02
56 TargetCompID = trader
6 AvgPx = 0
11 ClOrdID = 45
14 CumQty = 0
37 OrderID = A20062720096Y00
39 OrdStatus = 0 NEW
54 Side = 1 BUY
55 Symbol = AUD/JPY
60 TransactTime = 20061001-21:48:02
66 ListID = 1159739243883
68 TotNoOrders = 10
73 NoOrders = 10
-> 6 AvgPx = 0
-> 11 ClOrdID = 8
-> 14 CumQty = 0
-> 39 OrdStatus = 0 NEW
-> 151 LeavesQty = 500000

82 NoRpts = 1
83 RptSeq = 1
151 LeavesQty = 600000
429 ListStatusType = 2 RESPONSE
431 ListOrderStatus = 1 INBIDDINGPROCESS
10 CheckSum = 078

I know there is missing tag 84 (CxlQty) but I am not sure that's the reason for this kind of behavior.



 Comments   
Comment by Steve Bate [ 08/Oct/06 ]

Hello,

Are you sure you were using a data dictionary when parsing the message? If you don't use a data dictionary, QFJ cannot parse the groups correctly and
the calculated message length will be incorrect (because normally fields can't be repeated except in a group).

Comment by Plamen Vassilev [ 08/Oct/06 ]

Hello,

Yes, I double-checked that. I also send and receive other messages containing repeating groups (MarketDataRequest.NoRelatedSym, MarketDataIncrementalRefresh for example) without problems. I realize that this is odd, because as far as I understand - the parsing algorithm is universal for all messages, and it makes no sense for it to work for one kind and to not work for other. If you need any additional information, that I can provide regarding this problem - I am ready to provide it.

Thanks for your time and consideration!





[QFJ-82] Reconnection not working in 1.0.3 because of blocking .join() within exception callback Created: 05/Oct/06  Updated: 12/Oct/06  Resolved: 12/Oct/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine, Networking
Affects Version/s: 1.0.3
Fix Version/s: 1.0.4

Type: Bug Priority: Critical
Reporter: Andrzej Hajderek Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-71 Initiator's application.onLogout() is... Closed

 Description   

The exceptionCaught() callback in quickfix.mina.AbstractIoHandler calls quickFixSession.disconnect() which is now a 'blocking call' (changed from non-blocking to blocking in 1.0.3). As result, when a correctly operating connection breaks, the callback invokes the blocking quickFixSession.disconnect() and hangs indefinitely in quickfix.mina.IoSessionResponder.disconnect() on ioSession.close().join() (because the close operation cannot be completed).

It is not a good idea to mix asynchronous callbacks with blocking API calls.

The reconnection mechanism is broken now, which isn't good. Especially when your application is waiting for trades worth millions of dollars and it experiences a temporary network related problem.



 Comments   
Comment by Steve Bate [ 05/Oct/06 ]

There's nothing inherently wrong with mixing the calls. The problem in this specific case is that the thread doing to the close (in the case of an exception) is the same thread doing the join call. In other situations this would work. As noted in the related issue, the problem is also related to the threading model we are using in QFJ which is intended to minimize threads and was also needed to work around a MINA bug. The bug in MINA is fixed now but rather than modifying the thread pool model, I've chosen to remove the join calls in 1.1.0. See the related issue for more details.

Comment by Andrzej Hajderek [ 05/Oct/06 ]

Well, some kind of academic style discussion could start here, also following the discussion related to QFJ-71, but the simple fact is that the latest released version is badly broken. Is there any option or workaround to make 1.0.3 not hang on disconnection? If not, is there a chance for a fixed release soon?

Comment by Steve Bate [ 12/Oct/06 ]

Removed the join calls on MINA close operations.





[QFJ-81] Upgrade to MINA 1.0.1 Created: 26/Sep/06  Updated: 08/Jan/07  Resolved: 08/Jan/07

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: None
Fix Version/s: 1.0.5, 1.1.0

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Upgrade to MINA 1.0 after it is released.



 Comments   
Comment by Steve Bate [ 07/Nov/06 ]

Apparently 1.0 has quite a few bugs that will be fixed in 1.0.1.





[QFJ-80] Support nonpersistent message store (for market data) Created: 25/Sep/06  Updated: 12/Apr/07  Resolved: 07/Nov/06

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

(Compatibility) Also check related session configuration. QF Rev. 1721






[QFJ-79] Add embedded SSL support. Created: 25/Sep/06  Updated: 12/Apr/07  Resolved: 05/Oct/06

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Use MINA filters to provide SSL capabilities. Integrate this into the connectors (based on session settings).

http://www.quickfixj.org/confluence/display/qfj/SSL+Support






[QFJ-78] Support session configuration to use closed range for resend request. Created: 25/Sep/06  Updated: 04/Jul/07  Resolved: 10/Jun/07

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current implementation always asks for a an open-ended resend (to infinity, as recommended by the FIX specifications). This feature would support a close range (explicit end sequence) for organizations that require this behavior.



 Comments   
Comment by Jörg Thönnes [ 10/Jun/07 ]

Thanks, Steve. Actually, you were a bit faster than me. I also was about to commit this...

Your implementation is identical to ours except for the naming:
We call it ResendRequestToInfinity with default true to indicate that all ResendRequest use infinity as the end.

Do you think this sounds better?

Also: Do we need a unit test for this?

Cheers, Jörg





[QFJ-77] Support big decimal in message generation. Created: 25/Sep/06  Updated: 21/Jun/11  Resolved: 12/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: None
Fix Version/s: 1.2.0

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-612 BigDecimal for stock prices Closed

 Description   

Provide a new field type that can be specified in a custom data dictionary. This field type would cause the generated code to use BigDecimal instead of doubles.



 Comments   
Comment by Rob Gilliam [ 27/Mar/07 ]

I would suggest instead just ditching double and Double altogether and using BigDecimal instead for ALL fields of FIX type "float", as very few monetary values (for example) can actually be represented in IEEE 754 format with 100% accuracy

Also, I'm currently working round issues with, for example, "Percentage" format fields which need to be multiplied by 100 to get from the factor value that FIX specifies to the percentage value needed by our system (e.g. from "0.0386" to 3.86%) as this may introduce rounding errors and/or make previously-ignorable inaccuracies significant: for example multiplying a BidYield of 0.0386 by 100.0 and converting the result to String results in 3.8600000000000003 (%)

I'm therefore having to extract field data using Message.getString(int) and then construct a BigDecimal from the String value. My life would be MUCH easier if DoubleField.getValue() just returned a BigDecimal! OK, for backwards compatibilty it might be necessary to add a DoubleField.getBigDecimal() method instead, plus appropriate implementations of DoubleField.setValue(BigDecimal) and valueEquals(BigDecimal)

Comment by Steve Bate [ 10/Jun/07 ]

There is an option for the code generator to use BigDecimal instead of double for fields like price and quantity. The generated code can be used as a replacement for the default QFJ message JARs. The enabled the feature pass a "-Dgenerator.decimal" option on the command line when running the generate.code Ant target.





[QFJ-76] Support ordering of non-group fields (header, trailer, body) Created: 25/Sep/06  Updated: 04/Jul/07  Resolved: 12/Jun/07

Status: Closed
Project: QuickFIX/J
Component/s: Message Generation
Affects Version/s: None
Fix Version/s: 1.2.0

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current idea is to extend the code generation to support an attribute in the data dictionary that will cause the generated messages to have ordered fields. The ordering would be defined by the data dictionary order.



 Comments   
Comment by Steve Bate [ 10/Jun/07 ]

There is an option for the code generator that specifies the field ordering for regular messages in the same way as it is for repeating groups. It's possible this is not currently working for header and trailer objects. To enable the option pass a "-Dgenerate.ordered" option on the Ant command line.





[QFJ-75] Make table names for JdbcLog configurable Created: 23/Sep/06  Updated: 02/Jun/09  Resolved: 13/Jul/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.3.0

Type: Improvement Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current implementation of the JdbcLog (jdbc logger) hard-codes the resulting table names to be "messages_log" and "events_log".

The tables are hardcoded constants, and no calls exist to modify the name of the table.

I'd be ideal if we could specify the names of the logging tables in the config file (or programmatically).
That'd would allow for easy prototyping with Rails to log all the messages to the DB and easily display them in a webapp.

The constructor for JdbcLog takes in the SessionSettings object, so it can easily read the table names from it.



 Comments   
Comment by Steve Bate [ 09/Jun/07 ]

Toli, do you still need this feature?

Comment by Toli Kuznets [ 10/Jun/07 ]

It's not high-priority at all, i just think it would be nice to be able to configure these things instead of having them be hard-coded. Can be something that's tackled when we start moving all the configs to be more Spring-like

Comment by Steve Bate [ 12/Jul/07 ]

See also QF C++ rev 1914.

Comment by Eric Gao [ 02/Jun/09 ]

How's this issue going? Being able to change the table name for logs is very useful.

thanks,





[QFJ-74] Explicitly control the String encoding of the FIX messages Created: 22/Sep/06  Updated: 09/Jun/14  Resolved: 25/May/07

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3
Fix Version/s: 1.2.0

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 1
Labels: None

Attachments: Java Source File ChecksumTest.java    
Issue Links:
Duplicate
duplicates QFJ-38 FIX Message support double-byte charset. Closed

 Description   

This is currently and issue either with multibyte characters in FIX messages (somewhat rare, but it's been requested by a user) and with checksum problem with unintentional nonprinting characters in messages. The default encoding differs by platform so it's not a good idea to use the implicit default encoding.



 Comments   
Comment by Steve Bate [ 22/Sep/06 ]

We'll need to modify both the FIX decoder and encoder.

Comment by Brad Harvey [ 23/Sep/06 ]

I think the checksum validation/calculation should be in the decoder/encoder on the bytes just received/about to be sent. This makes it possible to correctly calculate the checksum on messages you receive which contain byte sequences that can't be mapped to your charset.

Comment by Brad Harvey [ 07/Oct/06 ]

I've attached some tests I was playing with to help me understand my checksum problem. I was surprised by the result of testDecodeDoubleByte - it passes in trunk - so I thought it was worth sharing. Most of the other tests aren't as interesting.

It seems that the change to FIXMessageDecoder.getMessageString to use the new String(byte[], charsetName) constructor has fixed the issue I was seeing with double bytes causing checksum failures in 1.0.2. From the javadoc:

The behavior of this constructor when the given bytes are not valid in the given charset is unspecified. The java.nio.charset.CharsetDecoder class should be used when more control over the decoding process is required.

It seems that the "unspecified" behaviour is to allow the invalid bytes through unchanged. What I found surprising was that there doesn't seem to be a way to emulate this behaviour using the Ignore/Replace/Report mechanism of CharsetDecoder. So hopefully the unspecified behaviour is consistent across JVMs (and alternate charsets?)!

Comment by Steve Bate [ 10/Nov/06 ]

I'm moving this to a post 1.1 release. I can see what needs to be done but the trick will be finding a way to do that doesn't impact performance too negatively. The comments and tests have addressed the checksum and related unsigned byte issues but there are also issues with message length calculations when using MB character sets.

Comment by Brad Harvey [ 10/Nov/06 ]

When I looked at it I actually wondered if two options might be needed - the "old" one (that so far seems to do the job for most people) and a new one that handles double byte chars but may be slower. Having said that, I'd imagine choice of MessageStore would have a bigger performance impact.

Comment by Steve Bate [ 10/Nov/06 ]

That's basically the approach I've been taking. One issue is that the way the body length and checksum is currently calculated, the specified charset would have to be pushed down to the field level and each field would need to do a character decoding to a byte array to determine it's length in bytes and it's contribution to the checksum. If I do that and I have the conditional to provide the current behavior if the default charset (US-ASCII) is being used, then it might be reasonable.

Comment by Jörg Thönnes [ 21/Mar/07 ]

We have issues with German and Italian character sets. These character sets use
values beyound the normal ASCII range (0..127) for QF/ 1.0.3.

After the log line for the incoming log, the error displayed is:

Mar 21, 2007 12:01:05 PM quickfix.mina.AbstractIoHandler messageReceived
SEVERE: Invalid message: Expected CheckSum=199, Received CheckSum=182

At the moment, we have no way to check automatically for this error. Is there anyway to
use a MINA error handler?

Comment by Jörg Thönnes [ 31/Mar/07 ]

Looking at some CharsetDecoder examples, I am wondering whether setting the encoding/decoding char set to Latin-1
would help in our case.

Comment by Jörg Thönnes [ 31/Mar/07 ]

In the code, I found two places where the char set name "US-ASCII" is used.

To check the conversion of umlauts, I used the following snippet:

//String charSet = "US-ASCII";
//String charSet = "ISO_8859-1";
System.out.println(charSet);
String s = "äbc";
int offset = s.length();
int sum = 0;
for (int i = 0; i < offset; i++) {
int val = s.charAt;
System.out.print(val+"+");
sum+=val;
};
System.out.println( "Checksum: " + sum % 256 );
sum=0;
byte[] bb = s.getBytes( charSet );
sum=0; offset=bb.length;
for (int i = 0; i < offset; i++) {
int val = bb[i];
System.out.print(val+"+");
sum+=val;
}
System.out.println( "Checksum: " + sum % 256 );
System.out.println();

The output is

ISO_8859-1
228+98+99+Checksum: 169
-28+98+99+Checksum: 169

US-ASCII
228+98+99+Checksum: 169
63+98+99+Checksum: 4

So in our case, setting the char set name to "ISO_8859-1" would help.

That is, we need a char set configurable globally or per session.

Comment by Steve Bate [ 02/Apr/07 ]

Is the US-ASCII you saw used in the Multibyte branch? I couldn't find it in the trunk and I don't currently have a branch workspace checked out.

Comment by Jörg Thönnes [ 02/Apr/07 ]

FIXMessageDecoder.java, SVN 555:
public FIXMessageDecoder()

{ this("US-ASCII"); }

FIXMessageEncoder.java, SVN 555:
public FIXMessageDecoder() { this("US-ASCII"); }
Comment by Jörg Thönnes [ 11/Apr/07 ]

This little Java program shows the current default charset:

public class ShowDefaultCharset {
public static void main( String[] args )

{ System.out.println(java.nio.charset.Charset.defaultCharset().toString()); }

}

On Linux, the output depends on the setting of the LANG environment variable:

LANG=POSIX java -cp . ShowDefaultCharset
US-ASCII

LANG=en_US.iso88591 java -cp . ShowDefaultCharset
ISO-8859-1

LANG=de_DE.utf8 java -cp . ShowDefaultCharset
UTF-8

Since the ISO-8859-1 character sets covers the whole 8 bits of a byte, it should work well for most 1 byte non- ASCII charsets.

Comment by Jörg Thönnes [ 11/Apr/07 ]

Here is an extended java program which also checks the byte to character mappings:

public class ShowDefaultCharset {
public static void main( String[] args ) {
System.out.println(java.nio.charset.Charset.defaultCharset().toString());

byte[] b = new byte[256];
for ( int i=0; i<256; i++ )

{ b[i] = (byte)i; }

final String x = new String ( b );
System.out.println( "Looking for non 1:1 byte to character mappings..." );
for ( int i=0; i<x.length(); i++ ) {
if ( x.charAt( i ) != i )

{ System.out.println( i + " -> " + (int)x.charAt ( i ) ); }

}
System.out.println("Done.");
}
}

Applying this program to ISO_8859-1 shows no change, ie this charset is really 1:1.

This means that the default character set for QuickFIX/J should be ISO_8859-1.

For multi-byte character sets, extra effort has to be done.

Comment by Jörg Thönnes [ 11/Apr/07 ]

Another extension checks for the reverse direction. Due to the signed integer, I add 256 modulo 256 to get the positive value:

public class ShowDefaultCharset {
public static void main( String[] args ) {
System.out.println(java.nio.charset.Charset.defaultCharset().toString());

byte[] b = new byte[256];
for ( int i=0; i<256; i++ )

{ b[i] = (byte)i; }

final String x = new String ( b );
final byte[] bx = x.getBytes();
System.out.println( "Looking for non 1:1 byte to character mappings..." );
for ( int i=0; i<x.length(); i++ ) {
if ( x.charAt( i ) != i )

{ System.out.println( i + " -> " + (int)x.charAt ( i ) ); }

final int bb = (bx[i]+256) % 256;
if ( bb != i )

{ System.out.println( i + " <- " + bb ); }

}
System.out.println("Done.");
}
}

For ISO_8859-1, this works fine.

Comment by Jörg Thönnes [ 11/Apr/07 ]

I suggest to make this patch to the 1.1.0 release to make the FIXMessageEncoder equivalent to the FIXMessageDecoder:

Index: /export/home/joerg/workspace/quickfixj/core/src/main/java/quickfix/mina/message/FIXMessageEncoder.java
===================================================================
— /export/home/joerg/workspace/quickfixj/core/src/main/java/quickfix/mina/message/FIXMessageEncoder.java (revision 617)
+++ /export/home/joerg/workspace/quickfixj/core/src/main/java/quickfix/mina/message/FIXMessageEncoder.java (working copy)
@@ -19,6 +19,7 @@

package quickfix.mina.message;

+import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.Set;

@@ -50,6 +51,8 @@
return TYPES;
}

+ private String charsetName = "ISO_8859-1";
+
public void encode(IoSession session, Object message, ProtocolEncoderOutput out)
throws ProtocolCodecException

{ String fixMessageString; @@ -65,7 +68,11 @@ }

ByteBuffer buffer = ByteBuffer.allocate(fixMessageString.length());

  • buffer.put(fixMessageString.getBytes());
    + try { + buffer.put(fixMessageString.getBytes(charsetName)); + }

    catch (UnsupportedEncodingException e)

    { + throw new ProtocolCodecException( e ); + }

    buffer.flip();
    out.write(buffer);
    }

Steve, what do you think?

Comment by Jörg Thönnes [ 11/Apr/07 ]

The suggested patch would complement the changes made with revision 527 in the FIXMessageDecoder.
For some reason, the equivalent change in the FIXMessageEncoder is missing.

Comment by Jörg Thönnes [ 12/Apr/07 ]

I would also remove the setCharset methods in both FIXMessageEncoder/Decoder since
setting a Charset different from the ISO_8859-1 is not supported at the moment.

To allow other charsets, more work in the validation method has to be done.

Comment by Steve Bate [ 12/Apr/07 ]

I originally was using US-ASCII (in the branch) because that's the FIX specification requires ASCII for nonencoded fields. However, I have no problem supporting other character sets (single byte, for now). Is there any reason why we wouldn't use UTF-8 instead of ISO_8859-1?

Comment by Jörg Thönnes [ 12/Apr/07 ]

Because ISO_8859-1 is the only charset with 1:1 mapping.
Just try my example program above with different LANG settings.

I tried US-ASCII, UTF-8 and ISO_8859-15, and every of these charsets mapping some of the bytes differently.

Therefore, exposing the setCharset() method makes sense as soon as the validate() method computes the checksums on the plain bytes.

My idea is to have a factory (FramingStrategyFactory) which returns a FramingStrategy for a given charset.
This would be the central entry point for the MINA en-/decoders and the validate() message to compute
both the checksum and the message length.

The FramingStrategy for ISO_8859-1 could simply take the String length and operate on the Java String directly, while single-byte strategies could take the String length, but compute the checksum on the bytes and multi-byte strategies also compute the length on the bytes.

The FIX Message constructor would have an optional charset argument, and if the message is sent down the link, a check is made whether the encoder charset is compatible to the Message charset. If not, the checksum and possibly the length are recomputed.

But I would promote this FramingStrategy stuff to a new JIRA issue.

Comment by Jörg Thönnes [ 12/Apr/07 ]

Today I noticed that outgoing message with national characters are encoded wrong on the first attempt,
but are re-coded correctly on resend. Will investigate further...

Comment by Jörg Thönnes [ 19/Apr/07 ]

OK, for outgoing messages, it currently works as follows:

1. Without PossDup=Y: The checksum is computed on the String directly and then forwarded to the encoder. The checksum is wrong.

2. Inside ResendRequest: The String is retrieved from MessageStore, where it has saved as byte[] array. In this way, the "bad" characters seem
to be replaced by "?". The checksum computed in the String domain now matched the checksum if it would have been computed on the bytes.

In summary, non ASCII characters cause exactly one resend round-trip for outgoing messages.

Comment by Steve Bate [ 25/May/07 ]

I checked in changes to allow the message encoding to be set on a JVM-wide basis. See the CharsetSupport and it's uses to see the specific changes. I apologize that I forgot to add the issue tag to the commit so they SVN changes aren't linked to this issue.

Comment by amichair [ 09/Jun/14 ]

Following resolution of QFJ-38 and QFJ-382, UTF-8 should now work as well (or any other charset which is backward-compatible with ASCII).





[QFJ-73] AllocRejCode field is missing enumeration values Created: 21/Sep/06  Updated: 12/Apr/07  Resolved: 26/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: John McKeown Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The AllocRejCode field is missing the following enumeration values:

'10' unknown or stale ExecID (17)
'11' mismatched data value (further in Note 58=)
'12' unknown ClOrdID (11)
'13' warehouse request rejected



 Comments   
Comment by Steve Bate [ 26/Sep/06 ]

FIX44.xml updated in trunk.





[QFJ-72] Configuration shoule be allowed more information in case of FIX hosting server highly security Created: 20/Sep/06  Updated: 26/Sep/06  Resolved: 26/Sep/06

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

Type: Improvement Priority: Major
Reporter: Nguyen Bao Quoc Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Dear all,
I'm implementing FIX.4.4 and trying with QuickFIX/J released version 1.0.3 but I found that It's not suitable with our need because there are only few parameters in configuration file.For example: SenderCompID, TargetCompID, SocketConnectHost, SocketConnectPort

Should we allow user to configure more paramteter to fit with their need ? Ex:
+ SenderSubID (Tag=50)
+ MessageType (Tag=35)
+ Username (Tag=553) that use for session logon message
+ Password (Tag=554) that use for session logon message
+ ...
Beside that should we open source code for package quickfix-jni.jar that allow user customize each of elements....to meet their requirements.

Thanks and best regards,

Quoc Nguyen.

P/S: Any remark/ comment is always appreciated (mailto [email protected])



 Comments   
Comment by Steve Bate [ 20/Sep/06 ]

Hello,

Have you looked at the related article on the wiki?

http://www.quickfixj.org/confluence/display/qfj/Using+Custom+Settings

Does this provide what you need? In general, you can add settings to the configuration file even if the existing QFJ code doesn't know about them. The SenderSubID fields cannot be used (currently) to identify a session, but they can be passed to the QFJ application and added to messages before they are sent.

Steve

Comment by Steve Bate [ 26/Sep/06 ]

Provided additional information about how to do this. I haven't heard back whether this was sufficient or not.





[QFJ-71] Initiator's application.onLogout() is not called if Acceptor connection is forcibly closed Created: 18/Sep/06  Updated: 12/Oct/06  Resolved: 22/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.0.4

Type: Bug Priority: Major
Reporter: Rob Gilliam Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Java2 RE 1.4.2, Windows XP, Eclipse 3.1


Issue Links:
Relates
relates to QFJ-82 Reconnection not working in 1.0.3 be... Closed

 Description   

Set up two QuickFIX/J applications (one as acceptor, on as initiator) and connect them together, then terminate/kill the acceptor application (i.e. as if it had crashed) - the inititator application gets the "Disconnecting" event but its implementation of application.onLogout() is not called

Diagnostic investigation suggests that Session.disconnect() is not returning from the line

responder.disconnect();

Terminating the initiator application in the same way doesn't have the same problem - the acceptor gets the "Disconnecting" event, followed by a call to its implementation of application.onLogout() as expected.

I tried re-building both applications on QFJ 1.0.2 and doing the same tests; this seems to work OK for both sides, so I guess something's changed between the two releases.



 Comments   
Comment by Christian Braeuner [ 19/Sep/06 ]

Hi, I've come across the same problem.
This seems to have been fixed in mina.0.9.5 library. Is there a chance that we can get a quickfix that is compiled with the latest mina release?
Thanks,
Christian

Comment by Steve Bate [ 20/Sep/06 ]

I want to upgrade to 0.9.5 (or even 1.0 if it's released in time) for the QFJ 1.1 release. I'm currently not sure if there are compatibility issues between 0.9.3 and 0.9.5 that require changes to QFJ? Do either of you have time to investigate the needed changes (if any)? I'd basically like to be sure the unit and acceptance tests pass with the 0.9.5 MINA version.

Comment by Rob Gilliam [ 21/Sep/06 ]

I have an issue with the "upgrade to mina 0.9.5 and it'll go away" approach, which is that it risks addressing the symptom, rather than the cause.

As I said above, this problem is not evident when I run the same applications with QFJ 1.0.2 (also based on mina 0.9.3), so something has changed between the two releases of QuickFIX/J, and that's a concern.

As for doing the testing against mina 0.9.5: unfortunately I really don't have the time myself right now and can't see it happening in the immediate future. My project isn't live yet and getting the last few features implemented and working is more pressing than handling the un-expected disconnects right now (sorry).

Comment by Steve Bate [ 21/Sep/06 ]

I've found the source of the problem. In the IoSessionResponder.disconnect() method, the MINA close operation is now followed by a join so that disconnect will not return until the asynchronous close operation is complete. Apparently, calling minaSession.close().join() blocks the calling thread and doesn't allow the asynchronous event to be processed. This isn't expected behavior from my perspective but I need to check with the MINA team to see if this is what they'd expect.

The problem still exists with 0.9.5 so I'm not sure if Christian is seeing a different issue or not.

To restore the 1.0.2 behavior you can remove the join() call after the close call in the disconnect method.

Comment by Steve Bate [ 22/Sep/06 ]

ALthough the MINA behavior related to close().join() is not considered a bug, it is error prone and can lead to unexpected thead blocking depending on the thread calling the code. Although we'd prefer a synchronous return from close(), it's not strictly necessary and given the danger of thread blocking I'm removing the join calls in the SVN branch and the trunk.

Comment by Brad Harvey [ 22/Sep/06 ]

I think the reason it happens on the initiator but not acceptor is because MINA's thread pool filter was removed from the initiator (QFJ-34).

I tried commenting out the ThreadModel.MANUAL line in IoSessionInitiator and it seemed to solve this problem - Responder.disconnect() was called in one of the AnonymousIoService threads instead of the main SocketConnectorIoProcessor thread.

The MINA issue causing the thread leak was resolved in 0.9.5 so potentially the default ThreadModel could be used again if join() is the more desirable behaviour.

Comment by Steve Bate [ 22/Sep/06 ]

OK, that's good to know. It makes sense that if a thread pool is used then the close() and join() won't happen in the io processor thread. I added the joins because I thought it was logically more correct behavior. However, allowing the close to be asynchronous wasn't causing any known problems so it's probably ok to leave them out. Thanks again for the information.





[QFJ-70] sessionCreated not called for custom filters Created: 15/Sep/06  Updated: 12/Apr/07  Resolved: 05/Nov/06

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

Type: Bug Priority: Trivial
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The sessionCreated event is never called on custom filters. This is because the filters are only added in AbstractIoHandler.sessionCreated, so the event is called before the filter was added.






[QFJ-69] Document the VM_PIPE configuration. Created: 07/Sep/06  Updated: 12/Apr/07  Resolved: 07/Sep/06

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add documentation for the VM_PIPE socket protocol.



 Comments   
Comment by Steve Bate [ 07/Sep/06 ]

Documentation updated.





[QFJ-68] SocketConnectProtocol=vm_pipe Created: 07/Sep/06  Updated: 07/Sep/06  Resolved: 07/Sep/06

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

Type: Other Priority: Minor
Reporter: Michael Briganti Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows NT/jdk1.5.0_06



 Description   

The default protocol is tcp and the documentation makes no reference to Sockect [ Connect | Accept ] Protocol, nonetheless...

When I set initiator/acceptor to use vm_pipe I receive the following on the initiator,

event> (Connection failed: Failed to get the session.)

Is the option currently being supported for the current engine in Windows NT/jdk1.5.0_06, if so I will try to dig a little further.

Thanks



 Comments   
Comment by Steve Bate [ 07/Sep/06 ]

I'm assuming both the initiator and acceptor are running in the same JVM. I modified the SocketInitiatorTest in my workspace to use VM_PIPE and it worked. I was able to cause the message you mentioned if my ports did not match between the initiator and acceptor. For example, if I used port 9879 for the initiator and port 9878 for the acceptor. Is it possible that this is causing your problem? The port is used for the VM_PIPE, but not the host.

Comment by Michael Briganti [ 07/Sep/06 ]


Thanks for your comments. The code works correctly upon synchronization of the ports. I don't have permissions to mark the issue closed so please do at your convenience.

Comment by Steve Bate [ 07/Sep/06 ]

OK, good. Thanks for letting me know.





[QFJ-67] FIX44.xml PartyRole enumeration incomplete Created: 06/Sep/06  Updated: 12/Apr/07  Resolved: 07/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.0.3
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: John Hensley Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: File partyrole.patch    

 Description   

The FIX 4.4 spec defines more values for PartyRole (452) than are currently contained in core/src/main/resources/FIX44.xml. Patch attached.



 Comments   
Comment by John Hensley [ 06/Sep/06 ]

Diffed to QF/J trunk, revision 508.

Comment by Steve Bate [ 07/Sep/06 ]

It's been patched and committed. Thanks.





[QFJ-66] Cannot receive incoming header DATA field Created: 06/Sep/06  Updated: 12/Apr/07  Resolved: 10/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: André Malenfant Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

When a DATA field is received, the quickfix looks for the corresponding LENGTH field in the received fields list BUT if the LENGTH and DATA fields are part of the header, they are not found. The extractField method from the Message class should check if the LENGTH fields is a header field and search for it in the corresponding list. (Not sure what to do with the group fields though)

ex:
try {
if (group == null) {
if (isHeaderField(lengthField))

{ fieldLength = header.getInt(lengthField); }

else

{ fieldLength = getInt(lengthField); }

} else

{ fieldLength = group.getInt(lengthField); }

} catch (FieldNotFound e1)

{ throw new InvalidMessage(e1.getMessage()); }




[QFJ-65] Wrong error reported on parse Created: 06/Sep/06  Updated: 12/Apr/07  Resolved: 11/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.3
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: André Malenfant Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Whenever a parsing error occurs, an InvalidMessage exception is thrown but is never reported and the processing continues to the validation method which may or not find a validation error. If, for instance, a LENGTH type field is missing for a specific DATA field, the error reported is:

Invalid message: Actual body length=x, Expected body length=x

whereas the real error is that the LENGTH field is missing.

form the fromString method of the Message class:

try

{ parseHeader(dd); parseBody(dd); parseTrailer(dd); }

catch (InvalidMessage e)

{ isValidStructure = false; }

if (doValidation)

{ validate(messageData); }

 Comments   
Comment by John McKeown [ 05/Dec/06 ]

This issue can be easily reproduced by parsing a message which has the MsgType field in the wrong place (i.e. not the third field).

Comment by Steve Bate [ 11/Feb/07 ]

The message parser will now report the correct error. I've added a unit test for the specific case of a missing data field length.





[QFJ-64] Component group copy incorrect Created: 06/Sep/06  Updated: 12/Apr/07  Resolved: 07/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: HTML File ATT24810.htm    

 Description   

The component group copy was skipping the groups. See attach Lin Lejiang message.



 Comments   
Comment by Lejiang [ 06/Sep/06 ]

I think the method "copyTo" of MessageComponent has problem too.
I cann't set the right component value to Message by invoking methed "Message.set(Parties component)".

Comment by Steve Bate [ 07/Sep/06 ]

I've added a new test and fixed the copyTo functionality. Thanks for the report.





[QFJ-63] Added src.zip containing both engine core source and generated source to binary package Created: 05/Sep/06  Updated: 12/Jun/07  Resolved: 12/Jun/07

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

Type: Task Priority: Default
Reporter: Jörg Thönnes Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

It is helpful to have the source files which are the basis of the binary release in a src.zip.

This can be used in Eclipse user defined libraries to add a source attachment. This allows to browse the QF/J source code
from the referencing code in the project (in read-only mode).

The src.zip should contain the src/quickfix directory merged with output/ant/src-generated/quickfix which contains the FIX classes generated
from the FIX4x.xml specs. The top-level directory should be "quickfix".






[QFJ-62] Session Initiator Fails with "Connection failed: Failed to get the session." Created: 05/Sep/06  Updated: 22/Sep/06  Resolved: 22/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3
Fix Version/s: None

Type: Other Priority: Default
Reporter: kevin samuel Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Win 2k3 Server, Dell 2650 Dual 2.4Ghz 2GB Ram, BEA jrockit-R26.3.0-jdk1.5.0_06


Attachments: File JFIX.cfg    

 Description   

I tried posting this to the Mailing list, but was rejected:
Failed to deliver to '[email protected]'
SMTP module(domain lists.sourceforge.net) reports:
host mail.sourceforge.net says:
550 Sender verify failed
(i did register for the mailing list)

I've been trying to port a pojo application from QuickFix-JNI to QuickFixJ 1.0.x, however, my (initiator) session never connects, instead failing with "Connection failed: Failed to get the session."

I haven't seen anything about this in the mail-archives, the closest thing being the issue of having to delete the quickfix fixmsg log files to avoid an EOFException, which I had already encountered.

– as far as I can tell "Failed to get session." is a MINA IOException message, wrapped in "ConnectionFailed: " when caught by IoSessionInitiator.connect(), however I am not familiar enough with MINA for that to help me much – I would have guessed that the connection was never even being attempted, but an ethereal capture reveals the connection is at least initiated, showing

TEST1 -> TEST2 : SYN
TEST2 -> TEST1 : SYN,ACK
TEST1 -> TEST2 : ACK

I tried using both the SocketInitiator and ThreadedSocketInitiator classes, to no effect
I also tried upgrading to mina-core-0.9.4.jar, in the blind hope that it might fix something, but it didn't.
Tried downgrading QuickfixJ to 1.0.0, 1.0.1, 1.0.2

below is the code being called, along with the log output (which includes the session settings), any help would be greatly appreciated.

thanks,

kevin ( [email protected] )
class FIXProxy extends Proxy implements quickfix.Application
{
public static void startupFix()
{
try
{
Log.dbg("ENTER startupFix");
instance = new FIXProxy();

Log.info(" FixProxy instantiated.");

SessionSettings settings = new SessionSettings(new FileInputStream(instance.fixCfgFile));
MessageStoreFactory storeFactory = new FileStoreFactory(settings);
LogFactory logFactory = new SLF4JLogFactory(settings);
MessageFactory messageFactory = new DefaultMessageFactory();

Log.info("SETTINGS: [DEFAULT]");
Properties dprop = settings.getDefaultProperties();
Enumeration de = dprop.keys();
while( de.hasMoreElements() )

{ String key=(String)de.nextElement(); String val = (String)dprop.get(key); Log.info(" " + key + " = " + val); }

SessionID sid = new SessionID("FIX.4.0","TEST1","TEST2");
Log.info("SETTINGS: ["+sid.toString()+"]");
Properties prop = settings.getSessionProperties(sid);
Enumeration en = prop.keys();
while( en.hasMoreElements() )

{ String key = (String)en.nextElement(); String val = prop.getProperty(key); Log.info(" " + key + " = " + val); }

instance.start();
Log.info(" FixProxy started");

try

{ initiator = new SocketInitiator(instance,storeFactory,settings, logFactory,messageFactory); }

catch(Exception e)

{e.printStackTrace();return;}

Log.info(" SocketInitiator instantiated.");
try

{ initiator.start(); }

catch(Exception e2)

{e2.printStackTrace();return;}

Log.info(" SocketInitiator started.");
}
catch(Exception ex)

{ Log.err(ex.getMessage()); ex.printStackTrace(); }

finally

{ Log.dbg("LEAVE startupFix"); }

}

2006/08/29 19:34:05 | Init session: FIX.4.0:TEST1->TEST2
2006/08/29 19:34:05 | SETTINGS: [DEFAULT]
2006/08/29 19:34:05 | ConnectionType = initiator
2006/08/29 19:34:05 | LogonTimeout = 30
2006/08/29 19:34:05 | BeginString = FIX.4.0
2006/08/29 19:34:05 | ValidateFieldsOutOfOrder = Y
2006/08/29 19:34:05 | ReconnectInterval = 30
2006/08/29 19:34:05 | HeartBtInt = 60
2006/08/29 19:34:05 | FileStorePath = D:/Logs/FixStore
2006/08/29 19:34:05 | UseDataDictionary = N
2006/08/29 19:34:05 | FileLogPath = D:/Logs/FixMsgs
2006/08/29 19:34:05 | SETTINGS: [FIX.4.0:TEST1->TEST2]
2006/08/29 19:34:05 | EndTime = 23:59:00
2006/08/29 19:34:05 | StartTime = 00:01:00
2006/08/29 19:34:05 | TargetCompID = TEST2
2006/08/29 19:34:05 | SocketConnectPort = 700
2006/08/29 19:34:05 | SenderCompID = TEST1
2006/08/29 19:34:05 | SocketConnectHost = 127.0.0.1
2006/08/29 19:34:05 | FixProxy started
2006/08/29 19:34:05 | FIXProxy Transitions FROM STATE_INITIAL TO STATE_STARTING
2006/08/29 19:34:05 | ENTER: STATE_STARTING
2006/08/29 19:34:05 | FIXProxy Transitions FROM STATE_STARTING TO STATE_RUNNING
2006/08/29 19:34:05 | ENTER: STATE_RUNNING
2006/08/29 19:34:05 | Aug 29, 2006 7:34:05 PM quickfix.SLF4JLog log
2006/08/29 19:34:05 | FIX.4.0:TEST1->TEST2: Session FIX.4.0:TEST1->TEST2 schedule is daily, 00:01:00 UTC - 23:59:00 UTC
2006/08/29 19:34:05 | FixEngine.onCreate FIX.4.0:TEST1->TEST2
2006/08/29 19:34:05 | Aug 29, 2006 7:34:05 PM quickfix.SLF4JLog log
2006/08/29 19:34:05 | FIX.4.0:TEST1->TEST2: Created session: FIX.4.0:TEST1->TEST2
2006/08/29 19:34:05 | SocketInitiator instantiated.
2006/08/29 19:35:05 | Aug 29, 2006 7:35:05 PM quickfix.SLF4JLog log
2006/08/29 19:35:05 | FIX.4.0:TEST1->TEST2: Connection failed: Failed to get the session.
2006/08/29 19:35:05 | SocketInitiator started.
2006/08/29 19:35:05 | DEBUG: LEAVE startupFix



 Comments   
Comment by Steve Bate [ 06/Sep/06 ]

The message does mean that MINA can't establish the socket session (versus the QF session). For example, if I start Banzai without an acceptor running I'll see this message. I can try the example code sometime but it won't be for a few days at least. I really don't have any other theories. Do you have any firewalls running on either test box?

Comment by Steve Bate [ 06/Sep/06 ]

I'd expect them to behave the same. It seems like a long shot but maybe there are some low level differences in the way the sockets are configured. This is just a guess. I haven't seen any related issues being discussed on the MINA mailing list. If you gather any more information that might help diagnose the problem, please let me know.

Comment by Steve Bate [ 07/Sep/06 ]

Hi Kevin,

I used the order executor and Banzai to try your configuration file. I made the following modifications...

Order Executor:

  • Config: Changed FIX version to 4.0 and port to 700
  • Config: Changed compIDs to TEST2, TEST1.

Banzai:

  • Config: Change file log and store paths for my file system.
  • Banzai.java: Used a FileLogFactory instead of ScreenLogFactory

When I run the apps, Banza is able to connect to the executor and it creates the file logs properly.

Order Executor:

<20060907-13:38:16, FIX.4.0:TEST2->TEST1, event> (Session FIX.4.0:TEST2->TEST1 schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060907-13:38:16, FIX.4.0:TEST2->TEST1, event> (Valid order types: [F, 2])
<20060907-13:38:16, FIX.4.0:TEST2->TEST1, event> (Created session: FIX.4.0:TEST2->TEST1)
press <enter> to quit
Sep 7, 2006 3:38:16 PM quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:700
Sep 7, 2006 3:38:22 PM quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:2295
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, incoming> (8=FIX.4.09=6135=A34=949=TEST152=20060907-13:38:2256=TEST298=0108=6010=036)
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, event> (Accepting session FIX.4.0:TEST2->TEST1 from /127.0.0.1:2295)
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, event> (Acceptor heartbeat set to 60 seconds)
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, event> (Received logon request)
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, outgoing> (8=FIX.4.09=6135=A34=949=TEST252=20060907-13:38:2256=TEST198=0108=6010=036)
<20060907-13:38:22, FIX.4.0:TEST2->TEST1, event> (Responding to logon request)

Banzai:

<20060907-13:38:21, FIX.4.0:TEST1->TEST2, event> (Session FIX.4.0:TEST1->TEST2 schedule is daily, 00:01:00 UTC - 23:59:00 UTC)
<20060907-13:38:21, FIX.4.0:TEST1->TEST2, event> (Created session: FIX.4.0:TEST1->TEST2)
<20060907-13:38:22, FIX.4.0:TEST1->TEST2, outgoing> (8=FIX.4.09=6135=A34=949=TEST152=20060907-13:38:2256=TEST298=0108=6010=036)
<20060907-13:38:22, FIX.4.0:TEST1->TEST2, event> (Initiated logon request)
<20060907-13:38:22, FIX.4.0:TEST1->TEST2, incoming> (8=FIX.4.09=6135=A34=949=TEST252=20060907-13:38:2256=TEST198=0108=6010=036)
<20060907-13:38:22, FIX.4.0:TEST1->TEST2, event> (Received logon response)
Sep 7, 2006 3:38:22 PM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:2295

So, I don't know. It appears the configuration file is fine. I'm running out of theories about why you are seeing different behavior on your system. I haven't had anyone else report this specific kind of problem. If you have any other ideas, I'll give you whatever support I can to resolve the problem.





[QFJ-61] Extend SessionState to track whether a Logout has been received Created: 04/Sep/06  Updated: 04/Sep/06  Resolved: 04/Sep/06

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

Type: Improvement Priority: Default
Reporter: Jörg Thönnes Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

If the onLogout() callback is executed, it would be nice to know whether this was a normal logout,
ie the other side sent a "Logout" (and we responded to it), or whether we sent a Logout and got an answer.

I suggest to add the boolean variable receivedLogout with appropriate setter and getter methods to the SessionState:

public boolean isLogoutReceived()
public void setLogoutReceived(boolean logoutReceived)

The flag is cleared initially and set in nextLogout() to indicate that a Logout has been received (or sent). In the method
disconnect(), the flag is cleared after the call to the onLogout() callback.

A delegate method isLogoutReceived() is added to the Session object to make the current state accessible from outside.

Example usage:

public void onLogout(SessionID sessionID)

{ String disconnectDescription = ( session.receivedLogout() ? "Regular" : "Unsolicited" ); ... }




[QFJ-60] Fix sequence number problem when RejectLogon is used. Created: 04/Sep/06  Updated: 12/Apr/07  Resolved: 22/Sep/06

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

Type: Task Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Comments   
Comment by Steve Bate [ 22/Sep/06 ]

Added sequence number increment when logon is rejected.





[QFJ-59] Doc Bug: "initiator" is misspelled in the sample configuration Created: 29/Aug/06  Updated: 24/Jan/07  Resolved: 29/Aug/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: 1.0.2
Fix Version/s: 1.0.3

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

"initiator" is misspelled in the sample configuration found at:

http://www.quickfixj.org/quickfixj/usermanual/usage/configuration.html#Sample%20Settings%20File

(search the page for "initator") It means that QuickFIX/J cannot startup using this configuration file.



 Comments   
Comment by Steve Bate [ 29/Aug/06 ]

Hi Toli and Graham. I've made the changes on both the 1.0.x branch and the trunk. Thanks for reporting the problem.





[QFJ-58] FIX enum values for fields of type MULTIPLEVALUESTRING are generated as type char Created: 29/Aug/06  Updated: 15/Nov/12  Resolved: 07/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: 1.0.0 B3, 1.0.0 Final, 1.0.1, 1.0.2, 1.0.3, 1.1.0
Fix Version/s: None

Type: Bug Priority: Default
Reporter: Jörg Thönnes Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None


 Description   

These fields are of type MULTIPLEVALUESTRING:

<field number="18" name="ExecInst" type="MULTIPLEVALUESTRING">
<field number="276" name="QuoteCondition" type="MULTIPLEVALUESTRING">
<field number="277" name="TradeCondition" type="MULTIPLEVALUESTRING">
<field number="286" name="OpenCloseSettlFlag" type="MULTIPLEVALUESTRING">
<field number="286" name="OpenCloseSettleFlag" type="MULTIPLEVALUESTRING">
<field number="291" name="FinancialStatus" type="MULTIPLEVALUESTRING">
<field number="292" name="CorporateAction" type="MULTIPLEVALUESTRING">
<field number="529" name="OrderRestrictions" type="MULTIPLEVALUESTRING">
<field number="546" name="Scope" type="MULTIPLEVALUESTRING">

Normally, I would use e.g.

new ExecInst( ExecInst.IMMEDIATE )

but this fails since ExecInst.IMMEDIATE is of type char, while the constructor of ExecInst requires a String argument.



 Comments   
Comment by Jörg Thönnes [ 29/Aug/06 ]

Extend src/codegen/Fields.xsl to map all possible types. Missing types are:

DATA
DATE
DAYOFMONTH
EXCHANGE
LOCALMKTDATE
MONTHYEAR
MULTIPLEVALUESTRING
TIME

At least extend the XSL templates get-type and get-field-type to include a line for MULTIPLEVALUESTRING:

<xsl:when test="@type='MULTIPLEVALUESTRING'">String</xsl:when>

Comment by Jörg Thönnes [ 30/Aug/06 ]

Steve, please merge this to the trunk.

How about adding mappings for the other missing types as

DATA
DATE
DAYOFMONTH
EXCHANGE
LOCALMKTDATE
MONTHYEAR
TIME

and drop the catch-all other to spot missing types?

Comment by Steve Bate [ 03/Sep/06 ]

I have some bad news. The changes for MULTIPLEVALUESTRING broke the JNI API compatibility (which uses chars for the enum). Unfortunately, there were gaps in the API unit tests so they didn't fail after the change. I've modified the API unit tests to catch these types of problems. I've reverted the changes on the branch. We can speak to Oren about changing this in the JNI API and then make the changes in QFJ again. I agree that using a string is a better idea. I'm leaving the issue active but not assigned to a release for now.

Comment by Steve Bate [ 07/Sep/06 ]

I'm marking this as "not a bug" for now. If Oren decides to change the types in the JNI API, we can reopen this issue as a feature.





[QFJ-57] Make QFJ timer thread a daemon. Created: 25/Aug/06  Updated: 25/Jul/14  Resolved: 25/Jul/14

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

Type: Bug Priority: Default
Reporter: André Malenfant Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

There appears to be another "thread leak", at least in my environment. The faulty thread seam to be the QFC timer thread. I have created my own SocketInitiator to be able to override the time thread factory and so far I have discovered two things.

1- First, the method close on IOSessionInitiator never seems to be called.
2- The ScheduledExecutorService is never "shutdowned". Not sure if it has to be but if it's done, it fixes my problem.



 Comments   
Comment by Steve Bate [ 26/Aug/06 ]

The QFJ timer thread is shared by all sessions in all initiators and sessions. The ScheduledExecutorService can't be shutdown after an initiator or acceptor is stopped (unless I add some type of reference counting to it). Starting a new initiator or acceptor shouldn't create any more threads. Are you seeing multiple QFJ timer threads or just concerned that the thread still exists after you shut down your session connector?

Comment by Steve Bate [ 26/Aug/06 ]

The uncalled close method was a good catch. The ioSession is closed elsewhere so I'll remove that code, but I'm still investigating the reconnect job issues related to not calling close. Thanks.

Comment by André Malenfant [ 28/Aug/06 ]

I never see more than one QFJ Timer thread but it does not seem to be destroyed when I exit my application unless I manually terminate the VM. I was suspecting the QFJ Timer thread so I managed to override a few classes to gain control over it and shutting down the ScheduledExecutorService did the trick.

Maybe this only fixes my problem indirectly and the real issue lies somewhere else but I think it would be more elegant to gracefully shutdown the ScheduledExecutorService. I realize that the current implementation does not allow that but if there was one ScheduledExecutorService instance per initiator/acceptor instance it would be possible (in logoutAllSessions) and would not do any harm as I don't see much difference between 10 tasks on one thread and 5 tasks on 2 threads...

Comment by Steve Bate [ 28/Aug/06 ]

It sounds like your program's issue is caused by the QFJ thread not being a daemon thread. The QFTimerThreadFactory should set this flag so the thread doesn't keep the JVM from exiting. I'll make that change. Thanks for the report.

Comment by André Malenfant [ 28/Aug/06 ]

Funny because this was our first intuition and I did test the deamon thread fix but I must have done my testing wrong... Now it works.

I'll be waiting for an update, thanks for your responsiveness.

Comment by Steve Bate [ 02/Sep/06 ]

The fix for this problem for this problem has been added to the 1.0.x branch and the trunk.





[QFJ-56] Support null LogFactories. Created: 24/Aug/06  Updated: 24/Jan/07  Resolved: 02/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 Final, 1.0.1, 1.0.2
Fix Version/s: 1.0.3

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

I may be wrong, but it seems that in the constructor for Session there's code that both accesses the incoming logFactory and also checks it for null, but not in the right order:

constructor {
Log log = logFactory.create(sessionID);

try {
<snip>
if (logFactory != null)

{ state.setLog(log); }

log.onEvent("Session " + this.sessionID + " schedule is " + sessionSchedule);
}

seems like if it's possible for the logFactory to be null, that assumption should be tested on the earlier line as wel.



 Comments   
Comment by Toli Kuznets [ 24/Aug/06 ]

oh, i should do a better job of checking HEAD before posting a bug. apparently this has already been addressed in the last checkin.
great job steve!
http://svn.sourceforge.net/viewvc/quickfixj/trunk/core/src/main/java/quickfix/Session.java?r1=474&r2=483

all right, you can close this. thanks!

Comment by Steve Bate [ 26/Aug/06 ]

Already fixed. Thanks for the report.

Comment by Steve Bate [ 26/Aug/06 ]

I'll reopen this for editing this since I didn't create a Jira issue for the original fix. It's more convenient to have an issue for change log and release note purposes.





[QFJ-55] I have sessions that start Sunday Created: 18/Aug/06  Updated: 15/Nov/12  Resolved: 26/Aug/06

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

Type: Other Priority: Default
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

These sessions start on Sunday evening end terminate friday evening, how do I configure this. The sessions recycle daily.

When I set a start and end time does it reconnect on saturday and sunday ?



 Comments   
Comment by Steve Bate [ 26/Aug/06 ]

Hi Richard. QuickFIX and QFJ currently don't support this specific type of scheduling. You'll need to use something like a cron job (on *nix) to stop the FIX processes for the weekend.





[QFJ-54] Occasional NPE in block method during acceptor start. Created: 17/Aug/06  Updated: 18/Sep/08  Resolved: 04/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.0.1, 1.0.2
Fix Version/s: 1.0.3

Type: Bug Priority: Default
Reporter: Toli Kuznets Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File logFile.txt     Text File threadDump.txt    

 Description   

From Toli Kuznets...

I have a basic app that uses QFJ to communicate. I have a bunch of uni
tests running continiously, and they've been passing with the app
linked to 1.0.0-final of QuickFix/J.

However, as soon as i tried switching to 1.0.2 i get the following error:
Exception in thread "QFJ Socket Acceptor 126f75b" java.lang.NullPointerException
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:131)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Unknown Source)

There's no nested exception, and it's a thread created by QFJ and not my app.

Switching the code back to using 1.0.0-final fixes the problem. I
never used 1.0.1 so i can't tell if the problem manifests itself there
as well.

Any ideas on what could be causing this?
This is happening both on Ubuntu Linux and MacOSX. Not even sure how
to debug this since the exception is coming from a QFJ/mina code.

-------------------------------------------------------------------------------------------------------------------------------
From Joerg Thoennes...

Steve, the same happened to me. Today I got with version 1.0.1 this error:

[2006-08-15 17:41:47,472] [INFO ] [quickfix.mina.acceptor.AcceptorIoHandler] (SocketAcceptor-0) MINA
session created: /192.168.1.8:57611
[2006-08-15 17:41:47,573] [DEBUG] [FixLogFactory] (AnonymousIoService-1-2)
FIX.4.2:FixGateway->FixClient: incoming:
8=FIX.4.2|9=62|35=5|34=1|49=FixClient|52=20060815-15:41:47.540|56=FixGateway|10=091|
Exception in thread "QFJ Socket Acceptor 992bae" java.lang.NullPointerException
at
quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:131)
at
quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at
quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:595)

If I can reproduce this error tomorrow, I will send you more details.



 Comments   
Comment by Steve Bate [ 17/Aug/06 ]

I've found a way that this error could occur. This is the scenario...

1. An acceptor
2. A new connection is accepted but not associated with a session
3. A message, other than a logon, is received on the connection.

It's easy to check for this condition and ignore the message with a warning, but
is this scenario consistent with the context where you were seeing this error?

Comment by Jörg Thönnes [ 17/Aug/06 ]

My scenaria is as follows:

1. An initiator process continuously tries to connect to the acceptor.
2. The acceptor is starting up, has been partially blocked in a debugger or is rejecting logons (throw RejectLogon in fromAdmin()).

Up to now, I did no further analysis, but my guess is that this is somehow related to the RejectLogon. Does this make sense?
I wonder what the message other than Logon could be in my scenario.

Comment by Toli Kuznets [ 18/Aug/06 ]

Steve,

I think what you described is similar to what is happening with me.
I've collected some more information, and i'm attaching a bit more logging.

In my unit test i created an Acceptor which starts up, and then i create an initiator which immediately tries to connect to the acceptor.

The acceptor is basically a thin wrapper around quickix.SocketAcceptor, and the intiator is just a wrapper around quickfix.SocketInitiator (code is at http://trac.marketcetera.org/trac.fcgi/browser/platform/trunk/core/src/main/java/org/marketcetera/quickfix/QuickFIXInitiator.java).

Looking at the log above the exception, i'm now seeing that it looks like Exchange (acceptor) stars up, but then rejects the incoming message:
<20060816-09:01:00, FIX.4.2:test-exchange->test-sender, event> (Session FIX.4.2:test-exchange->test-sender schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060816-09:01:00, FIX.4.2:test-exchange->test-sender, event> (Created session: FIX.4.2:test-exchange->test-sender)
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (Session FIX.4.2:test-sender->test-exchange schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (Session state is not current; resetting FIX.4.2:test-sender->test-exchange)
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (No responder, not sending message)
02:01:01,106 DEBUG [main] marketcetera.exchange.ExchangeMainTest$MyQFInitiator (QuickFIXInitiator.java:165) - new session created: FIX.4.2:test-sender->test-exchange
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (Created session: FIX.4.2:test-sender->test-exchange)
<20060816-09:01:01, FIX.4.2:test-exchange->test-sender, incoming> (8=FIX.4.29=6735=534=149=test-sender52=20060816-09:01:01.23756=test-exchange10=120)
Exception in thread "QFJ Socket Acceptor 1e97f9f" java.lang.NullPointerException
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:131)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Unknown Source)

For example, i don't see these 2 lines when the tests pass:
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (Session state is not current; resetting FIX.4.2:test-sender->test-exchange)
<20060816-09:01:01, FIX.4.2:test-sender->test-exchange, event> (No responder, not sending message)

From the stacktrace at time of bug, it appears that my unit test is waiting for the onLogon() event to happen in the Initator.

stack-trace attached, and more logging (above included) is also attached.

But overall, it seems that it could be similar to what Steve is describing.
We are using
ResetOnLogout=Y
ResetOnDisconnect=Y
SendResetSeqNumFlag=Y

if that makes any difference.

Comment by Toli Kuznets [ 18/Aug/06 ]

Thread dump of the unit test that has a race-condition exhibiting the NPE

Comment by Toli Kuznets [ 18/Aug/06 ]

Log file for the unit test exhibiting the NPE

Comment by Toli Kuznets [ 18/Aug/06 ]

Not sure if this helps, but i have another set of logs and a use case

1. start my exchange simulator
2. connect to it from 2 places (web app that displays the simulator) and an OMS (that sends a few sample order to seed the market).
everything is peachy.
3. connect with 2nd OMS (different senderCompID) and it generates the NPE.
The simulator knows about that session (it's in simulator's config file).

here's the log from sending (OMS) side:
<20060818-18:28:00, FIX.4.2:sender-1501-OMS->MRKTC-EXCH, event> (Session FIX.4.2:sender-1501-OMS->MRKTC-EXCH schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
<20060818-18:28:00, FIX.4.2:sender-1501-OMS->MRKTC-EXCH, event> (Session state is not current; resetting FIX.4.2:sender-1501-OMS->MRKTC-EXCH)
<20060818-18:28:00, FIX.4.2:sender-1501-OMS->MRKTC-EXCH, event> (No responder, not sending message)
11:28:00,712 DEBUG [main] marketcetera.quickfix.QuickFIXInitiator (QuickFIXInitiator.java:165) - new session created: FIX.4.2:sender-1501-OMS->MRKTC-EXCH
<20060818-18:28:00, FIX.4.2:sender-1501-OMS->MRKTC-EXCH, event> (Created session: FIX.4.2:sender-1501-OMS->MRKTC-EXCH)
Aug 18, 2006 11:28:00 AM quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /10.1.9.112:52297
<20060818-18:28:00, FIX.4.2:sender-1501-OMS->MRKTC-EXCH, event> (Disconnecting)

and on the simulator side, the request triggers the NPE and subsequently all the other previous 2 connections get dropped:
Aug 18, 2006 11:28:01 AM quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
INFO: MINA session created: /66.92.9.46:52297
<20060818-18:28:01, FIX.4.2:MRKTC-EXCH->sender-1501-OMS, incoming> (8=FIX.4.29=6835=534=149=sender-1501-OMS52=20060818-18:28:00.92856=MRKTC-EXCH10=083)
Exception in thread "QFJ Socket Acceptor ef137d" java.lang.NullPointerException
at quickfix.mina.SingleThreadedEventHandlingStrategy$SessionMessageEvent.processMessage(SingleThreadedEventHandlingStrategy.java:131)
at quickfix.mina.SingleThreadedEventHandlingStrategy.block(SingleThreadedEventHandlingStrategy.java:70)
at quickfix.mina.SingleThreadedEventHandlingStrategy$1.run(SingleThreadedEventHandlingStrategy.java:86)
at java.lang.Thread.run(Thread.java:595)
<20060818-18:28:12, FIX.4.2:MRKTC-EXCH->MRKTC-DISPLAY, incoming> (8=FIX.4.29=6635=034=849=MRKTC-DISPLAY52=20060818-18:28:12.78856=MRKTC-EXCH10=141)
<20060818-18:28:13, FIX.4.2:MRKTC-EXCH->MRKTC-DISPLAY, outgoing> (8=FIX.4.29=6735=034=1349=MRKTC-EXCH52=20060818-18:28:13.21356=MRKTC-DISPLAY10=170)
Aug 18, 2006 11:28:16 AM quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
INFO: MINA session created: /66.92.9.46:52298
<20060818-18:28:16, FIX.4.2:MRKTC-EXCH->sender-1501-OMS, incoming> (8=FIX.4.29=8635=A34=149=sender-1501-OMS52=20060818-18:28:15.93056=MRKTC-EXCH98=0108=30141=Y10=164)
<20060818-18:28:16, FIX.4.2:MRKTC-EXCH->sender-1501-OMS, event> (Accepting session FIX.4.2:MRKTC-EXCH->sender-1501-OMS from /66.92.9.46:52298)
<20060818-18:28:16, FIX.4.2:MRKTC-EXCH->sender-1501-OMS, event> (Acceptor heartbeat set to 30 seconds)
<20060818-18:28:25, FIX.4.2:MRKTC-EXCH->MRKTC-DEMO-LOADER-OMS, incoming> (8=FIX.4.29=7535=034=1849=MRKTC-DEMO-LOADER-OMS52=20060818-18:28:25.00156=MRKTC-EXCH10=187)
<20060818-18:28:26, FIX.4.2:MRKTC-EXCH->MRKTC-DEMO-LOADER-OMS, outgoing> (8=FIX.4.29=7535=034=1949=MRKTC-EXCH52=20060818-18:28:26.21256=MRKTC-DEMO-LOADER-OMS10=193)
<20060818-18:28:27, FIX.4.2:MRKTC-EXCH->sender-1501-OMS, event> (Disconnecting)

I think at this point i'm rolling back to 1.0.0

steve, can you tell me what the patch may be? that way i can patch it locally and test

Comment by Steve Bate [ 19/Aug/06 ]

Toli, I will be away from my development computer until Tuesday. From memory, the patch was to quickfix.mina.acceptor.AcceptorIoHandler. Look for a section of code that processes logons before they are forwarded to the session. After that code the message is forwarded to the event handling strategy. The problem is that when a non-logon message is received before any session has been established, the quickfixSession is null. Check for the null session before forwarding it to even handling strategy. I don't have the code here so I can't give you more exact information. Looking at your log, it appears you are receiving a logout immediately after the network connection is established (before the logon). That would trigger the NPE.

Comment by Steve Bate [ 04/Sep/06 ]

I've added another task to test the RejectLogon issues that Joerg described to be sure the current changes address that problem.





[QFJ-53] Update information on MINA filters in Wiki Created: 17/Aug/06  Updated: 12/Apr/07  Resolved: 10/Feb/07

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.1.0

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Also, move the updated information to "Articles and Information".



 Comments   
Comment by Brad Harvey [ 13/Sep/06 ]

I put a little bit up the top of the existing page. I was going to do a whitelist filter with addresses configurable per session but haven't got it working before bed time - hopefully next time.

Comment by Steve Bate [ 08/Nov/06 ]

Hi Brad,

I plan to incorporate some of this information into the documentation before the 1.1 release. Is there anything you want to add first?

Steve

Comment by Brad Harvey [ 10/Nov/06 ]

I guess it is hard to explain without delving deep into how Mina works. Maybe the docs could explain when to add a filter before the protocol and when to add one afterwards a bit better? A diagram would probably help.





[QFJ-52] NPE on invalid message group Created: 16/Aug/06  Updated: 12/Apr/07  Resolved: 07/Sep/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.2
Fix Version/s: 1.1.0

Type: Bug Priority: Default
Reporter: Chris Audley Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Any runtime environment


Attachments: Text File group.patch    

 Description   

The parseGroup method in Message does not correctly detect an invalid group that starts with a non-subgroup field that is not the appropriate 'first field' for the group.

For instance, this incorrect NoRelatedSym group:

NoRelatedSym (146): 1
SecurityID (48): 31406TPB1
SecurityIDSource (22): 1
....

The first field should be a Symbol(55), but the symbol field is missing in this message. The parseGroup method will try to add the SecurityID (48) field to the group, but the group reference is still null because it hasn't encountered the correct first field yet. The fix is to check the firstFieldFound flag and throw an InvalidMessage exception if it isn't true. This is done correctly in the code for a subgroup field.

As a side note, Quickfix/C++ accepts this message without problem, but it probably shouldn't.



 Comments   
Comment by Chris Audley [ 16/Aug/06 ]

patch correct NPE in Message.parseGroup when group does not start with
appropriate first field

Comment by Steve Bate [ 17/Aug/06 ]

Hi Chris,

Thanks for the bug report. I'll apply the patch.

Comment by Chris Audley [ 17/Aug/06 ]

After having patched this problem, I think there is still a problem. When a group is missing the first field, quickfixj emits a log message about actual body length not matching expected body length.

Shouldn't this method be throwing a FieldNotFound exception that is caught by the session object and a Reject or BusinessMessageReject message sent to the sender as appropriate?

Comment by Steve Bate [ 07/Sep/06 ]

Added a regressions for the fix.





[QFJ-51] QuickFIX/J Initiator failover multi-address has a wrong rolling sequence Created: 14/Aug/06  Updated: 02/Sep/06  Resolved: 14/Aug/06

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

Type: Bug Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: HTML File ATT00764.htm    

 Description   

See attachment...



 Comments   
Comment by Steve Bate [ 14/Aug/06 ]

Fixed in 1.0.x branch and trunk. Thanks for reporting the problem and investigating the cause.





[QFJ-50] Example code for sending messages is incorrect Created: 12/Aug/06  Updated: 12/Apr/07  Resolved: 17/Aug/06

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

Type: Bug Priority: Default
Reporter: Markus Khouri Assignee: Markus Khouri
Resolution: Fixed Votes: 0
Labels: None


 Description   

2 issues on the page http://www.quickfixj.org/quickfixj/usermanual/usage/sending_messages.html in the section "Most Type Safe... DO THIS!", the following code is shown:

{{{
quickfix.fix41.OrderCancelRequest message(
new OrigClOrdID("123"),
new ClOrdID("321"),
new Symbol("LNUX"),
new Side(Side.BUY));
}}}

This does not compile because the variable is not created correctly; it should be

{{{
quickfix.fix41.OrderCancelRequest message = new quickfix.fix41.OrderCancelRequest (
new OrigClOrdID("123"),
new ClOrdID("321"),
new Symbol("LNUX"),
new Side(Side.BUY));
}}}

Note the additional code "= new quickfix.fix41.OrderCancelRequest"

Second issue:

The line "Session.sendToTarget(message, "TW", "TARGET");" throws "SessionNotFound" which needs to be surrounded in a try..catch block



 Comments   
Comment by Steve Bate [ 17/Aug/06 ]

I've modified the example in the documentation. Thanks for reporting this.

Comment by Steve Bate [ 17/Aug/06 ]

Modification has been committed to the svn trunk.

Comment by Markus Khouri [ 22/Aug/06 ]

when this is updated on the web site, and i remember to check it, i will close the issue.





[QFJ-49] sample method not defined: OrderCancelRequest.get(ClearingAccount) Created: 12/Aug/06  Updated: 22/Aug/06  Resolved: 17/Aug/06

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

Type: Bug Priority: Default
Reporter: Markus Khouri Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The example code on page http://www.quickfixj.org/quickfixj/usermanual/usage/receiving_messages.html in the section "Most Type Safe... DO THIS!" does not compile; the error message is

The method get(OrigClOrdID) in the type OrderCancelRequest is not applicable for the arguments (ClearingAccount)

This is noted in the sample code, i.e. "// compile time error!! field not defined for OrderCancelRequest", but there is no JIRA ticket on it.



 Comments   
Comment by Steve Bate [ 17/Aug/06 ]

This example is intended to have a compile time error because of the missing function. The point of the example is to show that incorrect code will be detected at compiled time and is therefore safer than the alternative methods that may only result in runtime errors.





[QFJ-48] Fix class path in examples scripts Created: 12/Aug/06  Updated: 24/Jan/07  Resolved: 04/Sep/06

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

Type: Bug Priority: Default
Reporter: Markus Khouri Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: File banzai.bat     File banzai.updated.bat     File banzai.updated.sh     File executor.bat     File executor.bat     File executor.updated.bat     File executor.updated.sh    

 Description   

I downloaded "quickfixj-1.0.1-bin.zip". expanding this created a directory named "bin", amoung others. inside of this were 4 files. "banzai.bat" contains the following code... note the path reference to "output/eclipse/classes". The path "output/eclipse/classes" is not included in the zip file; likewise, "output/ant/jars/quickfixj.jar" is also not in the zip..... thus I cannot execute the scripts. Also, if you execute these script files from the "bin" subdirectory, as would be expected, the paths starting with "lib/" should start with "../lib/"

@echo off
set CP=%CLASSPATH%;output/eclipse/classes
set CP=%CP%;output/ant/jars/quickfixj.jar
set CP=%CP%;lib/mina-core-0.9.3.jar
set CP=%CP%;lib/backport-util-concurrent-2.1.jar
set CP=%CP%;lib/slf4j-jdk14-1.0.1.jar

cd ..
java -classpath "%CP%" quickfix.examples.banzai.Banzai



 Comments   
Comment by Markus Khouri [ 12/Aug/06 ]

I was able to get this working with the following changes:

(1) removing the path to the quickfixj.jar in the following line
"set CP=%CP%;output/ant/jars/quickfixj.jar "

(2) removed the "cd .." so that when the script exits, I was in the same directory as when i started, allowing my to re-execute the script file.

Comment by Markus Khouri [ 12/Aug/06 ]

My modified banzai.bat that works for me

Comment by Markus Khouri [ 12/Aug/06 ]

I had a similar issue with "executor.bat".

I changed the classpath entries per the previos comment.

I had to leave in the line that changed the directory, since the sample app seems to be looking for the Fixxx.XML file under the "etc" directory.

Comment by Markus Khouri [ 12/Aug/06 ]

Attaching my modified "executor.bat" file which works for me.

Comment by Markus Khouri [ 12/Aug/06 ]

use this attachment, not the other one. this one include the following line at the end, so that the command prompt is left where it began. "cd bin"

Comment by Steve Bate [ 17/Aug/06 ]

Would you have time to modify the .bat files so that they detect the location of the batch file and set up the class path relative to that? For example, if someone ran C:/foo/bar/baz/banza.bat, the base directory would be set to C:/foo/bar/baz/ and the classpath would be defined relative to that. I could do something similar for the *nix shell scripts.

The eclipse and ant paths are there for development environments. However, there should obviously have been a class path entry for the library location in a binary distribution. Thanks for reporting that problem.

Comment by Steve Bate [ 17/Aug/06 ]

Hi Markus. Thanks for helping on this issue. When you are complete, please reassign the issue back to me and I'll close it after modifying the *nix scripts (unless you want to do that too ). Thanks again.

Comment by Markus Khouri [ 22/Aug/06 ]

Attaching "banzai.updated.bat" and "executor.updated.bat", which contain the corrected classpath setup

Comment by Markus Khouri [ 22/Aug/06 ]

Attaching updated "banzai.updated.sh" and "executor.updated.sh" files.

NOTE: These have not been validated since I do not have a linux environment to test them out.

Comment by Steve Bate [ 26/Aug/06 ]

Thanks Markus. I appreciate it. I'll reopen the issue until I have a chance to try to *nix scripts.

Comment by Steve Bate [ 02/Sep/06 ]

I've modified the DOS and *nix scripts to be independent of the execution directory. They both find the script directory from the path of the script and then initialize classpaths and other paths relative to that location. I've also factored out some of the duplication between the scripts.





[QFJ-47] no sample config file for sample code Created: 12/Aug/06  Updated: 22/Aug/06  Resolved: 17/Aug/06

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

Type: Bug Priority: Default
Reporter: Markus Khouri Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None


 Description   

The sample code on http://www.quickfixj.org/quickfixj/usermanual/usage/application.html does not include the configuration file.

Using the configuration file found on http://www.quickfixj.org/quickfixj/usermanual/usage/configuration.html returns the following errors when executing the sample code:

Exception in thread "main" quickfix.ConfigError: No acceptor sessions found in settings.
at quickfix.mina.acceptor.AbstractSocketAcceptor.createSessions(AbstractSocketAcceptor.java:135)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:62)
at quickfix.mina.acceptor.AbstractSocketAcceptor.<init>(AbstractSocketAcceptor.java:78)
at quickfix.SocketAcceptor.<init>(SocketAcceptor.java:36)
at xxx.Brook.mainAcceptor(Brook.java:228)
at xxx.Brook.main(Brook.java:169)

{{{
public static void main(String args[]) throws Exception {
if(args.length != 1) return;
String fileName = args[0];

Application application = new Application();
Settings settings = new Settings(new FileInputStream(fileName));
MessageStoreFactory storeFactory = new FileStoreFactory(settings);
LogFactory logFactory = new FileLogFactory(settings);
MessageFactory messageFactory = new DefaultMessageFactory();

// ERROR occurs on following line
Acceptor acceptor = new SocketAcceptor (application, storeFactory, settings, logFactory, messageFactory);
acceptor.start();
// while( condition == true )

{ do something; }

acceptor.stop();
}
}}}



 Comments   
Comment by Steve Bate [ 17/Aug/06 ]

Yes, the sample configuration and the sample Application implementation are independent examples and not intended to be used together. For complete examples with associated configuration files, see the sources for quickfix.examples.banzai.Banzai (initiator) and the quickfix.examples.executor.Executor (acceptor).





[QFJ-46] add method to get all Session IDs from SessionSettings object Created: 12/Aug/06  Updated: 24/Sep/07  Resolved: 17/Aug/06

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

Type: Improvement Priority: Default
Reporter: Markus Khouri Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

This might already be possible, but I cannot find the method; being new, i obviously am learning a lot.

Consider adding a method with the following signature to SessionSettings

public void List getSessionIds()

This would return a non-null implementation of List, probably an ArrayList. I would not expect this method to throw an error. The SessionID object is immutable, i.e. there are no setXXX() methods, so I do not think that there ought to be an issue with returning the keys to the underlining hash.... though I could be wrong.

Such a method would seem to make sense since most of the other methods in SessionSettings take a SessionID parameter.



 Comments   
Comment by Steve Bate [ 17/Aug/06 ]

There is a method SessionSettings.sectionIterator() that may do what you want. It will return the SessionIDs for each non-default section of the settings files. You can then use those IDs to access information about the various sessions. You can also get the SessionIDs for the created sessions from the socket acceptor or initiator. There is a getSessions() method on both of those that returns a list of SessionIDs being connected by that connector.





[QFJ-45] When rejecting a logon, allow logout message to be optional before disconnect. Created: 12/Aug/06  Updated: 12/Apr/07  Resolved: 12/Aug/06

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

Type: Improvement Priority: Default
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-43 Throwing RejectLogon causes Logout me... Closed

 Description   

When the RejectLogon exception is thrown, it can be configured to inhibit the outgoing logout message before the disconnect.






[QFJ-44] Config issue - end time before start time - does it work ? Created: 11/Aug/06  Updated: 15/Nov/12  Resolved: 12/Aug/06

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

Type: Other Priority: Default
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

We have seveal clients that recycle on the same day.

I tried to configure the connection such that the end time is before the start, the connection stops but is never restarted.

[SESSION]
SessionQualifier=CURRENEX_STREAM_TEST
SenderCompID=tudorstream
BeginString=FIX.4.2
TargetCompID=CURRENEX-FXTRADES-FIX
#StartTime=17:15:00
#EndTime=17:00:00
StartTime=08:50:00
EndTime=08:45:00
StartDay=Sunday
EndDay=Friday
HeartBtInt=30
SocketConnectPort=7143
SocketConnectHost=bs1-sdv.grn.tudor.com
DataDictionary=./etc/FIX42.xml
ResetOnLogout=Y
ResetOnDisconnect=Y
SendResetSeqNumFlag=Y
FileStorePath=/prod/OMSdatadev/FIX/CURRENEX_STREAM_TEST
FileLogPath=/prod/OMSdatadev/FIX/CURRENEX_STREAM_TEST
StartDay=Sunday
EndDay=Friday



 Comments   
Comment by Steve Bate [ 12/Aug/06 ]

There are some scheduling bug fixes in the upcoming 1.0.2 release. That might solve your problem. If not, reopen this question and we'll change to a bug report. You might also want to look at the scheduling unit test and see if any cases are missed. There are quite a few test cases. Thanks.

Comment by Richard Pike [ 14/Aug/06 ]

Where can I get a cut of the code to test ?

Comment by Steve Bate [ 14/Aug/06 ]

Hi Richard.

The SVN branch is https://svn.sourceforge.net/svnroot/quickfixj/branches/QFJ_RELEASE_1_0_x.

However, I'll be releasing 1.0.2 very soon and you could try that.

Comment by Richard Pike [ 15/Aug/06 ]

Is it possible for you to send me a patched zip files of a copiled version, I am switching the production links here to use quick fix (after hailing it) only to find the start / stop times dont work.

I am unable to get to / compile the source tree ..

Thanks ...

Comment by Steve Bate [ 15/Aug/06 ]

The 1.0.2 binaries are now released on SourceForge. If the
schedule-related fixes don't solve your problem, I'm sure we
can work it out quickly.

https://sourceforge.net/project/showfiles.php?group_id=163099

Comment by Richard Pike [ 16/Aug/06 ]

Alas this did not work. Is there a net beans project for building qf ?

Comment by Steve Bate [ 17/Aug/06 ]

Hi Richard, there is no net beans project but the Ant script is very easy to use. Just type 'ant jar' to build the QFJ JAR file. I haven't used net beans but I assume they have good integration with Ant if you don't want to build it from the command line.

I'm very curious about what is happening in your situation. Your configuration specifies that you want weekly sessions starting at 8:50 on Sunday and end at 8:45 on Friday. Is that the behavior you want? I'd expect the connections to be closed Friday morning and not reopen until Sunday morning. If you want daily sessions ending at 8:45 and starting at 8:50, you should remove the startDay and endDay configurations since those are specifying weekly sessions.

Steve

Comment by Richard Pike [ 17/Aug/06 ]

Again, on the money. Thanks for the attention, this product is outstanding.

Again, thanks for the help..





[QFJ-43] Throwing RejectLogon causes Logout message before Disconnect Created: 10/Aug/06  Updated: 15/Nov/12  Resolved: 12/Aug/06

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

Type: Bug Priority: Default
Reporter: Rob Gilliam Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows XP, Sun JVM 1.4.2_06


Issue Links:
Relates
is related to QFJ-45 When rejecting a logon, allow logout ... Closed

 Description   

Trying to reject invalid (potentially malicious) Logon requests from an unrecognised IP address fromAdmin by throwing RejectLogon exception when a "bad" Logon is detected.

The JavaDoc for RejectLogon says:

"This exception causes a logon to be reject with an immediate disconnect."

However Session.next(Message) is calling generateLogout() when RejectLogon is caught, so the disconnect is not "immediate", and the "unauthorized" logon attempt consumes a sequence number in the outgoing direction which the "authorized" connecting system may not be aware of when next it logs in, causing a ResendRequest to be sent when a valid logon is finally established (see FIX Protocol 4.4 with Errata 20030618, Vol 2 - "Session Protocol", page 6).



 Comments   
Comment by Steve Bate [ 10/Aug/06 ]

I'll investigate this. I understand the issue with the consumed sequence number. However, on page 9 of the specification it states...

The only exception to the "do not terminate the session" rule is for an invalid
Logon attempt. The session acceptor has the right to send a Logout message
and terminate the session immediately. This minimizes the threat of
unauthorized connection attempts.

I'll check on the behavior of the C++ engine. I'd like to keep it consistent. In any case, the Javadocs should be updated to be more accurate.

Comment by Steve Bate [ 12/Aug/06 ]

The behavior is consistent with the C++ engine and the FIX spec so I'm reclassifying this issue as an improvement rather than a bug. However, I'll add the capability for the behavior to be optional. See the linked issue for more details.

Comment by Rob Gilliam [ 14/Aug/06 ]

OK, we can make that work, although you also might like to consider the inconsistency that then appears to occur when throwing RejectLogon if the Logout message is sent: the engine uses up a MsgSeqNum for its Logout, but doesn't appear to advance the sequence number it expects from the initiator.





[QFJ-42] quickfix.InvalidMessage: Actual body length=115, Expected body length=675 - I can replicate Created: 31/Jul/06  Updated: 15/Nov/12  Resolved: 01/Aug/06

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

Type: Bug Priority: Major
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windoze XP Pro, Netbeans 5.0


Attachments: Text File message.txt    

 Description   

I have replicated the problem with the following code and message, I have been using a dictionary,

String messageString = "8=FIX.4.29=67535=X49=HSFX-FIX-BRIDGE56=UAT_MD_TUDO ... see attached file
String beginString = messageString.substring(2, 9);
String messageType = MessageUtils.getMessageType(messageString);
quickfix.Message message = messageFactory.create(beginString, messageType);
message.fromString(messageString, dataDictionary,dataDictionary != null);



 Comments   
Comment by Richard Pike [ 31/Jul/06 ]

I create the dictionary (for the sample)

DataDictionary dataDictionary = new DataDictionary("E:\\libs\\quickfixj\\etc
FIX42.xml");

I have attached a file with the message

Comment by Steve Bate [ 31/Jul/06 ]

Richard, are you sure that field 5071 is defined in your FIX42.xml for MarketDataIncrementalRefresh? I was able to reproduce the problem before adding the field. We should validate the group count in this case and give a better error message.

Comment by Richard Pike [ 01/Aug/06 ]

Steve, this must be the issue, how do I add the field ?

Comment by Richard Pike [ 01/Aug/06 ]

You're on the money, Thanks!!!!!!!!

Comment by Steve Bate [ 01/Aug/06 ]

OK, great.





[QFJ-41] AllocLinkType has different descriptions for enum in FIX42.xml and FIX44.xml Created: 26/Jul/06  Updated: 03/Mar/07  Resolved: 29/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: None
Fix Version/s: 1.0.2

Type: Improvement Priority: Minor
Reporter: Nick Fortescue Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
is related to QFJ-148 FIX42.xml out of sync with QuickFIX e... Closed

 Description   

Despite them having the same name in the FIX spec document "F/X Netting" and "F/X Swap" the enum values for AllocLinkType are different in FIX42.xml and FIX43.xml / FIX44.xml.

In FIX42.xml they are FX_NETTING and FX_SWAP, in FIX44.xml they are F_X_NETTING and F_X_SWAP. I prefer the FIX42 value, but if this was changed it would break existing code, as the FIX44 value is used to generate the Field class, so for backwards compatibility reasons, the best thing to do is probably change FIX42.xml.



 Comments   
Comment by Steve Bate [ 29/Jul/06 ]

I've updated the 1.0.x branch and the trunk. Thanks.





[QFJ-40] MarketDepth enum status inconsistent Created: 25/Jul/06  Updated: 02/Sep/06  Resolved: 29/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Metadata/Specs
Affects Version/s: None
Fix Version/s: 1.0.2

Type: Bug Priority: Default
Reporter: Nick Fortescue Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: XML File FIX42.xml     XML File FIX43.xml     XML File FIX44-nospace.xml     XML File FIX44.xml    

 Description   

1) A very minor inconsistency is that FIX42 and 43 end elements like "/> (without a space) and 44 ends like " /> (with a space).

2) MarketDepth is a funny Field. It is like an enum, in that values for 0 and 1 have names. It is different from an enum in that values >1 are legal,
so not all values are enumerated. This is a problem, as we would like the code generation to generate the magic constants, but we don't want validation to insist on only having 0 or 1.

At the moment the 3 relevant FIX xml files are inconsistent. FIX42.xml has the enum in, FIX43.xml has it in, but commented out with an explanatory comment,
and FIX44.xml doesn't have the enumerated fields mentioned at all. Because FIX44.xml is checked first, this leads to the magic constants not being generated, and validation working as hoped.

Possible solutions:
1) I'll attach a search and replace version of FIX44 to make the formatting consistent for both. A good reason for this is it makes doing a diff between the files much easier.

2) I can't find anywhere in the code that breaks if the enums for MarketDepth are there, but I might not be looking in the right place. After all, you would hope enums were validated. Can the enums just be put back in (for 43 and 44)? I'll attached the files with the enums back in, and a comment mentioning the N>1 case if you want to add them back.



 Comments   
Comment by Nick Fortescue [ 25/Jul/06 ]

A file with some extra space removed before the close of XML elements, so the file is consistent with the FIX42.xml and FIX43.xml files

Comment by Nick Fortescue [ 25/Jul/06 ]

The FIX 42,43, and 44 files with the enumerated values for MarketDepth added back in, and a comment added to mention the N>1 case

Comment by Jörg Thönnes [ 26/Jul/06 ]

How about having an empty value element:

<field ...>
<value enum="..." ...>
...
<value/>
</field>

which would indicate that other values are possible?

Or
...
<value from="2" to="inf" description=""/>

etc. etc.

We should also check native QF whether it works there.

Comment by Nick Fortescue [ 26/Jul/06 ]

Those are both good ideas, I think I prefer the <value enum="..."> solution, as it would work for non-integer enums.

Another possibility is have a

<value constant="0" description ="FULL_BOOK"/>
<value constant="1" description ="TOP_OF_BOOK"/>

indicating this isn't an enum, it was just a special constant value. However, this fails to encapsulate the knowledge that values <0 are illegal. Checking with native QF is a good idea, we should keep the files the same ideally.

Comment by Steve Bate [ 26/Jul/06 ]

I haven't looked since this issue was raised, but the QuickFIX C++ spec files were also inconsistent for this enum. They might have been changed since I looked last so I'll look again when I have some time.

Comment by Steve Bate [ 26/Jul/06 ]

It looks like the QuickFIX C++ spec files comment the enums for 4.2-4.4. The only issue I can think of for uncommenting the fields is that it may cause validation to start failing with existing installations. Is the lack of constant generation the only problem with the commented fields?

Comment by Steve Bate [ 29/Jul/06 ]

I've decided to comment the enums in all versions. I've updated the 1.0.x branch and the trunk.





[QFJ-39] ClassCastException in MessageCracker Created: 24/Jul/06  Updated: 02/Sep/06  Resolved: 24/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.1
Fix Version/s: 1.0.2

Type: Bug Priority: Default
Reporter: Eddie Robertsson Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP, Java 1.5.0_07



 Description   

QuickFIX didn't respond correctly to a ResendRequest from our counterparty.

Normally this is what happens when I have to restart during the day:

XXX = Me
YYY = Counterparty

8=FIX.4.29=5335=A34=720049=XXX52=20060718-08:07:30.23156=YYY10=108
8=FIX.4.29=6635=A34=720149=XXX52=20060718-08:07:30.26156=YYY98=0108=18010=195
8=FIX.4.29=6635=A34=1422549=YYY52=20060718-08:07:29.59656=XXX98=0108=3010=212
8=FIX.4.29=6235=234=720249=XXX52=20060718-08:07:32.13456=YYY7=116=010=222
8=FIX.4.29=7535=134=720349=XXX52=20060718-08:07:32.13456=YYY112=ResendHasFinished10=224

ResendRequest from YYY:
8=FIX.4.29=6635=234=1422649=YYY52=20060718-08:07:29.60056=XXX7=715016=010=182

Correct respons from QuickFIX/J:
8=FIX.4.29=9435=434=715043=Y49=XXX52=20060718-08:07:32.18456=YYY122=20060718-08:07:3236=7204123=Y10=080
8=FIX.4.29=7535=134=720449=XXX52=20060718-08:07:38.14356=YYY112=Test
OS, 10:07:3810=149
8=FIX.4.29=7535=134=720549=XXX52=20060718-08:07:41.14756=YYY112=Test
OS, 10:07:4110=142

Yesterday's scenario:

8=FIX.4.29=6735=A34=3049949=XXX52=20060718-11:29:33.50456=YYY98=0108=18010=004
8=FIX.4.29=6735=A34=6125449=YYY52=20060718-11:29:34.08356=XXX98=0108=18010=000
8=FIX.4.29=6335=234=3050049=XXX52=20060718-11:29:36.72856=YYY7=116=010=023
8=FIX.4.29=7635=134=3050149=XXX52=20060718-11:29:36.73856=YYY112=ResendHasFinished10=026

ResendRequest from YYY:
8=FIX.4.29=6735=234=6125549=YYY52=20060718-11:29:34.08756=XXX7=3049816=010=249

The correct Sequence Reset message is missing from QuickFIX/J...

8=FIX.4.29=7635=134=3050249=XXX52=20060718-11:29:42.75756=YYY112=Test
OS, 13:29:4210=201
8=FIX.4.29=7635=134=3050349=XXX52=20060718-11:29:45.76156=YYY112=Test
OS, 13:29:4510=203

When checking the Event log I found the following:

20060718-11:29:31.220: Session FIX.4.2:XXX->YYY schedule is daily,
00:00:00 UTC - 00:00:00 UTC
20060718-11:29:31.241: Created session: FIX.4.2:XXX->YYY
20060718-11:29:33.554: Initiated logon request
20060718-11:29:36.728: Received logon response
20060718-11:29:36.728: MsgSeqNum too high, expecting 1 but received 61254
20060718-11:29:36.738: Sent ResendRequest FROM: 1 TO: 0
20060718-11:29:36.788: Received ResendRequest FROM: 30498 TO: 0
20060718-11:29:36.819: Error during message processing
java.lang.ClassCastException: quickfix.Message
at quickfix.MessageCracker.crack(MessageCracker.java:48)
at trader.quickfix.QuickFIXApplication.toApp(QuickFIXApplication.java:373)
at quickfix.Session.resend(Session.java:757)
at quickfix.Session.nextResendRequest(Session.java:698)
at quickfix.Session.next(Session.java:585)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:75)



 Comments   
Comment by Steve Bate [ 24/Jul/06 ]

Eddie,

I've done some investigation on this issue and there is something strange. The log file indicates the messages are FIX 4.2 but the MessageCracker is failing because the resent message BeginString is FIX.4.3 and the message being resent is not a subclass of quickfix.fix43.Message. I'd expect the latter because the messages are FIX 4.2 and I assume a FIX 4.2 message factory is being used. However, I'm not sure how the message would have a FIX 4.3 BeginString. Do you have any ideas? Did you switch the FIX version during the session so that some messages in the store had differing FIX versions in the BeginString?

Steve

Comment by Eddie Robertsson [ 24/Jul/06 ]

Steve,

Hmm, how do you now the MessageCracker is failing because the resent message BeginString is FIX.4.3?

Both me and the coutnerparty are using FIX.4.2 and I just rechecked the message log from the day when the problem occurred and all messages in that log are FIX.4.2. However, I just checked the BugReport and it seems that the normal FIX field delimiter has been removed when I pasted the messages in the BugTracker. Hence, it appears that the start of the message is 8=FIX.4.29=7635... when it really should be 8=FIX.4.2|9=7635...

Other than that I have no clue as to why any messages would have a FIX 4.3 BeginString and I can't find any of those messages in my FIX logs either.
Cheers,
/Eddie

Comment by Steve Bate [ 24/Jul/06 ]

OK, the stack trace was confusing me. The line 48 doesn't correspond to a source code line that could raise class cast exceptions (it's between two lines that could raise it). After more looking, I think I see what's happening. I'm curious. Why are you using the message cracker in the toApp method? Normally, it's used in the fromApp method to delegate to a a type-safe method for processing an incoming message.

The session is creating a generic Message for the resend and that's what's causing the ClassCastException in the message cracker which is looking for a message subtype corresponding to the FIX version. I will modify the Session class to create a message of the correct subtype using the specified message factory but I'm still curious about your use of MessageCracker.

Steve

Comment by Eddie Robertsson [ 24/Jul/06 ]

I'm using the message cracker in the toApp in the same way,

Comment by Eddie Robertsson [ 24/Jul/06 ]

I'm using the message cracker in the toApp in the same way, to delegate to a type-safe method for further pro

Comment by Eddie Robertsson [ 24/Jul/06 ]

Appologize for the multiple posts but apparently Ctrl+Enter submits the comment...

I'm using the message cracker in the toApp in the same way, to delegate to a type-safe method for further processing. For example, I use it to catch when QuickFIX is sending Heartbeats that may indicate a faulty connection.

Would it be easy for me to modify the Session class so I don't have to wait for a new release?

Thanks,
/Eddie

Comment by Steve Bate [ 24/Jul/06 ]

What I'm planning to do is modify the nextResendRequest method in Session.java. There is a line...

Message msg = new Message((String) messages.get, dataDictionary);

in the loop where message are reconstructed from the strings in the message store. I intend to replace with something like...

String msgString = (String)messages.get;
Message msg = messageFactory.create(
MessageUtils.getStringField(msgString, 8), // BeginString
MessageUtils.getMessageType(msgString));
msg.fromString(msgString, dataDictionary, false);

It's a bit uglier and requires some preparsing of the message, which is why is wasn't done before. However, I
didn't anticipate users using the MessageCracker for type safe dispatching of outgoing messages (not that there
is anything wrong with it).

I'm going to modify my ATApplication (acceptance test) to use a MessageCracker in toApp. This should recreate the problem since several of the acceptance tests trigger message resends. I'll then make the changes above and ensure all the tests still pass. If you make the changes first and it seems to work (or not), please tell me. Thanks.

Comment by Eddie Robertsson [ 24/Jul/06 ]

Steve,

I've done the modifications you suggested and done some initial testing. Unfortunately the problem didn't occur everytime a ResendRequest was initiated by the counterparty. However, the modified code seems to work fine so I'll keep testing and check if the ClassCastException reappear.

Thanks and keep up the good work!
/Eddie

Comment by Steve Bate [ 24/Jul/06 ]

The fix has been committed to the 1.0.x branch and to the trunk.





[QFJ-38] FIX Message support double-byte charset. Created: 21/Jul/06  Updated: 02/Apr/15  Resolved: 09/Jun/14

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.1
Fix Version/s: 1.6.0

Type: New Feature Priority: Default
Reporter: Lejiang Assignee: amichair
Resolution: Fixed Votes: 0
Labels: encoding

Attachments: Text File Field.java     Text File Message.java     Text File MessageUtils.java    
Issue Links:
Duplicate
is duplicated by QFJ-74 Explicitly control the String encodin... Closed
is duplicated by QFJ-805 Set GBK charset will silently drop me... Closed
is duplicated by QFJ-382 Foreign Language Support - Multibyte ... Closed
is duplicated by QFJ-666 FIXMessageEncoder got BufferOverflowE... Closed
Relates
relates to QFJ-789 Fully support alternate encodings (ch... Open
is related to QFJ-631 Wrong checksum calculation in "quickf... Closed

 Description   

We use double-byte charset in no english country.QFJ get the fix message length using String.length(),get checksum using String.charAt().But these String method not support double-byte charset,e.g. GBK.

In GBK encoding:
"青".charAt(0)=38738
"青".getBytes()[0] unsiged byte = 199
"青".getBytes()[1] unsiged byte = 244

We wish QFJ to support double-byte charset.



 Comments   
Comment by Steve Bate [ 26/Jul/06 ]

Can you describe a little more how you are using multibyte charsets? Are you only placing the multibyte data in "Encoded*" FIX fields (e.g., EncodedText) or the entire FIX message? The patch makes it appear that you are encoding the entire message.

Comment by Lejiang [ 27/Jul/06 ]

Yes,the mutil-bytes charset chars are in the body fields of message,not only in the "encoded*" FIX fields.

I'm working on the FIX Dialect(Subset) and its default charset is double-bytes charset--GBK.

Now the primary problem is it.

See more about this FIX Dialect,please refer to QF maillist:QFJ:The problems in definite a new protocol of FIX subset.

We have changed some codes of QFJ to adapt this FIX Dialect.If the QFJ can directly support this feature,will be perfect for us.

Comment by amichair [ 09/Jun/14 ]

It should work now for any charset that is a superset of ASCII, which is most of them. The issue title is a bit misleading, since GBK (stated in description) is a multibyte charset that is backward-compatible with ASCII, and so should work now, whereas a double-byte charset such as UTF-16 will not (all double-byte charsets are by definition not backward-compatible with ASCII).

The current solution uses the global CharsetSupport, but there is still no proper support for all (non-ASCII compatible) encodings, MessageEncoding fields, etc. I'll open a separate issue for that.





[QFJ-37] Make executor in examples handle Forex limit orders too Created: 20/Jul/06  Updated: 02/Sep/06  Resolved: 26/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: 1.0.0 B3, 1.0.0 Final, 1.0.1, 1.0.2, 1.1.0
Fix Version/s: 1.0.2

Type: Improvement Priority: Minor
Reporter: Nick Fortescue Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The Executor example code has several copies of the line pair:

if (ordType.getValue() != OrdType.LIMIT)
throw new IncorrectTagValue(ordType.getField());

The code would work just as well if it accepted orders of type OrdType.FOREX_LIMIT. Could this be modified to

if (ordType.getValue() != OrdType.LIMIT && ordType.getValue() != OrdType.FOREX_LIMIT)
throw new IncorrectTagValue(ordType.getField());

Even better would be to extract this code to a method called something like validateOrdType(), then you wouldn't need the same code duplicated across all the methods.

Not urgent, I realise this is just example code, but it had me confused for a bit, and is quite easy to fix



 Comments   
Comment by Steve Bate [ 26/Jul/06 ]

I agree about the comments on duplicated code. I inherited these examples from the parent QuickFIX project and I've never done much to clean up the code. I've made a few changes to the executor application so that order types can now be configured in the session settings (see executor.cfg). By default, I've included Limit and Forex Limit but other types could be specified if needed. This is in the trunk and the 1.0.x branch.





[QFJ-36] Missing enums for SecurityTradingStatus (Tag #326) Created: 19/Jul/06  Updated: 02/Sep/06  Resolved: 22/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.1
Fix Version/s: 1.0.2

Type: Bug Priority: Minor
Reporter: Matyas Barakonyi Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Either Windows or Linux operating systems...



 Description   

Missing valid values (enums) in the quickfix fix44 SecurityTradingStatus class.

Valid values: (according the FIX.4.4 specifications)
1 = Opening Delay
2 = Trading Halt
3 = Resume
4 = No Open/No Resume
5 = Price Indication
6 = Trading Range Indication
7 = Market Imbalance Buy
8 = Market Imbalance Sell
9 = Market On Close Imbalance Buy
10 = Market On Close Imbalance Sell
11 = (not assigned)
12 = No Market Imbalance
13 = No Market On Close Imbalance
14 = ITS Pre-Opening
15 = New Price Indication
16 = Trade Dissemination Time
17 = Ready to trade (start of session)
18 = Not Available for trading (end of session)
19 = Not Traded on this Market
20 = Unknown or Invalid
21 = Pre-Open
22 = Opening Rotation
23 = Fast Market

Need to be added from 11 to 23.



 Comments   
Comment by Steve Bate [ 22/Jul/06 ]

These were already included in the trunk, but they apparently had not been merged to the 1.0 branch. I've done the merge so the fix will be in 1.0.2.





[QFJ-35] external tool builder for eclipse gone? Created: 09/Jul/06  Updated: 15/Nov/12  Resolved: 14/Jul/06

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

Type: Other Priority: Trivial
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Hi,

The external tool builder to generate the message classes in eclipse seems to have been deleted from svn trunk. Has it been replaced by another way of doing it?

Thanks,
Brad.



 Comments   
Comment by Steve Bate [ 14/Jul/06 ]

I had trouble with the Ant builder breaking across different installations and not running at appropriate times. I've moved the code generation to an external Ant-based program on the external programs menu. I might try again with the builder approach with Eclipse 3.2.

Comment by Amy Nicoll [ 16/Apr/12 ]

Hi,

I tried to follow the Eclipse IDE installation instructions on your site:
http://www.quickfixj.org/quickfixj/usermanual/1.5.1/installation.html

However, it appears the external tool builder referenced in the instructions ("Generate FIX Messages") is not in the svn trunk. Has the code generation been moved again?

Thanks,
Amy





[QFJ-34] Thread leak in socket connector Created: 09/Jul/06  Updated: 15/Feb/07  Resolved: 15/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Networking
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.2

Type: Bug Priority: Critical
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Originally observed in quickfix/j 1.0.0, jdk 1.4.2, mina 0.9.3.
Also Reproduced with quickfix/j trunk, jdk 1.5, mina 0.9.5 trunk.


Attachments: JPEG File Banzai thread leak.jpg    

 Description   

A few new threads are created by MINA each time an initiator connects to a remote host. Two of these (AnonymousIoService-x-y) are not cleaned up which can event lead to OutOfMemoryError or other strange behaviour.

This can easily be reproduced using Banzai and Executor. Change the SenderCompId in Banzai to BANZAI2 which will cause the executor to disconnect it after the logon. Start the executor and start Banzai in the debugger. As it reconnects you'll see three threads hanging around each time:
SocketConnector-0
AnonymousIoService-1-1
AnonymousIoService-1-2

The SocketConnector threads do eventually get cleaned up after an idle period, but the AnonymousIoService threads hang around forever.

Thread [SocketConnector-1] (Suspended)
WindowsSelectorImpl$SubSelector.poll0(long, int, int[], int[], int[], long) line: not available [native method]
WindowsSelectorImpl$SubSelector.poll() line: 275
WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl$SubSelector) line: 257
WindowsSelectorImpl.doSelect(long) line: 138
WindowsSelectorImpl(SelectorImpl).lockAndDoSelect(long) line: 69
WindowsSelectorImpl(SelectorImpl).select(long) line: 80
SocketConnector$Worker.run() line: 394
Thread [AnonymousIoService-2-3] (Suspended)
Object.wait(long) line: not available [native method]
LeaderFollowersThreadPool$Worker.waitForPromotion() line: 402
LeaderFollowersThreadPool$Worker.run() line: 309
Thread [AnonymousIoService-2-4] (Suspended)
Object.wait(long) line: not available [native method]
BlockingQueue(Object).wait() line: 474
BlockingQueue.waitForNewItem() line: 55
LeaderFollowersThreadPool$Worker.fetchRunnable() line: 339
LeaderFollowersThreadPool$Worker.run() line: 312



 Comments   
Comment by Brad Harvey [ 09/Jul/06 ]

I actually think this is a bug in MINA. The PooledThreadModel which is used by the default configuration creates a new ThreadPoolFilter which is what is creating these wayward threads. I don't think the destroy method of this filter ever gets called. If the PooledThreadModel used a ReferenceCountingIoFilter to wrap the ThreadPoolFilter before adding it to the chain then destroy would be called

I'm also not sure if quickfix should even be using the PooledThreadModel - I think the event handling strategies do this part instead. So you might be able to do something like this in IoSessionInitiator to use no threading:

public synchronized void connect() {
lastReconnectAttemptTime = SystemTime.currentTimeMillis();
try

{ IoConnector ioConnector = ProtocolFactory.createIoConnector(getNextSocketAddress()); BaseIoServiceConfig connectorConfig = (BaseIoServiceConfig) ioConnector.getDefaultConfig().clone(); connectorConfig.setThreadModel(ThreadModel.MANUAL); ConnectFuture connectFuture = ioConnector.connect(getNextSocketAddress(), ioHandler, connectorConfig); connectFuture.join(); ioSession = connectFuture.getSession(); }

catch (Throwable e)

{ quickfixSession.getLog().onEvent("Connection failed: " + e.getMessage()); }

}

It seems to work ok for Banzai stops all the extra thread creation, but I haven't tried it beyond that.

Comment by Brad Harvey [ 09/Jul/06 ]

Slightly off topic:

I think the PooledThreadModel/ThreadPoolFilter would take care of quickfix/j's thread pool needs as described in http://sourceforge.net/mailarchive/forum.php?thread_id=10923994&forum_id=103.

ThreadPoolFilter uses an internal queue (ThreadPoolFilter$SessionBuffer) per MINA session. Each queue can be processed by at most one worker thread from the thread pool at once, so each message would be processed in order. The EventHandlingStrategies would no longer be used as onMessage would be called by one of the worker threads.

The worker thread will process events on the queue until it is empty, and more events can be added while it is running. I think this means a busy Session could starve other sessions if the thread pool is too small so it may not be directly suitable as a SingleThreadedEventHandlingStrategy replacement - an alternate ThreadPoolFilter that only processes one event from the queue may be required. ThreadPerSession could be implemented by supplying an unbounded thread pool.

This all assumes that the ThreadPoolFilter gets cleaned up properly when the session is closed, of course.

Comment by Steve Bate [ 09/Jul/06 ]

Brad, thanks for investigating this issue. I'm traveling internationally right now but I'll review all your comments when I return. I definitely appreciate the help.

Comment by Steve Bate [ 15/Jul/06 ]

I added the code for your original suggestion. The other suggestion about using MINA thread pooling is interesting, but I'd like to wait until the 0.9.x API stabilizes (MINA 1.0 release) before I tie to the QFJ code into it very deeply. The changes are on the branch: QFJ_RELEASE_1_0_x (and merged to the trunk).

Comment by Brad Harvey [ 18/Jul/06 ]

Thanks Steve. Note that my code was a bit naughty in that it used the base class instead of the interface for IoServiceConfig.

Comment by Steve Bate [ 15/Feb/07 ]

I noticed some additional discussion about MINA thread models. It appears that Trustin and Peter want to remove the interface from MINA and recommend using the "manual" thread pool management (which we are doing). Brad (or anyone else), have you been following the discussion and are you familiar with the latest thoughts on th issue?

http://www.nabble.com/Is-ThreadModel-really-useful--t2778892.html

Comment by Brad Harvey [ 15/Feb/07 ]

Thanks for the link, no I hadn't been following it. Sounds like you'll just have to remove the setThreadModel calls and come back a full circle

To implement thread handling I think they're still recommending using a ThreadPoolFilter but adding it manually to the filter chain, as opposed to using the ThreadModel abstraction. So most of the "slightly off topic" stuff about ThreadPoolFilter above should still apply if anyone is after a thread pool in quickfix.

Cheers,
Brad.





[QFJ-33] Receiving vendor stream yields SEVERE: Invalid message: Actual body length=xxx, Expected body length=yyy Created: 03/Jul/06  Updated: 15/Nov/12  Resolved: 14/Jul/06

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

Type: Bug Priority: Default
Reporter: Richard Pike Assignee: Steve Bate
Resolution: Not a bug Votes: 1
Labels: None
Environment:

Windoze, preparing for Linux (64 bit) in a bid to replace APPIA and prove open source over vendor. Quickfix rocks



 Description   

When receiving a SNAPSHOT / INCREMENTAL update I receive this error.

Jul 3, 2006 9:28:22 AM quickfix.mina.AbstractIoHandler messageReceived
SEVERE: Invalid message: Actual body length=116, Expected body length=676

Here's a sample vendor message:

8=FIX.4.2☺9=418☺35=W☺49=HSFX-FIX-BRIDGE☺56=UAT_MD_TUDOR☺34=3184☺52=20060703-13:31:13☺55=CAD/JPY☺107=
67285☺268=11☺269=0☺270=103.25☺271=13500000☺269=0☺270=103.24☺271=6900000☺269=0☺270=103.22☺271=2150000
0☺269=0☺270=103.2☺271=10200000☺269=0☺270=103.18☺271=500000☺269=0☺270=103.17☺271=100000☺269=1☺270=103
.26☺271=8500000☺269=1☺270=103.29☺271=4400000☺269=1☺270=103.31☺271=15300000☺269=1☺270=103.32☺271=7600
000☺269=1☺270=103.33☺271=10600000☺10=181☺



 Comments   
Comment by Richard Pike [ 03/Jul/06 ]

This is an issue in my software, please close and ignore. Apologies.....

Comment by Richard Pike [ 03/Jul/06 ]
            • THE ISSUE IS STILL THERE *****

I thought initially that my simple proxy was getting messages messages up but now it appears not to be the case. I moved the connections to a direct point and the session still fails.

Comment by Steve Bate [ 14/Jul/06 ]

Sorry about the delay on the response. I've been traveling (and recovering from traveling ). Were you using a data dictionary when this happened? If not, repeating groups cannot be handled correctly.

Comment by Steve Bate [ 14/Jul/06 ]

I was able to parse the message you included if I used a data dictionary. Without a data dictionary I received a similar message to the one you reported.





[QFJ-32] SessionSchedule race condition causes disconnect at midnight UTC Created: 25/Jun/06  Updated: 02/Sep/06  Resolved: 15/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 B3, 1.0.0 Final, 1.0.1, 1.1.0
Fix Version/s: 1.0.2

Type: Bug Priority: Minor
Reporter: Scott Harrington Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

The current implementation of Session.checkSessionTime() has a race condition caused
by multiple calls to System.currentTimeMillis(). (Not a thread access race, but a race against
the wall clock.) This will not be caught by the Junit tests unless you happen to be running them
right around midnight on a slow computer, but it's QUITE LIKELY to be seen in a running server
with multiple sessions open every night!

Suppose the method is entered just before midnight UTC, e.g. 23:59:59.999, and the clock has
not yet ticked over by the time the SessionSchedule fields are updated by adjustSessionTimes.

But then the calls to "getTimeOnly" occur after the clock has ticked over and isDailySessionTime
starts comparing times from yesterday against the new "time only" calendar instance.

The end result is a "false" return from checkSessionTime when it really should be true, leading
to disconnect.



 Comments   
Comment by Steve Bate [ 15/Jul/06 ]

I've redesigned the SessionSchedule class so that it doesn't do a double query of the system time. The changes are on the branch: QFJ_RELEASE_1_0_x (and merged to the trunk).





[QFJ-31] Configuring logger TimeZone Created: 23/Jun/06  Updated: 15/Nov/12  Resolved: 12/Aug/06

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

Type: New Feature Priority: Default
Reporter: Faraz Parhami Assignee: Steve Bate
Resolution: Won't Fix Votes: 0
Labels: None
Environment:

All



 Description   

Currently there is no way to change the logger TimeZone. It would be nice if the 'TimeZone' configuration ID works for both session scheduling and logger.



 Comments   
Comment by Steve Bate [ 26/Jul/06 ]

I don't think the same time zone would also be desired for session scheduling and logging. For example, the session scheduling might be done in the exchange time zone but logging formatted for the local time zone. Have you considered using Log4j and the QFJ SLF4JLog? Log4J allows the time zone to be configured on a per-appender basis. I think you can even control the timezone per logging category if needed. Would that work for you?

Comment by Steve Bate [ 12/Aug/06 ]

Since I haven't received and feedback on my previous comments, I'll close the issue. You can reopen it later if you'd like.





[QFJ-30] Weekly session does not work Created: 19/Jun/06  Updated: 12/Sep/06  Resolved: 15/Jul/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.2

Type: Bug Priority: Major
Reporter: Christian Braeuner Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows XP, Sun JVM 1.4.2_06



 Description   

When a weekly session is configured, quickfixj would stop and start sessions on other weekdays than the one configured. In my particular case I have a session that is reset on a Friday afternoon, so quickfixj was configured for a weekly session lasting from Friday 16:00 to Friday next week 13:00. Errors in the calculation made it log out, reset and log in on other weekdays as well.

Here are suggested code changes:

SessionSchedule.java line 221:
int time1Range = timestamp1.get(Calendar.DAY_OF_WEEK) - startDay;
int time2Range = timestamp2.get(Calendar.DAY_OF_WEEK) - startDay;

if (time1Range == 0) {
Calendar timeOnly = getTimeOnly(timestamp1, calendar1);
if (timeOnly.before(startTime))

{ time1Range = 7; }
  • } else if (time1Range < 0) { * time1Range +=7 ; }

if (time2Range == 0) {
Calendar timeOnly = getTimeOnly(timestamp2, calendar2);
if (timeOnly.before(startTime))

{ time2Range = 7; }
  • } else if (time2Range < 0) { * time2Range +=7 ; }

SessionSchedule.java line 262:

if (startDay == endDay) {

  • //Session can go from 13:00-15:00 or from 15:00 - 13:00 ( incl. 7 days)
  • if (startTime.before(endTime)) { * if (currentDay != startDay || currentTime.before(startTime) || currentTime.after(endTime)) * return false; * }

    else

    { * if (currentDay == startDay && currentTime.before(startTime) && currentTime.after(endTime)) * return false; * }

} else if (startDay < endDay) {

Christian



 Comments   
Comment by Steve Bate [ 15/Jul/06 ]

I've redesigned the SessionSchedule class and changed the algorithm for calculating weekly schedules. I also added a test to look for problems with week-long schedule by periodically checking the schedule throughout a simulated weeklong time period. I used your schedule as the test case. It appears to work well now. The changes are on the branch: QFJ_RELEASE_1_0_x (and merged to the trunk).

Comment by Christian Braeuner [ 24/Aug/06 ]

Hi Steve,

unfortunately there are different problems with the new SessionSchedule it seems. I've had 2 resets during in the middle of the active weekly schedule. My schedule is from Friday 22:00 to Friday next week 18:00, i.e. there is only a 4h down time in which the session is reset.
I'll try and reproduce it, when I've got some spare time, but as my version works, I'll revert back to that one for the time being.

Comment by Christian Braeuner [ 04/Sep/06 ]

Hi Steve,

sorry, I wasn't clear on my previous comment. I have tried your version 1.0.2 and your change has got a different problem now in that the weekly session is reset when it shouldn't .

Comment by Steve Bate [ 04/Sep/06 ]

Hi Christian,

I'd really like to know what's happening here (I'm guessing you feel the same way ). I have a unit test that scans an entire week every at an interval of 5 seconds (configurable if we want 1 second test resolution, but the test is then slow) and ensures the session schedule gives the correct information about session boundaries. The test is SessionScheduleTest.testWeeklyPeriodically(). Do you have any ideas about how to use a test case to reproduce the problem you are seeing?

Comment by Christian Braeuner [ 04/Sep/06 ]

Hi Steve,

Thanks for your efforts so far. I could have something to do with boundary conditions when it switches over, but have you tried combining that with different "last session creation time" values? I am sure it has something to do with different combinations of local time, last session creation time and the active schedule.
Here are some combinations that I'd try out:

Session schedule Last created Now Active Reset
Wed 14:00 - Wed 12:00 Mon 09:00 this week Mon 09:00 this week Y N
Wed 14:00 - Wed 12:00 Mon 09:00 this week Mon 13:00 this week Y N
Wed 14:00 - Wed 12:00 Mon 09:00 this week Mon 15:00 this week Y N
Wed 14:00 - Wed 12:00 Mon 09:00 this week Wed 09:00 this week Y N
Wed 14:00 - Wed 12:00 Mon 09:00 this week Wed 13:00 this week N Y
Wed 14:00 - Wed 12:00 Mon 09:00 this week Wed 15:00 this week Y Y
Wed 14:00 - Wed 12:00 Mon 09:00 this week Fri 09:00 this week Y Y
Wed 14:00 - Wed 12:00 Mon 09:00 this week Fri 13:00 this week Y Y
Wed 14:00 - Wed 12:00 Mon 09:00 this week Fri 13:00 this week Y Y

Then combine 'now' times above with different 'last created' times below
.... Fri 09:00 2 wks ago varied 'now' as above all 'Y'
.... Mon 09:00 last week .... as above all 'Y'
.... Wed 09:00 last week .... as above all 'Y'
.... Wed 15:00 last week .... as above as above
.... Fri 09:00 last week .... as above as above
.... Mon 09:00 this week .... as above as above
.... Wed 09:00 this week .... as above as above
.... Wed 13:00 this week .... as above as above
.... Wed 15:00 this week .... as above all 'N'
.... Thu 09:00 this week .... as above all 'N'

You can also combine the combinations above with different weekly session schedules, but the one above is the case I am using. I am using the standard time zone, i.e. UTC.
Suggestions for different schedules would be

Wed 14:00 - Wed 12:00
Wed 14:00 - Tue 18:00
Wed 14:00 - Tue 12:00
Wed 14:00 - Fri 18:00
Wed 14:00 - Fri 12:00
and then inverting the times, i.e.
Wed 12:00 - Wed 14:00 etc.

I think that would exhaustively cover all possible combinations that I can think of. I haven't looked at your unit tests, but I guess you are doing something similar and my hope is that you've missed something out. Maybe you can compare your schedules with mine and hopefully we'll find a gap in the existing tests that my connection fails on. Otherwise it is going to be difficult to explain and I'd have to try your version again, put some debug output in there and hope it fails soon. But it is safer to reproduce it with a full set of tests.

Comment by Steve Bate [ 12/Sep/06 ]

Hello,

I've tried many different combinations of tests and I still can't reproduce the problem. I currently have a test case that tests a range of schedule start/end combinations, session creation times and current times. There are literally thousands of tests and I'm almost sure they include all the cases you listed above. I also created tests specifically for many, but not all, of the specific scenarios you listed and they passed. I'm beginning to wonder if the problem is at a higher level, possibly in the session logic that uses the session schedule.





[QFJ-29] Clean example scripts classpath. Created: 14/Jun/06  Updated: 02/Sep/06  Resolved: 17/Jun/06

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

Type: Bug Priority: Minor
Reporter: Nick Fortescue Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows


Attachments: File banzai.bat     Text File banzai.sh     File executor.bat     Text File executor.sh    

 Description   

The examples .bat/.sh scripts have not been kept up to date for the latest svn release. In order to work, banzai.sh, banzai.bat, executor.sh and executor.bat need to have the classpath updated from slf4j-jdk14.jar to slf4j-jdk14-1.0.1.jar.

Secondly, currently the scripts add stuff to the classpath every time they are run, meaning the classpath gets longer and longer, if the files are used from a shell/command prompt. I've modified the scripts to use a local variable and the java -classpath option instead of the $CLASSPATH global variable.

I'll attach improved scripts.



 Comments   
Comment by Nick Fortescue [ 14/Jun/06 ]

.bat and .sh files with the issues fixed. Could someone with a Unix system test the .sh files, I've only tried them under cygwin.

Comment by Steve Bate [ 17/Jun/06 ]

Patched in 1,0.x branch and merged to trunk.





[QFJ-28] FileStore: working directory patch Created: 14/Jun/06  Updated: 02/Sep/06  Resolved: 17/Jun/06

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Ok, my apologies for sending an incomplete email earlier. Had an
"enter key" malfunction.

I'm working on a multi-module project driven by Maven (instead of
ant), where couple of the modules use QuickfixJ.

The directory layout is as follows:
parentModule

  • childModule
  • src
  • test
  • java
    *.java files are here

I'm noticing a very strange situation: i have a unit test that runs
just fine if you run it directly from the <childModule> directory, it
initializes the Session correctly which creates the appropriate
output/ and store/ directories for FIX.4.2-xxx files.

However, if i run the same test from a parent directory (ie one level
up) then it fails in to create/locate the output/ directory:
java.io.FileNotFoundException:
output/data/server/FIX.4.2-test-exchange-test-sender.body (No such
file or directory)
java.lang.RuntimeException: java.io.FileNotFoundException:
output/data/server/FIX.4.2-test-exchange-test-sender.body (No such
file or directory)
at quickfix.FileStoreFactory.create(FileStoreFactory.java:65)
at quickfix.Session.<init>(Session.java:191)
at quickfix.DefaultSessionFactory.create(DefaultSessionFactory.java:125)
at quickfix.mina.acceptor.AbstractSocketAcceptor.createSessions(AbstractSocketAcceptor.java:129)

with the real error coming from here:
Caused by: java.io.FileNotFoundException:
output/data/server/FIX.4.2-test-exchange-test-sender.body (No such
file or directory)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(Unknown Source)
at java.io.RandomAccessFile.<init>(Unknown Source)
at quickfix.FileStore.initialize(FileStore.java:97)
at quickfix.FileStore.<init>(FileStore.java:87)
at quickfix.FileStoreFactory.create(FileStoreFactory.java:63)

I've traced the cause of the error itself to a Maven bug (incorrect
working dir setup) which i've filed with them:
http://jira.codehaus.org/browse/MSUREFIRE-133

In QuickFixJ it gets manifested in quickfix.FileStore class
constructor. If the incoming "path" is changed to be an absolute path
(instead of relative) the rest of initialization works fine.

I understand this a maven bug and not Quickfix, but i was hoping you
would incorporate the workaround for it anyway b/c it makes sense
regardless: it's just to take the incoming path and to always treat it
as an absolute path. That makes the code more defensive.

It's a one-line change. all the unit tests pass.

I"m attaching a patch for the changes (it's just one line).

toli



 Comments   
Comment by Steve Bate [ 14/Jun/06 ]

Index: src/quickfix/FileStore.java
===================================================================
— src/quickfix/FileStore.java (revision 416)
+++ src/quickfix/FileStore.java (working copy)
@@ -67,6 +67,8 @@
if (path == null)

{ path = "."; }

+ path = new File(path).getAbsolutePath();
+
String sessionId = sessionID.getBeginString() + "" + sessionID.getSenderCompID() + ""
+ sessionID.getTargetCompID();
if (sessionID.getSessionQualifier() != null && !sessionID.getSessionQualifier().equals("")) {

Comment by Steve Bate [ 17/Jun/06 ]

Unfortunately, the changes were committed with a different issue number so they aren't linked here.





[QFJ-27] hashCode implementation of Field is not correct Created: 13/Jun/06  Updated: 15/Nov/12  Resolved: 17/Jun/06

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

Type: Bug Priority: Minor
Reporter: Tim Wright Assignee: Steve Bate
Resolution: Cannot Reproduce Votes: 0
Labels: None


 Description   

Two objects can be equal but have different hashcodes - this means they cannot be used as a key in a hashmap!

public boolean equals(Object object)

{ if (super.equals(object) == true) return true; if (!(object instanceof Field)) return false; return tag == ((Field) object).getField() && getObject().equals(((Field) object).getObject()); }

public int hashCode()

{ return object.hashCode(); }

 Comments   
Comment by Steve Bate [ 14/Jun/06 ]

Hi Tim,

What type of field object was giving different hashCodes when the field objects were equal? If you could describe a small test case, that will help. Thanks.

Comment by Steve Bate [ 14/Jun/06 ]

I've added a test for checking consistency of equals and hashcode when the object are equalivalent. It's currently passing but I might have missed the case you are describing. You can review the test case by looking at the subversion commits linked above ("Subversion Commits" tab).

Comment by Brad Harvey [ 15/Jun/06 ]

Hi Steve,

I can't see the Subversions Commits tab (only All/Comments/Change History). Possibly a permissions issue?

I don't think you'll get a case where two equal objects have different hashCodes, but you might get better hash distribution (assuming different tags have the same values I suppose) if tag was included in the hash.

Comment by Steve Bate [ 15/Jun/06 ]

Yes, you are right. I didn't know that. I've modified the permissions so you should be able to see the subversion commits now.

Comment by Brad Harvey [ 16/Jun/06 ]

Yep can see commits now, thanks.





[QFJ-26] Add clear and isEmpty operation to FieldMap (Message) Created: 10/Jun/06  Updated: 02/Sep/06  Resolved: 10/Jun/06

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to QFJ-25 Message constructor throws NullPointe... Closed

 Description   

This was part of the QFJ-25 patch submitted by Oren.



 Comments   
Comment by Steve Bate [ 10/Jun/06 ]

Patches applies to both 1.0.x branch and trunk





[QFJ-25] Message constructor throws NullPointerException with empty string Created: 09/Jun/06  Updated: 02/Sep/06  Resolved: 10/Jun/06

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

Type: Bug Priority: Minor
Reporter: Oren Miller Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File patch_msg.txt    
Issue Links:
Relates
is related to QFJ-26 Add clear and isEmpty operation to Fi... Closed

 Description   

I discovered this when passing an empty (not null) string into the message constructor. The parseHeader assumes that BeginString, Length, and MsgType will be present in the string, when in fact they might not be. This causes parseHeader to operate on a nul field returned by extractField. Below is a patch with tests.



 Comments   
Comment by Steve Bate [ 10/Jun/06 ]

Patches applied to both the 1.0.x branch and the trunk





[QFJ-24] Upgrade to SLF4J 1.0.1 Created: 06/Jun/06  Updated: 07/Apr/10  Resolved: 07/Apr/10

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

This addresses a few SLF4J bugs in the JDK logging adapter.






[QFJ-23] Create initial Spring Framework support and examples Created: 04/Jun/06  Updated: 10/Jan/10  Resolved: 10/Jan/10

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

Type: New Feature Priority: Major
Reporter: Steve Bate Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: None


 Comments   
Comment by Toli Kuznets [ 22/Dec/06 ]

Steve,

we took a first crack at configuring QuickfixJ through Spring in our latest release.
we have created 2 sets of files, quickfix.appctx.xml and quickfixj.xml that you can find at
http://trac.marketcetera.org/trac.fcgi/browser/platform/trunk/oms/src/main/resources

The first one sets up the paths for DataDictionaries to load, the quickfixj.xml deals with creating the log factories,
specifying session defaults, socket initiators, etc.

the overall app for us is setup in a different file (oms.xml),but perhaps these could act as a starting point for other examples.

Comment by David Gibbs [ 13/Oct/09 ]

In case it helps any one I did the following

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:util="http://www.springframework.org/schema/util" xmlns="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<bean id="quickfixConfig" class="java.io.FileInputStream">
<constructor-arg value="./src/test/config.uat/quick-fix.cfg" />
</bean>

<bean id="sessionSettings" class="quickfix.SessionSettings">
<constructor-arg ref="quickfixConfig" />
</bean>

<bean id="logFactory" class="quickfix.SLF4JLogFactory">
<constructor-arg ref="sessionSettings" />
</bean>

<bean id="messageFactory" class="quickfix.DefaultMessageFactory">
</bean>

<bean id="messageStoreFactory" class="quickfix.FileStoreFactory">
<constructor-arg ref="sessionSettings" />
</bean>

</beans>

Which is then included in a master config file where the acceptor is configured.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:util="http://www.springframework.org/schema/util"
xmlns="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<context:annotation-config />

<import resource="spring.quickfixj.xml"/>
.....

<bean id="acceptor" class="quickfix.SocketAcceptor">
<constructor-arg ref="application" />
<constructor-arg ref="messageStoreFactory" />
<constructor-arg ref="sessionSettings" />
<constructor-arg ref="logFactory" />
<constructor-arg ref="messageFactory" />
</bean>

<bean id="choreographer" class="com.iggroup.fix.otc.trading.Choreographer">
<constructor-arg>
<list>
.......
</list>
</constructor-arg>
<constructor-arg ref="acceptor" />
</bean>

.....

</beans>

Comment by Steve Bate [ 10/Jan/10 ]

Nobody has been asking for this, so I'm closing the feature request (which I submitted).





[QFJ-22] Update QFJ with QuickFIX C++ changes Created: 04/Jun/06  Updated: 12/Apr/07  Resolved: 11/Feb/07

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

Type: Task Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Last update: svn rev. 1871






[QFJ-21] Add CheckCompID option to Session (from C++) Created: 04/Jun/06  Updated: 12/Apr/07  Resolved: 04/Jun/06

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

Type: New Feature Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

If set to Y, messages must be received from the counterparty with the correct SenderCompID and TargetCompID. Some systems will send you different CompIDs by design, so you must set this to N.






[QFJ-20] Database statement leak in JDBCStore Created: 03/Jun/06  Updated: 02/Sep/06  Resolved: 04/Jun/06

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.1

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

We moved a FIX gateway server built on quickfixj into production a few
days ago, and it quickly became quite clear that the java program
leaked menory somehow, and so did the mysql server. Both servers grew
to about 2GB each in a few hours. After that, we had to restart the
processes because of performance problems.

Anyway, I traced the problem to the JdbcStore class, which allocates a
new statement for each call. The statement is never closed.
Depending on the Jdbc driver, these statements might or might not be
garbage collected, but in our case they were at least not.

After patching the code everything seems to run really well and fast.

Anyway, I'm a bit reluctant to post a patch since the one I made is so
ugly... It seems that someone started work on caching prepared
statements in the JdbcStore class (using the statementCache member),
but since it is not finished, it results in the leak. The JdbcLog
class does not have this problem.

At first glance it seems very easy to make the cache work (the only
missing statement is one that actually adds the statement to the
cache). It seems to me that thread safety needs to be taken into
account, which might not be trivial. Maybe that's why the cache
mechanism was never finished?

Btw, my current patch just adds a close() call to a number of places.

Staffan



 Comments   
Comment by Steve Bate [ 04/Jun/06 ]

Added database connection (and statement) pooling and support for JDBC data sources. This should address the memory leak and the threading issues.





[QFJ-19] Logout timeout defaults to 0 Created: 31/May/06  Updated: 15/Nov/12  Resolved: 31/May/06

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

Type: Bug Priority: Minor
Reporter: Tim Wright Assignee: Steve Bate
Resolution: Duplicate Votes: 0
Labels: None

Issue Links:
Duplicate
duplicates QFJ-16 Logon Timeout defaults to 0 Closed

 Description   

The logout timeout seems to default to 0.
Also the logout timeout is not documented in the configuration section.



 Comments   
Comment by Steve Bate [ 31/May/06 ]

This is fixed in subversion. The issue with the configuration documentation was only with the online documentation. I had forgotten to update it with the 1.0.0 final documentation. I've made that change now. Thanks for reporting it.





[QFJ-18] Logout not sent at session expiration time Created: 26/May/06  Updated: 02/Sep/06  Resolved: 26/May/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.1

Type: Bug Priority: Minor
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

As far as I can see its doing something as follows:

Timer triggers in SessionConnector, calls session.next()
checkSessionTime() returns false, calls session.reset() -> session.disconnect()
disconnect() calls responder.disconnect(), closes TCP session

I think session.next() perhaps needs changing when checkSessionTime is false to generate a logout message rather than calling reset(), unless there's another timer somewhere meant to do that which might have missed.

Reported by Toby Shepheard



 Comments   
Comment by Steve Bate [ 26/May/06 ]

Added a generateLogout to the reset method. This was added to the C++ last fall but I apparently missed the change. Thanks for the report.





[QFJ-17] Improve reporting of invalid repeating groups Created: 26/May/06  Updated: 12/Apr/07  Resolved: 26/May/06

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.1.0

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Attachments: Text File rg.patch    

 Description   

Steve,

I ran into a problem with repeating groups that I think this patch would help. A counterparty was sending a message containing a repeating group that was out of order (the first field was actually second) and QF/J threw an NPE in parseGroup() when it tried to add the first field it found to the not-yet-constructed group. This patch changes parseGroup() to throw InvalidMessage when the first field found is out of order, and
fromString() to rethrow that.

John Hensley



 Comments   
Comment by Steve Bate [ 26/May/06 ]

Patch from John.

Comment by Steve Bate [ 26/May/06 ]

Patch applied. Thanks John.





[QFJ-16] Logon Timeout defaults to 0 Created: 26/May/06  Updated: 02/Sep/06  Resolved: 26/May/06

Status: Closed
Project: QuickFIX/J
Component/s: None
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.1

Type: Bug Priority: Major
Reporter: Brad Harvey Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Duplicate
is duplicated by QFJ-19 Logout timeout defaults to 0 Closed

 Description   

We were getting many timeouts while waiting for logon confirm when initially starting quickfix/j immediately after sending the logon. As far as I could tell it was defaulting to 0.

To work around we set the LogonTimeout session setting to 10 explicitly.



 Comments   
Comment by Brad Harvey [ 26/May/06 ]

Here's a log:

15:53:07,707 INFO  [outgoing] FIX.4.4:CL1_FIX44->ASX: 8=FIX.4.4☺9=81☺35=A☺34=1☺4
9=CL1_FIX44☺52=20060526-05:53:07.607☺56=ASX☺98=0☺108=600☺141=Y☺7953=Y☺10=046☺
15:53:07,787 INFO  [event] FIX.4.4:CL1_FIX44->ASX: Initiated logon request
15:53:08,378 INFO  [event] FIX.4.4:CL1_FIX44->ASX: Timed out waiting for logon response
15:53:08,378 INFO  [event] FIX.4.4:CL1_FIX44->ASX: Disconnecting
Comment by Steve Bate [ 26/May/06 ]

The timeout defaults were not being set in SessionState. I'm added the defaults for login (10 seconds) and logout (2 seconds) and a related unit test. Thanks again for the report.

Comment by Colin Ruthven [ 01/Jun/06 ]

Curiously, when testing through my vendor's gateway tunnel (for encryption via internet) the session would drop every 10 minutes or less. It would reconnect and carry on. Then it would drop again, etc. I set the option in the config file and the problem went away.





[QFJ-15] Connect/reconnect generates phony error during seqnum resync Created: 25/May/06  Updated: 15/Nov/12  Resolved: 26/May/06

Status: Closed
Project: QuickFIX/J
Component/s: Engine
Affects Version/s: 1.0.0 B3
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Colin Ruthven Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

RedHat Linux Enterprise 4, JDK 1.4.2_09. x86 architecture.



 Description   

Sequence -
1) Send order (Limit)
2) Drop connection
3) Order executes in series of parials
4) Reconnect
5) Sequence number resend/reset messages are exchanged interleaved with execution reports
6) The Application is passed the execution reports as if no error occurred

The final execution report is passed to the application, but a rejection is sent to the initiator complaining that Tag 122 is missing. Execution report is not required to have Tag 122 and the previous message received did have Tag 122.
This happens each time this test is repeated. Sometimes the last two messages preceding are execution reports and both are rejected.
Log excerpt from the reconnect follows -
8=FIX.4.2^A9=67^A35=A^A34=5811^A49=direct3^A52=20060524-18:58:49.012^A56=direct4^A98=0^A108=30^A10=225^A
8=FIX.4.2^A9=67^A35=A^A34=5812^A49=direct3^A52=20060524-18:59:14.928^A56=direct4^A98=0^A108=30^A10=235^A
8=FIX.4.2^A9=0105^A35=A^A34=007202^A43=N^A52=20060524-19:00:00^A49=direct4^A56=direct3^A98=0^A108=30^A6272=BOX/OPT,PHLX/OPT^A6273=BOX/OPT^A10=110^A
8=FIX.4.2^A9=0073^A35=2^A34=007203^A43=N^A52=20060524-19:00:00^A49=direct4^A56=direct3^A7=5811^A16=5812^A10=069^A
8=FIX.4.2^A9=71^A35=2^A34=5813^A49=direct3^A52=20060524-18:59:15.027^A56=direct4^A7=7201^A16=99999^A10=183^A
8=FIX.4.2^A9=0285^A35=8^A34=007201^A43=Y^A52=20060524-19:00:00^A49=direct4^A56=direct3^A37=00000015.00003b5b.4474a8c6.0001^A11=000000004159467^A17=00002b0c.88e7d58a.01.01^A150=1^A20=0^A39=1^A55=F^A54=1^A100=NYSE^A207=NYSE^A38=500^A44=7^A32=100^A30=NYSE^A31=7^A14=100^A151=400^A6=7^A167=CS^A1=U515^A60=20060524-18:59:59^A40=2^A59=1^A204=1^A10=067^A
8=FIX.4.2^A9=0094^A35=4^A34=007202^A43=Y^A52=20060524-19:00:00^A49=direct4^A56=direct3^A122=20060524-19:00:00^A123=Y^A36=7204^A10=109^A
8=FIX.4.2^A9=0073^A35=2^A34=007204^A43=N^A52=20060524-19:00:00^A49=direct4^A56=direct3^A7=5813^A16=5813^A10=073^A
8=FIX.4.2^A9=0285^A35=8^A34=007205^A43=N^A52=20060524-19:00:02^A49=direct4^A56=direct3^A37=00000015.00003b5b.4474a8c6.0001^A11=000000004159467^A17=00002b0c.88e7d58c.01.01^A150=1^A20=0^A39=1^A55=F^A54=1^A100=NYSE^A207=NYSE^A38=500^A44=7^A32=100^A30=NYSE^A31=7^A14=200^A151=300^A6=7^A167=CS^A1=U515^A60=20060524-19:00:02^A40=2^A59=1^A204=1^A10=039^A
8=FIX.4.2^A9=96^A35=4^A34=5811^A43=Y^A49=direct3^A52=20060524-18:59:25.415^A56=direct4^A122=20060524-18:59:25^A36=5813^A123=Y^A10=167^A
8=FIX.4.2^A9=96^A35=4^A34=5813^A43=Y^A49=direct3^A52=20060524-18:59:25.478^A56=direct4^A122=20060524-18:59:25^A36=5814^A123=Y^A10=179^A
8=FIX.4.2^A9=71^A35=2^A34=5814^A49=direct3^A52=20060524-18:59:25.482^A56=direct4^A7=7203^A16=99999^A10=192^A
8=FIX.4.2^A9=0094^A35=4^A34=007203^A43=Y^A52=20060524-19:00:11^A49=direct4^A56=direct3^A122=20060524-19:00:11^A123=Y^A36=7205^A10=115^A
8=FIX.4.2^A9=0285^A35=8^A34=007205^A43=Y^A52=20060524-19:00:11^A49=direct4^A56=direct3^A37=00000015.00003b5b.4474a8c6.0001^A11=000000004159467^A17=00002b0c.88e7d58c.01.01^A150=1^A20=0^A39=1^A55=F^A54=1^A100=NYSE^A207=NYSE^A38=500^A44=7^A32=100^A30=NYSE^A31=7^A14=200^A151=300^A6=7^A167=CS^A1=U515^A60=20060524-19:00:02^A40=2^A59=1^A204=1^A10=050^A
8=FIX.4.2^A9=107^A35=3^A34=5815^A49=direct3^A52=20060524-18:59:25.643^A56=direct4^A45=7205^A58=Required tag missing^A371=122^A372=8^A373=1^A10=081^A



 Comments   
Comment by Steve Bate [ 26/May/06 ]

Hello Colin,

The FIX 4.2 specification states that OrigSendingTime (tag=122) is "required for messages resent as a
result of a ResendRequest". In other words, any message with 43=Y should have a tag 122. Are the
execution reports being sent from a QuickFIX/J engine? QFJ should be filling in this field
automatically.

Steve

Comment by Colin Ruthven [ 26/May/06 ]

The target is a home grown system.

I'll let them know.

I take it then that my app processed the first occurrence of the message and QuickFIX/J threw away the second one and complained about the missing tag 122?

Please close this issue.

Thanks, Colin





[QFJ-14] Add JMX support Created: 25/May/06  Updated: 12/Apr/07  Resolved: 10/Feb/07

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

Type: New Feature Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

http://www.quickfixj.org/confluence/display/qfj/JMX+Instrumentation



 Comments   
Comment by Jörg Thönnes [ 05/Sep/06 ]

The "new" Java 5 JVM has built-in JMX support. How about moving to Java 5 with release 1.1.0?

What kind of features are you thinking about?

Comment by Steve Bate [ 05/Sep/06 ]

I've updated the related wiki page and included a link in the description of this issue. Using MX4J we can support JMX functionality in JDK 1.4 while being compatible with Java 5. The Java 5 users just wouldn't include the MX4J JAR file. However, I have other reasons I'd like to move to Java 5 but that's a separate discussion.





[QFJ-13] Exception when initiating a session using mina-core-0.9.3.jar Created: 24/May/06  Updated: 15/Nov/12  Resolved: 25/May/06

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

Type: Bug Priority: Major
Reporter: Tom Dilatush Assignee: Steve Bate
Resolution: Not a bug Votes: 0
Labels: None
Environment:

Windows Server 2003, Java 1.5



 Description   

When executing this code:

// make sure we have no ongoing efforts...
m_session = null;
m_initiator = null;

// now set up our QuickFIX application and initiator...
try {
SessionSettings v_settings = new SessionSettings( m_settings );
m_settings.reset(); // so we can use them again as needed...
MessageStoreFactory v_store = new JdbcStoreFactory( v_settings );
LogFactory v_log = new JdbcLogFactory( v_settings );
MessageFactory v_msg = new DefaultMessageFactory();
>>>>>> m_initiator = new ThreadedSocketInitiator( m_app, v_store, v_settings, v_log, v_msg );
m_initiator.start();
ArrayList v_sessions = m_initiator.getSessions();
if( v_sessions.size() > 0 )

{ m_session = Session.lookupSession(( SessionID) v_sessions.get( 0 ) ); }

else

{ log.error( "No sessions exist after starting initiator!" ); }

m_sm.onInitiatorStarted();
}

I get this exception:

java.lang.NoClassDefFoundError: org/apache/mina/protocol/ProtocolProvider

On the line of code indicated. When I substitute mina-0.8.2.jar in the classpath, this code works.

Tom...



 Comments   
Comment by Steve Bate [ 24/May/06 ]

Yes, the class indicated doesn't exist in MINA 0.9.3. If you provide a more complete stack trace, it might give some hints about the problem. Is it possible that you accidently have a previous version of QFJ in the class path?

Comment by Steve Bate [ 25/May/06 ]

Tom verified that using an old QF JAR file was the problem.





[QFJ-12] CruiseControl reports success even when tests fail Created: 21/May/06  Updated: 02/Sep/06  Resolved: 03/Jun/06

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: 1.0.0 Final
Fix Version/s: 1.0.1

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Subissue
is a subissue of QFJ-3 Stabilize Cruise Control server Closed

 Description   

When acceptance tests fail, the build is still reported to be successful. It should report a failure in the email notificaiton so the subject line will give accurate information about the build.



 Comments   
Comment by Steve Bate [ 03/Jun/06 ]

I assume this is working for now. We'll reopen the issue if the problem continues.





[QFJ-11] Refactor session settings Created: 21/May/06  Updated: 10/Jan/10  Resolved: 10/Jan/10

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

Type: New Feature Priority: Default
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

Support dynamic session settings definition support (e.g., LDAP, JDBC, files, Spring configuration files).



 Comments   
Comment by Steve Bate [ 10/Jan/10 ]

Nobody has been asking for this.





[QFJ-10] Add support for repeating group count validation Created: 21/May/06  Updated: 12/Apr/07  Resolved: 21/May/06

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add support for repeating group count validation (compatibility with QF HEAD).



 Comments   
Comment by Steve Bate [ 21/May/06 ]

Added code to Message to place the original count back in the message after parsing the groups.





[QFJ-9] Add multiple acceptor port support Created: 19/May/06  Updated: 12/Apr/07  Resolved: 23/May/06

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Add multiple acceptor port support to be compatible with QF.



 Comments   
Comment by Steve Bate [ 23/May/06 ]

Multiple ports and protocols can be configured for an acceptor. Of course, only one acceptor address is allowed per session.





[QFJ-8] Modify example scripts classpath for Eclipse, Ant, and binary installations. Created: 19/May/06  Updated: 21/May/06  Resolved: 19/May/06

Status: Closed
Project: QuickFIX/J
Component/s: Examples
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None


 Description   

Modify example scripts classpath for Eclipse, Ant, and binary installations. This is a bit of hack for now. We need to find a better way.



 Comments   
Comment by Steve Bate [ 19/May/06 ]

Made sure all the classpaths were consistent.





[QFJ-7] Provide access for modifying MINA filters Created: 19/May/06  Updated: 12/Apr/07  Resolved: 12/Aug/06

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

Type: Improvement Priority: Major
Reporter: Steve Bate Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None


 Description   

... it'd be nice if a (far in the) future version made it
easy to insert MINA's IO and Protocol filters in the chain. In addition
to making things like IP filtering trivial, using MINA 0.9+ and Java5
would make it very easy to add SSL support
(http://directory.apache.org/subprojects/mina/apidocs/org/apache/mina/fi
lter/SSLFilter.html).

[email protected]



 Comments   
Comment by Brad Harvey [ 23/May/06 ]

This needn't be "Major" priority on my account - we don't have any current need to do this. I just thought it would be nifty

Comment by Steve Bate [ 27/Jul/06 ]

Wiki page: http://www.quickfixj.org/confluence/x/EgI

Comment by Steve Bate [ 12/Aug/06 ]

I've added support for customizing MINA filters in the trunk. Just add a filter builder to your acceptor or initiator when you create them. If you need access to settings, pass the SessionSettings into the filter builder when you create it. Comments are welcome.

Comment by Brad Harvey [ 13/Sep/06 ]

Hi Steve,

Looks good - certainly much cleaner without the extra factory some crazy guy suggested Could you maybe make setIoFilterChainBuilder part of the Connector interface? I don't think you should have to cast to SocketConnector (or subclass) to add it.

Cheers,
Brad.

Comment by Steve Bate [ 13/Sep/06 ]

Hi Brad,

I'm not sure that I want to put that method in the Connector interface because the interface is not socket-specific. For example, we might (probably will) have non-MINA connector implementation in the future. If you are setting the filter chain builder in your application set up, don't you already have a socket connector instance without needing the downcast?

Thanks for your suggestions and example code. I think this will be a good feature. When I have time I'll investigate how to provide SSL automatically in the MINA connector implementations.

Steve

Comment by Brad Harvey [ 13/Sep/06 ]

Fair enough - I can see it makes sense if you're not wanting to bind the public quickfix API to MINA. I'm just playing around with the order executor at the moment, which declares it as Acceptor so needs the cast.

I'm curious to see if the filters will be a useful extension point for people who want to do things that would otherwise require local changes to the engine - non standard begin strings, for example.





[QFJ-6] Move QFJ articles to confluence Created: 19/Apr/06  Updated: 18/May/06  Resolved: 18/May/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Task Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None





[QFJ-5] Set correct time and date on server Created: 19/Apr/06  Updated: 21/May/06  Resolved: 19/Apr/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
is required by QFJ-3 Stabilize Cruise Control server Closed

 Description   

The server time seems to be incorrect. I wasn't sure what timezone is the correct on for this region. I think this is causing problems with the timing of cruisecontrol builds and possibly even causing it to miss builds.



 Comments   
Comment by Laurent Danesi [ 19/Apr/06 ]

In fact, the server is using CEST (Paris) timezone but it doesn't pass to the summer time.
So it was 1hour in late.
The problem is resolved: I've just installed ntp daemon and reset the clock to the good time.





[QFJ-4] Import QFJ code into SourceForge subversion repository Created: 17/Apr/06  Updated: 18/May/06  Resolved: 18/May/06

Status: Closed
Project: QuickFIX/J
Component/s: Build
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Task Priority: Major
Reporter: Steve Bate Assignee: Steve Bate
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
requires QFJ-1 Install Subversion Closed

 Description   

Download CVS repository tarball from SourceForge. Use cvs2svn to import the tarball into a local svn repository. Once the import appears to work properly, export the local svn repository and import it into the SF repository.






[QFJ-3] Stabilize Cruise Control server Created: 17/Apr/06  Updated: 02/Sep/06  Resolved: 21/Apr/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
requires QFJ-5 Set correct time and date on server Closed
Subissue
has subissue QFJ-12 CruiseControl reports success even wh... Closed

 Description   

The CC server doesn't seem to be very reliable right now. I'd also like to be trained on how to administer it so I can help with any issues.



 Comments   
Comment by Steve Bate [ 19/Apr/06 ]

We also need to modify the ant build scripts so that CC reports a failure when the tests fail. One problem with this is that the acceptance tests occasionally and randomly timeout in the CruiseControl environment although they never do this in Eclipse. We may have to increase the reconnectDelay to longer than the current 100 ms (that had been previously causing a problem with CC atests) but this will also increase the time required to the run the tests (probably not a big issue for the CC environment).

Comment by Laurent Danesi [ 21/Apr/06 ]

Junit TestResults are available now.





[QFJ-2] Configure email server. Created: 17/Apr/06  Updated: 18/Apr/06  Resolved: 18/Apr/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Bug Priority: Major
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None


 Description   

The server is rejecting connections.






[QFJ-1] Install Subversion Created: 17/Apr/06  Updated: 21/May/06  Resolved: 18/Apr/06

Status: Closed
Project: QuickFIX/J
Component/s: Web site
Affects Version/s: None
Fix Version/s: 1.0.0 Final

Type: Task Priority: Major
Reporter: Steve Bate Assignee: Laurent Danesi
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Requires
is required by QFJ-4 Import QFJ code into SourceForge subv... Closed

 Comments   
Comment by Steve Bate [ 18/Apr/06 ]

I've installed Subversion 1.2.3 using yum. This is a relatively old version of svn but I'm not sure how to update the machine to a newer version. Laurent, you have any ideas please update the version when you have a moment. Thanks.





Generated at Sun May 19 02:49:36 UTC 2024 using JIRA 7.5.2#75007-sha1:9f5725bb824792b3230a5d8716f0c13e296a3cae.