【问题标题】:quickfix/field/HaltReason is not assignable to 'quickfix/IntFieldquickfix/field/HaltReason 不可分配给 \'quickfix/IntField
【发布时间】:2022-11-08 14:16:27
【问题描述】:

当我登录时,我正在发送一个应用程序消息请求 (BW) 并且服务器以多种类型的消息进行响应,但是对于安全状态之一,它返回 Halt Reason Exception。我有 2 个 onMessage 功能,这些用于安全定义报告和安全定义更新报告。 Security Status 没有 onMessage 功能,因为我没有使用此消息,因此我不希望处理其他类型的消息。当收到安全状态消息时,我们会收到 HaltReason 异常。毕竟,我们的客户端无法从服务器接收任何心跳,所以我们的客户端正在断开连接并发送另一个登录请求。它会导致一个循环,我们会收到消息,断开与 Halt 原因异常并再次请求。 我们将 FIX50SP2 与 FIXT1.1 一起使用,但 MessageCracker 将这些消息映射到 FIX50。此外,我们使用 quickfix 2.3.1 版本和 DefaultMessageFactory 来接收 FIX 消息。

例子:

事件>(收到登录)

传入> (8=FIXT.1.1 9=00000 35=f 49=foo 56=foo 34=0000 57=0000 52=20220302-10:11:09.908 1180=R 1181=0000 1350=0000 55=foo 48=0000 22=M 336=135 325=N 60=20220302-10:11:09.908 10=119)

错误>(java.lang.VerifyError:操作数堆栈上的类型错误 异常详情: 地点: quickfix/fix50/SecurityStatus.get(Lquickfix/field/HaltReason;)Lquickfix/field/HaltReason; @2:调用虚拟 原因: 类型“quickfix/field/HaltReason”(当前帧,堆栈 [1])不可分配给“quickfix/IntField” 当前帧: bci:@2 标志:{} 本地人:{ 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason' } 堆栈:{ 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason' } 字节码: 0x0000000: 2a2b b600 2457 2bb0

java.lang.VerifyError:操作数堆栈上的错误类型 异常详情: 地点: quickfix/fix50/SecurityStatus.get(Lquickfix/field/HaltReason;)Lquickfix/field/HaltReason; @2:调用虚拟 原因: 类型“quickfix/field/HaltReason”(当前帧,堆栈 [1])不可分配给“quickfix/IntField” 当前帧: bci:@2 标志:{} 本地人:{ 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason' } 堆栈:{ 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason' } 字节码: 0x0000000: 2a2b b600 2457 2bb0

at quickfix.fix50.MessageFactory.create(MessageFactory.java:120)
at quickfix.DefaultMessageFactory.create(DefaultMessageFactory.java:141)
at quickfix.MessageUtils.parse(MessageUtils.java:145)
at quickfix.mina.AbstractIoHandler.messageReceived(AbstractIoHandler.java:131)
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)

)

pom.xml:

<dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-core</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix40</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix41</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix42</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix43</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix44</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.quickfixj</groupId>
            <artifactId>quickfixj-messages-fix50</artifactId>
            <version>2.3.1</version>
        </dependency>

FIXApplication50.java:

import org.apache.log4j.Logger;
import quickfix.Message;
import quickfix.MessageCracker;
import quickfix.*;
import quickfix.field.*;
import quickfix.fix50.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class FIXApplication50 extends MessageCracker implements Application {

    public FIXApplication50() throws ConfigError {
    }

    public void onMessage(SecurityDefinition refData, SessionID sessionID) {
        
    }

    public void onMessage(SecurityDefinitionUpdateReport refData, SessionID sessionID) {

    }

    public void onCreate(SessionID sessionID) {

    }

    public void sendApplicationMessageRequest(Message message, SessionID sessionID) {

    }

    public void onLogon(SessionID sessionID) {
        Message message = new Message();

        sendApplicationMessageRequest(message, sessionID);
    }

    public void onLogout(SessionID sessionID) {

    }


    public void toAdmin(Message message, SessionID sessionID) {
      
    }


    public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {

    }


    public void toApp(Message message, SessionID sessionID) throws DoNotSend {

    }

    public void fromApp(Message message, SessionID sessionId)
            throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
        crack(message, sessionId);
    }
}

