• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 296
  • Last Modified:

Calling JAVA method from C++

Can i call JAVA IMPLEMENTATION from C++ program. I would appreciate if i get a sample program. Thanks in advance
0
vabdussamad
Asked:
vabdussamad
1 Solution
 
memingCommented:
Look into JNI of SUN JDK and www.java.sun.com
0
 
gadioCommented:
Use JNI. Have a look at the java tutorial (http://web2.java.sun.com/docs/books/tutorial/native1.1/index.html) they have a lot of samples there.
0
 
Ravindra76Commented:
Hi

Visit this URL too

www.javaworld.com/javaworld/jw-07-1997/jw-07-javadev.html

Best of luck
 
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
vabdussamadAuthor Commented:
But all these site talk of calling implementations which are in C++ but i had asked how to call java implementation from C++.
i hope you got diifference of what i am saying
0
 
vivexpCommented:
Hi,

Visit this site for info and an example..

http://www.javaworld.com/javaworld/jw-10-1999/jw-10-jni-2.html

Try out...

Bye
0
 
pbhagCommented:
JNI is a way to interface the Java programs with others. U can write the c program. see the code below:

#include <stdio.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include <sys/wait.h>

#ifdef SIGTSTP  /* true if BSD system*/
#include  <sys/file.h>
#include  <sys/ioctl.h>
#endif

#include <jni.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#define PATH_SEPARATOR ';'
#else /* UNIX */
#define PATH_SEPARATOR ':'
#endif

main()
{
          int childpid, fd ;
      
      void server(void);/* method definition */
      
      printf("in main\n");

      /* closing all the other open files */      
      for(fd = 0; fd < NOFILE; fd++)
      {
            close(fd);
      }

      /* Clear any inherited file mode creation mask */
      umask(0);

      /* goto root directory */
      chdir("/");

      /* To let the parent exit and running the prg as the independent             * server prg */
      childpid = fork();
      if( childpid  < 0)
      {
            fprintf(stderr, "can't fork first child\n");
            exit(1);
      }
      if( childpid > 0 )
      {
            exit(0);
      }
      setpgrp();
      signal(SIGCLD,SIG_IGN);
      signal(SIGHUP, SIG_IGN);

      childpid = fork();
      if( childpid < 0)
            fprintf(stderr, "can't fork first child");
      else if( childpid == 0 )
      {
            server();            
            exit(0);
      }
      else if(childpid > 0)
            exit(0);      
}

/* this is used to create a exe file by which a java prg can be directly run */

void server()
{
    JNIEnv *env;
    JavaVM *jvm;
    JDK1_1InitArgs vm_args;
    jint res;
    jclass cls;
    jmethodID mid;
    jstring jstr;
    jobjectArray args;
    char classpath[1024];      
      
      
      /* IMPORTANT: specify vm_args version # if you use JDK1.1.2 and             beyond */
    vm_args.version = 0x00010001;

    JNI_GetDefaultJavaVMInitArgs(&vm_args);

    /* Append USER_CLASSPATH to the end of default system class path */
    sprintf(classpath, "%s%c%s",
            vm_args.classpath, PATH_SEPARATOR, USER_CLASSPATH);
    vm_args.classpath = classpath;
    //fprintf(stderr, classpath);      
    /* Create the Java VM */
    res = JNI_CreateJavaVM(&jvm,&env,&vm_args);
    if (res < 0) {
        fprintf(stderr, "Can't create Java VM\n");
        exit(1);
    }

//classname = the .class name of ur Java file
    cls = (env)->FindClass("classname");/*Prog*/
    if (cls == 0) {
        fprintf(stderr);
        exit(1);
    }
 
    mid = (env)->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");
    if (mid == 0) {
        fprintf(stderr);
        exit(1);
    }
   
    jstr = (env)->NewStringUTF(" from C!");
    if (jstr == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    args = (env)->NewObjectArray(1,
                        (env)->FindClass("java/lang/String"), jstr);
    if (args == 0) {
        fprintf(stderr, "Out of memory\n");
        exit(1);
    }
    (env)->CallStaticVoidMethod(cls, mid, args);
      
    (jvm)->DestroyJavaVM();
}

void sig_child()
{
#ifdef BSD
      int pid;
      union wait status;
      while( (pid = wait3(&status,WNOHUNG, (struct rusage *) 0))>0);
#endif
}

by this code u can create an exe file where u can implement ur Java program.
0
 
vabdussamadAuthor Commented:
pbhaq, thanks for the code. But I am using VC++ 5 and i s\dont find header files like sys/param.h, unistd.h, sys/wait.h, sysfile.h, sys/ioctl.h and functions like fork(). Then i am using JDK1.2 so what should be the version number i have to set(vm_args.version = 0x00010001;). Then what is the value of USER_CLASSPATH is it predefned or i have to define it. and how should the setting of java be, because i found almost similar program in bit at a different site and compiled it but i did not know like how to set environment variable for java from VC++ environment and where should the lib files be and what java related dll should be copied and where.
0
 
pbhagCommented:
Hi vabdussamad,
The program which I gave u, actually it should be run on the Unix system. As u may know, Unix is basically done in C, so some terms r not there in current version of Vc++, the header files like sys/param.h, uniistd.h, sys/wait.h, sysfile.h etc, all come in Unix. The fork() method is used to separate out ur process from the parent process, so that ur Java prg can run as independent process even if the Parent processes r killed by any chance. USER_CLASSPATH, u have to define this, where u have put ur Java class file.
Also use javah to convert ur Java prg class file into .h file and include into the c++ prg.
For setting of the VM version, Pls see the following link,
http://java.sun.com/products/jdk/1.2/docs/guide/jni/spec/invocation.doc.html.
or forget the previous code and look at the following,
This will explain u where the Java related dll files should be copied.
 Java code is HookCtrlC.java

            /**
            * Steps:::::
            * Use javac HookCtrlC.java
            *    javah -jni HookCtrlC
            *
            * as a bonus use
            * javap -s -p HookCtrlC
            *
            * to get JNI signaturs for 'C' code
            *
            * Compile .dll and then run
            *    java HookCtrlC
            *
            * Press Ctrl+C and hope it runs!
            */
            public class HookCtrlC
            {
               public native void hookc();

               static {
                System.loadLibrary("hookc");
               }

               public static void main(String[] args) throws Exception
               {
                new HookCtrlC().hookc();
                while(true)
                {
                Thread.sleep(100);
                Thread.yield();
                }
               }

               public void javaCleanUp()
               {
                System.out.println("CLEANING UP man.");
               }
            }


            *************************************
            to compile to .dll in VC++6.0 use
            Before doing this goto
            (1)goto D:\Program Files\Microsoft Visual Studio\VC98\Bin
            (2)type vcvars32.bat
            (3)type set include=%include%;d:\jdk1.1.5\include;d:\jdk1.1.5\include\win32

            (4)type set lib=%lib%;d:\jdk1.1.5\lib
            (5)type cl -Ic:\java\include -Ic:\java\include\win32 -LD d:\HookCtrlCImp.c
            -Fehookc.dll

            copy resulting file called "hookc.dll" to say your Winnt home directory so that
            it is found in search path by system.

            'C" code in HookCtrlCImp.c
            #include <signal.h>
            #include "HookCtrlC.h"
            #include <stdio.h>
            #include <stdlib.h>

            #include <jni.h>

            //See
            //http://nswcpc.pvl.edu.au/hints/node4.html
            //http://www2.informatik.uni-halle.de/lehre/c/libc/libc.texinfo_21.html

            /* Forwards */
            void cleanup();
            JNIEnv *globalenv;
            jobject globalobj;
            jclass globalcls;
            jmethodID globalmid;

            void cleanup()
            {
            printf("In Ctrl-C handler\n");
            //Do some Java cleanup.
            printf("Before calling any 'C' code!\n");

            //causing problem HERE. Why?
            (*globalenv)->CallVoidMethod(globalenv,globalobj,globalmid);
            printf("Called HookCtrlC.javaCleanUp!\n");
            exit(0);
            }


            JNIEXPORT void JNICALL Java_HookCtrlC_hookc(JNIEnv *env, jobject obj)
            {
            printf("Calling native hookc()\n");
            signal(SIGTERM,cleanup);
            signal(SIGINT,cleanup);

            globalenv=env;
            globalobj=obj;
            globalcls = (*globalenv)->GetObjectClass(globalenv, globalobj);
            globalmid = (*globalenv)->GetMethodID(globalenv, globalcls, "javaCleanUp",
            "()V");

            printf("Calling Java void method here\n");
            //Ok calling here perfect
            (*globalenv)->CallVoidMethod(globalenv,globalobj,globalmid);
I hope this will help u out. All the best.          
0
 
vabdussamadAuthor Commented:
pbhaq, I think you have given a program which starts its control from java rather than C++. What i mean to say is i want to call java mathod from C++ and not from java to C++. If what you have given is correct then i would say this was not where i faced problem. I faced problem in loading the virtual machine before i could call any JAVA method. The program which i tried was.


#include <jni.h>

JavaVM *jvm;
JNIEnv *env;
JDK1_1InitArgs vm_args;
int verbose = 1;

main(int argc, char **argv )
{
      jclass cls;
      jmethodID mid;
      jthrowable jthr;

      vm_args.version = 0x00010002;
      /* Set up the environment */
      JNI_GetDefaultJavaVMInitArgs ( &vm_args );

      vm_args.classpath = "c:\\samples\\InstantiatedFromC.class;.";

      JNI_CreateJavaVM(&jvm, &env, &vm_args );
      
      /* Find the class we want to load */
      cls = (*env)->FindClass( env, "InstantiatedFromC" );

      if ( cls != (jclass)0 )
      {
            /* Find the method we want to use */
            mid = (*env)->GetMethodID( env, cls, "test", "(I)I" );
            /* Call the method we want to use */
            printf("First call to Java returns:%d\n",             (*env)->CallStaticIntMethod(env, cls, mid, 1) );
            /* Check for an exception */
            if ( hasExceptionOccurred ( env ) != (char *)0 )
            {
                  printf("Exception has occurred.\n");
            }

      }
}

The Java method i tried to call is shown below.

public class InstantiatedFromC
{
      public int test(int number) throws Exception
      {
            System.out.println("Number from C: " + number);
                if ( number == 2 )
                        throw new Exception("Exception raised in Java                   seen in C");
                      return ( number + 1 );
        }
}


Here,

      JNI_GetDefaultJavaVMInitArgs ( &vm_args );
this function returns 0 means success.But

      JNI_CreateJavaVM(&jvm, &env, &vm_args );

returns -1. I want to know why it fails.

is the setting of classpath correct(      vm_args.classpath = "c:\\samples\\InstantiatedFromC.class;.";
)
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now