Subject: JNI multiple String problem
From: Nicholas Burton <[email-masked]>
To: [email-masked]
Date: Wed, 12 Mar 2003 10:44:23 +0000

Hi

I am having a problem with java native interface under Cygwin that I
don't have under solaris.
Briefly, I am trying to pass 2 strings (a filename and open mode) from
java
to C native code in order to open a file and process the contents.

I can pass 1 string and print it out with printf().
If I pass 2 strings, I can print them out then I get
EXCEPTION_ACCESS_VIOLATION.
I tried to get round this by passing in an array of 2 strings, however
I can print out the array length and the first string then I get a
similar exception to above.
(I need to use a jlong to index the array. If I use int or jint the
exception occurs after the array size has been printed out).

I have spent quite a lot of time searching google groups, cygwin mailing
list etc and have not found a solution.

I am using:
gcc version 3.2 20020927 (prerelease) that came with cygwin.
(I installed cygwin from the cygwin.exe file in January 2003)
Windows 2000
bash shell
I am compiling and running the prog. in the Cygwin window.

The java file is StringEx.java (shown below)
The C file is nativ.c (shown below)
The relevant command lines are ...

$ javac StringEx.java
$ javah StringEx
$ gcc -c nativ.c
$ gcc -shared -o cygnativ.dll nativ.o
(I also tried the more extensive syntax for creating a dll, as suggested
on Cygwin web-site, but with no difference)

Output when calling nativePrintString(str1)
---------------------------------------------------
$ java StringEx
first string

Output when calling nativePrint2Strings(str1, str2)
---------------------------------------------------
$ java StringEx
first string
second string

An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : EXCEPTION_ACCESS_VIOLATION occurred at PC=0x6FAA3
Function=[Unknown.]
Library=(N/A)

NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

Current Java thread:
        at StringEx.nativePrint2Strings(Native Method)
        at StringEx.callNative(StringEx.java:30)
        at StringEx.main(StringEx.java:36)

Dynamic libraries:
0x00400000 - 0x00406000        
c:\Progra~1\Java\j2sdk1.4.1_01\bin\java.exe
0x77F80000 - 0x77FFB000         C:\WINNT\System32\ntdll.dll
0x77DB0000 - 0x77E0D000         C:\WINNT\system32\ADVAPI32.dll
0x77E80000 - 0x77F36000         C:\WINNT\system32\KERNEL32.DLL
0x77D30000 - 0x77DA1000         C:\WINNT\system32\RPCRT4.DLL
0x78000000 - 0x78046000         C:\WINNT\system32\MSVCRT.dll
0x6D330000 - 0x6D45A000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\client\jvm.dll
0x77E10000 - 0x77E75000         C:\WINNT\system32\USER32.dll
0x77F40000 - 0x77F7C000         C:\WINNT\system32\GDI32.DLL
0x77570000 - 0x775A0000         C:\WINNT\System32\WINMM.dll
0x681A0000 - 0x681A7000         C:\WINNT\System32\serwvdrv.dll
0x66740000 - 0x66747000         C:\WINNT\System32\umdmxfrm.dll
0x6D1D0000 - 0x6D1D7000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\hpi.dll
0x6D300000 - 0x6D30D000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\verify.dll
0x6D210000 - 0x6D229000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\java.dll
0x6D320000 - 0x6D32D000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\zip.dll
0x10000000 - 0x10009000        
C:\nickb\MouseAtlas\MyBuild\dll\jni\mailing\cygnativ.dll
0x61000000 - 0x6112B000         C:\cygwin\bin\cygwin1.dll
0x77920000 - 0x77943000         C:\WINNT\system32\imagehlp.dll
0x72A00000 - 0x72A2D000         C:\WINNT\system32\DBGHELP.dll
0x690A0000 - 0x690AB000         C:\WINNT\System32\PSAPI.DLL

Local Time = Tue Mar 11 15:52:17 2003
Elapsed Time = 0
#
# The exception above was detected in native code outside the VM
#
# Java VM: Java HotSpot(TM) Client VM (1.4.1_01-b01 mixed mode)
#
# An error report file has been saved as hs_err_pid416.log.
# Please refer to the file for further information.
#

Output when calling nativePrintArray(strar)
-------------------------------------------
$ java StringEx
string array length = 2
string = first string

Unexpected Signal : EXCEPTION_ACCESS_VIOLATION occurred at PC=0x6D36DF50
Function=[Unknown.]
Library=c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\client\jvm.dll

NOTE: We are unable to locate the function name symbol for the error
      just occurred. Please refer to release documentation for possible
      reason and solutions.

Current Java thread:
        at StringEx.callNative(StringEx.java:31)
        at StringEx.main(StringEx.java:36)

