You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@plc4x.apache.org by "IsmoLeszczynski (via GitHub)" <gi...@apache.org> on 2025/04/08 18:13:01 UTC

[I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

IsmoLeszczynski opened a new issue, #2054:
URL: https://github.com/apache/plc4x/issues/2054

   ### What happened?
   
   I'm trying out the Modbus driver with a simulator and things were going well while reading, for example, INT from holding registers, but when I tried to read a single BOOL from discrete inputs, the ModbusOptimizer throws an exception when handling the response. With a quick glance at the decompiled sources, I'm guessing this happens because BOOL is defined with a dataTypeLength of 2:
   
   `public enum ModbusDataType {
     BOOL((short)1, (short)2),
     ...
   }`
   
   Is this correct? I'd expect BOOL to be defined with a length of 1, but I'm not sure if there is some technical reason for this deeper down.
   
   The tag address I tested: `discrete-input:1:BOOL`
   
   `2025-04-08 20:52:05,056 ERROR [nioEventLoopGroup-3-1] org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer - Error processing response:
   java.lang.ArrayIndexOutOfBoundsException: arraycopy: last source index 2 out of bounds for byte[1]
   	at java.base/java.lang.System.arraycopy(Native Method)
   	at org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer$Response.getResponseDataForTag(ModbusOptimizer.java:410)
   	at org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer.processReadResponses(ModbusOptimizer.java:232)
   	at org.apache.plc4x.java.spi.optimizer.BaseOptimizer.lambda$1(BaseOptimizer.java:112)
   	at org.apache.plc4x.java.spi.optimizer.BaseOptimizer.lambda$8(BaseOptimizer.java:205)
   	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
   	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
   	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
   	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
   	at org.apache.plc4x.java.modbus.tcp.protocol.ModbusTcpProtocolLogic.lambda$11(ModbusTcpProtocolLogic.java:163)
   	at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
   	at org.apache.plc4x.java.spi.Plc4xNettyWrapper.decode(Plc4xNettyWrapper.java:194)
   	at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81)
   	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)
   	at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
   	at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
   	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
   	at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
   	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
   	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
   	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
   	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
   	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
   	at java.base/java.lang.Thread.run(Thread.java:1583)
   2025-04-08 20:52:05,068 ERROR [nioEventLoopGroup-3-1] org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer - Original Request:
   <PlcReadRequest>
     <PlcTagRequest>
       <tags isList="true">
         <ModbusTagDiscreteInput {address=0, quantity=1, dataType=BOOL, unitId=null }>
           <PlcTagItem>
             <tag>
               <ModbusTagDiscreteInput>
                 <address dataType="uint" bitLength="16">0</address>
                 <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
                 <dataType dataType="string" bitLength="32" encoding="UTF-8">BOOL</dataType>
               </ModbusTagDiscreteInput>
             </tag>
           </PlcTagItem>
         </ModbusTagDiscreteInput {address=0, quantity=1, dataType=BOOL, unitId=null }>
       </tags>
     </PlcTagRequest>
   </PlcReadRequest>
   java.lang.ArrayIndexOutOfBoundsException: arraycopy: last source index 2 out of bounds for byte[1]
   	at java.base/java.lang.System.arraycopy(Native Method)
   	at org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer$Response.getResponseDataForTag(ModbusOptimizer.java:410)
   	at org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer.processReadResponses(ModbusOptimizer.java:232)
   	at org.apache.plc4x.java.spi.optimizer.BaseOptimizer.lambda$1(BaseOptimizer.java:112)
   	at org.apache.plc4x.java.spi.optimizer.BaseOptimizer.lambda$8(BaseOptimizer.java:205)
   	at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
   	at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
   	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
   	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
   	at org.apache.plc4x.java.modbus.tcp.protocol.ModbusTcpProtocolLogic.lambda$11(ModbusTcpProtocolLogic.java:163)
   	at java.base/java.util.function.Consumer.lambda$andThen$0(Consumer.java:65)
   	at org.apache.plc4x.java.spi.Plc4xNettyWrapper.decode(Plc4xNettyWrapper.java:194)
   	at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81)
   	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)
   	at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
   	at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
   	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
   	at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
   	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
   	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
   	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
   	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
   	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
   	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
   	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
   	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
   	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
   	at java.base/java.lang.Thread.run(Thread.java:1583)
   2025-04-08 20:52:05,078 ERROR [nioEventLoopGroup-3-1] org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer - Sub Request:
   <PlcReadRequest>
     <PlcTagRequest>
       <tags isList="true">
         <registers0>
           <PlcTagItem>
             <tag>
               <ModbusTagDiscreteInput>
                 <address dataType="uint" bitLength="16">0</address>
                 <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
                 <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
               </ModbusTagDiscreteInput>
             </tag>
           </PlcTagItem>
         </registers0>
       </tags>
     </PlcTagRequest>
   </PlcReadRequest>
   2025-04-08 20:52:05,086 ERROR [nioEventLoopGroup-3-1] org.apache.plc4x.java.modbus.base.optimizer.ModbusOptimizer - Sub Response (Success):
   <PlcReadResponse>
     <request>
       <PlcReadRequest>
         <PlcTagRequest>
           <tags isList="true">
             <registers0>
               <PlcTagItem>
                 <tag>
                   <ModbusTagDiscreteInput>
                     <address dataType="uint" bitLength="16">0</address>
                     <numberOfElements dataType="uint" bitLength="16">1</numberOfElements>
                     <dataType dataType="string" bitLength="32" encoding="UTF-8">WORD</dataType>
                   </ModbusTagDiscreteInput>
                 </tag>
               </PlcTagItem>
             </registers0>
           </tags>
         </PlcTagRequest>
       </PlcReadRequest>
     </request>
     <values isList="true">
       <registers0>
         <PlcResponseItem>
           <code dataType="string" bitLength="16" encoding="UTF-8">OK</code>
           <value>
             <PlcRawByteArray dataType="byte" bitLength="8">0x00</PlcRawByteArray>
           </value>
         </PlcResponseItem>
       </registers0>
     </values>
   </PlcReadResponse>`
   
   ### Version
   
   v0.13.0-SNAPSHOT
   
   ### Programming Languages
   
   - [ ] plc4c
   - [ ] plc4go
   - [x] plc4j
   - [ ] plc4net
   - [ ] plc4py
   
   ### Protocols
   
   - [ ] AB-Ethernet
   - [ ] ADS /AMS
   - [ ] BACnet/IP
   - [ ] C-Bus
   - [ ] CANopen
   - [ ] EtherNet/IP
   - [ ] Firmata
   - [ ] IEC-69870
   - [ ] KNXnet/IP
   - [x] Modbus
   - [ ] OPC-UA
   - [ ] Profinet
   - [ ] S7
   - [ ] S7-light


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "chrisdutz (via GitHub)" <gi...@apache.org>.
chrisdutz commented on issue #2054:
URL: https://github.com/apache/plc4x/issues/2054#issuecomment-2787767043

   Discrete inputs are two byte values, right? 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "IsmoLeszczynski (via GitHub)" <gi...@apache.org>.
IsmoLeszczynski commented on issue #2054:
URL: https://github.com/apache/plc4x/issues/2054#issuecomment-2787873479

   Have to admit I'm not too savvy with the specifics, but the Coils and Discrete Inputs are single bits, and if I understand correctly, the result data is the resulting bits padded to the next full byte, `(InputCount + 7) / 8` bytes. In my case, the complete result would then be 3 bytes; the function code byte, the number of inputs byte, and the input data byte - with 1 bit result padded to a full byte.
   
   The Input/Holding Registers are always two bytes per address.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "hutcheb (via GitHub)" <gi...@apache.org>.
hutcheb commented on issue #2054:
URL: https://github.com/apache/plc4x/issues/2054#issuecomment-2787909170

   Yeah these get packed and padded into bytes, if you request 3 bits you'll receive one byte, 14 bits and you'll get 2 bytes.
   
   As the mspec specifies the number of bytes for a boolean, it doesn't really make sense, booleans (Discrete coils/inputs) are handled with custom logic in each implementation to unpack them.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "glcj (via GitHub)" <gi...@apache.org>.
glcj commented on issue #2054:
URL: https://github.com/apache/plc4x/issues/2054#issuecomment-2788223373

   Hi,
   You can try this branch; I think it solves the problem.
   I'll keep an eye out.
   
   https://github.com/apache/plc4x/tree/fix/modbus
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "IsmoLeszczynski (via GitHub)" <gi...@apache.org>.
IsmoLeszczynski commented on issue #2054:
URL: https://github.com/apache/plc4x/issues/2054#issuecomment-2789389081

   As far as I could tell, that solution didn't handle the Discrete Inputs nor Coils, when the response was a single byte - it was still trying to read too many bytes. To me it seems that the only required change is to handle Discrete Inputs just like the Coils, I made a pr for it #2055. This version, at least, worked for me with my modbus simulator (MOD_RSsim).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [I] [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException

Posted by "sruehl (via GitHub)" <gi...@apache.org>.
sruehl closed issue #2054: [Bug]: Modbus: Reading single discrete-input throws ArrayIndexOutOfBoundsException
URL: https://github.com/apache/plc4x/issues/2054


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@plc4x.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org