Project Class Loader

应用场景:

eclipse插件开发中,插件中的某个动作需要使用当前java工程的classpath。例如在插件需要访问的XML资源文件可能已经打包在某个jar文件中了,而jar文件正好设置在当前工程的classpath中;再例如数据库访问插件,需要调用jdbc驱动,插件本身为了保证体积是不会包含数据库JDBC驱动的,这时可能需要访问当前工程classpath中的JDBC驱动。

 

解决办法:

       因为已知当前工程(IProject),所以可以得到当前的Java工程(IJavaProject),根据IJavaProject可以得到所有的IPackageFragmentRoot,因而可以得到当前classpathURLs,根据这些URL创建URLClassLoader即可。为了使用方便,我们将会把这个过程封装在ProjectClassLoader中,ProjectClassLoader继承了URLClassLoader

 

实现:

 

 

import java.io.File;

import java.net.URL;

import java.net.URLClassLoader;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

 

import org.eclipse.core.resources.IWorkspaceRoot;

import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.core.runtime.FileLocator;

import org.eclipse.core.runtime.IPath;

import org.eclipse.jdt.core.IJavaProject;

import org.eclipse.jdt.core.IPackageFragmentRoot;

import org.eclipse.jdt.core.JavaModelException;

 

public class ProjectClassLoader extends URLClassLoader {

 

       public ProjectClassLoader (IJavaProject project) throws JavaModelException  {

              super(getURLSFromProject(project, null), Thread.currentThread().getContextClassLoader());

       }

 

       public ProjectClassLoader (IJavaProject project, URL[] extraUrls) throws JavaModelException  {

              super(getURLSFromProject(project, extraUrls), Thread.currentThread().getContextClassLoader());

       }

 

       private static URL[] getURLSFromProject (IJavaProject project, URL[] extraUrls) throws JavaModelException {

              List<URL> list = new ArrayList<URL>();

              if (null != extraUrls) {

                     for (int i=0; i<extraUrls.length; i++) {

                            list.add(extraUrls[i]);

                     }

              }

             

              IPackageFragmentRoot[] roots = project.getAllPackageFragmentRoots();

 

              IPath installPath = ResourcesPlugin.getWorkspace().getRoot().getLocation();

             

              for (int i=0; i<roots.length; i++) {

                     try {

                            if (roots[i].isArchive()) {

                                   File f = new File(FileLocator.resolve(installPath.append(roots[i].getPath()).toFile().toURL()).getFile());

                                   if(!f.exists()){

                                          f = new File(FileLocator.resolve(roots[i].getPath().makeAbsolute().toFile().toURL()).getFile());

                                   }

                                   list.add(f.toURL());

                            }

                            else {

                    IPath path = roots[i].getJavaProject().getOutputLocation();

                    if (path.segmentCount() > 1) {

                        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

                        path = root.getFolder(path).getLocation();

                        list.add(path.toFile().toURL());

                    }

                    else {

                        path = roots[i].getJavaProject().getProject().getLocation();

                        list.add(path.toFile().toURL());

                    }

                            }

                     }

                     catch (Exception e) {}

              }

             

              URL[] urls = new URL[list.size()];

              int index = 0;

              for (Iterator i=list.iterator(); i.hasNext(); index++) {

                     urls[index] = (URL) i.next();

              }

              return urls;

       }

}

 

 

IJavaProject javaProject = JavaCore.create(project);//IProject à IJavaProject

ProjectClassLoader loader = new ProjectClassLoader(javaProject);

 

 

 

 

Building Commercial-Quality Plug-ins, Second Edition》一书中给出了另外一种实现:

Chapter 20. Advanced Topics/ Plug-in ClassLoaders

public class ProjectClassLoader extends ClassLoader

{

    private IJavaProject project;

 

    public ProjectClassLoader(IJavaProject project) {

       if (project == null || !project.exists() || !project.isOpen())

          throw new IllegalArgumentException("Invalid project");

       this.project = project;

    }

 

    protected Class findClass(String name)

        throws ClassNotFoundException

    {

        byte[] buf = readBytes(name);

        if (buf == null)

           throw new ClassNotFoundException(name);

        return defineClass(name, buf, 0, buf.length);

    }

 

    private byte[] readBytes(String name) {

       IPath rootLoc = ResourcesPlugin

          .getWorkspace().getRoot().getLocation();

       Path relativePathToClassFile =

          new Path(name.replace(".","/") + ".class");

       IClasspathEntry[] entries;

       IPath outputLocation;

       try {

          entries = project.getResolvedClasspath(true);

          outputLocation =

             rootLoc.append(project.getOutputLocation());

       }

       catch (JavaModelException e) {

          FavoritesLog.logError(e);

          return null;

       }

       for (int i = 0; i < entries.length; i++) {

          IClasspathEntry entry = entries[i];

          switch (entry.getEntryKind()) {

 

             case IClasspathEntry.CPE_SOURCE :

                IPath path = entry.getOutputLocation();

                if (path != null)

                   path = rootLoc.append(path);

                else

                   path = outputLocation;

                path = path.append(relativePathToClassFile);

                byte[] buf = readBytes(path.toFile());

                if (buf != null)

                   return buf;

                break;

             case IClasspathEntry.CPE_LIBRARY:

             case IClasspathEntry.CPE_PROJECT:

                // Handle other entry types here.

                break;

 

             default :

                break;

          }

       }

       return null;

   }

 

   private static byte[] readBytes(File file) {

      if (file == null || !file.exists())

         return null;

      InputStream stream = null;

      try {

         stream =

            new BufferedInputStream(

               new FileInputStream(file));

         int size = 0;

         byte[] buf = new byte[10];

         while (true) {

            int count =

               stream.read(buf, size, buf.length - size);

            if (count < 0)

               break;

            size += count;

            if (size < buf.length)

               break;

            byte[] newBuf = new byte[size + 10];

            System.arraycopy(buf, 0, newBuf, 0, size);

            buf = newBuf;

         }

         byte[] result = new byte[size];

         System.arraycopy(buf, 0, result, 0, size);

         return result;

      }

      catch (Exception e) {

         FavoritesLog.logError(e);

         return null;

      }

      finally {

         try {

            if (stream != null)

               stream.close();

         }

         catch (IOException e) {

            FavoritesLog.logError(e);

            return null;

         }

      }

   }

}

 

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值