Java 自定义类加载器中的NullPointerException-Can';我找不到zipEntry
我正在制作一个类加载器,它可以接受一个jar,并基于此,它可以接受一个包名,并且只允许加载该包中的类。当我试图从那里加载一个类时,我得到一个错误: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
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());
}