JNI, call java from C++.

Discussion in 'Java' started by tony_lincoln@yahoo.com, Aug 16, 2005.

  1. Guest

    Dear friends,


    I am using JNI to call java from C++. I use j2sdk1.4.1 and Visual C++
    6.

    If my Java source code is like this:
    ******************************­**************************
    import com.tony.package1.classA;
    ....
    public static void main(String[] args) {
    System.out.println("This is a test");
    }// end main()
    ....
    ******************************­***************************
    It will work and C++ can call java successfully. But if the Java code
    is the following:

    ******************************­**************************
    import com.tony.package1.classA;
    ....
    public static void main(String[] args) {
    System.out.println("This is a test");
    String [] str = new classA.method1();
    System.out.println(str[0]);
    }
    ....
    ******************************­***************************

    When I invoke this java class from C++ codes in Visual C++, the "This
    is a test" can be shown in DOS shell, then it shows:
    " An unexpected error has been detected by HotSpot Virtual Machine:
    Internal Error (57437914380392184392743120947­000FF),
    pid = 3288, tid = 3292.
    ...."

    I am sure that classA was written and compiled in correct way, so the
    error is not about it. The error should be something about the path and
    package.
    E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
    is in E:\codes_Tony\com\tony\package1.
    Is there anything wrong about the path? Any hints?
    THanks a lot.
    Tony
     
    , Aug 16, 2005
    #1
    1. Advertising

  2. On 16 Aug 2005 10:15:12 -0700, wrote:
    > When I invoke this java class from C++ codes in Visual C++, the "This
    > is a test" can be shown in DOS shell, then it shows:
    > " An unexpected error has been detected by HotSpot Virtual Machine:
    > Internal Error (57437914380392184392743120947­000FF),
    > pid = 3288, tid = 3292.
    > ..."


    Quite simply, there is an error in your code. Read my latest response
    to your nearly identical question in the other thread where you
    initially brought this up. Please don't start new threads unless
    you've got new issues!

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Aug 16, 2005
    #2
    1. Advertising

  3. Guest

    I do not think that there is errors in my source code. I made a test
    and the source code is following:
    DemoMain.java is the java code invoked by C++ code. IOTest.class is the
    java class used by DemoMain.

    DemoMain.java
    ******************************************************************************************************
    import com.tony.jniClasses.IOTest;
    import java.io.*;

    public class DemoMain {
    public static void main(String[] args)
    throws java.io.IOException, java.lang.NullPointerException
    {
    System.out.println("This is a test.");
    IOTest.printLines();
    }// end main().
    }// end class DemoMain.
    **************************************************************************************************************************


    IOTest.java
    **************************************************************************************************************************
    package com.tony.jniClasses;
    import java.io.*;

    public class IOTest
    {
    public static void printLines()
    {
    System.out.println("Line 1: no input, no output");
    System.out.println("Line 2: no input, no output");
    }// end printLines()
    }// end class IOTest.
    *****************************************************************************************************************

    When I run the c++ code under Visual C++ studio 6.0,
    the "This is a test" can be shown in DOS shell, then it shows:
    " An unexpected error has been detected by HotSpot Virtual Machine:
    Internal Error (57437914380392184392743120947­000FF),
    pid = 3288, tid = 3292.
    ...."

    What is error ????? Any hints?
    TOny
     
    , Aug 17, 2005
    #3
  4. Andoni Guest


    > I do not think that there is errors in my source code. I made a test
    > and the source code is following:


    Unfortunately the code doesn't care whether you think there is an error or
    not!

    > DemoMain.java is the java code invoked by C++ code. IOTest.class is the
    > java class used by DemoMain.


    This code does not have the error.

    > What is error ????? Any hints?


    That's the attitude. The error in here:

    String [] str = new classA.method1();

    You need more brackets. What you are saying is effectively:
    String [] str = new (classA.method1());

    Which will give you an error. What you should be saying is:

    String [] str = (new classA).method1();

    Hope that helps,

    Andoni.
     
    Andoni, Aug 17, 2005
    #4
  5. Guest

    Thanks for the analysis. I am not sure if you are correct, but I know
    that this error is caused by CallStaticVoidMethod() in C++ codes. What
    I have done to prove this is:
    I simplied the C++ codes and Java codes, as following:

    /*for C++,debugged with Visual C++ 6.0*/
    // invoke.cpp

    #ifndef __cplusplus
    #define __cplusplus
    #endif

    #include "jni.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>

    #pragma comment (lib,"E:\\Programme\\Java\\jdk1.5.0_02\\lib\\jvm.lib")

    void main() {

    JavaVM *jvm;
    JNIEnv *env;

    JavaVMInitArgs vm_args;
    JavaVMOption options[3];

    options[0].optionString = "-Djava.compiler=NONE";
    options[1].optionString = "-Djava.classpath=.";
    options[2].optionString = "-verbose:jni";

    vm_args.version = JNI_VERSION_1_4;
    vm_args.nOptions = 3;
    vm_args.options = options;
    vm_args.ignoreUnrecognized = JNI_TRUE;

    jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
    if (res < 0) {
    fprintf(stderr, "Can't create Java VM\n");
    exit(1);
    };

    jclass cls = env->FindClass("DemoMain");
    if (cls == 0) printf("Sorry, I can't find the class");

    jmethodID get_main_id;

    if(cls != NULL)
    {
    get_main_id =
    env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");

    if(get_main_id != NULL )
    {
    jclass string = env->FindClass("java/lang/String");
    jobjectArray args = env->NewObjectArray(0,string, NULL);

    fprintf(stdout, "This is invokeSimplified6.\n");
    env->CallStaticVoidMethod(cls, get_main_id, args);
    fprintf(stdout, "This is invokeSimplified7.\n");

    }// end IF.

    }// end IF.


    jvm->DestroyJavaVM();
    fprintf(stdout, "Java VM destory\n");
    }//end main.

    **************************************************************************************************************

    In the main() of Java codes DemoMain.java, there are only 2 sentences:
    System.out.println ("This is a test");
    IOTest.print2Lines();

    IOTest is another java class located in a different directory. There
    are only 2 sentences in print2Lines():
    System.out.println ("Line1");
    System.out.println ("Line2");

    I simply these classes, so no parameter was transmitted in different
    methods or classes.
    I run the c++ codes, the output is like this:
    ________________________________________________________________________________
    ....
    This is invokeSimplified6.
    [Dynamic-linking native method java.io.FileOutputStream.writeBytes ...
    JNI]
    This is a test.
    This is invokeSimplified7.
    #
    # An unexpected error has been detected by HotSpot Virtual Machine:
    #
    # Internal Error (455843455054494F4E530E43505000FF), pid=3704,
    tid=4064
    #
    # Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 interpreted mode,
    sharing)
    # An error report file with more information is saved as
    hs_err_pid3704.log
    #
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    ---------------------------------------------------------------------------------------------------------------------------------

    So I know that this error is caused by CallStaticVoidMethod(). But how
    to change it so the output is correct?
    Thanks a lot.
    tony
     
    , Aug 17, 2005
    #5
  6. On 17 Aug 2005 05:30:49 -0700, wrote:
    > Thanks for the analysis. I am not sure if you are correct, but I
    > know that this error is caused by CallStaticVoidMethod() in C++
    > codes. What I have done to prove this is:


    First, main() always returns int, never void.

    Second, it's a good idea to use fprintf(stderr, ...) for your error
    messages or you risk missing the last ones prior to the crash due to
    buffering.

    What happens if you don't use DestroyJavaVM() at the end of the
    program, or don't call CallStaticVoidMethod()?

    > So I know that this error is caused by CallStaticVoidMethod().


    But the text line *following* CallStaticVoidMethod() is displayed!

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Aug 17, 2005
    #6
  7. Guest

    (1)
    Which main()? In DemoMain.java or in C++ codes? if in DemoMain(), I
    tried this, I do not call CallStaticVoidMethod(), but error appeared:
    *************************************error********************************************************************************
    [Dynamic-linking native method java.lang.ClassLoader.defineClass1 ...
    JNI]
    #
    # An unexpected error has been detected by HotSpot Virtual Machine:
    #
    # Internal Error (455843455054494F4E530E43505000FF), pid=3080,
    tid=3132
    #
    # Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 interpreted mode,
    sharing)
    # An error report file with more information is saved as
    hs_err_pid3080.log
    #
    # If you would like to submit a bug report, please visit:
    # http://java.sun.com/webapps/bugreport/crash.jsp
    #
    Press any key to continue
    *****************************************end of
    error***************************************************

    (2)
    If I do not call CallStaticVoidMethod(), there will be no error when I
    executed the c++ codes! So I doubt there is one error in this method,
    or I should not use this method!

    If I don't use DestroyJavaVM(), there are 2 cases:
    a. I do not call CallStaticVoidMethod(), then the C++ codes work and
    the result is:
    __________________________
    This is invokeSimplified6.
    This is invokeSimplified7.
    Press any key to continue
    -------------------------------------------
    b. if I call CallStaticVoidMethod(), then the result is:
    __________________________________
    This is invokeSimplified6.
    [Dynamic-linking native method java.io.FileOutputStream.writeBytes ...
    JNI]
    This is a test.
    This is invokeSimplified7.
    Java VM destory
    Press any key to continue
    ------------------------------------------------------------

    The method IOTest.print2Lines() is still not called. How to call this
    method?
    Thanks.
    tony
     
    , Aug 17, 2005
    #7
  8. Guest

    if the return of DemoMain() is int, for example, then the C++ codes
    were changed like this:

    ________________________________________________________________________________
    jclass cls = env->FindClass("DemoMain");
    if (cls == 0) printf("Sorry, I can't find the class");

    fprintf(stdout, "This is invokeSimplified4.\n");

    jmethodID get_main_id;

    if(cls != NULL)
    {
    get_main_id =
    env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");
    fprintf(stdout, "This is invokeSimplified5.\n");

    if(get_main_id != NULL )
    {
    jclass string = env->FindClass("java/lang/String");
    jobjectArray args = env->NewObjectArray(0,string, NULL);

    fprintf(stdout, "This is invokeSimplified6.\n");
    int i = env->CallIntMethod(cls, get_main_id, args);
    fprintf(stdout, i+ "This is invokeSimplified7.\n");

    }// end IF.

    }// end IF.
    _______________________________________________________________________

    Then the output will be:

    "This is invokeSimplified4.
    This is invokeSimplified5.
    Java VM destory
    Press any key to continue"

    This means, the get_main_id is NULL. So l wonder if the return of
    Main() in java code should be void.
    Best wishes.
    tony
     
    , Aug 17, 2005
    #8
  9. On 17 Aug 2005 07:28:26 -0700, wrote:
    > This means, the get_main_id is NULL. So l wonder if the return of
    > Main() in java code should be void.


    main() in Java always returns void.

    main() in C and C++ always returns int.

    /gordon

    --
    [ do not email me copies of your followups ]
    g o r d o n + n e w s @ b a l d e r 1 3 . s e
     
    Gordon Beaton, Aug 17, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Hunsley

    IBM's JNI fails where Sun's JNI works

    Alex Hunsley, Nov 3, 2003, in forum: Java
    Replies:
    4
    Views:
    851
    Alex Hunsley
    Nov 4, 2003
  2. Pasturel Jean-Louis

    Porting JNI Windows under JNI LINUX + Wine ?

    Pasturel Jean-Louis, Feb 29, 2004, in forum: Java
    Replies:
    5
    Views:
    907
    Pasturel Jean-Louis
    Mar 3, 2004
  3. vasanth
    Replies:
    0
    Views:
    2,703
    vasanth
    Jan 25, 2005
  4. Replies:
    13
    Views:
    6,089
  5. bgabrhelik
    Replies:
    0
    Views:
    819
    bgabrhelik
    Sep 29, 2009
Loading...

Share This Page