Solved

URGENT JNI ERRROR : Could not load type _jmethodID from assembly

Posted on 2004-04-13
42
1,024 Views
Last Modified: 2013-11-23
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
Comment
Question by:AruneshGupta
  • 19
  • 17
  • 4
  • +1
42 Comments
 
LVL 13

Expert Comment

by:Webstorm
ID: 10813070
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10813517
Please post more code before and after
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10813549
>>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
 

Author Comment

by:AruneshGupta
ID: 10820548

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
 

Author Comment

by:AruneshGupta
ID: 10820567

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
 
LVL 92

Expert Comment

by:objects
ID: 10820632
can u post your java code.
0
 

Author Comment

by:AruneshGupta
ID: 10820641
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
 

Author Comment

by:AruneshGupta
ID: 10820808
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
 
LVL 92

Expert Comment

by:objects
ID: 10820828
try defining the following in any source file:
struct _jmethodID {

};

0
 

Author Comment

by:AruneshGupta
ID: 10820904

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
 
LVL 92

Expert Comment

by:objects
ID: 10820948
as an experiment perhaps try a different compiler if you have one handy
0
 

Author Comment

by:AruneshGupta
ID: 10820957
im using VS.net 2003 to compile this - how else can I compile?
0
 
LVL 92

Expert Comment

by:objects
ID: 10820992
Yes thought thats what you might be using.
don't worry if you don't have another compiler available
0
 

Author Comment

by:AruneshGupta
ID: 10821014
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
 
LVL 92

Expert Comment

by:objects
ID: 10821041
can you run javap on your class just to be sure the signature is ok.
0
 

Author Comment

by:AruneshGupta
ID: 10821056
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
 
LVL 92

Expert Comment

by:objects
ID: 10821067
> 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
 

Author Comment

by:AruneshGupta
ID: 10821156
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
 
LVL 92

Expert Comment

by:objects
ID: 10821244
> I get the same error

what error are u referring to here?
0
 

Author Comment

by:AruneshGupta
ID: 10821249

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
 
LVL 92

Expert Comment

by:objects
ID: 10821256
possibly a bug with your compiler.
the original error is certainly a bug.
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:AruneshGupta
ID: 10821262
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
 

Author Comment

by:AruneshGupta
ID: 10821276

How can I get around this ?
0
 
LVL 92

Expert Comment

by:objects
ID: 10821331
Trying another (non .net) compiler would be worth a try.
http://www.cygwin.com/
0
 

Author Comment

by:AruneshGupta
ID: 10821519
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
 
LVL 92

Expert Comment

by:objects
ID: 10821542
from memory cygwin should include gcc
0
 

Author Comment

by:AruneshGupta
ID: 10821546
it doesnt seem so
it doesnt recognise gcc
0
 
LVL 13

Expert Comment

by:Webstorm
ID: 10821553
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
 
LVL 92

Expert Comment

by:objects
ID: 10821582
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
 

Author Comment

by:AruneshGupta
ID: 10821593
nope =(
0
 
LVL 92

Expert Comment

by:objects
ID: 10821622
0
 

Author Comment

by:AruneshGupta
ID: 10822170
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
 
LVL 86

Expert Comment

by:CEHJ
ID: 10822289
Try calling the method like this:

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

Author Comment

by:AruneshGupta
ID: 10822758
thats the C style convention, not C++
0
 
LVL 86

Expert Comment

by:CEHJ
ID: 10822839
Yes i know. Can you summarize where you are now in this long thread?
0
 
LVL 92

Expert Comment

by:objects
ID: 10830601
how did you go compiling it under linux?
0
 
LVL 92

Expert Comment

by:objects
ID: 10830670
> 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
 
LVL 92

Expert Comment

by:objects
ID: 10830689
0
 

Author Comment

by:AruneshGupta
ID: 10832120

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
 
LVL 92

Accepted Solution

by:
objects earned 500 total points
ID: 10837910
1) a VS.net compiler bug

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

Author Comment

by:AruneshGupta
ID: 10848140


yup even VS worked

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

Expert Comment

by:objects
ID: 10848177
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now