Cuando inicio sesión, envío una solicitud de mensaje de aplicación (BW) y el servidor responde con varios tipos de mensajes, pero para el estado de seguridad, devuelve la excepción de motivo de detención. Tengo 2 funciones onMessage, estas para el Informe de definición de seguridad y el Informe de actualización de definición de seguridad. El estado de seguridad no tiene la función onMessage porque no estoy usando este mensaje, por lo que no espero manejar otro tipo de mensajes. Cuando se recibe un mensaje de estado de seguridad, obtenemos la excepción HaltReason. Y después de todo esto, nuestro cliente no puede recibir ningún latido del servidor, por lo que nuestro cliente se está desconectando y enviando otra solicitud de inicio de sesión. Provoca un bucle en el que recibimos mensajes, nos desconectamos con la excepción del motivo Halt y solicitamos nuevamente. Estamos usando FIX50SP2 con FIXT1.1 pero MessageCracker asigna estos mensajes a FIX50. También usamos la versión Quickfix 2.3.1 y DefaultMessageFactory para recibir mensajes FIX.
Ejemplo:
evento> (Inicio de sesión recibido)
entrante> (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)
error> (java.lang.VerifyError: Tipo incorrecto en la pila de operandos Detalles de la excepción: Ubicación: quickfix/fix50/SecurityStatus.get(Lquickfix/field/HaltReason;)Lquickfix/field/HaltReason; @2: invoquevirtual Motivo: Escriba 'quickfix/ field/HaltReason' (fotograma actual, stack[1]) no se puede asignar a 'quickfix/IntField' Fotograma actual: bci: @2 flags: { } locales: { 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason ' } pila: { 'arreglo rápido/arreglo50/Estado de seguridad', 'arreglo rápido/campo/HaltReason' } Código de byte: 0x0000000: 2a2b b600 2457 2bb0
java.lang.VerifyError: Tipo incorrecto en la pila de operandos Detalles de la excepción: Ubicación: quickfix/fix50/SecurityStatus.get(Lquickfix/field/HaltReason;)Lquickfix/field/HaltReason; @2: Invoque virtual Motivo: Escriba 'quickfix/field/HaltReason' (fotograma actual, pila[1]) no se puede asignar a 'quickfix/IntField' Fotograma actual: bci: @2 indicadores: { } locales: { 'quickfix/fix50 /SecurityStatus', 'quickfix/field/HaltReason' } stack: { 'quickfix/fix50/SecurityStatus', 'quickfix/field/HaltReason' } Bytecode: 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>FIXAplicación50.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); } }sesión.propiedades:
[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.xmlNo estoy seguro exactamente de qué está causando su excepción, pero veo algunos problemas que debe abordar:
Problemas de configuración:
Parece que está utilizando FIX50SP2, por lo que necesita:
(En la edición inicial del autor de la pregunta, estos campos no estaban presentes)
Y no creo que quieras ValidateIncomingMessage=N . ¡Esta configuración siempre me dice que alguien no sabe lo que está haciendo! Si su conexión usa grupos repetidos (y nunca he visto uno que no lo haga), debe tener un DD correcto. Si su DD es correcto, entonces la validación no es motivo de preocupación.
Además, ¿realmente necesita CheckLatency=N ?
Probablemente necesite un controlador SecurityStatus
El estado de seguridad no tiene la función onMessage porque no estoy usando este mensaje, por lo que no espero manejar otro tipo de mensajes.
Si no proporciona un onMessage(SecurityStatus) , su aplicación responderá a esos mensajes con 35=j rechazos. Si realmente desea ignorar este mensaje, debe agregar este controlador con una implementación vacía.