会话属性:

[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60
ResetOnLogon=Y
FileLogPath=logs/plugins/foo/Client_Logs
SenderCompID=foo
SenderSubID=foo
ValidateIncomingMessage=N

[SESSION]
BeginString=FIXT.1.1
TargetCompID=foo
StartDay=sunday
EndDay=friday
StartTime=21:35:00
EndTime=21:30:00
HeartBtInt=30
CheckLatency=N
SocketConnectPort=0000
SocketConnectHost=00.00.00
DefaultApplVerID=FIX.5.0SP2
TransportDataDictionary=config/plugins/foo/FIXT11.xml
AppDataDictionary=config/plugins/foo/RefDataFIX50sp2.xml

【问题讨论】:

  • 前几天有一个类似的问题。为什么您在 QuickFIX/J 依赖项上使用不同的版本?可能 HaltReason 在 FIX5.0 和 FIX5.0SP2 之间改变了它的类型。
  • 它与其他修复版本有关吗?(FIX42,FIX44 ...)当我使用 FIX50SP2 的依赖项时,所有消息都被拒绝,它甚至不会传递给消息功能。 @克里斯托弗约翰
  • 您可能需要在消息破解程序中使用 fix50sp2 类。
  • 我在我的 FIXApplication50 中扩展了 quickfixj 核心的消息破解器。如果您的意思是同一类上的 onMessage 类,当我将 onMessage 更改为 FIX50SP2 时,修复引擎会拒绝所有消息。你能进一步解释一下吗? @克里斯托弗约翰
  • 您收到的消息中HaltReason 的值(标签 327)是什么?

标签: java fix-protocol quickfixj


【解决方案1】:

我不确定是什么导致了您的异常,但我确实看到了一些您应该解决的问题:

  1. 配置问题:

    看起来您正在使用 FIX50SP2,因此您需要:

    • 使用数据字典=Y
    • AppDataDictionary=<path/to/your/FIX50SP2.xml>
    • TransportDataDictionary=<path/to/your/FIXT11.xml>

    (在提问者的初始编辑中,这些字段不存在)

    和我认为你想要ValidateIncomingMessage=N。这个设置总是告诉我有人不知道他们在做什么!如果您的连接使用重复组(而且我从未见过不使用的组),那么您必须有一个正确的 DD。如果你的 DD 是正确的,那么验证就不用担心了。

    另外,你真的需要CheckLatency=N吗?

  2. 你可能需要一个 SecurityStatus 处理程序

    Security Status 没有 onMessage 功能,因为我没有使用此消息,因此我不希望处理其他类型的消息。

    如果您不提供onMessage(SecurityStatus) 处理程序,那么您的应用程序将以 35=j 拒绝响应这些消息。如果您真的想忽略此消息,那么您应该添加此处理程序并使用空实现。

【讨论】:

  • UseDataDictionary=Y ,AppDataDictionary=<path/to/your/FIX50SP2.xml>,TransportDataDictionary=<path/to/your/FIXT11.xml> 已存在于 session.prop 中。我没有将此字段放在示例 session.properties 中。我的DD是正确的。而且即使我放了onMessage函数,在onMessage之前的fromApp函数内部的crack(message, sessionId)行中也会出现Halt原因异常。此外,这些 ValidateIncomingMessage=N 和 CheckLatency=N 配置与问题有什么关系?
  • 虽然这些建议是我在您发布的内容中看到的有效问题,但我想它们与您的问题无关。
【解决方案2】:

您需要将其作为自定义标签读取,如下所示 - (已测试):

          try {
              
                    response.setHaltReason(report.getString(327));
            
            } catch (Exception e) {
                log.error...
            }

其中报告是 quickfix.fix44.SecurityStatus

【讨论】:

    猜你喜欢
    • 2022-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多