timob / jnigi

Golang Java JNI library
BSD 2-Clause "Simplified" License
163 stars 44 forks source link

I wanna know how to use jar library. #8

Closed MechanicKim closed 7 years ago

MechanicKim commented 7 years ago

I have an answer. How should I do to use jar library?

timob commented 7 years ago

You set the classpath:

http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/classpath.html

This can be done from jnigi by passing an argument:

_, env, err := jnigi.CreateJVM(jnigi.NewJVMInitArgs(false, true, jnigi.DEFAULT_VERSION, []string{"-Djava.class.path=/path/to/mylib.jar"}))

I usually just set this argument from the CLASSPATH environment variable. I probably should update the example to show this.

MechanicKim commented 7 years ago

Thanks @timob 👍

abhowmik commented 4 years ago

Hi Tim,

  1. Currently I am unable to call the CallNewMethod. Here is my java signature public String encrypt(String plainText){

... String finalStringInDB = new String("test");

return finalStringInDB;

}

  1. Same thing for CallStaticMethod. Here is the java code

public static String encrypt(String plainText){

... String finalStringInDB = new String("test");

return finalStringInDB;

}

3.In both cases when I call the above methods from my main.go I get the following error.

Exception in thread "main" java.lang.NoSuchMethodError: encrypt 2020/09/21 11:23:33 Java exception occured. check stderr

I have tried String I have tried as a Java Object nothing works.

Can you please help on what I should be differently while calling the above Java Methods.

I was able to invoke the java class from the main.go and it is entering the class constructor but not able to call

the methods like above.

Attached is the main-ask.go class that I am trying to call the above functions.

Please Help.

Thanks

Anshu Bhowmik main-ask.txt

timob commented 4 years ago

Hi 👋 , I've updated a fix to the master branch. Can you pull the latest from master and try again?

abhowmik commented 4 years ago

Hi Tim, I am still not able to get the CallMethod working. here is my Java Signature

public Object encrypt(String plainText){

    *...*

    finalStringInDB ="test"

    *return*  (Object)finalStringInDB;

}

below is the main.go. It fails while doing the CallMethod. Nere is the class below

package main

import ( "fmt" "github.com/timob/jnigi" "log" )

func main() { // if err := jnigi.LoadJVMLib(jnigi.AttemptToFindJVMLibPath()); err != nil { if err := jnigi.LoadJVMLib("/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/server/libjvm.dylib"); err != nil { log.Fatal(err) } //jvm, env, err := jnigi.CreateJVM(jnigi.NewJVMInitArgs(false, true, jnigi.DEFAULT_VERSION, []string{"-Xcheck:jni"})) jvm,env, err := jnigi.CreateJVM(jnigi.NewJVMInitArgs(false, true, jnigi.DEFAULT_VERSION, []string{"-Xcheck:jni","-Djava.class.path=/Users/ab/jnigi/kmtools-1.0-SNAPSHOT.jar"})) if err != nil { log.Fatal(err) } //obj, err := env.NewObject("java/lang/Object") obj, err := env.NewObject("com/keymgmt/EncryptionDecryptionFacadeJNI") if err != nil { log.Fatal(err) } //v, err := obj.CallMethod(env, "hashCode", jnigi.Int v, err := obj.CallMethod(env, "encrypt", jnigi.Object) --> Fails here with error

if err != nil {
    log.Fatal(err)
}
fmt.Printf("object hash code: %d\n", v.(int))
if err := jvm.Destroy(); err != nil {
    log.Fatal(err)
}

}

The error is : (Exception in thread "main" java.lang.NoSuchMethodError: encrypt 2020/09/21 23:05:38 Java exception occured. check stderr)

Please help Thanks

On Mon, Sep 21, 2020 at 10:05 PM timob notifications@github.com wrote:

Hi 👋 , I've updated a fix to the master branch. Can you pull the latest from master and try again?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timob/jnigi/issues/8#issuecomment-696510128, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIVD3NMD2B7CSQVZZMOGJLSHAWC5ANCNFSM4DRXKLMA .

timob commented 4 years ago

If you have public Object encrypt(String plainText), you want

 v, err := obj.CallMethod(env, "encrypt", jnigi.Object, plainText) 

You need to create the Java String object for plainText first and then pass it to CallMethod. See the code in the test here : https://github.com/timob/jnigi/blob/master/jnigi_test.go#L56 .

timob commented 4 years ago

Checkout https://github.com/timob/jnigi/blob/string_example/example/hello_world.go too.

abhowmik commented 4 years ago

Hi Tim, Thanks for the response. That helped! I am not getting the following warnings: WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod How do I handle the exception while making a call to the encrypt method. Can you please share any code to handle the exception please?

abhowmik commented 4 years ago

Hi Tim, Thanks Tim for the response. My encrypt is working. I want to get the same string back from encrypt and pass it to the decrypt function. My current main.go This works : str := "abc" jstr, err := env.NewObject("java/lang/String", []byte(str))

