[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1049
  • Last Modified:

URGENT JNI ERRROR : Could not load type _jmethodID from assembly

Hey,
     Im writing a VC++ program that creates a JVM and then finds a class "Send.java" of mine successfully.
     However when I invoke the following line, to call a function serve in that class:
          env->GetMethodID(cls, "serve", "()V");

     Everything stops running, and the error above is thrown
    (The program does not even start!)

    What could be causing this?
    The defn for it should be in the jni.h header

(Do I nead a Send.h file as an interface? )
0
AruneshGupta
Asked:
AruneshGupta
  • 19
  • 17
  • 4
  • +1
1 Solution
 
CEHJCommented:
Please post more code before and after
0
 
CEHJCommented:
>>and then finds a class "Send.java" of mine successfully.

That is not a class btw, it's a source file. Make sure 'cls' is a valid variable
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
AruneshGuptaAuthor Commented:

Please help me  - Im stuck and this is really important =/ .

The simple VC test program is as follows:

// This is the main project file for VC++ application project
// generated using an Application Wizard.
#define _WIN32_WINNT 0x0400
#define _MT

#include "stdafx.h"
#include <jni.h>
#include "RecvdSAS.h"

#using <mscorlib.dll>

using namespace System;
JavaVM *jvm = NULL;
jclass cls = 0;
JNIEnv *env = NULL;
jmethodID waitSAS = 0;

int _tmain()
{

      Console::WriteLine(S"C_Initialize");      

      JavaVMInitArgs vm_args;
      JavaVMOption options[3];

      // Initialize jvm
      vm_args.version = JNI_VERSION_1_4;

      JNI_GetDefaultJavaVMInitArgs(&vm_args);

      char *classPath = "-Djava.class.path=C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio Projects\\jvmtest]";
      options[0].optionString = classPath;
      vm_args.options = options;
      vm_args.nOptions = 1;

      // Create JVM
      jint res;
      res = JNI_CreateJavaVM(&jvm,(void **)&env,&vm_args);
      if (res < 0)
      {
            Console::WriteLine(S"Couldnt create Java VM");
      }
      else
          Console::WriteLine(S"Java VM created");

      // Find the class
      char *clsName = "RecvdSAS";
      cls = env->FindClass(clsName);
      if (cls == 0)
      {
            Console::WriteLine(S"***************************Couldnt find classes");
      }
      else
            Console::WriteLine(S"DEBUG: Found class");

      waitSAS = env->GetStaticMethodID(cls, "serve", "()V");

      if (waitSAS == 0)
            Console::WriteLine(S"DEBUG: waitSAS is 0");
      else
           env->CallStaticVoidMethod(cls, waitSAS);
      
    Console::WriteLine(S"Hello World");
      return 0;
}


There exists a file RecvdSAS.java in the same directory with a static void method serve that takes in no paremeteres
I have compiled this file using javac
And used javah RecvdSAS to generate the header file RecvdSAS.h included at the top
0
 
AruneshGuptaAuthor Commented:

If I remove the line:
waitSAS = env->GetStaticMethodID(cls, "serve", "()V");

The JVM and class are created, and I get DEBUG:waitSAS as expected

Once I put in the line,
my program does not even start to execute
throwing an error -  Could not load type _jmethodID from assembly
(where is the struct jmethodID defined anyway)
0
 
objectsCommented:
can u post your java code.
0
 
AruneshGuptaAuthor Commented:
The Java file RecvdSAS.java is :

import java.net.*;
import java.io.*;
import java.util.*;

public class RecvdSAS
{
   

   public static void serve()
    {
        ServerSocket s = (ServerSocket) null;
        Socket s1;
        int port = 4422;

              //make socket
        try
            {
                System.out.println("Connecting on " + port);
                s = new ServerSocket(port);
            }
        catch(Exception e)
            {
                System.out.println(e.toString() + "Socket in Use " + port);
            }
       
        //accept client connections        
         while (true)
            {
                try
                    {
                  String   inputLine;  

                  s1 = s.accept();
                  BufferedReader in = new BufferedReader(new InputStreamReader(s1.getInputStream()));
                         inputLine = in.readLine();
                           
                  if ( inputLine.equals("SAS") )
                      {
                        s1.close();
                        return;
                      }

                    s1.close();
            }
                catch (Exception e){}
      }
     }

}

//waits on port 4422, returns if SAS else loops



The machine generated RecvdSAS.h:
by, javah RecvdSAS
is:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class RecvdSAS */

#ifndef _Included_RecvdSAS
#define _Included_RecvdSAS
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
0
 
AruneshGuptaAuthor Commented:
what am i forgetting to do or doing wrong?
is there some lib apart from jvm.lib that I need to link to?
Any DLL's that need to be in my shystem path?
Is getting a method ID supposed to be done in a different way in c++ ?
0
 
objectsCommented:
try defining the following in any source file:
struct _jmethodID {

};

0
 
AruneshGuptaAuthor Commented:

With that added to my main testvjm.cpp source file :

The code now compiled nd runs ,

however after the line:

waitSAS according to the debugger has an undefined value and the program dies in the if (waitSAS==0) check

If I try and invoke the method anyway without the check I get the following error
'An unhandled exception of type 'System.NullReferenceException' occurred in jvmtest].exe'

Do I have to typedef the struct as something else?

Please figure this out =) - Im so close to getting my own GINA.dll that logs users into XP using a cellphone with bluetooth working
and this is my only error!


0
 
objectsCommented:
as an experiment perhaps try a different compiler if you have one handy
0
 
