ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

RPGLE Program Receiving Java Exception Error - Missing Argument

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • RPGLE Program Receiving Java Exception Error - Missing Argument

    We have encountered an error with an RPGLE program calling out to Java methods to perform credit card encryption and decryption. This problem was first seen in December 2011 but was treated as a one-off (a bad cc#). In the last 6 months we are seeing it more frequently, sometimes a couple times a week.

    For some background on where this is happening, this is a single RPGLE program and a single line of code, one for encryption one for decryption that is failing at times. This single program is part of a ?never-ending? job that is ended normally minutes before midnight and restarted minutes after midnight ? in other words, the job runs all day. As a transaction requires encryption and decryption, this job performs that function. The number of occurrences of encryption and decryption calls within this job ranges anywhere between 10,000 times to 100,000 times a day depending on the time of year. I point all this out to ensure it is clear that this one RPGLE program, with only one call to each method and these calls succeed without error 99.99% of the time.

    An example of the error we are receiving is:

    Message ID . . . . . . : RNQ0301 Severity . . . . . . . : 99
    Message type . . . . . : Inquiry
    Date sent . . . . . . : 05/23/13 Time sent . . . . . . : 02:05:53

    Message . . . . : Java exception received when calling Java method (C G D
    F).
    Cause . . . . . : RPG procedure CCR0032 in program CWMPPGM/CCR0032 received
    Java exception "java.lang.IllegalArgumentException: Missing argument" when
    calling method "decrypt" with signature "([B)[B" in class
    "com.cwi.encryption.CCEncryptDecrypt".


    Of course if it is the Encrypt that fails, the message will reflect this method instead of Decrypt. What this is telling me is that we are not passing the correct parameters to the method decrypt. The ?([B) [B? is expecting an array of bytes as an input and again as an output.

    When I look at the valid signatures for this method using qsh cmd('javap -s com.cwi.encryption.CCEncrypt Decrypt'), I receive the following information (I included only those signatures I think are relevant ? could be wrong!):

    Compiled from "CCEncryptDecrypt.java"
    public class com.cwi.encryption.CCEncryptDecrypt extends java.lang.Object{
    java.lang.String keySelector;
    Signature: Ljava/lang/String;
    public byte[] decrypt(byte[]);
    Signature: ([B)[B
    public byte[] encrypt(byte[]);
    Signature: ([B)[B


    Here is the definition of the java methods within the package being accessed.

    public byte[] decrypt(byte[] encryptedCard) {
    public byte[] encrypt(byte[] creditCard){


    That is three locations telling me that the decrypt & encrypt methods are expecting an array of bytes on input and returning an array of bytes. So that brings me to the prototype, invocation and declarations in the RPGLE program.

    Declarations
    C *Entry PLIST
    C Parm Company 3
    C Parm Action 1
    C Parm CCIn 16
    C CCOut Parm CCOut 16

    D EncDec S O Class(*JAVA:
    D 'com.cwi.encryption.CCEncryptDecrypt'
    D )

    Method Prototypes
    D decrypt PR 16A Varying
    D extProc(*JAVA:
    D 'com.cwi.encryption.CCEncryptDecrypt'
    D :'decrypt')
    D 16A varying const

    D encrypt PR 16A varying
    D ExtProc(*JAVA:
    D 'com.cwi.encryption.CCEncryptDecrypt'
    D :'encrypt')
    D 16A const varying

    Method Invocation
    * Call Encode routine
    C Action IFEQ 'E'
    C Eval CCOut = Encrypt(EncDec:CCIn)
    C Endif

    * Call Decode routine
    C Action IFEQ 'D'
    C Eval CCOut = Decrypt(EncDec:CCIn)
    C Endif


    When I look at all this, it all looks correct to me. I don?t quite follow why the instance is being passed on the RPGLE call when it is not defined as being expected in the java, but I am guessing that is likely the convention for doing this type of call -> pass the instance of the class as the first parm? I have never prototyped and called Java methods so I am out of my league here but nothing jumps out as completely wrong. Nothing jumps out at me as to how either method could be called and be missing an argument, as the error message indicated.

    Any assistance in pointing me in the right direction to finding and solving this mystery is very much appreciated. I can provide any additional code snippets, job logs or program dumps if there is a feel that these would be helpful. Thank you in advance.

  • #2
    Re: RPGLE Program Receiving Java Exception Error - Missing Argument

    Oh! I should have mentioned this, we are running OS V5R4 currently. PTFs are up to date.

    Comment


    • #3
      Re: RPGLE Program Receiving Java Exception Error - Missing Argument

      When calling Java, the fact that the error is an RNQ0301 means very little, since that message ID is used for all errors reported by Java (and there are millions of possible errors.)

      The part that is important is this piece of text: 'java.lang.IllegalArgumentException: Missing argument'

      What this is telling you is that you are not passing all of the parameters that the Java method is expecting -- or, at least, that's what Java thinks the error is! I don't see how you could've made that mistake here, since the program works most of the time. Instead, I'd suggest this is probably a bug in the Java class itself.

      Is there a good reason to use this Java class instead of the Cryptographic Services APIs? Seems to me that this would not only work better, but would run much faster, too.

      Comment


      • #4
        Re: RPGLE Program Receiving Java Exception Error - Missing Argument

        Try getting a Java exception trace so you can see which Java class is actually getting the exception.

        ADDENVVAR QIBM_RPG_JAVA_EXCP_TRACE VALUE('Y')

        You can add or remove or change that environment variable before or after the JVM has started. The RPG runtime checks the envvar every time it gets a Java exception, and if it finds it with the value 'Y', it asks Java for an exception trace.

        Comment


        • #5
          Re: RPGLE Program Receiving Java Exception Error - Missing Argument

          Scott & Barbara, thank you again for your responses.

          To answer your question Scott, this encryption/decryption is within a purchased package we are using. Going a different direction, outside of the package, on the encryption method is not feasible. That this is a supported package does mean I can get assistance from the vendor, which we are also doing. That being said, I opened a ticket on this issue with them on April 1 of this year and here I am 2 months later none the wiser and feeling my ticket is in limbo. I am actually typing up an email on my ticket with them now requesting an update .

          Barbara, I look into implementing your suggestion today.

          Thanks again to you both. Huge fans of both of your work over the years! I will continue to update this ticket until it is resolved.

          Comment


          • #6
            Re: RPGLE Program Receiving Java Exception Error - Missing Argument

            Was just cruising the forum and noticed this ancient post. We are a vendor of card software and use Java in a very limited capacity. Good that you have source to the app. Curious that a commercial package gives you source to a critical operation like that, but it is good in this case. For PCI, you are also required to record the decryption in a log file identifying the user and purpose. I assume the app does that, though I do not notice that in the code...

            What we would do is catch the exception, and retry. If you still (unlikely) have this issue, we can show you how to workaround (at no charge, as a service to the community.)

            Comment

            Working...
            X