/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.utils;
import java.io.*;
import java.util.*;
import java.util.jar.*;
public class JarClassLoader extends ClassLoader {
final Map<String, Class<?>> m_cache = new HashMap<String, Class<?>>();
final Set<String> m_classNames = new HashSet<String>();
final String m_jarFilePath;
public JarClassLoader(String jarFilePath) {
m_jarFilePath = jarFilePath;
loadAllClassNamesFromJar();
}
@Override
public synchronized Class<?> loadClass(String className) throws ClassNotFoundException {
System.out.printf("Loading %s... ", className);
// try the fast cache first
Class<?> result;
if (m_cache.containsKey(className)) {
System.out.println("found in cache.");
return m_cache.get(className);
}
// now look through the list
if (m_classNames.contains(className)) {
String classPath = className.replace('.', File.separatorChar) + ".class";
System.out.println("loading from jar.");
byte bytes[] = JarReader.readFileFromJarAtURL(m_jarFilePath, classPath);
if (bytes == null)
throw new ClassNotFoundException(className);
result = this.defineClass(className, bytes, 0, bytes.length);
resolveClass(result);
m_cache.put(className, result);
return result;
}
// default to parent
System.out.println("deferring to parent.");
return getParent().loadClass(className);
}
void loadAllClassNamesFromJar() {
JarInputStream jarIn = JarReader.openJar(m_jarFilePath);
if (jarIn == null)
throw new RuntimeException("Failed to locate jarfile '" + m_jarFilePath + "'");
try {
for (JarEntry catEntry = jarIn.getNextJarEntry(); catEntry != null; catEntry = jarIn.getNextJarEntry()) {
String classFileName = catEntry.getName();
if (!classFileName.endsWith(".class"))
continue;
String javaClassName = classFileName.replace(File.separatorChar, '.');
javaClassName = javaClassName.substring(0, javaClassName.length() - 6);
m_classNames.add(javaClassName);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}