call java from c++: where to put class

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

  1. Guest

    Dear friends,

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

    In Tools¡úOptions->Include Files:
    1. C:\j2sdk1.4.1_02\include
    2. C:\j2sdk1.4.1_02\include\win32

    In Tools->Options->Library Files:
    C:\j2sdk1.4.1_02\lib

    set Path = C:\j2sdk1.4.1_02\jre\bin\client

    All of these settings are correct. When I compiled the invoke.cpp, no
    errors. But when I execute it, DOS concole window popped up and one
    sentence appeared:
    "Sorry, I can't find the class. Press any key to continue"

    The "Sorry, I can't find the class" came from my invoke.cpp. This
    means, this cpp can not find my java class, even when I put the java
    class "Demo" into the same subdir as invoke.cpp. Where should I put the
    Demo class?

    Any hints? Thanks a lot!

    The related codes(Demo.java, invoke.cpp) are enclosed here:

    //Demo.java
    ************************************************
    package jni.test;

    public class Demo {

    public static int COUNT = 8;
    public String msg;
    private int[] counts;
    public Demo() {
    this("ȱʡ¹¹Ô캯Êý");
    }

    public Demo(String msg) {
    System.out.println("<init>:" + msg);
    this.msg = msg;
    this.counts = null;
    }

    public String getMessage() {
    return msg;
    }

    public int[] getCounts(){
    return counts;
    }

    public void setCounts(int[] counts){
    this.counts = counts;
    }

    public void throwExcp()
    throws IllegalAccessException{
    throw new IllegalAccessException
    ("exception occur.");
    }

    }// end class Demo.

    *****************************************************************+




    The c++ code is the following:
    // invoke.cpp
    ********************************************************************
    /*for C++,debugged with Visual C++ 6.0*/

    #ifndef __cplusplus
    #define __cplusplus
    #endif

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

    #pragma comment (lib,"C:\\j2sdk1.4.1_02\\lib\\jvm.lib")

    int JStringToChar(JNIEnv *env, jstring str, LPTSTR desc, int desc_len)
    {
    int len = 0;
    if(desc==NULL||str==NULL)
    return -1;

    wchar_t *w_buffer = new wchar_t[1024];
    ZeroMemory(w_buffer,1024*sizeof(wchar_t));

    wcscpy(w_buffer,env->GetStringChars(str,0));

    env->ReleaseStringChars(str,w_buffer);
    ZeroMemory(desc,desc_len);

    len =
    WideCharToMultiByte(CP_ACP,0,w_buffer,1024,desc,desc_len,NULL,NULL);

    if(len>0 && len<desc_len) desc[len]=0;
    delete[] w_buffer;
    return strlen(desc);
    }

    jstring NewJString(JNIEnv* env,LPTSTR str)
    {
    if(!env || !str) return 0;
    int slen = strlen(str);
    jchar* buffer = new jchar[slen];
    int len = MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,slen);
    if(len>0 && len < slen) buffer[len]=0;
    jstring js = env->NewString(buffer,len);
    delete [] buffer;
    return js;
    }


    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 = "";

    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("Demo");

    if (cls == 0) printf("Sorry, I can't find the class");

    jmethodID get_main_id =
    env->GetStaticMethodID(cls,"main","([Ljava/lang/String;)V");
    jclass string = env->FindClass("java/lang/String");
    jobjectArray args = env->NewObjectArray(0,string, NULL);
    env->CallStaticVoidMethod(cls,get_main_id,args);

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

    ***********************************************************************
    //end of invoke.cpp
     
    , Aug 14, 2005
    #1
    1. Advertising

  2. On 14 Aug 2005 13:36:57 -0700, wrote:
    > package jni.test;
    > public class Demo {


    [...]

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


    You spelled the name of the class wrong. Try "jni.test.Demo" or remove
    the package declaration. Note too that the class should be in
    ../jni/test/Demo.class if your classpath points to "." as it does in
    the code you've posted.

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


    > vm_args.nOptions = 3;


    I see only two meaningful arguments here. Why the empty string?

    /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 15, 2005
    #2
    1. Advertising

  3. On 15 Aug 2005 09:00:30 +0200, Gordon Beaton wrote:
    > You spelled the name of the class wrong. Try "jni.test.Demo"


    Sorry, that should have been: "jni/test/Demo" instead.

    /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 15, 2005
    #3
  4. Chris Uppal Guest

    Gordon Beaton wrote:
    > On 14 Aug 2005 13:36:57 -0700, wrote:
    > > jclass cls = env->FindClass("Demo");

    > [...]
    > You spelled the name of the class wrong. Try "jni.test.Demo"


    Should be:

    "jni/test/Demo"

    JNI names....

    --- chris
     
    Chris Uppal, Aug 15, 2005
    #4
  5. Guest

    Thanks a lot. I removed "package Jni.test;" in the Demo.java and
    compile it again, and it works.
    ( options[2].optionString = "-verbose: jni" )
    But new question comes:
    When the c++ codes run, a DOS console poped up, and the words like this
    appears:

    ___________________________________________________________________________________
    ....
    [Dynamic-linking native method java.lang.Thread start0 ... JNI]
    ....
    [Dynamic-linking native method java.lang.classLoader defineClass1 ...
    JNI]
    ---------------------------------------------------------------------------------------------------------------------

    Then a new Windows from Win2000 popped up and showed:
    "Test3_14Aug.exe has encountered a problem and needs to close.We are
    sorry from the inconvenience.
    Please tell Microsoft about this problem.
    We have created an error report that you can send to us...."

    Then the program was forced to stop.
    Is this the problem of win2000, or the bug in invoke.cpp/Demo.java?
    Thanks in advance.
    tony
     
    , Aug 15, 2005
    #5
  6. On 15 Aug 2005 06:39:55 -0700, wrote:
    > "Test3_14Aug.exe has encountered a problem and needs to close.We are
    > sorry from the inconvenience.
    > Please tell Microsoft about this problem.
    > We have created an error report that you can send to us...."
    >
    > Then the program was forced to stop.


    In the code you've posted, Demo doesn't have a main() method and you
    don't check the return value from GetStaticMethodID() before
    attempting to invoke it.

    /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 15, 2005
    #6
  7. Guest

    Thank you very much. You are right. Once I put main() method in it, it
    works. Thanks.
    Tony
     
    , Aug 16, 2005
    #7
  8. Guest

    But the new problem about package comes:

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

    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 (57437914380392184392743120947000FF),
    pid = 3288, tid = 3292.
    ...."

    So I thought this is the problem of path setting. I set the path as
    E:\codes_Tony. This dir is where I put my package com.tony.package1.*.
    But the same error apprears.
    I still guess that this is the problem of path setting. But how?
    Thanks a lot.
    Tony
     
    , Aug 16, 2005
    #8
  9. On 16 Aug 2005 07:36:40 -0700, wrote:
    > I set the path as
    > E:\codes_Tony. This dir is where I put my package com.tony.package1.*.
    > But the same error apprears.


    If E:\codes_Tony is in your classpath, then com.tony.package1.ClassA
    should be in E:\codes_Tony\com\tony\package1\ClassA.class.

    See also:
    http://www.yoda.arachsys.com/java/packages.html

    /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
    #9
  10. Guest

    Exactly. E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
    is in E:\codes_Tony\com\tony\package 1\ClassA.class.
    But why the error appears:
    " An unexpected error has been detected by HotSpot Virtual Machine:
    Internal Error (57437914380392184392743120947 000FF),
    pid = 3288, tid = 3292.
    ..."
    To do with this error, any hints?
    Thanks in advance.
    Tony
     
    , Aug 16, 2005
    #10
  11. On 16 Aug 2005 08:52:53 -0700, wrote:

    > Exactly. E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
    > is in E:\codes_Tony\com\tony\package 1\ClassA.class.


    Compare ..
    E:\codes_Tony\com\tony\package 1\ClassA.class
    ...to..
    E:\codes_Tony\com\tony\package1\ClassA.class

    --
    Andrew Thompson
    physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
    "I'll sing and I'll be merry when occasion I do see,." Steeleye Span 'All
    Around My Hat'
     
    Andrew Thompson, Aug 16, 2005
    #11
  12. Guest

    What do you mean "compare..."? They are the same... aren't they?
    tony
     
    , Aug 16, 2005
    #12
  13. On 16 Aug 2005 09:15:44 -0700, wrote:

    > What do you mean "compare..."? They are the same... aren't they?


    No.

    --
    Andrew Thompson
    physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
    "You make connections, you win elections, but that ain't gonna be enough.."
    The Angels 'City out of Control'
     
    Andrew Thompson, Aug 16, 2005
    #13
  14. Guest

    You are right. But what I want to say is,

    E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
    is in E:\codes_Tony\com\tony\package1\ClassA.class.
    But why the error appears:
    " An unexpected error has been detected by HotSpot Virtual Machine:
    Internal Error (57437914380392184392743120947 000FF),
    pid = 3288, tid = 3292.
    ..."
    To do with this error, any hints?
    Thanks in advance.
    Tony
     
    , Aug 16, 2005
    #14
  15. On 16 Aug 2005 09:29:46 -0700, wrote:

    > You are right. But what I want to say is, ..


    Hold it!

    In that case, some advice.

    Stop 'typing' the paths and package names.
    Copy/paste the information instead. You are
    simply wasting time otherwise.

    --
    Andrew Thompson
    physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
    "What was it you wanted? Tell me again, I forgot." Bob Dylan 'What Was It
    You Wanted'
     
    Andrew Thompson, Aug 16, 2005
    #15
  16. Guest

    So you mean that I should change the original source code
    ******************************­**************************
    import com.tony.package1.classA;
    ....
    public static void main(String[] args) {
    System.out.println("This is a test");
    String [] str = new classA.method1();
    }
    ....
    ******************************­***************************

    into
    ******************************­**************************
    // here without writting "import ..."
    ....
    public static void main(String[] args) {
    System.out.println("This is a test");
    String [] str = new classA.method1();
    }
    ....
    ******************************­***************************
    and put classA into the dir which is same as my source code?
    But this won't work...as classA was produced as a form of package...
     
    , Aug 16, 2005
    #16
  17. On 16 Aug 2005 09:46:11 -0700, wrote:

    (A.T. earlier)
    >> Stop 'typing' the paths and package names.
    >> Copy/paste the information instead.

    ...
    > So you mean that I should change the original source code


    No...

    My point was - Be precise, rather than approximate.

    When you type a path or classname, or some error output,
    there is room for 'typos'. So - *don't* type it.

    Allways *copy* the output from the command line,
    or error log, the address bar of the directory,
    or batch file.. wherever it actually occurs.

    --
    Andrew Thompson
    physci.org 1point1c.org javasaver.com lensescapes.com athompson.info
    "I got a raw deal, so I'm lookin' for a steel.." Tricky 'Black Steel'
     
    Andrew Thompson, Aug 16, 2005
    #17
  18. On 16 Aug 2005 09:29:46 -0700, wrote:
    > E:\codes_Tony is in my classpath, and com.tony.package1.ClassA
    > is in E:\codes_Tony\com\tony\package1\ClassA.class.
    > But why the error appears:
    > " An unexpected error has been detected by HotSpot Virtual Machine:
    > Internal Error (57437914380392184392743120947 000FF),
    > pid = 3288, tid = 3292.
    > ..."
    > To do with this error, any hints?


    This can be caused by many things, and all of them are errors in your
    code.

    In the code you posted earlier you had neglected to check return
    values from the various JNI functions you are calling. Before we
    continue to try to guess why your code is crashing, you need to add
    code to check the return values you were previously ignoring.

    If FindClass() fails and you continue to look up a method using the
    NULL value, your code will crash. If GetMethodID() fails and you
    continue to invoke the NULL method, your code will crash. And so on.

    Check the return values, and when one of them fails to return what you
    expect, use something like this to see why:

    cls = env->FindClass("com/tony/package1/ClassA");

    if (cls != NULL) {
    mid = env->GetStaticMethodID(...);

    if (mid != NULL) {
    env->CallStaticVoidMethod(...);
    }
    }

    if (env->ExceptionOccurred()) {
    env->ExceptionDescribe();
    }

    If your code continues to crash after that, you need to post more
    information, e.g. the real code you are using, and the exact point of
    the crash (which you can determine quickly using a debugger or simple
    print statements).

    /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
    #18
  19. Guest

    Thanks. I will try this...
    Tony
     
    , Aug 16, 2005
    #19
  20. 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
    #20
    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. E11
    Replies:
    1
    Views:
    4,774
    Thomas Weidenfeller
    Oct 12, 2005
  2. Gabriel Rossetti
    Replies:
    3
    Views:
    551
    Jerry Hill
    Apr 25, 2008
  3. Replies:
    8
    Views:
    407
    Greg Herlihy
    Jun 28, 2008
  4. Phlip
    Replies:
    2
    Views:
    448
    phlip
    Jul 1, 2008
  5. Phlip
    Replies:
    36
    Views:
    872
    phlip
    Jul 2, 2008
Loading...

Share This Page