通过ClassLoader调用外部jar包

我们大家都知道,每个运行中的线程都有一个成员contextClassLoader,用来在运行时动态地载入其它类。

系统默认的contextClassLoader是systemClassLoader,所以一般而言java程序在执行时可以使用JVM自带的类、$JAVA_HOME/jre/lib/ext/中的类和$CLASSPATH/中的类,对于非默认的jar,一般只能手动在配置环境添加。

但事实上,我们可以通过Thread.currentThread().setContextClassLoader()更改当前线程的contextClassLoader行为,实现在程序内加载外部jar。

PS:
ClassLoader的工作原理是:
1) 线程需要用到某个类时,contextClassLoader将被请求来载入该类
2) contextClassLoader请求它的父ClassLoader来完成该载入请求
3) 如果父ClassLoader无法载入类,则contextClassLoader试图自己来载入



package  org.loon.framework.jar;

/**
 * <p>Title: LoonFramework</p>
 * <p>Description:JarLoader,用于jar包的外部操作</p>
 * <p>Copyright: Copyright (c) 2007</p>
 * <p>Company: LoonFramework</p>
 * 
@author chenpeng  
 * @email:[email protected] 
 * 
@version 0.1
 
*/

import  java.io.BufferedInputStream;
import  java.io.ByteArrayInputStream;
import  java.io.ByteArrayOutputStream;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.IOException;
import  java.io.InputStream;
import  java.lang.reflect.Method;
import  java.net.MalformedURLException;
import  java.net.URL;
import  java.util.ArrayList;
import  java.util.HashMap;
import  java.util.Hashtable;
import  java.util.jar.JarEntry;
import  java.util.jar.JarInputStream;
import  java.util.jar.Manifest;

public   class  JarLoader  extends  ClassLoader  {
    
//资源缓存
    public static Hashtable resources = new Hashtable();
 
    
public static JarLoader loader = new JarLoader();

    
public static Class load(byte[] resource) throws Exception {
        
// 主函数所在类全称
        String mainClassName = "";
        
//class资源及实体缓存
        ArrayList classNames = new ArrayList();
        ArrayList classBuffers 
= new ArrayList();
        
// 存储依赖类
        HashMap depends = new HashMap();
        
// 将byte[]转为JarInputStream
        JarInputStream jar = new JarInputStream(new ByteArrayInputStream(
                resource));
        Manifest manifest 
= jar.getManifest();
        
// 当Main-Class被声明时,获得主函数所在类全称
        if (manifest != null{
            mainClassName 
= manifest.getMainAttributes().getValue("Main-Class");
        }

        
// 依次获得对应JAR文件中封装的各个被压缩文件的JarEntry
        JarEntry entry;
        
while ((entry = jar.getNextJarEntry()) != null{
            
// 当找到的entry为class时
            if (entry.getName().toLowerCase().endsWith(".class")) {
                
// 将类路径转变为类全称
                String name = entry.getName().substring(0,
                        entry.getName().length() 
- ".class".length()).replace(
                        
'/''.');
                
// 加载该类
                byte[] data = getResourceData(jar);
                
// 缓存类名及数据
                classNames.add(name);
    
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值