steveohara / j2mod

Enhanced Modbus library implemented in the Java programming language
Apache License 2.0
265 stars 111 forks source link

ClassCastException when timeout?? #96

Closed niclash closed 4 years ago

niclash commented 5 years ago

Expected Behavior

Correct decoding of message

Actual Behavior

java.lang.ClassCastException: com.ghgande.j2mod.modbus.msg.WriteSingleRegisterResponse cannot be cast to com.ghgande.j2mod.modbus.msg.ReadInputRegistersResponse at com.ghgande.j2mod.modbus.facade.AbstractModbusMaster.readInputRegisters(AbstractModbusMaster.java:209)

Steps to Reproduce the Problem

I am not exactly sure when it happens. It is very intermittent, but it seems to be a multi-threading issue and that the "read" will accidentally be "lost" in one thread (no answer) and the "write" thread gets the read result and gets confused...

I am running j2mod RTU mode. I am pretty sure I have seen somewhere that j2mod is thread-safe, and for the most part my multi-threaded app is doing fine (I don't depend on the resolution of this bug)

Specifications

bthulu commented 4 years ago

me, too, TCP mode. Version: 2.5.5 Platform: Windows 10 1903 JDK8 java.lang.ClassCastException: com.ghgande.j2mod.modbus.msg.WriteSingleRegisterResponse cannot be cast to com.ghgande.j2mod.modbus.msg.ReadMultipleRegistersResponse at com.ghgande.j2mod.modbus.facade.AbstractModbusMaster.readMultipleRegisters(AbstractModbusMaster.java:238) ~[j2mod-2.5.5.jar!/:2.5.5] at com.ghgande.j2mod.modbus.facade.AbstractModbusMaster.readMultipleRegisters(AbstractModbusMaster.java:426) ~[j2mod-2.5.5.jar!/:2.5.5] at bthulu.commons.combine.modbus.MbusMaster.readBytes(MbusMaster.java:233) ~[jcoutil-0.0.5.jar!/:na] at bthulu.commons.combine.modbus.MbusMaster.readShort(MbusMaster.java:202) ~[jcoutil-0.0.5.jar!/:na] at bthulu.commons.combine.modbus.MbusMaster.readShort(MbusMaster.java:198) ~[jcoutil-0.0.5.jar!/:na] at domiyi.paper.obp.prepare.PreparePlcManager.readRemoteControl(PreparePlcManager.java:107) ~[classes!/:na] at domiyi.paper.obp.prepare.PaperOnService.lambda$saveOnPrepareDisable$3(PaperOnService.java:160) ~[classes!/:na] at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.1.9.RELEASE.jar!/:5.1.9.RELEASE] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_231] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_231] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_231] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_231] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_231] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_231] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_231]

steveohara commented 4 years ago

I'm wondering if you are multiplexing calls to ModbusTCPMaster or ModbusSerialMaster because those are not thread safe. You should either synchronise your calls to these or not share them across threads. I've just created a test case and I'm getting the same result - the xxxxMaster classes are not thread safe and that is what is causing your issue.

steveohara commented 4 years ago

Fixed in 2.5.8