This is the mail archive of the java-discuss@sources.redhat.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Does jni work?


Hi Tom!

I tried your patch, but it didn't work.

I debugged a while and came up with the appended patch (only the patch to
URLClassLoader.java has been added, your's is unchanged).

Without this change, we will try to load 'java/io/PrintStream' but defineClass
wants 'java.io.PrintStream'.

After this patch, i came a bit further but got stuck in this:
./sample
Hello, Java
from C
java/lang/System::out lookup failed
Exception in thread "main" java.lang.NoSuchFieldError
   at 0x4019664a: java::lang::Throwable::Throwable() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4018ac6d: java::lang::Error::Error() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4018cdbd: java::lang::LinkageError::LinkageError() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4018bb7d: java::lang::IncompatibleClassChangeError::IncompatibleClassChangeError() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4018e57d: java::lang::NoSuchFieldError::NoSuchFieldError() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4016409f: _Jv_GetJavaVM() (/sw/snapshots/lib/libgcj.so.1)
   at 0x403f8881: Java_sample_myNative (./libsamplenat.so)
   at 0x0804bc20: sample::myNative(java::lang::String*) (/home/kahlert/LOCAL/Hello/sample.java:2)
   at 0x0804bd8b: sample::main(JArray<java::lang::String*>*) (/home/kahlert/LOCAL/Hello/sample.java:12)
   at 0x40173cab: gnu::gcj::runtime::FirstThread::run() (/sw/snapshots/lib/libgcj.so.1)
   at 0x4017e87b: java::lang::Thread::run_(java::lang::Object*) (/sw/snapshots/lib/libgcj.so.1)
   at 0x4028c5e5: _Jv_ThreadSetPriority(_Jv_Thread_t*, int) (/sw/snapshots/lib/libgcj.so.1)
   at 0x4042b6cc: GC_start_routine (/sw/snapshots/lib/libgcjgc.so.1)
   at 0x40443e93: pthread_detach (/lib/libpthread.so.0)
   at 0x4050365a: __clone (/lib/libc.so.6)

I inserted print statements into jni.cc (_Jv_GetJavaVM) but it seems, that
this function isn't even called. So perhaps the stack trace is misleading.

How is the JNI mechanism supposed to work? Where is GetStaticFieldID implemented?

Thanks for all your help,
Martin.

I compile using: 
gcj -C sample.java 
gcjh -jni sample
gcc -shared -fPIC -o libsamplenat.so sampNat.c
gcj -fjni -o sample --main=sample sample.java
./sample

The (hopefully corrected) sources are attached.


diff -Nrc3p gcc-20010122.orig/libjava/java/net/URLClassLoader.java gcc-20010122/libjava/java/net/URLClassLoader.java
*** gcc-20010122.orig/libjava/java/net/URLClassLoader.java	Sun Nov 26 04:58:56 2000
--- gcc-20010122/libjava/java/net/URLClassLoader.java	Fri Jan 26 12:45:54 2001
*************** public class URLClassLoader extends Clas
*** 247,253 ****
  	    off += c;
  	  }
  
! 	return defineClass (name, data, 0, len);
        } 
      catch (java.io.IOException x)
        {
--- 247,253 ----
  	    off += c;
  	  }
  
!         return defineClass (name.replace ('/', '.'), data, 0, len);
        } 
      catch (java.io.IOException x)
        {
diff -Nrc3p gcc-20010122.orig/libjava/jni.cc gcc-20010122/libjava/jni.cc
*** gcc-20010122.orig/libjava/jni.cc	Wed Nov  1 01:18:03 2000
--- gcc-20010122/libjava/jni.cc	Fri Jan 26 12:41:58 2001
***************
*** 1,6 ****
  // jni.cc - JNI implementation, including the jump table.
  
! /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
  
     This file is part of libgcj.
  
--- 1,6 ----
  // jni.cc - JNI implementation, including the jump table.
  
! /* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
  
     This file is part of libgcj.
  
*************** _Jv_JNI_GetAnyFieldID (JNIEnv *env, jcla
*** 1053,1066 ****
  
        _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
  
!       jclass field_class = NULL;
!       if (sig[0] == '[')
! 	field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
!       else
! 	{
! 	  _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
! 	  field_class = _Jv_FindClass (sig_u, NULL);
! 	}
  
        // FIXME: what if field_class == NULL?
  
--- 1053,1059 ----
  
        _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
  
!       jclass field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
  
        // FIXME: what if field_class == NULL?
  

-- 
The early bird gets the worm. If you want something else for       
breakfast, get up later.
#include <jni.h>
#include "sample.h"
#include <stdio.h>

void Java_sample_myNative(JNIEnv* env, jobject this, jstring s)
{
  jclass cls;
  jfieldID fid;
  jobject obj;
  jmethodID mid;

  printf("from C\n");

  cls = (*env)->FindClass(env, "java/lang/System");
  if (cls == 0) {
    printf("java/lang/System lookup failed\n");
    return;
  }
  fid = (*env)->GetStaticFieldID(env, cls, "out", "Ljava/io/PrintStream;");
  if (fid == 0) {
    printf("java/lang/System::out lookup failed\n");
    return;
  }
  obj = (*env)->GetStaticObjectField(env, cls, fid);
  if (obj == 0) {
    printf("GetStaticObjectField call failed\n");
    return;
  }
  cls = (*env)->GetObjectClass(env, obj);
  if (cls == 0) {
    printf("GetObjectClass(out) failed\n");
    return;
  }
  mid = (*env)->GetMethodID(env, cls, "println", "(Ljava/lang/String;)V");
  if (mid == 0) {
    printf("println method lookup failed\n");
    return;
  }
  (*env)->CallVoidMethod(env, obj, mid, s);
}

public class sample {
  public native void myNative(String s);

  public void myJava(String s) {
    s = s + ", Java";
    System.out.println(s);
  }

  public static void main(String args[]) {
    sample x = new sample();
    x.myJava("Hello");
    x.myNative("Hello, Java (from C)");
    x.myJava("Goodbye");
  }
  
  static {
    System.loadLibrary("samplenat");
  }
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]