自定义Classloader 加载类---Eclipse plugin开发

在Eclipse开发plugin时,因运行环境和运行时环境不一致,会出现ClassNotFoundException等问题。此时可自定义ClassLoader解决,动态加载类时,建议使用Thread.currentThread().getContextClassLoader()。文中给出了自定义ClassLoader的代码,其功能是加载指定路径下model目录的所有类,并展示了调用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在我们的代码中有很多是动态加载类的,但如果使用eclipse 开发plugin会有一些问题。
  例如:要求在plugin中使用某类型的class,但由于plugin的运行环境和运行时环境不一致,导致你在进行plugin开发时遇到ClassNotFoundException等问题。在这样的情况下就要自定义ClassLoader然后,在plugin中使用。同时需要注意的一个问题是:在动态家在类的时候,最好不要使用xxx.getClass().getClassLoader()或xxx.class.getClassLoader(),因为这样一样可能导致ClassNotFountException,最好是使用Thread.currentThread().getContextClassLoader().
这样在使用自定义ClassLoader的时候,就不用修改代码,直接把自定义ClassLoader放到Thread的contextClassLoad中既可。
  ClassLoade的代码:

/*
 * Created on 2005-12-1
 */
package org.jsports.plugin.classLoader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;


/**
 * @author Kobye
 */
public class JsportsClassLoader extends ClassLoader {
  private String dir ;
  
  public JsportsClassLoader (ClassLoader parent,String dir){
   super(parent);
   this.dir = dir;
  } 
 
 
 protected Class findClass(String name)throws ClassNotFoundException {
  byte[] bytes = loadClassBytes(name);
  Class theClass = defineClass(name, bytes, 0, bytes.length);
  if (theClass == null){
   throw new ClassFormatError();
  }
  return theClass;
   }


 private byte[] loadClassBytes(String className) throws ClassNotFoundException {
  try {
   String classFile = getClassFile(className);
   FileInputStream fis = new FileInputStream(classFile);
   FileChannel fileC = fis.getChannel();
   ByteArrayOutputStream baos = new
   ByteArrayOutputStream();
   WritableByteChannel outC = Channels.newChannel(baos);
   ByteBuffer buffer = ByteBuffer.allocate(1024);
   while (true) {
    int i = fileC.read(buffer);
    if (i == 0 || i == -1) {
    break;
    }
    buffer.flip();
    outC.write(buffer);
    buffer.clear();
   }
   fis.close();
   return baos.toByteArray();
  } catch (IOException fnfe) {
   throw new ClassNotFoundException(className);
  }
 }


 private String getClassFile(String name){
  StringBuffer sb = new StringBuffer(dir);
  name = name.replace('.', File.separatorChar) + ".class";
  sb.append(File.separator + name);
  return sb.toString();
 }
 

 
 protected URL findResource(String name) {              
  try {                                         
   URL url = super.findResource(name);           
   if (url != null){
    return url;                                   
   }
   url = new URL("file:///" + converName(name)); 
   return url;                                  
      } catch (MalformedURLException mue) {                  
    return null;                                
   }                                           
    }      
 
 
 private String converName(String name) {     
   StringBuffer sb = new StringBuffer(dir);
   name = name.replace('.', File.separatorChar);
   sb.append(File.separator + name);           
   return sb.toString();                       
 }                                            
                                                   

 private String getClassName(String dir,File f){
  String name = f.getAbsolutePath();  
  if(name.startsWith(dir)){ 
   name = name.substring(dir.length(),name.length());
  }
  name = name.replace(File.separatorChar,'.');
  if(name.endsWith(".class")){
   name = name.substring(0,name.length()-".class".length());
  }
  return name;
 }
 private List getAllFiles(File base){
  File[]dirs = base.listFiles(new ClassFileFilter());
  File[]classFile = base.listFiles(new ClassFileNameFilter());
  List files = new ArrayList();
  for(int i=0;i<classFile.length;i++){
   files.add(classFile[i]);
  }
  for(int i=0;i<dirs.length;i++){
   files.addAll(getAllFiles(dirs[i]));
  }
  return files;
 }
 
 private File getDirByName(File dir,String dirName,String baseDir){
  if(!dir.isDirectory()){
   return null;
  }   
  String dirPath = dir.getAbsolutePath(); 
  if(dirPath.startsWith(baseDir)){
   //检查  该目下的File dir  
   dirPath = dirPath.substring(baseDir.length(),dirPath.length());
   System.out.println();
   if(dirPath.endsWith("model")){
    return dir;
   }
  }
  File[]files = dir.listFiles();
  for(int i=0;i<files.length;i++){
   File f = getDirByName(files[i],dirName,baseDir);
   if(f!=null){
    return f;
   }
  }
  return null;
 }
 
}


这个ClassLoader的功能是把dir路径下的model目录中的所有类加载。
然后这样调用:
  String path = this.getCurrentProject().getLocation().toFile().getAbsolutePath()+"//bin";
  Thread.currentThread().setContextClassLoader(new JsportsClassLoader (Thread.currentThread().getContextClassLoader(),path));  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值