/* ... */ /* * Liste des classes au sens Java. * La clé représente le nom au format: monpackage/MaClasse.class */ private Hashtable<String, Class<?>> classes; /* * Liste des classes au sens bytes. * La clé représente le nom au format: monpackage/MaClasse.class */ private Hashtable<String, byte[]> classesData; /* ... */ @Override public Class<?> findClass(final String className) throws ClassNotFoundException{ Class<?> clazz = null; /* Conversion du nom en chemin, exemple monpackage.MaClasse devient monpackage/MaClasse.class */ final String classPath = className.replace('.', '/') + ".class"; /* Test si la classe est déjà chargée ou non */ /* Attention la jvm n'aime pas le double chargement... */ if (classes.containsKey(classPath)) return classes.get(classPath); /* Récupération des datas */ final byte[] classBytes = classesData.get(classPath); /* Si la classe n'est pas présente */ if (classBytes null) clazz super.findClass(classPath); else { /* Charge la classe */ clazz = defineClass(className, classBytes, 0, classBytes.length); resolveClass(clazz); } /* Ajoute la classe pour le prochain appel de findClass. */ classes.put(classPath, clazz); return clazz; }
public class ZipEntitiesLoader extends ClassLoader { private final ZipFile file; public ZipEntitiesLoader(String filename,ClassLoader classLoader) throws IOException { super(classLoader); this.file = new ZipFile(filename); } public List<Class<?>> loadClass() throws ClassNotFoundException { List<Class<?>> listOfClasses = new ArrayList<Class<?>>(); Enumeration<?> zipEntries = file.entries(); while (zipEntries.hasMoreElements()) { ZipEntry entry = (ZipEntry)zipEntries.nextElement(); if(entry.getName().endsWith(".class")) { String className = entry.getName().replace("/", ".").replace(".class", ""); System.out.println("creating " + className+ " --"); try { byte[] array = new byte[1024]; InputStream in = this.file.getInputStream(entry); ByteArrayOutputStream out = new ByteArrayOutputStream(array.length); int length = in.read(array); while (length > 0) { out.write(array, 0, length); length = in.read(array); } if(! listOfClasses.contains(className+".class")) listOfClasses.add(defineClass(className, out.toByteArray(), 0, out.size())); } catch (IOException exception) { throw new ClassNotFoundException(className, exception); } } else { System.out.println("will not convert "+ entry.getName()); } } return listOfClasses; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { ZipEntry entry = this.file.getEntry(name.replace('.', '/') + ".class"); if (entry == null) { throw new ClassNotFoundException(name); } try { byte[] array = new byte[1024]; InputStream in = this.file.getInputStream(entry); ByteArrayOutputStream out = new ByteArrayOutputStream(array.length); int length = in.read(array); while (length > 0) { out.write(array, 0, length); length = in.read(array); } return defineClass(name, out.toByteArray(), 0, out.size()); } catch (IOException exception) { throw new ClassNotFoundException(name, exception); } } }