JVMPI动态加载jar包path入当前classloader

类别:Java 点击:0 评论:0 推荐:

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)

本文地址:http://com.8s8s.com/it/it11495.htm