Name: krT82822 Date: 01/27/2000
java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)
The source code is just one CPP file, a simplified version of a Win32 app we
are develping that uses our existing JNDI code (The screen output follows the
source code):
#include <windows.h>
#include <jni.h>
#include <process.h>
#include <stdio.h>
JavaVM *jvm;
/*
* Function GetJNIEnv(void) returns the java environment pointer
* in case we are executing on a thread other than the one the
* jvm was created on.
*/
JNIEnv* GetJNIEnv(void){
JNIEnv *env = NULL;
jint nRet = jvm->GetEnv((void **)&env, JNI_VERSION_1_2);
if(nRet == JNI_EDETACHED){
jvm->AttachCurrentThread((void **)&env, NULL);
}
return env;
}
/*
* Function DoJNDI(void *arg) uses the Java Invocation API to
* execute the following Java code:
*
* Hashtable prop = new Hashtable();
* prop.put(
Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
* prop.put( Context.PROVIDER_URL, "ldap://nldap.com/??sub?" );
* ctxInitial = new InitialDirContext( prop );
*/
void DoJNDI(void *arg){
jclass clsHash, clsInitDirCx;
jmethodID mHashInit, mHashPut, mInitDirCxInit;
jobject objHash, objInitDirCx;
JNIEnv *env = GetJNIEnv(); // Get the environment if on a different
thread
clsHash = env->FindClass("java/util/Hashtable");
mHashInit = env->GetMethodID(clsHash, "<init>", "()V");
objHash = env->NewObject(clsHash, mHashInit);
mHashPut = env->GetMethodID
(clsHash, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
jstring jstrICxFactoryPut = env->NewStringUTF
("java.naming.factory.initial");
jstring jstrICxFactoryVal = env->NewStringUTF
("com.sun.jndi.ldap.LdapCtxFactory");
env->CallObjectMethod(objHash, mHashPut, jstrICxFactoryPut,
jstrICxFactoryVal);
jstring jstrProviderUrlPut = env->NewStringUTF
("java.naming.provider.url");
jstring jstrProviderUrlVal = env->NewStringUTF("ldap://nldap.com/??
sub?");
env->CallObjectMethod(objHash, mHashPut, jstrProviderUrlPut,
jstrProviderUrlVal);
clsInitDirCx = env->FindClass
("javax/naming/directory/InitialDirContext");
mInitDirCxInit = env->GetMethodID
(clsInitDirCx, "<init>", "(Ljava/util/Hashtable;)V");
objInitDirCx = env->NewObject(clsInitDirCx, mInitDirCxInit, objHash);
if(objInitDirCx == NULL){
printf("%s test FAILED:\n\n", (char*)arg);
}
else{
printf("%s test PASSED\n\n", (char*)arg);
}
jvm->DetachCurrentThread();
}
/*
* Function main(void) creates a JVM, and calls DoJNDI twice:
* Once as a regular function call, and once as a spun off thread.
*/
void main() {
JavaVMInitArgs vm_args;
JavaVMOption options[2]; //[3]; /* Use 3 for verbose jni messages */
options[0].optionString = "-Djava.compiler=NONE"; /* disable JIT */
options[1].optionString = "-Djava.class.path=F:\\jdk1.2.2
\\jre\\lib\\jaas.jar;F:\\jdk1.2.2\\jre\\lib\\ldapbp.jar;F:\\jdk1.2.2
\\jre\\lib\\ldap.jar;F:\\jdk1.2.2\\jre\\lib\\providerutil.jar;F:\\jdk1.2.2
\\jre\\lib\\jndi.jar"; /* user classes */
//options[2].optionString = "-verbose:jni"; /* Uncomment for verbose
jni messages */3;
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 2; //3; /* Use 3 for verbose jni messages *
vm_args.ignoreUnrecognized = TRUE;
JNIEnv *env;
jint res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
// *** Make the magic calls! (Both lines should do the same thing) ***
DoJNDI((void*)"Function call");
_beginthread(DoJNDI,0,(void *)"Thread call");
/* wait for thread(s) to finish */
Sleep(5000);
jvm->DestroyJavaVM();
}
**************** Screen Output ******************************
Function call test PASSED
Thread call test FAILED:
javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.jndi.l
dap.LdapCtxFactory. Root exception is java.lang.ClassNotFoundException: com/sun
/jndi/ldap/LdapCtxFactory
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:199)
at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.jav
a:49)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:6
60)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:250
)
at javax.naming.InitialContext.init(InitialContext.java:226)
at javax.naming.InitialContext.<init>(InitialContext.java:202)
at javax.naming.directory.InitialDirContext.<init>(InitialDirContext.jav
a:87)
Press any key to continue
-----------------------
1/27/2000 eval1127@eng -- in reply to our asking whether this was just a CLASSPATH problem (jndi.jar had been put in jre\lib vs. jre\lib\ext), user noted:
I put the files in the jre\lib\ext directory (I originally had them in jre\lib),
and I set my classpath accordingly (options[1].optionString =
"-Djava.class.path=F:\\jdk1.2.2\\jre\\lib\\ext\\ldap.jar;F:\\jdk1.
2.2\\jre\\lib\\ext\\jndi.jar";)
... and I still get the same results. I would imagine that if the classpath
was a problem, both tests would fail. But in this case, the non-threaded
test passes, and the spun-off thread fails, both using the same JVM handle.
Thanks for you response,
James Albright
(Review ID: 100392)
======================================================================
- relates to
-
JDK-6414270 Issue of a critical JDK/JNI related issue in customer product
-
- Closed
-