Monday, January 17, 2011

Custom class loader in Java

-->
/** Custom class loader for native classes
* @author sajal.maity
*
*/
package com.mycomp.component.core;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import net.refractions.udig.catalog.URLUtils;
/**
* NativeLoader loads native classes
*
* @author sajal.maity Oct 14, 2010
*
*/
public class NativeLoader extends ClassLoader {
private static String classPath;
static {
URL location = null;
try {
location = CorePlugin.class.getProtectionDomain().getCodeSource().getLocation();
} catch (Exception e) {
e.printStackTrace();
}
File file = URLUtils.urlToFile(location);
classPath = file.getAbsolutePath();
if (classPath.endsWith(".jar") == false) {
classPath = classPath + File.separator + "bin";
}
}
private Hashtable classes = new Hashtable(); // used to cache already
private NativeLoader() {
super(NativeLoader.class.getClassLoader());
}
public static NativeLoader getInstance() {
if (instance == null) {
instance = new NativeLoader();
}
return instance;
}
public static void dispose() {
instance = null;
}
public void finalize() {
System.out.println(this + " is garbage collected.");
}
public String toString() {
return NativeLoader.class.getName();
}
/**
* Uncomment the following method if you want to load all child class using
* the parent class loader
*/
/*
* public Class loadClass(String className) throws ClassNotFoundException {
* return findClass(className); }
*/
public Class findClass(String className) {
byte classByte[];
Class result = null;
result = (Class) classes.get(className); // checks in cached classes
if (result != null) {
return result;
}
try {
return findSystemClass(className);
} catch (Exception e) {
}
if (classPath.endsWith(".jar")) {
try {
result = loadFromJar(className, classPath);
} catch (Exception e) {
e.printStackTrace();
result = null;
}
} else {
result = loadFromFile(className);
}
return result;
}
private Class loadFromJar(String className, String jarFile)
throws Exception {
byte classByte[];
Class result = null;
String name = className.replace('.', '/') + ".class";
try {
JarFile jar = new JarFile(jarFile);
JarEntry entry = jar.getJarEntry(name);
InputStream is = jar.getInputStream(entry);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
int nextValue = is.read();
while (-1 != nextValue) {
byteStream.write(nextValue);
nextValue = is.read();
}
classByte = byteStream.toByteArray();
result = defineClass(className, classByte, 0, classByte.length,
null);
classes.put(className, result);
return result;
} catch (Exception e) {
return null;
}
}
public synchronized Class loadFromFile(String name) {
Class result = null;
String filepath = classPath + File.separatorChar;
filepath = filepath + name.replace('.', File.separatorChar) + ".class";
try {
File file = new File(filepath);
int size = (int) file.length();
byte buff[] = new byte[size];
DataInputStream in = new DataInputStream(new FileInputStream(
filepath));
in.readFully(buff);
in.close();
result = defineClass(name, buff, 0, buff.length);
classes.put(name, result);
resolveClass(result);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static NativeLoader instance;
}