Search code examples
javaquickfixfix-protocolquickfixj

quickfix.Message cannot be cast to quickfix.fix50sp2.Message


I'm using the latest quickfix version which is 1.6.0. I already have code which is written against 1.5.3 and what I'm trying to do is upgrade that to 1.6.0

The problem I have is when I use the crack(msg,sessionID) method it throws quickfix.Message cannot be cast to quickfix.fix50sp2.Message error. I'm sending a correct FIX50SP2 MarketDataSnapshotFullRefresh message from verifix. An extract of the exception is below

java.lang.ClassCastException: quickfix.Message cannot be cast to quickfix.fix50sp2.Message at quickfix.fix50sp2.MessageCracker.crack(MessageCracker.java:1555) at com.****.fixserver.FixMessageListener.fromApp(FixMessageListener.java:162) at quickfix.Session.fromCallback(Session.java:1731) at quickfix.Session.verify(Session.java:1682)

How can I crack the incoming message to the correct SP2 message?

There is a crack50() method, but that requires a SP2 message which is unavailable in the fromApp callback.


Solution

  • When the begin string is FIXT.1.1 quickfix will treat the message as FIX50 with the DefaultMessageFactory. So it will automatically generate a FIX.5.0 message.

    The resolution is to write your own custom message factory to generate a SP2 message when the transport is FIXT.1.1. Here's how I did it.

    Write a custom message factory implementing quickfix.MessageFactory interface. You can copy the DefaultMessageFactory code and change the create() method as follows.

     public Message create(String beginString, String msgType) {
        MessageFactory messageFactory = messageFactories.get(beginString);
        if (beginString.equals(BEGINSTRING_FIXT11)) {
            // The default message factory assumes that only FIX 5.0 will be
            // used with FIXT 1.1 sessions. A more flexible approach will require
            // an extension to the QF JNI API. Until then, you will need a custom
            // message factory if you want to use application messages prior to
            // FIX 5.0 with a FIXT 1.1 session.
            //
            // TODO: how do we support 50/50SP1/50SP2 concurrently?
            //
            // If you need to determine admin message category based on a data
            // dictionary, then use a custom message factory and don't use the
            // static method used below.
            if (!MessageUtils.isAdminMessage(msgType)) {
                messageFactory = messageFactories.get(FIX50SP2);
            }
        }
    
        if (messageFactory != null) {
            return messageFactory.create(beginString, msgType);
        }
    
        Message message = new Message();
        message.getHeader().setString(MsgType.FIELD, msgType);
    
        return message;
    }