java本身建议创建ClassLoader子类,并完成类似addURL方法已达到动态加载类路径。但在第三方包运行时,对方已经实现了ClassLoader子类且未提供此方法。则可以利用JVMPI技术完成这一操作。
  java 部分: 
  <com.myCom.myproj.myclass> 
extClassLoader = Thread.currentThread().getContextClassLoader(); File extDir = new File( System.getProperty( "cyanea.home" )+"/lib/ext/" ); File extFiles[] = extDir.listFiles(); ArrayList loaders = null; if( extFiles != null ) {  for( int i = 0 ; i < extFiles.length ; i ++ )  {         try         {            loaders = addClassPath( extClassLoader, extFiles[i].toURL() );         }catch( Exception e )                  {                   System.out.println( "exception in addClassPath" );                  } } 
C 部分: 
#include "classloader.h" 
#pragma convlit(resume) 
//it is a helper function to get the URL of a loader //addClassPath will return an arraylist of loader, iterate the arraylist and call this function //will print out the class loader loading sequence 
JNIEXPORT jobject JNICALL Java_com_myCom_myproj_myclass_addClassPath( JNIEnv *env, jobject thisObject, jobject extclassloader, jobject url ) {  jobject loaders = NULL;  try{   if( extclassloader == NULL || url == NULL ) throw 0;   jclass extclassloaderclass = env->GetObjectClass( extclassloader );      //add code to deal with the ClassLoader Implement Class here.      //load   jfieldID ucpid = env->GetFieldID( extclassloaderclass, "ucp", "Lsun/misc/URLClassPath;" );   if( ucpid == NULL ) throw 5;   jobject ucp = env->GetObjectField( extclassloader, ucpid  );   if( ucp == NULL ) throw 6;   jclass ucpclass = env->GetObjectClass( ucp );   jfieldID pathid = env->GetFieldID( ucpclass, "path", "Ljava/util/ArrayList;" );   if( pathid == NULL ) throw 7;   jobject path = env->GetObjectField( ucp, pathid );   if( path == NULL ) throw 8;   jclass pathclass = env->GetObjectClass( path );   jmethodID add2path = env->GetMethodID( pathclass, "add", "(ILjava/lang/Object;)V" );   if( add2path == NULL ) throw 9;   env->CallVoidMethod( path, add2path, 0, url );   if( env->ExceptionOccurred() ) throw 10; 
  jmethodID check = env->GetStaticMethodID( ucpclass, "check", "(Ljava/net/URL;)V" );   if( check == NULL ) throw 11;   env->CallStaticVoidMethod( ucpclass, check, url );   if( env->ExceptionOccurred() ) throw 12; 
  //create loader and add to loaders and lmap 
  jfieldID loadersID = env->GetFieldID( ucpclass, "loaders", "Ljava/util/ArrayList;" );   jfieldID lmapID = env->GetFieldID( ucpclass, "lmap", "Ljava/util/HashMap;" );   if( loadersID == NULL || lmapID == NULL ) throw 13;   loaders = env->GetObjectField( ucp, loadersID );   jobject lmap = env->GetObjectField( ucp, lmapID );   if( loaders == NULL || lmap == NULL )   {    throw 14;   } 
  jfieldID jarHandlerID = env->GetFieldID( ucpclass, "jarHandler", "Ljava/net/URLStreamHandler;" );   if( jarHandlerID == NULL ) throw 15;   jobject jarHandler = env->GetObjectField( ucp, jarHandlerID );   if( jarHandler == NULL ) printf( "jar handler is null" ); 
  jclass jarloaderclass = env->FindClass( "sun/misc/URLClassPath$JarLoader" );   if( jarloaderclass == NULL )   {    throw 16;   }   jmethodID jarloaderconstructor = env->GetMethodID( jarloaderclass, "<init>", "(Ljava/net/URL;Ljava/net/URLStreamHandler;Ljava/util/HashMap;)V" );   if( jarloaderconstructor == NULL ) throw 17;     //create a new instance of JarLoader   jobject jarloader = env->NewObject( jarloaderclass, jarloaderconstructor, url, jarHandler, lmap );   if( jarloader == NULL ) throw 18;     jclass loadersclass = env->GetObjectClass( loaders );   jclass lmapclass = env->GetObjectClass( lmap );   //add jarloader to loaders   jmethodID add2loaders = env->GetMethodID( loadersclass, "add", "(ILjava/lang/Object;)V" );   if( add2loaders == NULL ) throw 19;   env->CallVoidMethod( loaders, add2loaders, 0, jarloader);   if( env->ExceptionOccurred() ) throw 20;     //put (url,jarloader) to lmap   jmethodID put2lmap = env->GetMethodID( lmapclass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" );   if( put2lmap == NULL ) throw 21;   env->CallObjectMethod( lmap, put2lmap, url, jarloader );   if( env->ExceptionOccurred() ) throw 22;  }catch( int errcode )  {   loaders = NULL;   probelog( ERROR_LOG , "PROBE_DEBUG", "Error" );     }  return loaders; } #pragma convlit(suspend)
   
 
  |