Patch for ClassLoader
Niklas Mehner <[email protected]>
| Newsgroups | gmane.comp.jakarta.bcel.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi! I had some problems, when trying to "stack" the org.apache.bcel.util.ClassLoader (use the result of a ClassLoader and modify the resulting batecode with a different ClassLoader). This does not work, because ClassLoader does not override getResourceAsStream(). getResourceAsStream(Classname) returns the original bytecode, even if loadClass() returns a modified class. The attached patch fixes this. Also can you add hansel (http://hansel.sourceforge.net, a code coverage testing extension to JUnit) to the list of projects using BCEL? thanks, Niklas --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
patch.txt
(text/plain, 4.4 KB)
? patch.txt
Index: ClassLoader.java
===================================================================
RCS file: /home/cvspublic/jakarta-bcel/src/java/org/apache/bcel/util/ClassLoader.java,v
retrieving revision 1.6
diff -u -r1.6 ClassLoader.java
--- ClassLoader.java 13 Jun 2002 09:32:50 -0000 1.6
+++ ClassLoader.java 4 Apr 2003 09:36:53 -0000
@@ -84,6 +84,8 @@
*/
public class ClassLoader extends java.lang.ClassLoader {
private Hashtable classes = new Hashtable(); // Hashtable is synchronized thus thread-safe
+ private Hashtable javaClasses = new Hashtable();
+
private String[] ignored_packages = {
"java.", "javax.", "sun."
};
@@ -122,48 +124,64 @@
this.ignored_packages = new_p;
}
+ private JavaClass loadSpecialClass(String class_name) throws ClassNotFoundException {
+ JavaClass clazz = null;
+ if((clazz=(JavaClass)javaClasses.get(class_name)) == null) {
+ // Special request?
+ if(class_name.indexOf("$$BCEL$$") >= 0) {
+ clazz = createClass(class_name);
+ } else {
+ // Load classes via repository
+ if ((clazz = repository.loadClass(class_name)) != null) {
+ clazz = modifyClass(clazz);
+ } else {
+ throw new ClassNotFoundException(class_name);
+ }
+ }
+
+ javaClasses.put(class_name, clazz);
+ }
+
+ return clazz;
+ }
+
+ private boolean ignoreClass(String class_name) {
+ for(int i=0; i < ignored_packages.length; i++) {
+ if(class_name.startsWith(ignored_packages[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
protected Class loadClass(String class_name, boolean resolve)
- throws ClassNotFoundException
- {
+ throws ClassNotFoundException {
+
Class cl = null;
- /* First try: lookup hash table.
+ /* lookup hash table.
*/
if((cl=(Class)classes.get(class_name)) == null) {
- /* Second try: Load system class using system class loader. You better
+ /* Load system class using system class loader. You better
* don't mess around with them.
*/
- for(int i=0; i < ignored_packages.length; i++) {
- if(class_name.startsWith(ignored_packages[i])) {
- cl = deferTo.loadClass(class_name);
- break;
- }
- }
-
- if(cl == null) {
- JavaClass clazz = null;
-
- /* Third try: Special request?
- */
- if(class_name.indexOf("$$BCEL$$") >= 0)
- clazz = createClass(class_name);
- else { // Fourth try: Load classes via repository
- if ((clazz = repository.loadClass(class_name)) != null) {
- clazz = modifyClass(clazz);
+ if (ignoreClass(class_name)) {
+ cl = deferTo.loadClass(class_name);
+ } else {
+ JavaClass clazz = loadSpecialClass(class_name);
+
+ if(clazz != null) {
+ byte[] bytes = clazz.getBytes();
+ cl = defineClass(class_name, bytes, 0, bytes.length);
+ } else {
+ // Use default class loader
+ cl = Class.forName(class_name);
}
- else
- throw new ClassNotFoundException(class_name);
- }
-
- if(clazz != null) {
- byte[] bytes = clazz.getBytes();
- cl = defineClass(class_name, bytes, 0, bytes.length);
- } else // Fourth try: Use default class loader
- cl = Class.forName(class_name);
- }
- if(resolve)
- resolveClass(cl);
+ if(resolve)
+ resolveClass(cl);
+ }
}
classes.put(class_name, cl);
@@ -171,6 +189,25 @@
return cl;
}
+ public InputStream getResourceAsStream(String name) {
+ if (name.endsWith(".class")) {
+ String classname = name.substring(0, name.length() - 6).replace('/', '.');
+
+ if (!ignoreClass(classname)) {
+ try {
+ JavaClass clazz = loadSpecialClass(classname);
+ if (clazz != null) {
+ return new ByteArrayInputStream(clazz.getBytes());
+ }
+ } catch (ClassNotFoundException cnfe) {
+ cnfe.printStackTrace();
+ }
+ }
+ }
+
+ return deferTo.getResourceAsStream(name);
+ }
+
/** Override this method if you want to alter a class before it gets actually
* loaded. Does nothing by default.
*/
@@ -181,7 +218,7 @@
/**
* Override this method to create you own classes on the fly. The
* name contains the special token $$BCEL$$. Everything before that
- * token is consddered to be a package name. You can encode you own
+ * token is considered to be a package name. You can encode you own
* arguments into the subsequent string. You must regard however not
* to use any "illegal" characters, i.e., characters that may not
* appear in a Java class name too<br>