From dccb958c636e1a082b8b910c422a851df75b83ba Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 12 Feb 2005 13:51:11 +0000 Subject: [PATCH] Fixes bug libgcj/8170 * java/lang/ClassLoader.java (loadClass): Don't rewrap ClassNotFoundException. * gnu/java/lang/MainThread.java (run): Chain NoClassDefFoundError. * gnu/gcj/runtime/NameFinder.java (remove_interpreter): Removed. (remove_internal): New field superceding remove_interpreter. (sanitizeStack): Remove all no-package classes starting with "_Jv_". Remove no-class methods starting with "_Jv_". And Replace null class or method names with the empty string. Stop at either the MainThread or a real Thread run() method. (newElement): Made static. * java/net/URLClassLoader.java (findClass): Throw ClassNotFoundExceptions including urls, plus parent using toString(). (thisString): New field. (toString): New method. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94935 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 18 ++++++++ libjava/gnu/gcj/runtime/NameFinder.java | 75 ++++++++++++++++++++++----------- libjava/gnu/java/lang/MainThread.java | 4 +- libjava/java/lang/ClassLoader.java | 15 +------ libjava/java/net/URLClassLoader.java | 41 ++++++++++++++++-- 5 files changed, 110 insertions(+), 43 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c17af7b7a8c..579ee763451 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,21 @@ +2005-02-12 Mark Wielaard + + Fixes bug libgcj/8170 + * java/lang/ClassLoader.java (loadClass): Don't rewrap + ClassNotFoundException. + * gnu/java/lang/MainThread.java (run): Chain NoClassDefFoundError. + * gnu/gcj/runtime/NameFinder.java (remove_interpreter): Removed. + (remove_internal): New field superceding remove_interpreter. + (sanitizeStack): Remove all no-package classes starting with "_Jv_". + Remove no-class methods starting with "_Jv_". And Replace null + class or method names with the empty string. Stop at either the + MainThread or a real Thread run() method. + (newElement): Made static. + * java/net/URLClassLoader.java (findClass): Throw + ClassNotFoundExceptions including urls, plus parent using toString(). + (thisString): New field. + (toString): New method. + 2005-02-10 Tom Tromey * external/sax/Makefile.in: Rebuilt. diff --git a/libjava/gnu/gcj/runtime/NameFinder.java b/libjava/gnu/gcj/runtime/NameFinder.java index 024a6eeb232..b14bbf93327 100644 --- a/libjava/gnu/gcj/runtime/NameFinder.java +++ b/libjava/gnu/gcj/runtime/NameFinder.java @@ -37,8 +37,8 @@ import java.io.File; * Whether calls to unknown functions (class and method names are unknown) * should be removed from the stack trace. Only done when the stack is * sanitized. - *
    gnu.gcj.runtime.NameFinder.remove_interpreter - * Whether runtime interpreter calls (methods in the _Jv_InterpMethod class + *
      gnu.gcj.runtime.NameFinder.remove_internal + * Whether runtime internal calls (methods in the internal _Jv_* classes * and functions starting with 'ffi_') should be removed from the stack * trace. Only done when the stack is sanitized.
    *
      gnu.gcj.runtime.NameFinder.use_addr2line @@ -72,10 +72,18 @@ public class NameFinder = Boolean.valueOf(System.getProperty ("gnu.gcj.runtime.NameFinder.remove_unknown", "true") ).booleanValue(); - private static final boolean remove_interpreter - = Boolean.valueOf(System.getProperty + + // The remove_interpreter name is an old 3.3/3.4 (deprecated) synonym. + private static final boolean remove_internal + = (Boolean.valueOf(System.getProperty + ("gnu.gcj.runtime.NameFinder.remove_internal", "true") + ).booleanValue() + || + Boolean.valueOf(System.getProperty ("gnu.gcj.runtime.NameFinder.remove_interpreter", "true") - ).booleanValue(); + ).booleanValue() + ); + private static final boolean use_addr2line = Boolean.valueOf(System.getProperty ("gnu.gcj.runtime.NameFinder.use_addr2line", "true") @@ -280,7 +288,7 @@ public class NameFinder consName = className.substring(lastDot + 1) + '('; int unknown = 0; - int interpreter = 0; + int internal = 0; int last_throw = -1; int length = elements.length; int end = length-1; @@ -300,19 +308,23 @@ public class NameFinder || MName.startsWith("fillInStackTrace(")))) { last_throw = i; - // Reset counting of unknown and interpreter frames. + // Reset counting of unknown and internal frames. unknown = 0; - interpreter = 0; + internal = 0; } else if (remove_unknown && CName == null && (MName == null || MName.startsWith("0x"))) unknown++; - else if (remove_interpreter + else if (remove_internal && ((CName == null && MName != null && MName.startsWith("ffi_")) - || (CName != null && CName.equals("_Jv_InterpMethod")))) - interpreter++; - else if ("main(java.lang.String[])".equals(MName)) + || (CName != null && CName.startsWith("_Jv_")) + || (CName == null && MName != null + && MName.startsWith("_Jv_")))) + internal++; + else if (("java.lang.Thread".equals(CName) + || "gnu.java.lang.MainThread".equals(CName)) + && "run()".equals(MName)) { end = i; break; @@ -321,11 +333,11 @@ public class NameFinder int begin = last_throw+1; // Now filter out everything at the start and the end that is not part - // of the "normal" user program including any elements that are interpreter + // of the "normal" user program including any elements that are internal // calls or have no usefull information whatsoever. // Unless that means we filter out all info. - int nr_elements = end-begin-unknown-interpreter+1; - if ((begin > 0 || end < length-1 || unknown > 0 || interpreter > 0) + int nr_elements = end - begin - unknown - internal + 1; + if ((begin > 0 || end < length-1 || unknown > 0 || internal > 0) && nr_elements > 0) { stack = new StackTraceElement[nr_elements]; @@ -337,14 +349,27 @@ public class NameFinder if (remove_unknown && CName == null && (MName == null || MName.startsWith("0x"))) ; // Skip unknown frame - else if (remove_interpreter + else if (remove_internal && ((CName == null - && MName != null && MName.startsWith("ffi_")) - || (CName != null && CName.equals("_Jv_InterpMethod")))) - ; // Skip interpreter runtime frame + && MName != null && MName.startsWith("ffi_")) + || (CName != null && CName.startsWith("_Jv_")) + || (CName == null && MName != null + && MName.startsWith("_Jv_")))) + ; // Skip internal runtime frame else { - stack[pos] = elements[i]; + // Null Class or Method name in elements are not allowed. + if (MName == null || CName == null) + { + MName = MName == null ? "" : MName; + CName = CName == null ? "" : CName; + stack[pos] = newElement(elements[i].getFileName(), + elements[i].getLineNumber(), + CName, MName, + elements[i].isNativeMethod()); + } + else + stack[pos] = elements[i]; pos++; } } @@ -359,11 +384,11 @@ public class NameFinder * Native helper method to create a StackTraceElement. Needed to work * around normal Java access restrictions. */ - native private StackTraceElement newElement(String fileName, - int lineNumber, - String className, - String methName, - boolean isNative); + native static private StackTraceElement newElement(String fileName, + int lineNumber, + String className, + String methName, + boolean isNative); /** * Creates a StackTraceElement given a string and a filename. diff --git a/libjava/gnu/java/lang/MainThread.java b/libjava/gnu/java/lang/MainThread.java index 5937b870d3e..14a00ca8d9b 100644 --- a/libjava/gnu/java/lang/MainThread.java +++ b/libjava/gnu/java/lang/MainThread.java @@ -95,7 +95,9 @@ final class MainThread extends Thread } catch (ClassNotFoundException x) { - throw new NoClassDefFoundError(klass_name); + NoClassDefFoundError ncdfe = new NoClassDefFoundError(klass_name); + ncdfe.initCause(x); + throw ncdfe; } } diff --git a/libjava/java/lang/ClassLoader.java b/libjava/java/lang/ClassLoader.java index 71f41c1cf1b..46e523c6834 100644 --- a/libjava/java/lang/ClassLoader.java +++ b/libjava/java/lang/ClassLoader.java @@ -288,8 +288,6 @@ public abstract class ClassLoader if (c != null) return c; - ClassNotFoundException ex = null; - // Can the class be loaded by a parent? try { @@ -306,20 +304,9 @@ public abstract class ClassLoader } catch (ClassNotFoundException e) { - ex = e; } // Still not found, we have to do it ourself. - try - { - c = findClass(name); - } - catch (ClassNotFoundException cause) - { - if (ex != null) - throw new ClassNotFoundException(ex.toString(), cause); - else - throw cause; - } + c = findClass(name); if (resolve) resolveClass(c); return c; diff --git a/libjava/java/net/URLClassLoader.java b/libjava/java/net/URLClassLoader.java index 3efc5dca76f..0da6a0356b2 100644 --- a/libjava/java/net/URLClassLoader.java +++ b/libjava/java/net/URLClassLoader.java @@ -1,5 +1,6 @@ /* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -958,7 +959,7 @@ public class URLClassLoader extends SecureClassLoader resource = loader.getResource(resourceName); } if (resource == null) - throw new ClassNotFoundException(className + " not found in " + urls); + throw new ClassNotFoundException(className + " not found in " + this); // Try to read the class data, create the CodeSource, Package and // construct the class (and watch out for those nasty IOExceptions) @@ -1039,9 +1040,43 @@ public class URLClassLoader extends SecureClassLoader } catch (IOException ioe) { - throw new ClassNotFoundException(className, ioe); + ClassNotFoundException cnfe; + cnfe = new ClassNotFoundException(className + " not found in " + this); + cnfe.initCause(ioe); + throw cnfe; } } + + // Cached String representation of this URLClassLoader + private String thisString; + + /** + * Returns a String representation of this URLClassLoader giving the + * actual Class name, the URLs that are searched and the parent + * ClassLoader. + */ + public String toString() + { + if (thisString == null) + { + StringBuffer sb = new StringBuffer(); + sb.append(this.getClass().getName()); + sb.append("{urls=[" ); + URL[] thisURLs = getURLs(); + for (int i = 0; i < thisURLs.length; i++) + { + sb.append(thisURLs[i]); + if (i < thisURLs.length - 1) + sb.append(','); + } + sb.append(']'); + sb.append(", parent="); + sb.append(getParent()); + sb.append('}'); + thisString = sb.toString(); + } + return thisString; + } /** * Finds the first occurrence of a resource that can be found. The locations -- 2.11.4.GIT