Dynamic libraries:
0x00400000 - 0x00406000        
c:\Progra~1\Java\j2sdk1.4.1_01\bin\java.exe
0x77F80000 - 0x77FFB000         C:\WINNT\System32\ntdll.dll
0x77DB0000 - 0x77E0D000         C:\WINNT\system32\ADVAPI32.dll
0x77E80000 - 0x77F36000         C:\WINNT\system32\KERNEL32.DLL
0x77D30000 - 0x77DA1000         C:\WINNT\system32\RPCRT4.DLL
0x78000000 - 0x78046000         C:\WINNT\system32\MSVCRT.dll
0x6D330000 - 0x6D45A000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\client\jvm.dll
0x77E10000 - 0x77E75000         C:\WINNT\system32\USER32.dll
0x77F40000 - 0x77F7C000         C:\WINNT\system32\GDI32.DLL
0x77570000 - 0x775A0000         C:\WINNT\System32\WINMM.dll
0x681A0000 - 0x681A7000         C:\WINNT\System32\serwvdrv.dll
0x66740000 - 0x66747000         C:\WINNT\System32\umdmxfrm.dll
0x6D1D0000 - 0x6D1D7000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\hpi.dll
0x6D300000 - 0x6D30D000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\verify.dll
0x6D210000 - 0x6D229000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\java.dll
0x6D320000 - 0x6D32D000        
c:\Progra~1\Java\j2sdk1.4.1_01\jre\bin\zip.dll
0x10000000 - 0x10009000        
C:\nickb\MouseAtlas\MyBuild\dll\jni\mailing\cygnativ.dll
0x61000000 - 0x6112B000         C:\cygwin\bin\cygwin1.dll
0x77920000 - 0x77943000         C:\WINNT\system32\imagehlp.dll
0x72A00000 - 0x72A2D000         C:\WINNT\system32\DBGHELP.dll
0x690A0000 - 0x690AB000         C:\WINNT\System32\PSAPI.DLL

Local Time = Tue Mar 11 15:53:54 2003
Elapsed Time = 0
#
# HotSpot Virtual Machine Error : EXCEPTION_ACCESS_VIOLATION
# Error ID : 4F530E43505002E6
# Please report this error at
# http://java.sun.com/cgi-bin/bugreport.cgi
#
# Java VM: Java HotSpot(TM) Client VM (1.4.1_01-b01 mixed mode)
#
# An error report file has been saved as hs_err_pid868.log.
# Please refer to the file for further information.
#

listing for StringEx.java
-------------------------
// StringEx.java

import java.io.*;

public class StringEx {

   public native void nativePrintString(String str1);
   public native void nativePrint2Strings(String str1, String str2);
   public native void nativePrintArray(String[] arr);

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

   String str1 = "";
   String str2 = "";

   String[] strar = null;
   int[] ints = null;

   public StringEx() {
      str1 = new String("first string");
      str2 = new String("second string");

      strar = new String[2];
      strar[0] = str1;
      strar[1] = str2;
   }

   public void callNative() {
      nativePrintString(str1);
/*
      nativePrint2Strings(str1, str2);
      nativePrintArray(strar);
*/
   }

   public static void main(String[] args) {
      StringEx strex = new StringEx();
      strex.callNative();
   }
}listing for nativ.c
-------------------
/* nativ.c */

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include "StringEx.h"

JNIEXPORT void JNICALL
Java_StringEx_nativePrintString(JNIEnv *env,
                                jobject obj,
                                jstring str1) {

   const char *utf_string1;
   jboolean isCopy1;

   utf_string1 = (*env)->GetStringUTFChars(env, str1, &isCopy1);
   printf("%s\n", utf_string1);

   if(isCopy1 == JNI_TRUE) {
      (*env)->ReleaseStringUTFChars(env, str1, utf_string1);
   }

}

JNIEXPORT void JNICALL
Java_StringEx_nativePrint2Strings(JNIEnv *env,
                                jobject obj,
                                jstring str1,
                                jstring str2) {

   const char *utf_string1;
   const char *utf_string2;
   jboolean isCopy1;
   jboolean isCopy2;

   utf_string1 = (*env)->GetStringUTFChars(env, str1, &isCopy1);
   printf("%s\n", utf_string1);

   if(isCopy1 == JNI_TRUE) {
      (*env)->ReleaseStringUTFChars(env, str1, utf_string1);
   }

   utf_string2 = (*env)->GetStringUTFChars(env, str2, &isCopy2);
   printf("%s\n", utf_string2);

   if(isCopy2 == JNI_TRUE) {
      (*env)->ReleaseStringUTFChars(env, str2, utf_string2);
   }
}
JNIEXPORT void JNICALL
Java_StringEx_nativePrintArray(JNIEnv *env,
                                jobject obj,
                                jobjectArray arr) {

   const char * utf_string1;
   const char * utf_string2;
   jstring jstr1;
   jstring jstr2;
   jboolean isCopy1;
   jboolean isCopy2;
   jsize arrlen; 
   jlong i; 

   arrlen = (*env)->GetArrayLength(env, arr);
   printf("string array length = %d\n", arrlen);

   i = 0;
   jstr1 = (jstring)((*env)->GetObjectArrayElement(env, arr, i));
   utf_string1 = (*env)->GetStringUTFChars(env, jstr1, &isCopy1);
   printf("string = %s\n", utf_string1);

   if(isCopy1 == JNI_TRUE) {
      (*env)->ReleaseStringUTFChars(env, jstr1, utf_string1);
   }
   (*env)->DeleteLocalRef(env, jstr1);

   i = 1;
   jstr2 = (jstring)((*env)->GetObjectArrayElement(env, arr, i));
   utf_string2 = (*env)->GetStringUTFChars(env, jstr2, &isCopy2);
   printf("string = %s\n", utf_string2);

   if(isCopy2 == JNI_TRUE) {
      (*env)->ReleaseStringUTFChars(env, jstr2, utf_string2);
   }
   (*env)->DeleteLocalRef(env, jstr2);

   return;

}

-- 
Nick Burton
[email-masked]
----------------------

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/