Question

We are using jpos server with ASCIChannel and custom package which contains one field with max length 9999 to do this we implemented IFB_LLLLCHAR as follow

public class IFB_LLLLCHAR extends ISOStringFieldPackager {
    public IFB_LLLLCHAR() {
        super(NullPadder.INSTANCE, AsciiInterpreter.INSTANCE, BcdPrefixer.LLLL);
    }

    public IFB_LLLLCHAR(int len, String description) {
        super(len, description, NullPadder.INSTANCE, AsciiInterpreter.INSTANCE, BcdPrefixer.LLLL);
        checkLength(len, 9999);
    }

    public void setLength(int len)
    {
        checkLength(len, 9999);
        super.setLength(len);
    }
}

Problem is that i couldn't use the whole 9999 because if the size of whole message goes over 9999 it throws following exception while sending it

<exception name="len exceeded">
    java.io.IOException: len exceeded
    at org.jpos.iso.channel.ASCIIChannel.sendMessageLength(ASCIIChannel.java:80)
    at org.jpos.iso.BaseChannel.send(BaseChannel.java:528)
    at com.advam.gateway.terminalmanagementserver.gateway.LogUploadFuncTest.testLogUpload(LogUploadFuncTest.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at junit.framework.TestCase.runTest(TestCase.java:154)
    at junit.framework.TestCase.runBare(TestCase.java:127)
    at junit.framework.TestResult$1.protect(TestResult.java:106)
    at junit.framework.TestResult.runProtected(TestResult.java:124)
    at junit.framework.TestResult.run(TestResult.java:109)
    at junit.framework.TestCase.run(TestCase.java:118)
    at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    </exception>

Can anybody tell me why i am getting this exception and how to fix it. Kindly keep in mind while answering that I don't have much knowledge about inside of jpos. Thanks

Was it helpful?

Solution

The total length of the complete message cannot exceed 9999 using the AsciiChannel (like @gerrytan already pointed out).

The AsciiChannel assumes a protocol where the first four bytes are the ASCII value of the length digits.

You might want to look at HEXChannel or NACChannel as they can accommodate larger lengths. HEXChannel and NACChannel allow length up to 0xFFFF.

OTHER TIPS

Please see the source code for AsciiChannel class, length is capped at maximum 9999

/**
 * @param len the packed Message len
 * @exception IOException
 */
protected void sendMessageLength(int len) throws IOException {
    if (len > 9999)
        throw new IOException ("len exceeded");

    try {
        serverOut.write(
            ISOUtil.zeropad(Integer.toString(len), 4).getBytes()
        );
    } catch (ISOException e) { }
}

Also the checkLength() method you call isn't actually trimming the length, it only threw exception when the content is too long. if you don't want exceptions then don't call this method / capture the exception and trim it

 protected void checkLength(int len, int maxLength) throws IllegalArgumentException
    {
        if (len > maxLength)
        {
            throw new IllegalArgumentException("Length " + len + " too long for " + getClass().getName());
        }
    }

The channel definition is something that you have agreed with the system you are talking to. If you need to send more than 9999 you need to change the channel as mentioned in earlier response and so does the other entity. Both sides of the communication need to make sure that they have the same understanding of what the length header is to extract the full message.

Options you have

  • Both sides fo the communication channel update the size that can be sent or received by using a different channel.
  • You compress the large data encoded as base64, assuming the other side of the comm channel is told about this change so that they can handle it.
  • Sometimes the specification/protocol indicates how one can split this data into multiple requests, see if thats available.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top