This discussion is archived
1 2 Previous Next 25 Replies Latest reply: Oct 29, 2012 9:55 AM by jim.marion Go to original post RSS
  • 15. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    You are on the right track and are making great progress. PeopleSoft is now able to find and read your Java class. This means you have the class file in the correct location and that you compiled it with the correct Java compiler version. Here is what I think you need to do:

    Change:
    &strDecEmail = &oDecrypt.decryptString("encryptedstringhere");
    To:
    &strDecEmail = &oDecrypt.decryptString(&oByteStr);
    You called it with a string parameter, but the definition requires a byte array. That is why you get the "No overload matches" error. What it is saying is that PeopleSoft found the decryptString method, but it didn't find one that took a string parameter.

    PeopleSoft is able to find the SSOCrypto.class file because it knew that there was no method matching your call signature. Do not change the location in the class path. com.peoplesoft.util is not just a file path. It is also a package specification. If you move the file into a different folder path, then you also have to add a package declaration to the SSOCrypto.java file and recompile it.

    The best practice, actually, is to include a package specification based on your company's domain name, and then place the *.java file in a folder structure matching the package specification. You would then compile the java file into a class file and copy the class file and folder structure into your app server's class path. For Oracle, com.peoplesoft is one of its domain names, and, therefore, why it used that for a package specification. You would not use the same package specification (except in the rare instance where you are creating integration broker target and listening connectors).

    Since you have your app server recognizing the SSOCrypto.class file, I don't recommend changing the .java file or .class file location unless you have to make other changes to the .java file. Any change to the Java or its location will require you to restart your app server. First, get the PeopleCode side working. If it works with no errors, then leave the Java alone. If you have to change the Java for any other reason, then you might consider a package specification.
  • 16. Re: Invoking a Java Method from Peoplecode
    Jeremy Leung Newbie
    Currently Being Moderated
    Hi Jim,
    Would you know what is the cause of this error?

    Java Exception: javax.crypto.BadPaddingException: Given final block not properly padded

    I have followed the syntax given for the code.

    /* Call java class SSOCrypto */
    &oDecrypt = CreateJavaObject("SSOCrypto");

    Local JavaObject &oByteStr = CreateJavaObject("java.lang.String", &strEncEmail).getBytes();

    try
    &strDecEmail = &oDecrypt.decryptString(&oByteStr);
    catch Exception &e1
    SetAuthenticationResult( False, &USERID, "Test: " | &e1.ToString(), False);
    end-try;

    Thank you.
  • 17. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    Usually that error means that the passed in value was not properly encrypted (missing a character, etc). Since you have a working Java program here is how I would test this:

    Modify the working program to iterate over the bytes in the array and print those bytes to a file.
    Modify your PeopleCode to iterate over the bytes in the array and print those bytes to a file.
    Compare the two files.

    Before you do that though, print &strEncEmail to a file and make sure the value shown is what you expect.
  • 18. Re: Invoking a Java Method from Peoplecode
    Jeremy Leung Newbie
    Currently Being Moderated
    Hi Jim

    Is this the correct way of printing the contents of the string?

    &MyFile = GetFile("Output.txt", "A");
    Local JavaObject &oByteStr = CreateJavaObject("java.lang.String", &strEncEmail).getBytes();
    &MyFile.WriteLine(&oByteStr);


    Somehow, when I open the file, the output is byte[].
  • 19. Re: Invoking a Java Method from Peoplecode
    Jeremy Leung Newbie
    Currently Being Moderated
    I tried this as well.

    &emailid = "SCHMIT_L@XXXXX.COM";
    &EncEmail = &oDecrypt.encrypt(&emailid);
    &MyFile.WriteLine(&EncEmail);

    The output on the file is also byte[].
  • 20. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    It is a little more involved than that. When you print &oByteStr, that is the same as calling &oByteStr.toString(). That will return a cryptic string, not the actual contents of the byte array. What you need to do is iterate over the array and print each element in the array. Each element is a byte (number between 0 and 255). Hakan demonstrated how to iterate over a Java Array. Your code to print the results would look something like this:
    &MyFile = GetFile("Output.txt", "A");
    Local JavaObject &oByteStr = CreateJavaObject("java.lang.String", &strEncEmail).getBytes();
    Local array of Any &pca = CreateArrayAny();
    Local number &byteIndex = 0;
    
    REM ** resize array;
    &pca[&oBytStr.length] = null;
    CopyFromJavaArray(&oByteStr, &pca);
    
    While &pca.next(&byteIndex)
       &MyFile.WriteLine(&pca[&byteIndex].toString());
    end-while;
    You will do something similar in the Java Code you tested from the command line that performed the decode without errors.
  • 21. Re: Invoking a Java Method from Peoplecode
    Jeremy Leung Newbie
    Currently Being Moderated
    I managed to find a solution by modifying the Java code for decrypt that instead of accepting a byte as a parameter, we changed this to string, and the SSO now works.
    Thank you all for your help.
    public String decryptString(String message) throws Exception {
              final MessageDigest md = MessageDigest.getInstance("md5");
              final byte[] digestOfPassword =
                   md.digest("Schiphol2012".getBytes("utf-8"));
              final byte[] keyBytes = new byte[24]; //Arrays.copyOf(digestOfPassword, 24);
              System.arraycopy(digestOfPassword,0,keyBytes,0,digestOfPassword.length);
              for (int j = 0, k = 16; j < 8;) {
                   keyBytes[k++] = keyBytes[j++];
              }
              final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
              final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
              final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
              decipher.init(Cipher.DECRYPT_MODE, key, iv);
              final byte[] encData = new sun.misc.BASE64Decoder().decodeBuffer(message);
              final byte[] plainText = decipher.doFinal(encData);
              String result = new String (plainText);
              result = result.replaceAll("[\n\r]", "");
              return result;
         }
  • 22. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    Ah yes, that is a MUCH better solution!
  • 23. Re: Invoking a Java Method from Peoplecode
    user10505735 Newbie
    Currently Being Moderated
    Jim,

    We got one scenario where we need to convert Byte[] to string. How can we acieve that in Peoplesoft? we are able to paste the byte[] into one file but we dont need it. we want to convert to string and put into some record.

    Please help.

    Thanks,
  • 24. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    Java's String class has a constructor that takes a byte array and converts it to a String. When using Java, that is the appropriate way to convert a byte array into a String. Unfortunately, using String's byte constructor from PeopleCode requires reflection (more than one overload matches). An alternative way to create a String from a Java Array is to use the ByteArrayOutputStream. This blog post shows how to construct a ByteArrayOutputStream, copy an array into the stream, and then calls &out.toString() to convert the stream into a string: http://jjmpsj.blogspot.com/2012/10/manipulating-zip-files-with-peoplecode.html. Look for MessageBox(0, "", 0, 0, &out.toString()); in the example. That is where the final conversion happens.
  • 25. Re: Invoking a Java Method from Peoplecode
    jim.marion Pro
    Currently Being Moderated
    I was wrong. Yes, you can use ByteArrayOutputStream, but you don't have to. The String constructor option does work with PeopleCode. Here is an example:
    REM ** Create an array of bytes for testing purposes;
    Local JavaObject &input = CreateJavaObject("java.lang.String", "This is a test string.");
    Local JavaObject &bytes = &input.getBytes();
    
    REM Convert the bytes back into a String;
    Local JavaObject &out = CreateJavaObject("java.lang.String", &bytes);
    
    MessageBox(0, "", 0, 0, &out.toString());
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points