Java 自定义类加载器中的NullPointerException-Can';我找不到zipEntry

Java 自定义类加载器中的NullPointerException-Can';我找不到zipEntry,java,jar,nullpointerexception,zip,classloader,Java,Jar,Nullpointerexception,Zip,Classloader,我正在制作一个类加载器,它可以接受一个jar,并基于此,它可以接受一个包名,并且只允许加载该包中的类。当我试图从那里加载一个类时,我得到一个错误: Exception in thread "main" java.lang.NullPointerException at com.classloader.CustomClassLoader.getClassBytes(CustomClassLoader.java:64) at com.classloader.CustomClassLoader.get

我正在制作一个类加载器,它可以接受一个jar,并基于此,它可以接受一个包名,并且只允许加载该包中的类。当我试图从那里加载一个类时,我得到一个错误:

Exception in thread "main" java.lang.NullPointerException
at com.classloader.CustomClassLoader.getClassBytes(CustomClassLoader.java:64)
at com.classloader.CustomClassLoader.getClass(CustomClassLoader.java:48)
at com.classloader.CustomClassLoader.loadClass(CustomClassLoader.java:89)
at com.classloader.TestJar.main(TestJar.java:46)
即使包名和条目名是正确的。你知道问题出在哪里以及如何解决吗?下面是代码,我相信它是非常不言自明的

CustomLoader

package com.classloader;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

public class CustomClassLoader extends ClassLoader implements LoaderConstraints {

private Map<String, Class> loaded = new HashMap<String, Class>();
private Map<String, String> available = new LinkedHashMap<String, String>();
private Set<String> allowed = new LinkedHashSet<String>();

public Set<String> getPermited() {
    return allowed;
}

public Map<String, String> getAvailable() {
    return available;
}

public Map<String, Class> getLoaded() {
    return loaded;
}

public CustomClassLoader() {
    super(CustomClassLoader.class.getClassLoader());
}

private Class<?> getClass(String className, String pack)  throws ClassNotFoundException {

    Class<?> c = null;
    String classPath = className.replace('.', File.separatorChar) + ".class";
    byte[] b = null;
    try {
        b = getClassBytes(classPath, pack);

         c = defineClass(className, b, 0, b.length);
        resolveClass(c);

        return c;
    } catch (IOException e) {
        e.printStackTrace();

    }
    return c;
 }

private byte[] getClassBytes(String classPath, String pack) throws IOException {
       ZipFile zip = new ZipFile(pack);
       // System.out.println(classPath); classPath is right , as well as pack
       ZipEntry entry = zip.getEntry(classPath);//This return null, for some reason ???       
       InputStream in = zip.getInputStream(zip.getEntry(classPath));       
       long size = entry.getSize();
       byte buff[] = new byte[(int)size];
       in.read(buff);
       in.close();
       return buff;
}   

    @Override
    public Class<?> loadClass(String className) throws ClassNotFoundException {



        Class<?> found = null;

        if(loaded.get(className) != null){
                        return loaded.get(className);
                }

        if(available.get(className ) != null){
                if(allowed.contains(className ) == true){
                                found = getClass(className, available.get(className));
                                if(found != null)
                                        loaded.put(className, found);
                }
        }
        else{
                        found = super.loadClass(className);
                        if(found != null)
                                loaded.put(className, found);
        }

        return found;
    }

public void files(ZipFile zip, Map<String,String> list) throws ZipException, IOException{

    Enumeration<? extends ZipEntry> entries = zip.entries();

    while(entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        if (!entry.isDirectory() && entry.getName().endsWith(".class")) {
            String className = entry.getName().replace('/', '.');
            list.put(className.substring(0, className.length() - ".class".length())
                                ,zip.getName());
        }               
    }

}

public void addJar (File jarFile) {
    try {
        files(new ZipFile(jarFile), available);
    } catch (ZipException e) {

        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public void deleteJar(File jarFile) {
    Map<String,String> removes = new HashMap<String, String>();
    try {
        files(new ZipFile(jarFile), removes );
    } catch (ZipException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    available.keySet().removeAll(removes.keySet());

}

public void allowPackage(final String p) {
    for(String s : available.keySet()){
        if(s.startsWith(p))
            allowed.add(new String(s));
    }

}

public void denyPackage(final String p) {
    Set<String> newPermited = new HashSet<String>();
    for(String s : allowed){
        if(!s.startsWith(p))
            newPermited.add(new String(s));
    }
    allowed = newPermited;

}

}
package com.classloader;
导入java.io.ByteArrayOutputStream;
导入java.io.DataInputStream;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.util.Enumeration;
导入java.util.HashMap;
导入java.util.HashSet;
导入java.util.LinkedHashMap;
导入java.util.LinkedHashSet;
导入java.util.List;
导入java.util.Map;
导入java.util.Set;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipException;
导入java.util.zip.ZipFile;
公共类CustomClassLoader扩展ClassLoader实现LoaderConstraints{
已加载私有映射=新建HashMap();
私有映射可用=新建LinkedHashMap();
允许的私有集=新LinkedHashSet();
公共集getPermited(){
允许返回;
}
公共地图getAvailable(){
返回可用;
}
公共映射getLoaded(){
返回装载;
}
公共CustomClassLoader(){
super(CustomClassLoader.class.getClassLoader());
}
私有类getClass(字符串类名称,字符串包)抛出ClassNotFoundException{
c类=空;
字符串classPath=className.replace('.',File.separatorChar)+“.class”;
字节[]b=null;
试一试{
b=getClassBytes(类路径,包);
c=定义类(类名,b,0,b.长度);
(c)级;
返回c;
}捕获(IOE异常){
e、 printStackTrace();
}
返回c;
}
私有字节[]getClassBytes(字符串类路径,字符串包)引发IOException{
ZipFile zip=新ZipFile(包装);
//System.out.println(classPath);classPath是正确的,还有pack
ZipEntry entry=zip.getEntry(classPath);//出于某种原因,此返回值为null???
InputStream in=zip.getInputStream(zip.getEntry(classPath));
long size=entry.getSize();
字节buff[]=新字节[(int)大小];
in.read(buff);
in.close();
返回buff;
}   
@凌驾
公共类loadClass(字符串className)引发ClassNotFoundException{
发现的类=null;
if(loaded.get(className)!=null){
返回loaded.get(className);
}
if(可用。get(className)!=null){
if(allowed.contains(className)==true){
found=getClass(className,available.get(className));
如果(找到!=null)
load.put(className,found);
}
}
否则{
found=super.loadClass(类名);
如果(找到!=null)
load.put(className,found);
}
发现退货;
}
公共无效文件(ZipFile zip,映射列表)引发ZipException,IOException{
枚举clazz=ccl.loadClass(“org.apache.derby.jdbc.EmbeddedDriver”);//给出异常,第46行
System.out.println(clazz.getClass());
对象实例=clazz.newInstance();
System.out.println(instance.getClass());
}

derby.jar
位于项目文件夹中。欢迎提供任何帮助:)

尝试将File.separatorChar替换为“/”

public static void main(String[] args) throws ZipException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {

CustomClassLoader ccl = new CustomClassLoader();
    ccl.addJar(new File("derby.jar"));

    ccl.allowPackage("org.apache.derby.jdbc");

    //System.out.println(ccl.getAvailable().get("org.apache.derby.jdbc.EmbeddedDriver")); --> returns "derby.jar"

    Class<?> clazz = ccl.loadClass("org.apache.derby.jdbc.EmbeddedDriver");//Gives exception , line 46 
    System.out.println(clazz.getClass());
    Object instance = clazz.newInstance();
    System.out.println(instance.getClass());
 }