if err != nil {
log.Fatal(err)
}

v, err := obj.CallMethod(env, "encrypt",

jnigi.ObjectType("java/lang/String"), jstr)

if err != nil {
log.Fatal(err)
}

What does not work: v, err := obj.CallMethod(env, "encrypt", jnigi.ObjectType("java/lang/String"), jstr) greeting := v.(*jnigi.ObjectRef)

v, err = greeting.CallMethod(env, "decrypt", jnigi.Byte|jnigi.Array)

if err != nil {
    log.Fatal(err)
}
goGreeting := string(v.([]byte))
fmt.Printf("encrypted value %s\n", goGreeting)

This my decrypt java unction

public String decrypt(byte[] b) throws CryptoException{

    *int* len = 0;

    *if* (b == *null*){

        len = -1;

    } *else* {

        len = b.length;

    }

    *return* "abc";

}

Please help. Basically I wanted to convert the returned objectref from the encrypt function to a byte array or String

to pass on to the decrypt function.

Thanks

On Mon, Sep 21, 2020 at 11:40 PM timob notifications@github.com wrote:

If you have public Object encrypt(String plainText), you want

v, err := obj.CallMethod(env, "encrypt", jnigi.Object, plainText)

You need to create the Java String object for plainText first and then pass it to CallMethod. See the code in the test here : https://github.com/timob/jnigi/blob/master/jnigi_test.go#L56 .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timob/jnigi/issues/8#issuecomment-696537825, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIVD3MJYUDJRHAF4TBXYITSHBBFDANCNFSM4DRXKLMA .

abhowmik commented 4 years ago

Hi Tim, ok its working now. I Did the following based on your github hello world example: v, err := obj.CallMethod(env, "encrypt", jnigi.ObjectType("java/lang/String"), jstr) v1 := v.(*jnigi.ObjectRef)

v, err = v1.CallMethod(env, "getBytes", jnigi.Byte|jnigi.Array)
if err != nil {
  log.Fatal(err)
}
v2 := string(v.([]byte))

fmt.Printf("encrypted value %s\n", v2) os.Exit(3)

I am doing os.Exit(3) but its not coming out of the go program. Can you please let me know how to exit out of the go main go program please? Thanks

On Tue, Sep 22, 2020 at 12:09 PM Anshuman Bhowmik < anshuman.bhowmik@gmail.com> wrote:

Hi Tim, Thanks Tim for the response. My encrypt is working. I want to get the same string back from encrypt and pass it to the decrypt function. My current main.go This works : str := "abc" jstr, err := env.NewObject("java/lang/String", []byte(str))

if err != nil {
log.Fatal(err)
}

v, err := obj.CallMethod(env, "encrypt",

jnigi.ObjectType("java/lang/String"), jstr)

if err != nil {
log.Fatal(err)
}

What does not work: v, err := obj.CallMethod(env, "encrypt", jnigi.ObjectType("java/lang/String"), jstr) greeting := v.(*jnigi.ObjectRef)

v, err = greeting.CallMethod(env, "decrypt", jnigi.Byte|jnigi.Array)

if err != nil {
    log.Fatal(err)
}
goGreeting := string(v.([]byte))
fmt.Printf("encrypted value %s\n", goGreeting)

This my decrypt java unction

public String decrypt(byte[] b) throws CryptoException{

    *int* len = 0;

    *if* (b == *null*){

        len = -1;

    } *else* {

        len = b.length;

    }

    *return* "abc";

}

Please help. Basically I wanted to convert the returned objectref from the encrypt function to a byte array or String

to pass on to the decrypt function.

Thanks

On Mon, Sep 21, 2020 at 11:40 PM timob notifications@github.com wrote:

If you have public Object encrypt(String plainText), you want

v, err := obj.CallMethod(env, "encrypt", jnigi.Object, plainText)

You need to create the Java String object for plainText first and then pass it to CallMethod. See the code in the test here : https://github.com/timob/jnigi/blob/master/jnigi_test.go#L56 .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timob/jnigi/issues/8#issuecomment-696537825, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIVD3MJYUDJRHAF4TBXYITSHBBFDANCNFSM4DRXKLMA .

timob commented 4 years ago

Can you please open a new issue regarding exiting the program please? This issue is about something else.

abhowmik commented 4 years ago

Hi Tim, I submitted a new request regarding multiple JVM invocations. Request to please advise. Here is the issue link https://github.com/timob/jnigi/issues/46 Thanks

On Wed, Sep 23, 2020 at 2:15 AM timob notifications@github.com wrote:

Can you please open a new issue regarding exiting the program please? This issue is about something else.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/timob/jnigi/issues/8#issuecomment-697240564, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIVD3LKME26DLOKOMG7ZWTSHG4D3ANCNFSM4DRXKLMA .