`
yuancihang
  • 浏览: 145175 次
  • 性别: Icon_minigender_1
  • 来自: 洛阳
社区版块
存档分类
最新评论

自定义类加载器 二

阅读更多

package com.yuan.common.asm;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yuan.common.collection.ListEnumeration;
import com.yuan.common.compress.JarTool;
import com.yuan.common.file.DefaultFilenameFilter;

public class LibClassLoader extends AbstractClassLoader {

    private static final Logger logger = LoggerFactory.getLogger(LibClassLoader.class);
   
    protected List<File> jarList = new ArrayList<File>();
   
    public LibClassLoader(String libPath, ClassLoader parent){
        super(parent);
        File[] jars = new File(libPath).listFiles(new DefaultFilenameFilter("jar", true));
        jarList = Arrays.asList(jars);
    }
    public LibClassLoader(List<String> libPathList, ClassLoader parent){
        super(parent);
        for(String libPath : libPathList){
            File[] jars = new File(libPath).listFiles(new DefaultFilenameFilter("jar", true));
            jarList.addAll(Arrays.asList(jars));
        }
    }
   
    protected byte[] loadClassData(String name)throws ClassNotFoundException {
        String classEntryName = name.replaceAll("\\.", "/") + ".class";
        byte[] classData = null;
        for(File jarFile : jarList) {
            try {
                classData = JarTool.readEntry(jarFile.getAbsolutePath(), classEntryName);
            } catch (IOException e) {
                logger.warn(e.getMessage(), e);
                throw new ClassNotFoundException(e.getMessage(), e);
            }
            if(classData != null ){
                break;
            }
        }
        if(classData == null){
            throw new ClassNotFoundException(name);
        }
        return classData;
    }
   
    protected URL findResource(String name) {
        for (File jarFile : jarList) {
            try {
                if (JarTool.existsEntry(jarFile.getAbsolutePath(), name)) {
                    return getJarUrl(jarFile.getAbsolutePath(), name);
                }
            } catch (IOException e) {
                logger.warn(e.getMessage(), e);
            }
        }
        return null;
    }

    protected Enumeration<URL> findResources(String name) throws IOException {
        ListEnumeration<URL> list = new ListEnumeration<URL>();
        for (File jarFile : jarList) {
            try {
                if (JarTool.existsEntry(jarFile.getAbsolutePath(), name)) {
                    list.add(getJarUrl(jarFile.getAbsolutePath(), name));
                }
            } catch (IOException e) {
                logger.warn(e.getMessage(), e);
            }
        }
        return list;
    }
   
    protected URL getJarUrl(String jarFile, String entryName){
        try {
            return new URL("jar:file:/"+jarFile+"!/"+entryName);
        } catch (MalformedURLException e) {
            logger.warn(e.getMessage(), e);
        }
        return null;
    }

}

 

 

package com.yuan.common.file;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import com.yuan.common.util.AssertUtil;

public class DefaultFilenameFilter implements FilenameFilter {
   
    private boolean ignoreDir = false; //是否忽略文件夹,默认不忽略
    private List<String> extList = new ArrayList<String>();
   
    public DefaultFilenameFilter(final String ext){
        this.extList.add("."+ext);
    }
    public DefaultFilenameFilter(final String... exts){
        if((exts != null) && (exts.length > 0)){
            for(String ext : exts){
                this.extList.add("."+ext);
            }
        }
       
    }
   
    public DefaultFilenameFilter(final String ext, boolean ignoreDir){
        this.ignoreDir = ignoreDir;
        this.extList.add("."+ext);
    }
   
    public void addExt(final String ext){
        this.extList.add("."+ext);
    }
   
    public boolean accept(File dir, String name) {
        if(ignoreDir){
            if(new File(dir+File.separator+name).isDirectory()){
                return false;
            }else{
                return endsWithExt(name);
            }
        }else{
            return endsWithExt(name)||new File(dir+File.separator+name).isDirectory();
        }//if
    }//accept
   
    protected boolean endsWithExt(String name){
        if(!AssertUtil.notEmpty(extList)){
            return true;
        }
        for(String ext : extList){
            if(name.endsWith(ext)){
                return true;
            }
        }
       
        return false;
    }

}

 

 

package com.yuan.common.compress;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 将java类文件打包
 * @author yuan
 *
 */
public class JarTool {
   
    private static final Integer BUFFER_SIZE = 512;
   
    /**
     * Logger for this class
     */
    private static final Logger logger = LoggerFactory.getLogger(JarTool.class);

   
    /**
     * 压缩文件夹及其子文件夹
     * @param source String 源文件夹,如: d:/tmp
     * @param dest String 目标文件,如: e:/tmp.jar
     * @throws IOException
     */
    public static void compressFolder(String source, String dest)throws IOException{
        JarOutputStream jos = new JarOutputStream(new FileOutputStream(dest));
        jos.setLevel(Deflater.BEST_COMPRESSION);
        compressJarFolder(jos, new File(source),"");
        jos.close();
    }
   
    private static void compressJarFolder(JarOutputStream jos, File f, String base)throws IOException{
        if(f.isFile()){
            compressJarFile(jos, f, base);
        }else if(f.isDirectory()){
            compressDirEntry(jos, f, base);
           
            String[] fileList = f.list();
            for(String file:fileList){
                String newSource = f.getAbsolutePath() + File.separator + file;
                File newFile = new File(newSource);
                String newBase = base + "/" + f.getName()+"/"+newFile.getName();
                if(base.equals("")){
                    newBase = newFile.getName();//f.getName()+"/"+newFile.getName();
                }else{
                    newBase = base + "/" + newFile.getName();
                }
               
                logger.info("正在压缩文件从 "+newSource+"    到 "+newBase);
                compressJarFolder(jos, newFile, newBase);
               
            }//for
           
        }//if
    }
   
    //压缩单个文件
    private static void compressJarFile(JarOutputStream jos, File f, String base)throws IOException{
        jos.putNextEntry(new ZipEntry(base));
       
        BufferedInputStream bin = new BufferedInputStream(new FileInputStream(f));
       
        byte[] data = new byte[JarTool.BUFFER_SIZE];
        while ((bin.read(data)) != -1) {
            jos.write(data);
        }
        bin.close();
        jos.closeEntry();
    }
   
    public static void compressFile(String sourceFile)throws IOException{
        String jarFile = sourceFile.substring(0, sourceFile.lastIndexOf('.')) + ".jar";
        compressFile(sourceFile, jarFile);
    }
   
    //压缩单个文件到JAR文件中
    public static void compressFile(String sourceFile, String jarFile)throws IOException{
        File f = new File(sourceFile);
        String base = f.getName();
        JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
        jos.putNextEntry(new ZipEntry(base));
       
        BufferedInputStream bin = new BufferedInputStream(new FileInputStream(f));
       
        byte[] data = new byte[JarTool.BUFFER_SIZE];
        while ((bin.read(data)) != -1) {
            jos.write(data);
        }
        bin.close();
        jos.closeEntry();
        jos.close();
    }
   
    //压缩空文件夹
    private static void compressDirEntry(JarOutputStream jos, File f, String base)throws IOException{
        jos.putNextEntry(new ZipEntry(base + "/"));
       
        jos.closeEntry();
    }
   
    public static byte[] readEntry(String jarFile, String entryName)throws IOException{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        boolean existEntry = readEntry(jarFile, entryName, baos);
        if(!existEntry){
            return null;
        }
        return baos.toByteArray();
    }
   
    public static boolean readEntry(String jarFile, String entryName, OutputStream os)throws IOException{
        JarFile jar = new JarFile(new File(jarFile));
        JarEntry entry = jar.getJarEntry(entryName);
        if(entry == null){
            return false;
        }
        InputStream is = new BufferedInputStream(jar.getInputStream(entry));
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = is.read(b, 0, b.length)) != -1) {
            os.write(b, 0, len);
        }
        is.close();
        return true;
    }
   
    public static InputStream getEntryInputStream(String jarFile, String entryName) throws IOException{
        JarFile jar = new JarFile(new File(jarFile));
        JarEntry entry = jar.getJarEntry(entryName);
        if(entry == null){
            return null;
        }
        return jar.getInputStream(entry);
    }
   
    public static InputStream getEntryInputStream(URL url) throws IOException{
        JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
       
        return jarConnection.getInputStream();
    }
   
    public static boolean existsEntry(String jarFile, String entryName)throws IOException{
        JarFile jar = new JarFile(new File(jarFile));
        JarEntry entry = jar.getJarEntry(entryName);
        if(entry == null){
            return false;
        }
        return true;
    }
   
    public static String readTextEntry(String jarFile, String entryName, String encoding)throws IOException{
        String entryContent = "";
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        boolean existEntry = readEntry(jarFile, entryName, baos);
        if(!existEntry){
            return null;
        }
        byte[] content = baos.toByteArray();
        baos.close();
        if(encoding == null){//按平台默认编码
            entryContent = new String(content);
        }else{
            entryContent = new String(content, encoding);
        }
        return entryContent;
    }
   
    public static String readTextEntry(String jarFile, String entryName)throws IOException{
        return readTextEntry(jarFile, entryName, null);
    }

    public static void uncompress(String jarFile)throws IOException{
        File f = new File(jarFile);
        String path = f.getAbsolutePath();
        int index = path.lastIndexOf(".");
        if(index > 0){
            path = path.substring(0, index);
        }
        uncompress(jarFile, path);
    }
    public static void uncompress(String jarFile, String outputDir)throws IOException{
        if(!new File(outputDir).exists()){
            new File(outputDir).mkdirs();
        }
        JarFile jar = new JarFile(new File(jarFile));
        Enumeration<JarEntry> e = jar.entries();
        while(e.hasMoreElements()){
            JarEntry entry = e.nextElement();
            saveEntry(jar, entry, outputDir);
        }

    }
    private static void saveEntry(JarFile jar, JarEntry entry, String outputDir)throws IOException{
        logger.info("解压缩" + entry.getName() + " ... ... ");
        File f = new File(new File(outputDir), entry.getName());
        if(entry.isDirectory()){
            f.mkdirs();
            return ;
        }else{
            f.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(f);
        InputStream is = new BufferedInputStream(jar.getInputStream(entry));
        int len = 0;
        byte[] b = new byte[1024];
        while ((len = is.read(b, 0, b.length)) != -1) {
            fos.write(b, 0, len);
        }
        is.close();
        fos.close();
    }
}

分享到:
评论

相关推荐

    自定义类加载器实现自定义加载

    在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。

    自定义类加载器

    本文将深入探讨自定义类加载器的基本概念、工作原理以及如何创建一个简单的基于磁盘的自定义类加载器。 ### 类加载器的层次结构 Java中的类加载器通常形成一个树状的层次结构,其中Bootstrap ClassLoader是最顶层...

    自定义Java类加载器

    - **安全沙箱**:每个加载器都有自己的命名空间,可以通过自定义加载器限制代码访问权限。 - **插件系统**:插件有自己的类加载器,使得插件可以独立于主程序加载和卸载。 在编写`MyClassLoader`时,需要注意的是,...

    3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4

    3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4

    Java加壳源码-自定义类加载器

    默认的类加载器包括Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和AppClassLoade(应用程序类加载器),它们按照双亲委派模型工作。 自定义类加载器的创建通常涉及以下步骤: 1...

    java类加载器学习二、自定义类加载器

    java类加载器学习二、自定义类加载器

    自定义类加载代码

    本篇将深入探讨自定义类加载器的实现、双亲委派模型以及如何指定父类加载器。 首先,我们来了解自定义类加载器的实现。在Java中,类加载的过程包括加载、验证、准备、解析和初始化。当JVM需要加载一个类时,它会...

    Java基于自定义类加载器实现热部署过程解析

    "Java基于自定义类加载器实现热部署过程解析" Java中基于自定义类加载器实现热部署是指在不重启应用的情况下,当类的定义即字节码文件修改后,能够替换该Class创建的对象。热部署是Java中的一个重要概念,它可以...

    Java实现的自定义类加载器示例

    Java 实现的自定义类加载器示例 Java 实现的自定义类加载器是 Java 语言中的一种机制,允许开发者自定义类加载器,以满足特定的需求。本文将详细介绍 Java 实现的自定义类加载器的原理和实现技巧。 ClassLoader 类...

    ClassLoader类加载器

    2. Extension ClassLoader:扩展类加载器,负责加载`&lt;JAVA_HOME&gt;/lib/ext`目录下的扩展类库,或者被`-Djava.ext.dirs`指定的路径中的类。 3. Application ClassLoader:也称为系统类加载器,负责加载用户类路径`-cp...

    tomcat类加载器

    这个"DevLoader.zip"文件可能包含与Tomcat自定义类加载器相关的资料,特别是名为"DevLoader"的类加载器,这可能是Tomcat为开发者提供的一种特殊加载器。 首先,我们来理解一下类加载器的基本概念。在Java中,类加载...

    java自定义类加载classloader文档,包括代码

    ### Java自定义类加载器(Class Loader)详解 #### 一、引言 在Java语言中,类加载机制是其动态特性的核心之一。通过类加载器(Class Loader),Java程序能够在运行时根据需要加载所需的类,从而实现高度的灵活性...

    类加载器文件

    这种设计遵循了**委托模式**,即自定义类加载器在尝试加载类之前会先询问其父加载器是否能加载该类,只有在父加载器无法加载时才会尝试自己加载。 #### 八、类的卸载与重载 1. **卸载**: Java类一旦被加载到JVM中...

    java自定义类加载器代码示例

    Java自定义类加载器代码示例 Java自定义类加载器代码示例是一种使用Java语言实现的类加载器示例,主要用于加载Java类文件。类加载器是Java虚拟机(JVM)中的一种机制,用于将Java类文件加载到JVM中,以便JVM可以...

    java 类加载与自定义类加载器详解

    自定义加载器需要重写`findClass()`或`loadClass()`方法。在`MyClassLoader2`示例中,它尝试从指定路径查找类的字节码文件,并通过`defineClass()`方法将字节码转换为Class对象。 ```java public Class&lt;?&gt; find...

    3-7Tomcat中自定义类加载器的使用与源码实现(2).mp4

    3-7Tomcat中自定义类加载器的使用与源码实现(2).mp4

    Java类加载器原理

    2. 主要的类加载器: - 引导(Bootstrap)类加载器:这是最基础的类加载器,由本地代码实现,负责加载JRE的基础类库,如rt.jar,它不直接暴露给开发者。 - 扩展(Extension)类加载器:由ExtClassLoader实现,加载...

    JVM类加载器说明文档

    2. 安全性问题:如果允许用户自定义类加载器任意加载代码,可能会破坏系统的安全策略,因为类加载器可以加载不受限制的代码。 3. 单例模式的实现:在多线程环境中,如果每个线程都有自己的类加载器,可能导致单例...

    java类加载器

    2. **扩展类加载器(Extension Class Loader)**:负责加载`java.ext.dirs`系统属性指定路径下的扩展库。这些类库提供了Java运行时之外的功能。 3. **应用程序类加载器(Application Class Loader)**:也称为系统类...

    java 类加载器 加密

    在这个例子中,`EncryptedClassLoader`是我们的自定义加载器,它覆盖了`findClass`方法以处理加密的类。`main`方法中,我们使用`Class.forName`加载类,并传入我们的自定义类加载器。找到main方法后,通过反射调用它...

Global site tag (gtag.js) - Google Analytics