-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
1.1, 1.1.4, 1.1.5, 1.1.6, 1.2.0
-
sparc
-
solaris_2.4
Name: akC45999 Date: 03/25/98
The following test shows that JVM cannot link native methods to classes
loaded with user-defined classloader.
As a result, all our Java Native Interface tests and
some other VM test fail in same-jvm mode.
To run the test, copy following 4 files in a working directory,
edit shell-script runtest to reflect actial path to your installation of JCK
(used only to find include files) and run the script.
The script compiles c and java files, runs the test with
default classloader to verify installation, and runs the
test via user-defined classloader.
============================================================ gver00101.c
/* File: @(#)gver00101.c 1.2 97/01/27
Copyright 01/27/97 Sun Microsystems, Inc. All Rights Reserved
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "jckjni.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
#ifndef JNI_ENV_ARG1
#define JNI_ENV_ARG1(x)
#define JNI_ENV_PTR(x) x
#endif
#else
#ifndef JNI_ENV_ARG1
#define JNI_ENV_ARG1(x) x
#define JNI_ENV_PTR(x) (*x)
#endif
#endif
JNIEXPORT jboolean JNICALL
/*Java_javasoft_sqe_tests_vm_gver001_gver00101_gver00101_gver00101nm*/
Java_gver00101_gver00101nm
(JNIEnv *env,jobject obj,
jint val)
{
jint res_val;
res_val = JNI_ENV_PTR(env) -> GetVersion(JNI_ENV_ARG1(env));
return !(res_val==val);
}
#ifdef __cplusplus
}
#endif
============================================================ gver00101.java
//File: @(#)gver00101.java 1.3 97/08/25
//Copyright 08/25/97 Sun Microsystems, Inc. All Rights Reserved
//package javasoft.sqe.tests.vm.gver001.gver00101;
import java.io.PrintStream;
public class gver00101 {
private static boolean res = false;
public static void main(String argv[])
{
System.exit(run(argv, System.out) + 95/*STATUS_TEMP*/);
}
public native boolean gver00101nm(int val);
static {
try {
loadLib("gver00101");
} catch ( UnsatisfiedLinkError e ) {
System.out.println("gver00101.static:"+e);
}
}
private static void check( gver00101 tob, int val) {
try {
boolean res= tob.gver00101nm(val);
System.out.println("res="+res);
} catch (Throwable e) {
res = true;
System.out.println("Exception caught: "+e);
}
}
static void loadLib( String libName ) {
SecurityManager mgr = System.getSecurityManager();
boolean canLoad = true;
linkStatus=2/*STATUS_FAILED*/;
if( mgr != null ) {
try {
mgr.checkLink( libName );
} catch (SecurityException e) {
canLoad = false;
}
}
try {
System.loadLibrary( libName );
if (canLoad) {
cannotBeRun = null;
} else {
cannotBeRun = "Incorrectly loaded library: " + libName;
}
} catch (SecurityException e) {
if (!canLoad) {
linkStatus = 0/*STATUS_PASSED*/;
cannotBeRun = "Correctly prevented loadLibrary: " + libName;
} else {
cannotBeRun = "Incorrectly prevented loadLibrary: " + libName;
}
} catch (UnsatisfiedLinkError e) {
cannotBeRun = "Cannot find library: " + libName;
throw e;
}
}
static String cannotBeRun;
static int linkStatus;
public static int run(String argv[], PrintStream out) {
if (cannotBeRun!=null) {
out.println(cannotBeRun);
return linkStatus;
}
gver00101 tob = new gver00101();
int valVer = 0x00010001;
check( tob, valVer );
if (res)
return 2/*STATUS_FAILED*/;
return 0/*STATUS_PASSED*/;
}
}
============================================================ TestWrapper.java
import java.io.*;
import java.lang.reflect.*;
class TestWrapper extends ClassLoader {
File store;
TestWrapper(File store) {
this.store=store;
}
void debug(String msg) {
// System.out.println(msg);
}
byte readClass(String className)[] {
byte result[];
try {
FileInputStream fi
= new FileInputStream(new File(store, className+".class"));
result = new byte[fi.available()];
fi.read(result);
debug(" >> readClass("+className+") OK");
return result;
} catch (Exception e) {
debug(" >> readClass("+className+"):"+e);
return null;
}
}
public Class loadClass(String className, boolean resolve) throws
ClassNotFoundException {
Class result;
byte classData[];
debug("> Load class : "+className);
/* Try to load it from our repository */
classData = readClass(className);
if (classData == null) {
/* Check with the primordial class loader */
result = super.findSystemClass(className);
debug(" >> returning class in CLASSPATH.:"+result);
return result;
}
/* Define it (parse the class file) */
result = defineClass(classData, 0, classData.length);
if (result == null) {
throw new ClassFormatError();
}
debug(" >> Returning newly loaded class:"+className);
return result;
}
public static void runClass(Class executeClass) {
PrintStream out=System.out;
Class[] argTypes = {String[].class, PrintStream.class};
Method runMethod = null;
try {
runMethod = executeClass.getDeclaredMethod("run", argTypes);
} catch (SecurityException e) {
out.println("While looking for run() method in the test class " +
executeClass + "\nSecurityException arose: " + e);
return;
} catch (NoSuchMethodError e) {
out.println("run() not found in the test class " + executeClass);
return;
} catch (NoSuchMethodException e) {
out.println("run() not found in the test class " + executeClass);
return;
} catch (Throwable e) {
out.println("Unexpected exception on executeClass.getDeclaredMethod()
invocation: " + e);
return;
}
Object[] args={null, out};
try {
Integer result = (Integer)runMethod.invoke(null, args);
out.println("TestWrapper.runClass: result=" + result.intValue());
} catch (ClassCastException e) {
out.println("run() must return an int value in the test class " +
executeClass);
} catch (NullPointerException e) {
out.println("run() must be static in the test class " + executeClass);
} catch (IllegalAccessException e) {
out.println("run() is not accessible in the test class " + executeClass);
} catch (InvocationTargetException e) {
Throwable ee = e.getTargetException();
out.println("TestWrapper.runClass:runtime exception: " + ee);
} catch (Throwable e) {
out.println("Unexpected exception on runMethod.invoke() invocation: " +
e);
}
}
public static void test(String argv[]) {
System.out.println("========TestWrapper.test("+argv[0]+ ","+argv[1]+")");
File store=new File(argv[0]);
TestWrapper sc = new TestWrapper(store);
Class executeClass;
try {
executeClass=sc.loadClass(argv[1]);
} catch (Throwable e) {
System.out.println("TestWrapper.loadClass:"+e);
return;
}
runClass(executeClass);
}
public static void main(String argv[]) {
test(argv);
test(argv);
test(argv);
}
}
========================================================== runtest
#!/bin/sh
rm -rf *.so *class store
#CC=/export/ld4/set/dist/sparc-S2/SC4.2/bin/cc
CC=cc
# set JCK to the path to your JCK workspace
JCK=/export/ld21/java/sqe/jck116/jck11-nsk/port
cmd="$CC -KPIC -G -o libgver00101.so -I$JCK/tests/vm/jni/include
-I$JCK/tests/vm/jni/include/solaris -I/include -I/include/solaris gver00101.c"
echo $cmd; eval $cmd
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
CLASSPATH=store
export LD_LIBRARY_PATH CLASSPATH
mkdir store
cmd="javac TestWrapper.java"
echo $cmd; eval $cmd
cmd="javac -d store gver00101.java"
echo $cmd; eval $cmd
java gver00101
CLASSPATH=.
export CLASSPATH
cmd="java TestWrapper store gver00101"
echo $cmd; eval $cmd
============================================================
when run under jdk1.1.x, test throws UnsatisfiedLinkError each time
it is run:
novo64% runtest
cc -KPIC -G -o libgver00101.so
-I/export/ld21/java/sqe/jck116/jck11-nsk/port/tests/vm/jni/include
-I/export/ld21/java/sqe/jck116/jck11-nsk/port/tests/vm/jni/include/solaris
-I/include -I/include/solaris gver00101.c javac TestWrapper.java
Note: TestWrapper.java uses a deprecated API. Recompile with "-deprecation"
for details. 1 warning
javac -d store gver00101.java
res=false
java TestWrapper store gver00101
========TestWrapper.test(store, gver00101)
Exception caught: java.lang.UnsatisfiedLinkError: gver00101nm
TestWrapper.runClass: result=2
========TestWrapper.test(store, gver00101)
Exception caught: java.lang.UnsatisfiedLinkError: gver00101nm
TestWrapper.runClass: result=2
========TestWrapper.test(store, gver00101)
Exception caught: java.lang.UnsatisfiedLinkError: gver00101nm
TestWrapper.runClass: result=2
when run under jdk1.2 (including the latest current release 12beta3N),
test passes first time but throws UnsatisfiedLinkError
for consequent calls of TestWrapper.test() method:
novo64% jdk12
novo64% runtest
cc -KPIC -G -o libgver00101.so
-I/export/ld21/java/sqe/jck116/jck11-nsk/port/tests/vm/jni/include
-I/export/ld21/java/sqe/jck116/jck11-nsk/port/tests/vm/jni/include/solaris
-I/include -I/include/solaris gver00101.c javac TestWrapper.java
Note: TestWrapper.java uses or overrides a deprecated API. Recompile with
"-deprecation" for details. 1 warning
javac -d store gver00101.java
res=true
java TestWrapper store gver00101
========TestWrapper.test(store, gver00101)
res=true
TestWrapper.runClass: result=0
========TestWrapper.test(store, gver00101)
gver00101.static:java.lang.UnsatisfiedLinkError: Native Library
/export/home/rfq/ws/bugexamples/NewFolder.2/libgver00101.so already loaded in
another classloader Cannot find library: gver00101
TestWrapper.runClass: result=2
========TestWrapper.test(store, gver00101)
gver00101.static:java.lang.UnsatisfiedLinkError: Native Library
/export/home/rfq/ws/bugexamples/NewFolder.2/libgver00101.so already loaded in
another classloader Cannot find library: gver00101
TestWrapper.runClass: result=2
novo64%
======================================================================
- duplicates
-
JDK-4052610 A class that is loaded by a non-default ClassLoader cannot link to its native me
- Closed