Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
share|improve this question
1  
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? –  Ymareth Feb 7 at 18:38
    
I don't see any definition for digest? –  Ymareth Feb 7 at 18:43
    
Digest is a member of the Java class MessageDigest –  JohnnyFever Feb 7 at 20:47
    
See above for the result –  JohnnyFever Feb 7 at 20:48
    
@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 []. –  Szabolcs Feb 7 at 21:56

1 Answer 1

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 ;.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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