AruneshGuptaAuthor Commented:
im using VS.net 2003 to compile this - how else can I compile?
0
 
objectsCommented:
Yes thought thats what you might be using.
don't worry if you don't have another compiler available
0
 
AruneshGuptaAuthor Commented:
ok - any guess as o what might be the problem??
is the opaque struct _jmethoID VM specific - and supposed to be declared in one of those files? and maybe a non-empty strcut

or do u think im building wrong or not incluing some file?
0
 
objectsCommented:
can you run javap on your class just to be sure the signature is ok.
0
 
AruneshGuptaAuthor Commented:
yup, did javap -s -p RecvdSAS

C:\Documents and Settings\Administrator\My Documents\Visual Studio Projects\jvmt
est]>javap -s -p RecvdSAS
Compiled from "RecvdSAS.java"
public class RecvdSAS extends java.lang.Object{
public RecvdSAS();
  Signature: ()V
public void serve();
  Signature: ()V
}

So thats not the problem right?
and anyway - this problem occurs before it hits this line and tries to load the function right?
its as though the return value type is missing or something, and once u add the line that type must exist?
0
 
objectsCommented:
> public void serve();
>  Signature: ()V


That says that serve() is not ststic but the code you posted above declares it as static.
Try recompiling to ensure you have the latest.
0
 
AruneshGuptaAuthor Commented:
Ok :

C:\Documents and Settings\Administrator\My Documents\Visual Studio Projects\jvmt
est]>javap -s -p RecvdSAS
Compiled from "RecvdSAS.java"
public class RecvdSAS extends java.lang.Object{
public RecvdSAS();
  Signature: ()V
public static void serve();
  Signature: ()V
}

And yea - If i set clsname =" java/lang/String"
And try waitSAS = env->GetStaticMethodID(cls, "valueOf", "(I)Ljava/lang/String");
with the 'javah java.lang.String' result java_lang_String included
I get the same error

So the problem is either in building or the C++ file and nothing to do witht the java file i believe
0
 
objectsCommented:
> I get the same error

what error are u referring to here?
0
 
AruneshGuptaAuthor Commented:

Any clue what sort of thing it could be?

Some lib/dll needed ?

some VM specific file line win32/jni_md.h included by jni.h supposed to declare something?
0
 
objectsCommented:
possibly a bug with your compiler.
the original error is certainly a bug.
0
 
AruneshGuptaAuthor Commented:
It throws :

An unhandled exception of type 'System.TypeLoadException' occurred in Unknown Module.

Additional information: Could not load type _jmethodID from assembly jvmtest], Version=1.0.1565.5523, Culture=neutral, PublicKeyToken=null.

Without running any of my code.

(And it breaks in mlock.c a function called unlock)
0
 
AruneshGuptaAuthor Commented:

How can I get around this ?
0
 
objectsCommented:
Trying another (non .net) compiler would be worth a try.
http://www.cygwin.com/
0
 
AruneshGuptaAuthor Commented:
After Ive installed cygwin

What c++ compiler do I download to Install ?

And then do I list all the .h include directories with the -I flag

And all the runtime lib files when i link?
0
 
objectsCommented:
from memory cygwin should include gcc
0
 
AruneshGuptaAuthor Commented:
it doesnt seem so
it doesnt recognise gcc
0
 
WebstormCommented:
Look at the following link : the code sample call a static method :

http://java.sun.com/j2se/1.3/docs/guide/jni/spec/invocation.doc.html#15926

Table of content is : http://java.sun.com/j2se/1.3/docs/guide/jni/spec/jniTOC.doc.html
0
 
objectsCommented:
http://www.mingw.org/ is another place to look
(sorry it's been a while since I used non-MS compilers with windows).

You would happen to have a non .net version of VS would u?
0
 
AruneshGuptaAuthor Commented:
nope =(
0
 
objectsCommented:
0
 
AruneshGuptaAuthor Commented:
The first example goes the other way, calls C from Java

Whast the easiest way to compile this? Any obvious checks I should be doing to fix this in VS.net?

If u think its seriously a compiler bug
I can build it on my colleges linux environment,
what is the syntax for that?

gcc myProg.c -MT -lpthread ...?

like '-L libjava.so' returns undefined references to me
0
 
CEHJCommented:
Try calling the method like this:

waitSAS = (*env)->GetStaticMethodID(env, cls, "serve", "()V");
0
 
AruneshGuptaAuthor Commented:
thats the C style convention, not C++
0
 
CEHJCommented:
Yes i know. Can you summarize where you are now in this long thread?
0
 
objectsCommented:
how did you go compiling it under linux?
0
 
objectsCommented:
> it doesnt seem so
> it doesnt recognise gcc

could just be because you haven't added the relevent directory to your PATH.

if not, try getting it here:
http://www.xraylith.wisc.edu/~khan/software/gnu-win32/gcc.html
0
 
objectsCommented:
0
 
AruneshGuptaAuthor Commented:

Hey you were right - The program compiles and works fine under linux.

However I need to build a Windows login DLL, and to do so w/o VS.net would be extremely hard,
So before I finally close this thread

1) any final guesses as to what the problem might be? a VS.net compiler bug, or some setting on my part?

2) Would it be easy for me to download the Windows API headers and build my windows XP login DLL on linux?
If yes then how?
0
 
objectsCommented:
1) a VS.net compiler bug

2) did u try with gcc? alternatively get a hold of 'standard' VS compiler.
0
 
AruneshGuptaAuthor Commented:


yup even VS worked

now need to get myself a copy-  even tho only .Net sells at stores
0
 
objectsCommented:
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 19
  • 17
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now