2
$\begingroup$

I have a simple JLink function as follows:

Needs["JLink`"]
sha256Signature[bytesList_] :=
JavaBlock[
  Module[{sig, mdc, mdo},
  InstallJava[];
  mdc = LoadJavaClass["java.security.MessageDigest"];
  mdo = mdc.getInstance["SHA-256"];
  mdo[update[bytesList]];
  sig = mdo[digest];
  ReleaseJavaObject[mdo];
  Return[sig]
 ]
];
sha256Signature[byteList]

It produces the following output

(JLink`JavaClass["java.security.MessageDigest", 0, {JLink`JVM["vm1"]}, 1,
java`security`MessageDigest`", False, True].getInstance["SHA-256"])[digest]

There is no error indication, but the code doesn't seem to do anything. I must be missing something simple.

Making suggested modifications (see below)

Needs["JLink`"];
InstallJava[];
sha256Signature[bytesList_] :=
  JavaBlock[
   Module[{sig, mdc, mdo},
    mdc = LoadJavaClass["java.security.MessageDigest"];
    mdo = MessageDigest`getInstance["SHA-256"];
    mdo[update[bytesList]];
    sig = mdo[digest];
    ReleaseJavaObject[mdo];
    Return[sig]
  ]
];
sha256Signature[byteList]

Produces

Java::fldx: Attempting to set field named digest defined in class
java.security.MessageDigest$Delegate to an incorrect type of value:
    JavaObject[java.security.MessageDigest$Delegate]».
$Failed
$\endgroup$
5
  • 1
    $\begingroup$ Move InstallJava[] out of the function to just below Needs["JLink"]; (and put a ; after both). Change mdc.getInstance to essageDigestgetInstance. Now what is your value for byteList? $\endgroup$
    – Ymareth
    Feb 7, 2014 at 18:38
  • $\begingroup$ I don't see any definition for digest? $\endgroup$
    – Ymareth
    Feb 7, 2014 at 18:43
  • $\begingroup$ Digest is a member of the Java class MessageDigest $\endgroup$ Feb 7, 2014 at 20:47
  • $\begingroup$ See above for the result $\endgroup$ Feb 7, 2014 at 20:48
  • $\begingroup$ @JohnnyFever While mdo[digest] and mdo@digest are truly equivalent, the former notation is very confusing and it's not how J/Link was designed to be used. Please use mdo@digest. With this notation it immediately becomes clear that you forgot the function call brackets: mdo@digest[]. This is visually analogous to mdo.digest() in Java, just replace . by @ and () by []. $\endgroup$
    – Szabolcs
    Feb 7, 2014 at 21:56

1 Answer 1

2
$\begingroup$

Try like this:

sha256Signature[bytesList_] := 
 JavaBlock@Module[{mdo}, 
   LoadJavaClass["java.security.MessageDigest"];
   mdo = MessageDigest`getInstance["SHA-256"];
   mdo@update[bytesList];
   mdo@digest[]
 ]

sha256Signature[Range[10]]

(* ==> {-56, 72, -31, 1, 63, -97, 4, -87, -42, 63, -92, 60, -25, -3, 74,
        -16, 53, 21, 44, 124, 102, -102, 74, 64, 75, 103, 16, 124, -18, 95,
         46, 78} *)

It's much clearer if you use @ instead of [ ... ] because it (almost) directly corresponds to the . in Java.

You do not need to use ReleaseJavaObject if you are already using JavaBlock.

You do not need to us an explicit Return at the end of the function in Mathematica. Just don't suppress returning the value by using ;.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.