RE: [cp-patches] RFC: Robustness fixes
Roman Kennke wrote: > my collegue Fridjof has been playing around with data flow > analysis and spotted some interesting points where we could improve > robustness a little. For the most part this creates local variables > for fields in some places (see ChangeLog entry below) and operates > on these instead of the fields themselves. This way we make 100% > sure that the fields isn't nullified in between. While it may appear > clear to us that this never happens, with the described approach > it can easily be proven(!) that this can't happen (for example, > using DFA tools). IMO the SystemProperties changes are wrong. If there is a bug somewhere that causes a property to by queried *during* the static initializer of SystemProperties, we *want* the system to crash with a NullPointerException, not to silently fail and cause problems down the road. Regards, Jeroen
RE: [cp-patches] Patch: RFC: changing parts of VM reflection API
Tom Tromey wrote: > I'm posting this for comment. > > This is the patch to change Method/Field/Constructor to have a > 'getModifiersInternal' method, which returns the un-masked modifiers > as read from the .class file. This lets us implement the new > 1.5 reflection predicates such as isSynthetic. Looks good to me. > Note that we could also do something similar to this for Class. I > think we ought to but I'd prefer to do it as a separate patch. VMClass.getModifiers() already should return the raw modifiers. Of course, for Class there is the added complication of inner classes that have an additional modifiers word (which ATM is selected by a boolean passed to VMClass.getModifiers, which is a bit ugly). Regards, Jeroen
RE: [cp-patches] [generics] FYI: Getting ready for concurrency
Andrew John Hughes wrote: > I'm committing the attached patch which adds some features required by > the new concurrency tree prepared by Tom Tromey and documented by > myself. +public class Unsafe Unsafe should be final, otherwise you can create an instance by subclassing and capturing the this in the finalize method. (Note that gnu.classpath.* classes aren't (shouldn't be) visible to untrusted code, so this is just an additional precaution.) Regards, Jeroen
[cp-patches] [generics] FYI: Method & Constructor fix
Hi, Committed. Regards, Jeroen 2006-03-27 Jeroen Frijters <[EMAIL PROTECTED]> * vm/reference/java/lang/reflect/Constructor.java (getTypeParameters): Check return value of getSignature for null. * vm/reference/java/lang/reflect/Method.java (getTypeParameters): Check return value of getSignature for null. Index: vm/reference/java/lang/reflect/Constructor.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Constructor.java,v retrieving revision 1.11.2.11 diff -u -r1.11.2.11 Constructor.java --- vm/reference/java/lang/reflect/Constructor.java 25 Mar 2006 01:46:13 - 1.11.2.11 +++ vm/reference/java/lang/reflect/Constructor.java 27 Mar 2006 09:44:22 - @@ -265,6 +265,8 @@ public TypeVariable>[] getTypeParameters() { String sig = getSignature(); +if (sig == null) + return new TypeVariable[0]; MethodSignatureParser p = new MethodSignatureParser(this, sig); return p.getTypeParameters(); } Index: vm/reference/java/lang/reflect/Method.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Method.java,v retrieving revision 1.12.2.9 diff -u -r1.12.2.9 Method.java --- vm/reference/java/lang/reflect/Method.java 25 Mar 2006 01:46:13 - 1.12.2.9 +++ vm/reference/java/lang/reflect/Method.java 27 Mar 2006 09:36:30 - @@ -302,6 +302,8 @@ public TypeVariable[] getTypeParameters() { String sig = getSignature(); +if (sig == null) + return new TypeVariable[0]; MethodSignatureParser p = new MethodSignatureParser(this, sig); return p.getTypeParameters(); }
RE: [cp-patches] FYI: Merging reflection stuff from generics branch
Tom Tromey wrote: > > "Twisti" == Christian Thalinger > <[EMAIL PROTECTED]> writes: > > Twisti> Sorry. Completely the wrong methods. I meant: > Twisti> isSynthetic > Twisti> isAnnotation > Twisti> isEnum > > Actually I've been curious to know why these don't simply use > getModifiers (or whatever the equivalent is on VMClass). > I was meaning to make that change... I suspect it was due to uncertainty about what VMClass.getModifier() returns (i.e. whether it masked out the relevant bits or not). Clearly it is better to do it the same way as you did it in Method et al. It may also be a good idea to factor the current VMClass.getModifiers() into two different methods instead of passing a boolean. Regards, Jeroen
RE: [cp-patches] Patch: FYI: mime.types parsing
Tom Tromey wrote: > This updates our internal mime type database in two ways. First, we > now parse /etc/mime.types, if it exists. IMO that needs to be factored into a VM interface. On Windows it doesn't make sense to try to read /etc/ (and it may in fact represent a security issue to do so). Plus on some platforms there might be a mime database available elsewhere. Regards, Jeroen
[cp-patches] FYI: Added Class.cast() method
Hi, Committed. Regards, Jeroen 2006-04-05 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Class.java (cast): New method. Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.44 diff -u -r1.44 Class.java --- java/lang/Class.java3 Apr 2006 20:09:13 - 1.44 +++ java/lang/Class.java5 Apr 2006 09:14:37 - @@ -1294,6 +1294,21 @@ } /** + * Returns the specified object, cast to this Class' type. + * + * @param obj the object to cast + * @throws ClassCastException if obj is not an instance of this class + * @since 1.5 + */ + /* FIXME[GENERICS]: Should be T cast(Object obj) */ + public Object cast(Object obj) + { +if (obj != null && ! isInstance(obj)) + throw new ClassCastException(); +return obj; /* FIXME[GENERICS]: Should be cast to T */ + } + + /** * Like getField(String) but without the security checks and * returns null instead of throwing NoSuchFieldException. */
RE: [cp-patches] RFC: fix for PR 24642
Casey Marshall wrote: > This patch implements seeding of all SecureRandom instances if you > call `nextBytes' without providing a seed yourself, and provides a > better implementation of the static `getSeed' method. > > This introduces a new VM class, `java.security.VMSecureRandom,' that > contains a single static method for generating real (or close to > real) random seed values. The default implementation uses a set of > eight "dueling" threads, each of which increments a counter in a > tight loop. I like this approach (as a default). +private byte value; +private boolean running; For it to work consistently on all VMs both the "value" and "running" field in Spinner must be marked volatile. Thanks, Jeroen
[cp-patches] FYI: Merged a few java.lang.* changes from generics branch
Hi, I merged a few things from the generics branch to the trunk. Regards, Jeroen 2006-04-17 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Boolean.java: Implemented Comparable. * java/lang/ClassLoader.java (getResources): Not final anymore in 1.5. * java/lang/Enum.java, java/lang/Iterable.java: Copied from generics branch. * java/lang/Thread.java (destroy): Marked deprecated. * java/lang/ThreadLocal.java (remove): New method. Index: java/lang/Boolean.java === RCS file: /cvsroot/classpath/classpath/java/lang/Boolean.java,v retrieving revision 1.24 diff -u -r1.24 Boolean.java --- java/lang/Boolean.java 7 Nov 2005 17:02:19 - 1.24 +++ java/lang/Boolean.java 17 Apr 2006 10:09:27 - @@ -1,5 +1,5 @@ /* Boolean.java -- object wrapper for boolean - Copyright (C) 1998, 2001, 2002, 2005 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2002, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -47,9 +47,9 @@ * @author Paul Fisher * @author Eric Blake ([EMAIL PROTECTED]) * @since 1.0 - * @status updated to 1.4 + * @status updated to 1.5 */ -public final class Boolean implements Serializable +public final class Boolean implements Serializable, Comparable { /** * Compatible with JDK 1.0.2+. @@ -223,34 +223,37 @@ } /** - * If the String argument is "true", ignoring case, return true. - * Otherwise, return false. + * Compares this Boolean to another. * - * @param b String to parse + * @param b the Boolean to compare this Boolean to + * @return 0 if both Booleans represent the same value, a positive number + * if this Boolean represents true and the other false, and a negative + * number otherwise. * @since 1.5 */ - public static boolean parseBoolean(String b) + public int compareTo(Boolean other) { -return "true".equalsIgnoreCase(b) ? true : false; +return value == other.value ? 0 : (value ? 1 : -1); } - + /** - * Compares this Boolean to another. - * @param b the Boolean to compare this Boolean to - * @return 0 if both Booleans represent the same value, a positive number - * if this Boolean represents true and b represents false, or a negative - * number otherwise. + * Bridge method + */ + public int compareTo(Object other) + { +return compareTo((Boolean)other); + } + + /** + * If the String argument is "true", ignoring case, return true. + * Otherwise, return false. + * + * @param b String to parse * @since 1.5 */ - public int compareTo (Boolean b) + public static boolean parseBoolean(String b) { -if (b == null) - throw new NullPointerException("argument passed to compareTo(Boolean) cannot be null"); - -if (this.value == b.value) - return 0; -if (this.value == true) - return 1; -return -1; +return "true".equalsIgnoreCase(b) ? true : false; } + } Index: java/lang/ClassLoader.java === RCS file: /cvsroot/classpath/classpath/java/lang/ClassLoader.java,v retrieving revision 1.58 diff -u -r1.58 ClassLoader.java --- java/lang/ClassLoader.java 21 Sep 2005 22:35:32 - 1.58 +++ java/lang/ClassLoader.java 17 Apr 2006 09:20:26 - @@ -628,8 +628,9 @@ * @return an enumaration of all resources found * @throws IOException if I/O errors occur in the process * @since 1.2 + * @specnote this was final prior to 1.5 */ - public final Enumeration getResources(String name) throws IOException + public Enumeration getResources(String name) throws IOException { Enumeration parentResources; if (parent == null) Index: java/lang/Enum.java === RCS file: java/lang/Enum.java diff -N java/lang/Enum.java --- /dev/null 1 Jan 1970 00:00:00 - +++ java/lang/Enum.java 17 Apr 2006 10:18:51 - @@ -0,0 +1,146 @@ +/* Enum.java - Base class for all enums + Copyright (C) 2004, 2005 Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath 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 2, or (at your option) +any later version. + +GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically
[cp-patches] FYI: Implement java.lang.Iterable in java.util.Collection
Hi, Committed. Regards, Jeroen 2006-04-17 Jeroen Frijters <[EMAIL PROTECTED]> * java/util/Collection.java: Implemented java.lang.Iterable. Index: java/util/Collection.java === RCS file: /cvsroot/classpath/classpath/java/util/Collection.java,v retrieving revision 1.12 diff -u -r1.12 Collection.java --- java/util/Collection.java 2 Jul 2005 20:32:41 - 1.12 +++ java/util/Collection.java 17 Apr 2006 10:36:21 - @@ -81,9 +81,9 @@ * @see Arrays * @see AbstractCollection * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 (minus generics) */ -public interface Collection +public interface Collection extends Iterable { /** * Add an element to this collection.
[cp-patches] [generics] FYI updated AccessibleObject to 1.5
Hi, I updated java.lang.reflect.AccessibleObject to 1.5. I wrote some throwaway code to figure out the JDK 1.5 behavior for these methods and duplicated that. Regards, Jeroen 2006-04-21 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/reflect/AccessibleObject.java: Implemented AnnotatedElement. (getAnnotation, getAnnotations, getDeclaredAnnotations, isAnnotationPresent): New methods. Index: java/lang/reflect/AccessibleObject.java === RCS file: /cvsroot/classpath/classpath/java/lang/reflect/AccessibleObject.java,v retrieving revision 1.4.2.3 diff -u -r1.4.2.3 AccessibleObject.java --- java/lang/reflect/AccessibleObject.java 2 Aug 2005 20:12:23 - 1.4.2.3 +++ java/lang/reflect/AccessibleObject.java 21 Apr 2006 08:53:14 - @@ -1,5 +1,5 @@ /* java.lang.reflect.AccessibleObject - Copyright (C) 2001, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,8 @@ package java.lang.reflect; +import java.lang.annotation.Annotation; + /** * This class is the superclass of various reflection classes, and * allows sufficiently trusted code to bypass normal restrictions to @@ -53,9 +55,10 @@ * @see Method * @see ReflectPermission * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class AccessibleObject +implements AnnotatedElement { /** * True if this object is marked accessible, which means the reflected @@ -156,4 +159,24 @@ throw new SecurityException("Cannot make object accessible: " + this); this.flag = flag; } + + public T getAnnotation(Class annotationClass) + { +throw new AssertionError("Subclass must override this method"); + } + + public Annotation[] getAnnotations() + { +return getDeclaredAnnotations(); + } + + public Annotation[] getDeclaredAnnotations() + { +throw new AssertionError("Subclass must override this method"); + } + + public boolean isAnnotationPresent(Class annotationClass) + { +return getAnnotation(annotationClass) != null; + } }
[cp-patches] FYI: Updated java.lang.reflect.AccessibleObject to 1.5
Hi, Merged from the generics branch. Regards, Jeroen 2006-04-21 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/reflect/AccessibleObject.java: Implemented AnnotatedElement. (getAnnotation, getAnnotations, getDeclaredAnnotations, isAnnotationPresent): New methods. Index: java/lang/reflect/AccessibleObject.java === RCS file: /cvsroot/classpath/classpath/java/lang/reflect/AccessibleObject.java,v retrieving revision 1.7 diff -u -r1.7 AccessibleObject.java --- java/lang/reflect/AccessibleObject.java 2 Jul 2005 20:32:39 - 1.7 +++ java/lang/reflect/AccessibleObject.java 21 Apr 2006 12:47:41 - @@ -1,5 +1,5 @@ /* java.lang.reflect.AccessibleObject - Copyright (C) 2001, 2005 Free Software Foundation, Inc. + Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,8 @@ package java.lang.reflect; +import java.lang.annotation.Annotation; + /** * This class is the superclass of various reflection classes, and * allows sufficiently trusted code to bypass normal restrictions to @@ -53,9 +55,10 @@ * @see Method * @see ReflectPermission * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class AccessibleObject +implements AnnotatedElement { /** * True if this object is marked accessible, which means the reflected @@ -156,4 +159,26 @@ throw new SecurityException("Cannot make object accessible: " + this); this.flag = flag; } + + /* FIXME[GENERICS]: T getAnnotation(Class ) */ + public Annotation getAnnotation(Class annotationClass) + { +throw new AssertionError("Subclass must override this method"); + } + + public Annotation[] getAnnotations() + { +return getDeclaredAnnotations(); + } + + public Annotation[] getDeclaredAnnotations() + { +throw new AssertionError("Subclass must override this method"); + } + + /* FIXME[GENERICS]: Signature is Class */ + public boolean isAnnotationPresent(Class annotationClass) + { +return getAnnotation(annotationClass) != null; + } }
[cp-patches] RFC: Class/VMClass merge from generics branch
Hi, Since we can now support annotations on the trunk I'd like to merge Class/VMClass with the versions from the generics branch (modulo any 1.5 language feature, of course). If your VM already supports the generics branch, no changes should be needed. If you don't yet support it, you need to implement VMClass.getDeclaredAnnotations, if you use a custom version of VMClass, you also need to copy VMClass.getEnumConstants. Unless someone complains, this will go in next week. Regards, Jeroen Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.47 diff -u -r1.47 Class.java --- java/lang/Class.java7 Apr 2006 19:45:45 - 1.47 +++ java/lang/Class.java21 Apr 2006 13:06:17 - @@ -1,5 +1,5 @@ /* Class.java -- Representation of a Java class. - Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -44,7 +44,9 @@ import java.io.InputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; @@ -100,7 +102,7 @@ * @see ClassLoader */ public final class Class - implements Serializable, Type, GenericDeclaration + implements Serializable, Type, AnnotatedElement, GenericDeclaration { /** * Compatible with JDK 1.0+. @@ -640,17 +642,16 @@ public boolean equals(Object o) { - if(o instanceof MethodKey) + if (o instanceof MethodKey) { - MethodKey m = (MethodKey)o; - if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) { - for(int i = 0; i < params.length; i++) + for (int i = 0; i < params.length; i++) { - if(m.params[i] != params[i]) - { - return false; - } + if (m.params[i] != params[i]) + return false; } return true; } @@ -1260,7 +1261,7 @@ return c.defaultAssertionStatus; } - /* + /** * * Casts this class to represent a subclass of the specified class. * This method is useful for `narrowing' the type of a class so that @@ -1369,6 +1370,20 @@ } /** + * Returns the enumeration constants of this class, or + * null if this class is not an Enum. + * + * @return an array of Enum constants + * associated with this class, or null if this + * class is not an enum. + * @since 1.5 + */ + public Object[] getEnumConstants() + { +return VMClass.getEnumConstants(this); + } + + /** * Returns true if this class is an Enum. * * @return true if this is an enumeration class. @@ -1421,6 +1436,50 @@ } /** + * Returns this class' annotation for the specified annotation type, + * or null if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this class' annotation for the specified type, or + * null if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: T getAnnotation(Class ) */ + public Annotation getAnnotation(Class annotationClass) + { +Annotation foundAnnotation = null; +Annotation[] annotations = getAnnotations(); +for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; +return foundAnnotation; + } + + /** + * Returns all annotations associated with this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return this class' annotations. + * @since 1.5 + */ + public Annotation[] getAnnotations() + { +HashSet set = new HashSet(); +set.addAll(Arrays.asList(getDeclaredAnnotations())); +Class[] interfaces = getInterfaces(); +for (int i = 0; i < interfaces.length; i++) + set.addAll(Arrays.asList(interfaces[i].getAnnotations())); +Class superClass = getSuperclass(); +if (superClass != null) + set.addAll(Arrays.asList(superClass.getAnnotations())); +return (Annotation[]) set.toArray(new Annotation[set.size()]); + } + + /**
RE: [cp-patches] RFC: Class/VMClass merge from generics branch
Andrew John Hughes wrote: > On Fri, 2006-04-21 at 15:23 +0200, Jeroen Frijters wrote: > > Since we can now support annotations on the trunk I'd like to merge > > Class/VMClass with the versions from the generics branch > > (modulo any 1.5 language feature, of course). > > I thought we agreed that these should be exactly the same, > and that new language features shouldn't be part of the runtime > interface? Yes, but these were already in the generics version of VMClass, so I just left them in. I definitely agree that it would be better to take them out (and also to move getEnumConstants entirely to Class, I don't see why anyone would want to specialize it). > > If your VM already supports the generics branch, no changes > > should be needed. If you don't yet support it, you need to > > implement VMClass.getDeclaredAnnotations, if you use a custom > > version of VMClass, you also need to copy VMClass.getEnumConstants. > > Is implementing getDeclaredAnnotations in full really the best way to > go? I'm not saying it isn't (you may have studied this in more detail > than I), but I was under the impression that some of it may be > simplified by a gnu.java.lang.annotation.Annotation with native parts. There's probably room for more Java code and IKVM has a bunch more that I'd be happy to check into Classpath, but I haven't thought deeply about it outside of the IKVM context. I also have annotation serialization support (compatible with the JDK), but that requires a class in the sun.* package (which I implemented by looking at the serialized form of an annotation) and I'm not sure if everyone would agree to that. Regards, Jeroen
[cp-patches] RFC: v2 of the Class/VMClass merge from generics branch
Hi, I moved getEnumConstant from VMClass to Class in this version of the patch. Again, unless anyone complains this will go in sometime next week. Regards, Jeroen Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.47 diff -u -r1.47 Class.java --- java/lang/Class.java7 Apr 2006 19:45:45 - 1.47 +++ java/lang/Class.java22 Apr 2006 09:09:25 - @@ -1,5 +1,5 @@ /* Class.java -- Representation of a Java class. - Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -44,7 +44,9 @@ import java.io.InputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; @@ -100,7 +102,7 @@ * @see ClassLoader */ public final class Class - implements Serializable, Type, GenericDeclaration + implements Serializable, Type, AnnotatedElement, GenericDeclaration { /** * Compatible with JDK 1.0+. @@ -640,17 +642,16 @@ public boolean equals(Object o) { - if(o instanceof MethodKey) + if (o instanceof MethodKey) { - MethodKey m = (MethodKey)o; - if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) { - for(int i = 0; i < params.length; i++) + for (int i = 0; i < params.length; i++) { - if(m.params[i] != params[i]) - { - return false; - } + if (m.params[i] != params[i]) + return false; } return true; } @@ -1260,7 +1261,7 @@ return c.defaultAssertionStatus; } - /* + /** * * Casts this class to represent a subclass of the specified class. * This method is useful for `narrowing' the type of a class so that @@ -1369,6 +1370,46 @@ } /** + * Returns the enumeration constants of this class, or + * null if this class is not an Enum. + * + * @return an array of Enum constants + * associated with this class, or null if this + * class is not an enum. + * @since 1.5 + */ + /* FIXME[GENERICS]: T[] getEnumConstants() */ + public Object[] getEnumConstants() + { +if (isEnum()) + { + try + { + return (Object[]) + getMethod("values", new Class[0]).invoke(null, new Object[0]); + } + catch (NoSuchMethodException exception) + { + throw new Error("Enum lacks values() method"); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + catch (InvocationTargetException exception) + { + throw new + RuntimeException("The values method threw an exception", + exception); + } + } +else + { + return null; + } + } + + /** * Returns true if this class is an Enum. * * @return true if this is an enumeration class. @@ -1421,6 +1462,50 @@ } /** + * Returns this class' annotation for the specified annotation type, + * or null if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this class' annotation for the specified type, or + * null if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: T getAnnotation(Class ) */ + public Annotation getAnnotation(Class annotationClass) + { +Annotation foundAnnotation = null; +Annotation[] annotations = getAnnotations(); +for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; +return foundAnnotation; + } + + /** + * Returns all annotations associated with this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return this class' annotations. + * @since 1.5 + */ + public Annotation[] getAnnotations() + { +HashSet set = new HashSet(); +set.addAll(Arrays.asList(getDeclaredAnnotations())
RE: [cp-patches] RFC: Class/VMClass merge from generics branch
Andrew John Hughes wrote: > Ah, so IKVM already has some of this implemented? Great. I guess it > depends on other VM implementors and how much control they want over > this. I think the implementation of the signature parser was a good > idea, and the annotation support should have a similar division. Yeah. Annotation support in IKVM is an interesting case, because Java annotation are so similar to .NET custom attributes, I convert the annotations into .NET attributes to make it possible to use them in other .NET languages as well. Because of these special requirements I haven't really thought about how more traditional VM would handle them, but I welcome input from other VM implementers and share code where possible. Regards, Jeroen
RE: [cp-patches] [generics] FYI updated AccessibleObject to 1.5
Andrew John Hughes wrote: > Please document new methods as you add them. There are already > plenty of new undocumented methods on the generics branch, and I'd > appreciate it if we didn't add more. > These methods are very similar to those in java.lang.Class, so they > could be more or less copied across. I was under the impression that the documentation is simply inherited from the interface, is that not the case? I'm not very familair with how Javadoc works, so maybe I'm missing something. Regards, Jeroen
[cp-patches] [generics] FYI: Removed VMPackage and implemented Package.getDeclaredAnnotations()
Hi, I removed the VMPackage class, because Package.getDeclaredAnnotations can easily be implemented without VM specific code. Implementing Package.getDeclaredAnnotations required access to the class loader that defined the package, so I added a ClassLoader argument to the Package constructor. If you're a VM maintainer and you use a custom version of VMClassLoader, this is a breaking change and your version of VMClassLoader will have to be updated as well. I will shortly merge these changes with the trunk. Regards, Jeroen 2006-04-21 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/ClassLoader.java (definePackage): Added argument to Package constructor. * java/lang/Package.java (Package): Added ClassLoader argument. (loader): New field. (getDeclaredAnnotations): Implemented without help from VMPackage. * vm/reference/java/lang/VMClassLoader.java (static): Added argument to Package constructor. * vm/reference/java/lang/VMPackage.java: Removed. Index: java/lang/ClassLoader.java === RCS file: /cvsroot/classpath/classpath/java/lang/ClassLoader.java,v retrieving revision 1.31.2.15 diff -u -r1.31.2.15 ClassLoader.java --- java/lang/ClassLoader.java 14 Dec 2005 09:30:45 - 1.31.2.15 +++ java/lang/ClassLoader.java 23 Apr 2006 08:50:49 - @@ -836,7 +836,7 @@ throw new IllegalArgumentException("Package " + name + " already defined"); Package p = new Package(name, specTitle, specVendor, specVersion, -implTitle, implVendor, implVersion, sealed); +implTitle, implVendor, implVersion, sealed, this); synchronized (definedPackages) { definedPackages.put(name, p); Index: java/lang/Package.java === RCS file: /cvsroot/classpath/classpath/java/lang/Package.java,v retrieving revision 1.11.2.4 diff -u -r1.11.2.4 Package.java --- java/lang/Package.java 2 Aug 2005 20:12:23 - 1.11.2.4 +++ java/lang/Package.java 23 Apr 2006 08:51:26 - @@ -101,6 +101,9 @@ /** If sealed the origin of the package classes, otherwise null */ private final URL sealed; + /** The class loader that defined this package */ + private ClassLoader loader; + /** * A package local constructor for the Package class. All parameters except * the name of the package may be null. @@ -118,7 +121,8 @@ */ Package(String name, String specTitle, String specVendor, String specVersion, - String implTitle, String implVendor, String implVersion, URL sealed) + String implTitle, String implVendor, String implVersion, URL sealed, + ClassLoader loader) { if (name == null) throw new IllegalArgumentException("null Package name"); @@ -131,6 +135,7 @@ this.specVendor = specVendor; this.specVersion = specVersion; this.sealed = sealed; +this.loader = loader; } /** @@ -368,7 +373,15 @@ */ public Annotation[] getDeclaredAnnotations() { -return VMPackage.getDeclaredAnnotations(this); +try + { +Class pkgInfo = Class.forName(name + ".package-info", false, loader); +return pkgInfo.getDeclaredAnnotations(); + } +catch (ClassNotFoundException _) + { +return new Annotation[0]; + } } /** Index: vm/reference/java/lang/VMClassLoader.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMClassLoader.java,v retrieving revision 1.16.2.14 diff -u -r1.16.2.14 VMClassLoader.java --- vm/reference/java/lang/VMClassLoader.java 17 Apr 2006 09:32:39 - 1.16.2.14 +++ vm/reference/java/lang/VMClassLoader.java 23 Apr 2006 08:52:53 - @@ -101,6 +101,7 @@ "GNU Classpath", "GNU", Configuration.CLASSPATH_VERSION, + null, null); definedPackages.put(packages[i], p); Index: vm/reference/java/lang/VMPackage.java === RCS file: vm/reference/java/lang/VMPackage.java diff -N vm/reference/java/lang/VMPackage.java --- vm/reference/java/lang/VMPackage.java 21 Sep 2005 21:32:40 - 1.1.2.2 +++ /dev/null 1 Jan 1970 00:00:00 - @@ -1,76 +0,0 @@ -/* VMPackage.java -- VM Specific Package methods - Copyright (C) 2005 Free Software Foundation - -This file is part of GNU Classpath. - -GNU Classpath 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 2, or (at your option) -any later version. - -GNU Classpath is distributed in t
[cp-patches] FYI: Merged Package annotation support from generics branch
Hi, This patch merges the package annotation support I just checked into the generics branch back to the trunk. Note again that if you're a VM maintainer and you use a custom version of VMClassLoader, this is a breaking change and your version of VMClassLoader will have to be updated as well (simply add an extra null parameter to the Package constructor). Regards, Jeroen 2006-04-23 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/ClassLoader.java (definePackage): Added argument to Package constructor. * java/lang/Package.java (Package): Added ClassLoader argument. (loader): New field. (getAnnotation, getAnnotations, getDeclaredAnnotations, isAnnotationPresent): Merged from generics branch. * vm/reference/java/lang/VMClassLoader.java (static): Added argument to Package constructor. Index: java/lang/ClassLoader.java === RCS file: /cvsroot/classpath/classpath/java/lang/ClassLoader.java,v retrieving revision 1.60 diff -u -r1.60 ClassLoader.java --- java/lang/ClassLoader.java 22 Apr 2006 22:22:08 - 1.60 +++ java/lang/ClassLoader.java 23 Apr 2006 09:46:51 - @@ -836,7 +836,7 @@ throw new IllegalArgumentException("Package " + name + " already defined"); Package p = new Package(name, specTitle, specVendor, specVersion, -implTitle, implVendor, implVersion, sealed); +implTitle, implVendor, implVersion, sealed, this); synchronized (definedPackages) { definedPackages.put(name, p); Index: java/lang/Package.java === RCS file: /cvsroot/classpath/classpath/java/lang/Package.java,v retrieving revision 1.17 diff -u -r1.17 Package.java --- java/lang/Package.java 2 Jul 2005 20:32:38 - 1.17 +++ java/lang/Package.java 23 Apr 2006 09:46:04 - @@ -39,6 +39,8 @@ import gnu.classpath.VMStackWalker; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.net.URL; import java.util.NoSuchElementException; import java.util.StringTokenizer; @@ -70,9 +72,10 @@ * @see ClassLoader#definePackage(String, String, String, String, String, * String, String, URL) * @since 1.2 - * @status updated to 1.4 + * @status updated to 1.5 */ public class Package + implements AnnotatedElement { /** The name of the Package */ private final String name; @@ -98,6 +101,9 @@ /** If sealed the origin of the package classes, otherwise null */ private final URL sealed; + /** The class loader that defined this package */ + private ClassLoader loader; + /** * A package local constructor for the Package class. All parameters except * the name of the package may be null. @@ -115,7 +121,8 @@ */ Package(String name, String specTitle, String specVendor, String specVersion, - String implTitle, String implVendor, String implVersion, URL sealed) + String implTitle, String implVendor, String implVersion, URL sealed, + ClassLoader loader) { if (name == null) throw new IllegalArgumentException("null Package name"); @@ -128,6 +135,7 @@ this.specVendor = specVendor; this.specVersion = specVersion; this.sealed = sealed; +this.loader = loader; } /** @@ -233,7 +241,7 @@ * * @return true if the version is compatible, false otherwise * - * @Throws NumberFormatException if either version string is invalid + * @throws NumberFormatException if either version string is invalid * @throws NullPointerException if either version string is null */ public boolean isCompatibleWith(String version) @@ -315,4 +323,82 @@ return ("package " + name + (specTitle == null ? "" : ", " + specTitle) + (specVersion == null ? "" : ", version " + specVersion)); } + + /** + * Returns this package's annotation for the specified annotation type, + * or null if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this package's annotation for the specified type, or + * null if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: T getAnnotation(Class ) */ + public Annotation getAnnotation(Class annotationClass) + { +Annotation foundAnnotation = null; +Annotation[] annotations = getAnnotations(); +for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; +return foundAnnotation; + } + + /** + * Returns all annotations associated with this package. If there are + * no annotations associated with this package, then a zero-len
[cp-patches] [generics] FYI: Moved getEnumConstants implementation from VMClass to Class
Hi, Since I'm shortly going to commit my change to trunk, I've committed this to the generics branch to make the VM interfaces the same. Regards, Jeroen 2006-04-23 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Class.java (getEnumConstants): Implemented without delegating to VMClass. * vm/reference/java/lang/VMClass.java (getEnumConstants): Removed. Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.22.2.23 diff -u -r1.22.2.23 Class.java --- java/lang/Class.java14 Apr 2006 06:50:29 - 1.22.2.23 +++ java/lang/Class.java23 Apr 2006 10:08:23 - @@ -1374,7 +1374,31 @@ */ public T[] getEnumConstants() { -return (T[])VMClass.getEnumConstants(this); +if (isEnum()) + { + try + { + return (T[]) getMethod("values").invoke(null); + } + catch (NoSuchMethodException exception) + { + throw new Error("Enum lacks values() method"); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + catch (InvocationTargetException exception) + { + throw new + RuntimeException("The values method threw an exception", + exception); + } + } +else + { + return null; + } } /** Index: vm/reference/java/lang/VMClass.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMClass.java,v retrieving revision 1.10.2.12 diff -u -r1.10.2.12 VMClass.java --- vm/reference/java/lang/VMClass.java 14 Apr 2006 06:50:38 - 1.10.2.12 +++ vm/reference/java/lang/VMClass.java 23 Apr 2006 10:07:22 - @@ -1,5 +1,5 @@ /* VMClass.java -- VM Specific Class methods - Copyright (C) 2003, 2004, 2005 Free Software Foundation + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -41,7 +41,6 @@ import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; @@ -333,46 +332,6 @@ } /** - * Returns the enumeration constants of this class, or - * null if this class is not an Enum. - * - * @param klass the class whose enumeration constants should be returned. - * @return an array of Enum constants - * associated with this class, or null if this - * class is not an enum. - * @since 1.5 - */ - static T[] getEnumConstants(Class klass) - { -if (isEnum(klass)) - { - try - { - return (T[]) - klass.getMethod("values").invoke(null); - } - catch (NoSuchMethodException exception) - { - throw new Error("Enum lacks values() method"); - } - catch (IllegalAccessException exception) - { - throw new Error("Unable to access Enum class"); - } - catch (InvocationTargetException exception) - { - throw new - RuntimeException("The values method threw an exception", - exception); - } - } -else - { - return null; - } - } - - /** * Returns all annotations directly defined by the specified class. If * there are no annotations associated with this class, then a zero-length * array will be returned. The returned array may be modified by the client
[cp-patches] FYI: Class annotation and getEnumConstant support
Hi, I committed my patch as previously announced. Regards, Jeroen 2006-04-23 Jeroen Frijters <[EMAIL PROTECTED]> * NEWS: Added information about annotation support. * java/lang/Class.java: Implement AnnotatedElement. (equals): Reformatted to match generics branch. (getEnumConstants): Implemented. (getAnnotation, getAnnotations, getDeclaredAnnotations, isAnnotationPresent): Merged from generics branch. * vm/reference/java/lang/VMClass.java (getDeclaredAnnotations): New method. Index: NEWS === RCS file: /cvsroot/classpath/classpath/NEWS,v retrieving revision 1.135 diff -u -r1.135 NEWS --- NEWS22 Apr 2006 21:52:18 - 1.135 +++ NEWS23 Apr 2006 10:20:19 - @@ -48,6 +48,11 @@ consistent with one another. As a result, the main branch includes an additional environ() function in VMSystem and an additional argument has been added to nativeSpawn() in VMProcess. +* Annotation support is now available in the main branch, if the VM supports + it. The VM should implement VMClass.getDeclaredAnnotations, + Constructor.getAnnotation, Constructor.getDeclaredAnnotations, + Field.getAnnotation, Field.getDeclaredAnnotations, Method.getAnnotation and + Method.getDeclaredAnnotations. New in release 0.90 (March 6, 2006) Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.47 diff -u -r1.47 Class.java --- java/lang/Class.java7 Apr 2006 19:45:45 - 1.47 +++ java/lang/Class.java22 Apr 2006 09:09:25 - @@ -1,5 +1,5 @@ /* Class.java -- Representation of a Java class. - Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -44,7 +44,9 @@ import java.io.InputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; @@ -100,7 +102,7 @@ * @see ClassLoader */ public final class Class - implements Serializable, Type, GenericDeclaration + implements Serializable, Type, AnnotatedElement, GenericDeclaration { /** * Compatible with JDK 1.0+. @@ -640,17 +642,16 @@ public boolean equals(Object o) { - if(o instanceof MethodKey) + if (o instanceof MethodKey) { - MethodKey m = (MethodKey)o; - if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) { - for(int i = 0; i < params.length; i++) + for (int i = 0; i < params.length; i++) { - if(m.params[i] != params[i]) - { - return false; - } + if (m.params[i] != params[i]) + return false; } return true; } @@ -1260,7 +1261,7 @@ return c.defaultAssertionStatus; } - /* + /** * * Casts this class to represent a subclass of the specified class. * This method is useful for `narrowing' the type of a class so that @@ -1369,6 +1370,46 @@ } /** + * Returns the enumeration constants of this class, or + * null if this class is not an Enum. + * + * @return an array of Enum constants + * associated with this class, or null if this + * class is not an enum. + * @since 1.5 + */ + /* FIXME[GENERICS]: T[] getEnumConstants() */ + public Object[] getEnumConstants() + { +if (isEnum()) + { + try + { + return (Object[]) + getMethod("values", new Class[0]).invoke(null, new Object[0]); + } + catch (NoSuchMethodException exception) + { + throw new Error("Enum lacks values() method"); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + catch (InvocationTargetException exception) + { + throw new + RuntimeException("The values method threw an exception", + exception); + } + } +else + { + return null; + } + } + + /** * Returns true if this class is an Enum. * * @return true if this is an enumeration class. @@ -1421,6 +1462,50 @@ }
RE: [cp-patches] FYI: Merged Package annotation support fromgenerics branch
Mark Wielaard wrote: > On Sun, 2006-04-23 at 11:57 +0200, Jeroen Frijters wrote: > > Note again that if you're a VM > > maintainer and you use a custom version of > > VMClassLoader, this is a breaking change and your version of > > VMClassLoader will have to be updated as well (simply add > an extra null > > parameter to the Package constructor). > > It would be nice to keep the constructor that doesn't take an extra > argument and passes null itself to make migration easier. Good suggestion. I will add that (and mark it deprecated). > Also this deserves a NEWS entry. OK. > Note that this breaks the build since Class.getDeclaredAnnotations() > isn't implemented on the trunk yet. Oops. Wrong commit order. I've committed my other change as well, so we should be OK now. Regards, Jeroen
[cp-patches] FYI: Added back Package constructor
Hi, As per Mark's suggestion, I've added back the Package constructor that doesn't take the ClassLoader. It's marked deprecated and will go away in the future, so please migrate to the new constructor. Regards, Jeroen 2006-04-23 Jeroen Frijters <[EMAIL PROTECTED]> * NEWS: Added entry about new Package constructor. * java/lang/Package.java: Added compatibility constructor to ease VM interface migration. Index: NEWS === RCS file: /cvsroot/classpath/classpath/NEWS,v retrieving revision 1.136 diff -u -r1.136 NEWS --- NEWS23 Apr 2006 10:21:56 - 1.136 +++ NEWS23 Apr 2006 10:30:55 - @@ -53,6 +53,9 @@ Constructor.getAnnotation, Constructor.getDeclaredAnnotations, Field.getAnnotation, Field.getDeclaredAnnotations, Method.getAnnotation and Method.getDeclaredAnnotations. +* java.lang.Package now has a new constructor that takes the defining + ClassLoader as an extra argument. If you use a custom version of + VMClassLoader, please switch it to use this constructor. New in release 0.90 (March 6, 2006) Index: java/lang/Package.java === RCS file: /cvsroot/classpath/classpath/java/lang/Package.java,v retrieving revision 1.18 diff -u -r1.18 Package.java --- java/lang/Package.java 23 Apr 2006 09:52:37 - 1.18 +++ java/lang/Package.java 23 Apr 2006 10:29:35 - @@ -1,5 +1,6 @@ /* Package.java -- information about a package - Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2005, 2006 + Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -104,6 +105,17 @@ /** The class loader that defined this package */ private ClassLoader loader; + /** @deprecated Please use the other constructor that takes the class loader + * that defines the Package. + */ + Package(String name, + String specTitle, String specVendor, String specVersion, + String implTitle, String implVendor, String implVersion, URL sealed) + { +this(name, specTitle, specVendor, specVersion, implTitle, implVendor, + implVersion, sealed, null); + } + /** * A package local constructor for the Package class. All parameters except * the name of the package may be null.
[cp-patches] [generics] FYI: Added back Package constructor
Hi, Same change as on the trunk. Regards, Jeroen 2006-04-23 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Package.java: Added compatibility constructor to ease VM interface migration. Index: java/lang/Package.java === RCS file: /cvsroot/classpath/classpath/java/lang/Package.java,v retrieving revision 1.11.2.5 diff -u -r1.11.2.5 Package.java --- java/lang/Package.java 23 Apr 2006 09:32:30 - 1.11.2.5 +++ java/lang/Package.java 23 Apr 2006 10:34:47 - @@ -104,6 +104,17 @@ /** The class loader that defined this package */ private ClassLoader loader; + /** @deprecated Please use the other constructor that takes the class loader + * that defines the Package. + */ + Package(String name, + String specTitle, String specVendor, String specVersion, + String implTitle, String implVendor, String implVersion, URL sealed) + { +this(name, specTitle, specVendor, specVersion, implTitle, implVendor, + implVersion, sealed, null); + } + /** * A package local constructor for the Package class. All parameters except * the name of the package may be null.
RE: [cp-patches] FYI: Merged Package annotation supportfromgenerics branch
Mark Wielaard wrote: > I believe that with your and Andrew's work we are now synced > for the VM Classes between generics and trunk. Yeah, I think so too. > There is one change to Class.newInstance() from you that > never went in. > I didn't see any objections to it, but also no strong support > for it. Do you still need that one? > http://developer.classpath.org/pipermail/classpath/2006-March/ > 000728.html I currently have a hack in place to replace the Class.newInstance method and while that's a bit ugly it works and I think I'd rather have that hack than some VM specific hook at this point in time, but I may revisit the issue when I'm more confident that the hook is correct and could possibly be appropriate for other VMs as well. > It would be a good point to declare the vm classes interface > frozen for now and work towards a new snapshot release that includes > them. Agreed. > Unfortunately I am going on vacation in about an hour and then attend > LinuxTag the week after so I won't be able to coordinate it. But if > someone else would and could see if the vm interface is doable for > other runtimes (I believe it works with jamvm and cacao already with > only minor patches that add some noops for now) that would be > appreciated. I would hardly call going on vacation "unfortunate" ;-) Prettige vakantie! I don't anticipate any difficulaties for the other VMs, but should they arise, I'm sure we'll work it out ;-) Regards, Jeroen
RE: [cp-patches] FYI: Merged Package annotation support fromgenerics branch
[EMAIL PROTECTED] wrote: > > "Mark" == Mark Wielaard <[EMAIL PROTECTED]> writes: > > Mark> It would be a good point to declare the vm classes interface > Mark> frozen for now and work towards a new snapshot release that > Mark> includes them. > > Actually I would like to make one more change before 0.91. This one > is very simple, though, and won't affect VMs much, since it is > compatible with what is in the tree now. > > I've appended it. Please comment, everybody. I'll check it in after > a few days if there is no objection. Yes, I agree we should put this in. Thanks, Jeroen
[cp-patches] FYI: Fixed StringBuilder to use VMSystem.arraycopy
Hi, As reported by Edwin Steiner, StringBuilder used System.arraycopy instead of VMSystem.arraycopy and that causes bootstrap issues. I committed the attached patch to fix this. Regards, Jeroen 2006-04-28 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/StringBuilder.java (ensureCapacity, getChars, append(StringBuffer), append(char[],int,int), delete, replace, insert(int,char[],int,int), insert(int,String), insert(int,char), trimToSize): Replaced System.arraycopy calls with VMSystem.arraycopy. Index: java/lang/StringBuilder.java === RCS file: /cvsroot/classpath/classpath/java/lang/StringBuilder.java,v retrieving revision 1.7 diff -u -r1.7 StringBuilder.java --- java/lang/StringBuilder.java2 Mar 2006 20:18:44 - 1.7 +++ java/lang/StringBuilder.java28 Apr 2006 06:45:22 - @@ -206,7 +206,7 @@ int max = value.length * 2 + 2; minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); char[] nb = new char[minimumCapacity]; -System.arraycopy(value, 0, nb, 0, count); +VMSystem.arraycopy(value, 0, nb, 0, count); value = nb; } } @@ -285,7 +285,7 @@ { if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) throw new StringIndexOutOfBoundsException(); -System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); +VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); } /** @@ -355,7 +355,7 @@ { int len = stringBuffer.count; ensureCapacity(count + len); - System.arraycopy(stringBuffer.value, 0, value, count, len); + VMSystem.arraycopy(stringBuffer.value, 0, value, count, len); count += len; } return this; @@ -395,7 +395,7 @@ if (offset < 0 || count < 0 || offset > data.length - count) throw new StringIndexOutOfBoundsException(); ensureCapacity(this.count + count); -System.arraycopy(data, offset, value, this.count, count); +VMSystem.arraycopy(data, offset, value, this.count, count); this.count += count; return this; } @@ -558,7 +558,7 @@ // This will unshare if required. ensureCapacity(count); if (count - end != 0) - System.arraycopy(value, end, value, start, count - end); + VMSystem.arraycopy(value, end, value, start, count - end); count -= end - start; return this; } @@ -599,7 +599,7 @@ ensureCapacity(count + delta); if (delta != 0 && end < count) - System.arraycopy(value, end, value, end + delta, count - end); + VMSystem.arraycopy(value, end, value, end + delta, count - end); str.getChars(0, len, value, start); count += delta; @@ -677,8 +677,8 @@ || str_offset < 0 || str_offset > str.length - len) throw new StringIndexOutOfBoundsException(); ensureCapacity(count + len); -System.arraycopy(value, offset, value, offset + len, count - offset); -System.arraycopy(str, str_offset, value, offset, len); +VMSystem.arraycopy(value, offset, value, offset + len, count - offset); +VMSystem.arraycopy(str, str_offset, value, offset, len); count += len; return this; } @@ -717,7 +717,7 @@ str = "null"; int len = str.count; ensureCapacity(count + len); -System.arraycopy(value, offset, value, offset + len, count - offset); +VMSystem.arraycopy(value, offset, value, offset + len, count - offset); str.getChars(0, len, value, offset); count += len; return this; @@ -814,7 +814,7 @@ if (offset < 0 || offset > count) throw new StringIndexOutOfBoundsException(offset); ensureCapacity(count + 1); -System.arraycopy(value, offset, value, offset + 1, count - offset); +VMSystem.arraycopy(value, offset, value, offset + 1, count - offset); value[offset] = ch; count++; return this; @@ -1063,7 +1063,7 @@ if (count < value.length) { char[] newValue = new char[count]; -System.arraycopy(value, 0, newValue, 0, count); +VMSystem.arraycopy(value, 0, newValue, 0, count); value = newValue; } }
[cp-patches] TransformerFactoryImpl
Hi Chris, I know nothing about the XML APIs, so I hope this isn't a dumb question but I just debugged some code from a user of IKVM and it did the following: SAXTransformerFactory factory = (SAXTransformerFactory)TransformerFactory.newInstance(); On the JDK this works. Now obviously the documentation doesn't specify that this is legal, but since there is code out there that assumes this work (dcm4che2, no idea what it does) I was wondering if we could/should support it too. What do you think? Regards, Jeroen
[cp-patches] RFC: java/util/Collections.java fails to compile with ECJ 3.2 RC3
Hi Tom, Since you're the resident JLS expert, could you please have a look at this patch? The cast fails on both ECJ 3.2 RC3 and javac 1.5.0, so I assume the code is incorrect (and I can vaguely see why it might be) and I would like to propose the following workaround. Thanks, Jeroen Index: java/util/Collections.java === RCS file: /cvsroot/classpath/classpath/java/util/Collections.java,v retrieving revision 1.28.2.20 diff -u -r1.28.2.20 Collections.java --- java/util/Collections.java 2 Apr 2006 22:36:33 - 1.28.2.20 +++ java/util/Collections.java 10 May 2006 06:45:29 - @@ -6576,7 +6576,7 @@ if (entries == null) { Class> klass = - (Class>) Map.Entry.class; + (Class>) (Class) Map.Entry.class; entries = new CheckedEntrySet,K,V>(m.entrySet(), klass, keyType,
RE: [cp-patches] Patch: RFC: splitting up URLClassLoader
Tom Tromey wrote: > I'm posting this for comments. > > In libgcj we have a divergence in URLClassLoader, because we have > other ways to load classes. In particular we can extract classes > from shared libraries via 'gcjlib' URLs, and URLClassLoader knows > about this. > > I'd like to re-merge here so that we have one less divergence to carry > around. > > This patch allows this by moving the URLLoader class, and friends, to > gnu.java.net.loader. Then it changes URLClassLoader to look for > other loaders via reflection. This will let us add new URLLoader > subclasses in the libgcj tree and have things work properly. I like it. > +catch (ClassNotFoundException ignore) > + { > +// Fall through. > + } > +catch (NoSuchMethodException ignore) > + { > +// Fall through. > + } > +catch (InstantiationException ignore) > + { > +// Fall through. > + } > +catch (InvocationTargetException ignore) > + { > +// Fall through. > + } > +catch (IllegalAccessException ignore) > + { > +// Fall through. > + } Do we really want to swallow all these exception? Obviously ClassNotFoundException, but others should only result from programming errors or classes that incorrectly follow the naming convention, right? Regards, Jeroen
[cp-patches] RE: java/awt/Toolkit.java fix
Committed. > -Original Message- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Jeroen Frijters > Sent: Monday, May 15, 2006 17:50 > To: GNU Classpath Project; Mark Wielaard > Subject: RFC: java/awt/Toolkit.java fix > > Hi Mark, > > Sorry for being so late, but I would like to get this patch in the > release, because I made some changes to IKVM class loading > that exposed > the fact that Toolkit incorrectly calls ClassLoader.loadClass > instead of > Class.forName (and hence failing to load my AWT toolkit). > > If you'd rather not make this change this late in the release, I > understand and I'll base my IKVM release on a patched version. > > Thanks, > Jeroen > > 2006-05-15 Jeroen Frijters <[EMAIL PROTECTED]> > > * java/awt/Toolkit.java (getDefaultToolkit): Use Class.forName() > instead of directly calling the class loader. > Index: java/awt/Toolkit.java === RCS file: /cvsroot/classpath/classpath/java/awt/Toolkit.java,v retrieving revision 1.40 diff -u -r1.40 Toolkit.java --- java/awt/Toolkit.java 20 Apr 2006 20:06:13 - 1.40 +++ java/awt/Toolkit.java 15 May 2006 15:36:12 - @@ -544,7 +544,7 @@ return ClassLoader.getSystemClassLoader(); } }); -Class cls = cl.loadClass(toolkit_name); +Class cls = Class.forName(toolkit_name, true, cl); Object obj = cls.newInstance(); if (!(obj instanceof Toolkit)) throw new AWTError(toolkit_name + " is not a subclass of " +
[cp-patches] RFC: Making java.lang.Thread.getContextClassLoader() lazy for threads created outside of Java
Hi, I would like to apply the attached patch. It fixes a potential initialization order issue for VMs that support running Java code without first initializing the VM explicitly (like IKVM does). The current code calls ClassLoader.getSystemClassLoader() in the Thread constructor that the VM uses to create thread objects for threads that are started outside of Java (for example, through JNI code that attaches a thread), this can cause problems if this is the first time that ClassLoader.getSystemClassLoader() is being called and the system class loader construction code path happens to call Thread.currentThread(). I can also fix this in IKVM specific code, but that would be uglier and I believe that other VMs will also benefit from this change (at the small cost of an extra boolean in each Thread instance). Any comments? Regards, Jeroen 2006-05-17 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Thread.java (contextClassLoaderIsSystemClassLoader): New field. (Thread(VMThread,String,int,boolean)): Set contextClassLoaderIsSystemClassLoader to true. (getContextClassLoader): Check contextClassLoaderIsSystemClassLoader. (setContextClassLoader): Clear contextClassLoaderIsSystemClassLoader. Index: java/lang/Thread.java === RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v retrieving revision 1.22 diff -u -r1.22 Thread.java --- java/lang/Thread.java 9 May 2006 14:42:13 - 1.22 +++ java/lang/Thread.java 17 May 2006 09:41:02 - @@ -131,7 +131,8 @@ /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; - + private boolean contextClassLoaderIsSystemClassLoader; + /** This thread's ID. */ private final long threadId; @@ -388,12 +389,11 @@ this.name = name; this.priority = priority; this.daemon = daemon; -this.contextClassLoader = ClassLoader.getSystemClassLoader(); +contextClassLoaderIsSystemClassLoader = true; synchronized (Thread.class) { this.threadId = nextThreadId++; } - } /** @@ -751,7 +751,8 @@ if (sm != null) // XXX Don't check this if the caller's class loader is an ancestor. sm.checkPermission(new RuntimePermission("getClassLoader")); -return contextClassLoader; +return contextClassLoaderIsSystemClassLoader ? +ClassLoader.getSystemClassLoader() : contextClassLoader; } /** @@ -772,6 +773,7 @@ if (sm != null) sm.checkPermission(new RuntimePermission("setContextClassLoader")); this.contextClassLoader = classloader; +contextClassLoaderIsSystemClassLoader = false; } /**
RE: [cp-patches] RFC: Making java.lang.Thread.getContextClassLoader() lazy for threads created outside of Java
Archie Cobbs wrote: > Jeroen Frijters wrote: > > I would like to apply the attached patch. It fixes a potential > > initialization order issue for VMs that support running Java code > > without first initializing the VM explicitly (like IKVM does). > > Dumb questions: why don't you initialize the VM in JNI_CreateJavaVM()? > What is gained by deferring initialization? In IKVM you can use statically compiled Java code from any another .NET language without ever knowing or caring that it was Java code, so there is no obvious place to call any initialize method. Regards, Jeroen
[cp-patches] FYI: Tiny perf and compatibility tweak for gnu/java/net/loader/JarURLLoader.java
Hi, I committed the attached "optimization" to the URL construction in JarURLLoader. Not really to improve performance, but to make Google's new Google Web Toolkit shell startup (it's broken and does an identity comparison on the string returned by URL.getProtocol()). Regards, Jeroen 2006-05-18 Jeroen Frijters <[EMAIL PROTECTED]> * gnu/java/net/loader/JarURLLoader.java (JarURLLoader): Use a slightly more efficient URL constructor. Index: gnu/java/net/loader/JarURLLoader.java === RCS file: /cvsroot/classpath/classpath/gnu/java/net/loader/JarURLLoader.java,v retrieving revision 1.1 diff -u -r1.1 JarURLLoader.java --- gnu/java/net/loader/JarURLLoader.java 15 May 2006 23:29:36 - 1.1 +++ gnu/java/net/loader/JarURLLoader.java 18 May 2006 11:45:30 - @@ -32,20 +32,14 @@ { super(classloader, cache, factory, baseURL, absoluteUrl); -// Cache url prefix for all resources in this jar url. -String external = baseURL.toExternalForm(); -StringBuffer sb = new StringBuffer(external.length() + 6); -sb.append("jar:"); -sb.append(external); -sb.append("!/"); -String jarURL = sb.toString(); - this.classPath = null; URL baseJarURL = null; JarFile jarfile = null; try { -baseJarURL = new URL(null, jarURL, cache.get(factory, "jar")); +// Cache url prefix for all resources in this jar url. +String base = baseURL.toExternalForm() + "!/"; +baseJarURL = new URL("jar", "", -1, base, cache.get(factory, "jar")); jarfile = ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
[cp-patches] FYI: A few java.lang.Thread fixes
Hi, Since nobody complained about my context class loader fix, I'm checking it in. I also made the generation of anonymous thread names thread safe and corrected the security check in getContextClassLoader. Regards, Jeroen 2006-05-19 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Thread.java (contextClassLoaderIsSystemClassLoader): New field. (Thread(ThreadGroup,Runnable)): Call createAnonymousThreadName. (Thread(VMThread,String,int,boolean)): Call createAnonymousThreadName and set contextClassLoaderIsSystemClassLoader. (Thread(ThreadGroup,Runnable,String,long)): Set contextClassLoaderIsSystemClassLoader. (createAnonymousThreadName): New method. (getContextClassLoader): Check contextClassLoaderIsSystemClassLoader and fixed security check. (setContextClassLoader): Clear contextClassLoaderIsSystemClassLoader. Index: java/lang/Thread.java === RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v retrieving revision 1.22 diff -u -r1.22 Thread.java --- java/lang/Thread.java 9 May 2006 14:42:13 - 1.22 +++ java/lang/Thread.java 19 May 2006 09:33:13 - @@ -38,6 +38,7 @@ package java.lang; +import gnu.classpath.VMStackWalker; import gnu.java.util.WeakIdentityHashMap; import java.security.Permission; import java.util.Map; @@ -131,7 +132,8 @@ /** The context classloader for this Thread. */ private ClassLoader contextClassLoader; - + private boolean contextClassLoaderIsSystemClassLoader; + /** This thread's ID. */ private final long threadId; @@ -248,7 +250,7 @@ */ public Thread(ThreadGroup group, Runnable target) { -this(group, target, "Thread-" + ++numAnonymousThreadsCreated, 0); +this(group, target, createAnonymousThreadName(), 0); } /** @@ -364,6 +366,8 @@ priority = current.priority; daemon = current.daemon; contextClassLoader = current.contextClassLoader; +contextClassLoaderIsSystemClassLoader = +current.contextClassLoaderIsSystemClassLoader; group.addThread(this); InheritableThreadLocal.newChildThread(this); @@ -373,6 +377,9 @@ * Used by the VM to create thread objects for threads started outside * of Java. Note: caller is responsible for adding the thread to * a group and InheritableThreadLocal. + * Note: This constructor should not call any methods that could result + * in a call to Thread.currentThread(), because that makes life harder + * for the VM. * * @param vmThread the native thread * @param name the thread name or null to use the default naming scheme @@ -384,16 +391,32 @@ this.vmThread = vmThread; this.runnable = null; if (name == null) - name = "Thread-" + ++numAnonymousThreadsCreated; + name = createAnonymousThreadName(); this.name = name; this.priority = priority; this.daemon = daemon; -this.contextClassLoader = ClassLoader.getSystemClassLoader(); +// By default the context class loader is the system class loader, +// we set a flag to signal this because we don't want to call +// ClassLoader.getSystemClassLoader() at this point, because on +// VMs that lazily create the system class loader that might result +// in running user code (when a custom system class loader is specified) +// and that user code could call Thread.currentThread(). +// ClassLoader.getSystemClassLoader() can also return null, if the system +// is currently in the process of constructing the system class loader +// (and, as above, the constructiong sequence calls Thread.currenThread()). +contextClassLoaderIsSystemClassLoader = true; synchronized (Thread.class) { this.threadId = nextThreadId++; } + } + /** + * Generate a name for an anonymous thread. + */ + private static synchronized String createAnonymousThreadName() + { +return "Thread-" + ++numAnonymousThreadsCreated; } /** @@ -746,12 +769,18 @@ */ public synchronized ClassLoader getContextClassLoader() { -// Bypass System.getSecurityManager, for bootstrap efficiency. +ClassLoader loader = contextClassLoaderIsSystemClassLoader ? +ClassLoader.getSystemClassLoader() : contextClassLoader; +// Check if we may get the classloader SecurityManager sm = SecurityManager.current; -if (sm != null) - // XXX Don't check this if the caller's class loader is an ancestor. - sm.checkPermission(new RuntimePermission("getClassLoader")); -return contextClassLoader; +if (loader != null && sm != null) + { +// Get the calling classloader + ClassLoader cl = VMStackWalker.getCallingClassLoader(); +if (cl != null && !cl.isAncestorOf(loader)) + sm.checkPermission(new RuntimePer
RE: [cp-patches] [generics] Patch: RFC: import jsr166
Tom Tromey wrote: > * A sanitize-jsr166 script which is run on a pristine download in > order to remove copyrighted code and to change sun.* references to > the appropriate gnu.* references. Is there a (legal?) reason why we can't keep the sun.* references? Regards, Jeroen
RE: [cp-patches] RFC: qt-peer: remove INIT_LOAD_LIBRARY
Tom Tromey wrote: > (It is kind of lame to have INIT_LOAD_LIBRARY > floating around just for libgcj... but I suppose it isn't a very big > maintenance burden. Or does IKVM use it too?) IKVM doesn't use it, because it replaces all VM classes that have native methods. As a long term goal, I'd still like to get rid of the Configuration class altogether, but I don't know if others support that goal too ;-) Regards, Jeroen
RE: [cp-patches] [generics] Patch: RFC: import jsr166
Tom Tromey wrote: > Jeroen> Tom Tromey wrote: > >> * A sanitize-jsr166 script which is run on a pristine download in > >> order to remove copyrighted code and to change sun.* references to > >> the appropriate gnu.* references. > > Jeroen> Is there a (legal?) reason why we can't keep the > sun.* references? > > Nope. When I initially was doing this we were still avoiding sun.*. > But I think we're going to have to break that tradition for > annotations (i.e., please submit your serialization thing). OK. In that case I propose we keep the jsr166 classes the same and implement the required methods of the two sun.* classes. This also solves Mark's point (which I agree with) that the access check method really doesn't belong in VMStackWalker. Also, I've cleaned up my version of AnnotationInvocationHandler and will post it shortly. > The other issues is not letting user code reference the new APIs, > which AIUI using gnu.classpath.* achieves. But, that solution could > be extended without much trouble. Right. We can easily add sun.* to the list of banned packages. Regards, Jeroen
[cp-patches] RFC: AnnotationInvocationHandler
Hi, As promised here is my cleaned up version of AnnotationInvocationHandler. I intend to check this into the trunk. Regards, Jeroen AnnotationInvocationHandler.java Description: AnnotationInvocationHandler.java
RE: [cp-patches] RFC: AnnotationInvocationHandler
Michael Koch wrote: > On Thu, Jun 08, 2006 at 11:05:53AM +0200, Jeroen Frijters wrote: > > Hi, > > > > As promised here is my cleaned up version of > > AnnotationInvocationHandler. I intend to check this into the trunk. > > Thanks. > > Please use a Unix file encoding when checking it in (line endings). I'm pretty sure cvs does that automatically. Unfortunately my mail server doesn't understand that *.java files are text files and I was too lazy to name the attachment *.txt Regards, Jeroen
[cp-patches] FYI: committed sun/reflect/annotation/AnnotationInvocationHandler.java
Hi, I committed the file as in the previous RFC. Regards, Jeroen 2006-06-09 Jeroen Frijters <[EMAIL PROTECTED]> * sun/reflect/annotation/AnnotationInvocationHandler.java: New file.
[cp-patches] FYI: Small patch for gnu/java/awt/font/opentype/truetype/VirtualMachine.java
Hi, While trying to get True Type font rendering to work I ran into a missing instruction. Fortunately it was a trivial one, so I implemented it. Regards, Jeroen 2006-06-09 Jeroen Frijters <[EMAIL PROTECTED]> * gnu/java/awt/font/opentype/truetype/VirtualMachine.java (executeInstruction): Added NOT support. Index: gnu/java/awt/font/opentype/truetype/VirtualMachine.java === RCS file: /cvsroot/classpath/classpath/gnu/java/awt/font/opentype/truetype/VirtualMachine.java,v retrieving revision 1.1 diff -u -r1.1 VirtualMachine.java --- gnu/java/awt/font/opentype/truetype/VirtualMachine.java 30 Apr 2006 09:45:11 - 1.1 +++ gnu/java/awt/font/opentype/truetype/VirtualMachine.java 9 Jun 2006 09:26:59 - @@ -1066,6 +1066,10 @@ stack[sp] = ((e1 != 0) || (stack[sp] != 0)) ? 1 : 0; break; +case 0x5C: // NOT + stack[sp] = (stack[sp] != 0) ? 0 : 1; + break; + case 0x5e: // SDB, Set Delta Base in the graphics state deltaBase = stack[sp--]; break; @@ -1764,7 +1768,7 @@ /* 50 */ "LT", "LTEQ", "GT", "GTEQ", /* 54 */ "EQ", "NEQ", "INST_56", "INST_57", /* 58 */ "IF", "EIF", "AND", "OR", -/* 5c */ "INST_5C", "INST_5D", "SDB", "SDS", +/* 5c */ "NOT", "INST_5D", "SDB", "SDS", /* 60 */ "ADD", "SUB", "DIV", "MUL", /* 64 */ "ABS", "NEG", "FLOOR", "CEILING", /* 68 */ "ROUND[0]", "ROUND[1]", "ROUND[2]", "ROUND[3]",
[cp-patches] [generics] FYI: Fixed compile error in java/util/Collections.java
Hi, Now that builder is using a new version of ecj, the generics branch no longer compiled due to a cast bug. I checked in a fix. Regards, Jeroen 2006-06-21 Jeroen Frijters <[EMAIL PROTECTED]> * java/util/Collections (entrySet): Fixed compile error. Index: java/util/Collections.java === RCS file: /cvsroot/classpath/classpath/java/util/Collections.java,v retrieving revision 1.28.2.22 diff -u -r1.28.2.22 Collections.java --- java/util/Collections.java 11 Jun 2006 18:23:24 - 1.28.2.22 +++ java/util/Collections.java 18 Jun 2006 08:25:55 - @@ -6619,7 +6619,7 @@ if (entries == null) { Class> klass = - (Class>) Map.Entry.class; + (Class>) (Class) Map.Entry.class; entries = new CheckedEntrySet,K,V>(m.entrySet(), klass, keyType,
RE: [cp-patches] FYI: Add remaining missing Thread methods
Andrew John Hughes wrote: > The attached patch adds the two missing stack trace methods to > Thread. Currently, they are untested, as nothing yet implements > the new VM method for thread stacktraces. Thanks! It doesn't yet work, as ManagementFactory.getThreadMXBean() is currently still unimplemented. > On that note, if there is some way we can reuse the existing stack > trace stuff, let me know. I'm not sure how it respects individual > threads at present. I don't think so and the problems are somewhat different too. Obtaining the stack trace of the current thread is (a little) easer than that of an arbitrary thread (where you have to suspend the thread to be able to safely walk the stack). Regards, Jeroen
RE: [cp-patches] FYI: Handle thread state
Andrew John Hughes wrote: > This patch puts a bit more into thread state handling. I apologize for being blunt, but this patch is unacceptable. It doesn't cover all cases, it's incorrect and inefficient. I really think it's best to leave determining the thread state up to VMThread, except of course that there still needs to be support for threads that don't yet (or no longer) have a VMThread. Below is a patch that shows what I think getState should look like. Regards, Jeroen Index: java/lang/Thread.java === RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v retrieving revision 1.26 diff -u -r1.26 Thread.java --- java/lang/Thread.java 27 Jun 2006 21:57:29 - 1.26 +++ java/lang/Thread.java 29 Jun 2006 08:30:11 - @@ -1239,7 +1239,11 @@ public String getState() { VMThread t = vmThread; -return t == null ? null : t.getState(); +if (t != null) + return t.getState(); +if (group == null) + return "TERMINATED"; +return "NEW"; } /**
RE: [cp-patches] FYI: Handle thread state
Andrew John Hughes wrote: > Based on your comments, it seems you agree with my original intuition > of making this a native VM call (by default) in the majority of > cases, but efficiency would seem to be fairly VM specific. Sure, but Thread.getState() is unlikely to be used very often and should definitely not be performance critical, so it makes sense to have it do some more work, instead of doing the work upfront. > I suppose I was aiming on lightening the load on the VM interface, as > I seem to be throwing tons down there lately. I'd be interested in > comments from other VM coders as to what they feel is best. Providing a correct (but, for example, inefficient) default implementation is a great idea for the VM interface, but IMHO we should not be providing partial implementations. A compile error or exception is way better than subtly incorrect behavior. > I'll revert to something similar this evening, but the real > test will be when I add some of this to gcj. Thanks. I've already implemented the interface in IKVM, so my feedback is based on real experience ;-) Regards, Jeroen
[cp-patches] FYI: New VM helper method ThreadGroup.getThreadFromId
Hi, I added a helper method to ThreadGroup that the VM can use to (relativelyly) efficiently resolve a thread id into a Thread object. Regards, Jeroen 2006-07-01 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/ThreadGroup.java (getThreadFromId, getThreadFromIdImpl): New methods. Index: java/lang/ThreadGroup.java === RCS file: /cvsroot/classpath/classpath/java/lang/ThreadGroup.java,v retrieving revision 1.21 diff -u -r1.21 ThreadGroup.java --- java/lang/ThreadGroup.java 10 May 2006 13:54:51 - 1.21 +++ java/lang/ThreadGroup.java 1 Jul 2006 12:39:11 - @@ -749,4 +749,43 @@ parent.removeGroup(this); } } + + /* + * Helper method for the VM. Find a Thread by its Id. + * + * @param id The Thread Id. + * @return Thread object or null if thread doesn't exist. + */ + static Thread getThreadFromId(long id) + { +return root.getThreadFromIdImpl(id); + } + + private Thread getThreadFromIdImpl(long id) + { +synchronized (threads) + { +for (int i = 0; i < threads.size(); i++) + { +Thread t = (Thread) threads.get(i); +if (t.getId() == id) + return t; + } + } +Vector groups = this.groups; +if (groups != null) + { +synchronized (groups) + { +for (int i = 0; i < groups.size(); i++) + { +ThreadGroup g = (ThreadGroup) groups.get(i); +Thread t = g.getThreadFromIdImpl(id); +if (t != null) + return t; + } + } + } +return null; + } } // class ThreadGroup
RE: [cp-patches] FYI: Fix thread ID start value
Andrew John Hughes wrote: > The attached patch fixes the initialization of the thread IDs > in java.lang.Thread so that it starts at 1. 0 is not a valid > thread ID, and was rightly being thrown out by the managment stuff. You just beat me to it! I hope you don't mind but I checked in my slightly more efficient fix. This way Thread doesn't need to have a static initializer method. Regards, Jeroen 2006-07-01 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/Thread.java: Make thread IDs start from 1 in a more efficient way. Index: java/lang/Thread.java === RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v retrieving revision 1.30 diff -u -r1.30 Thread.java --- java/lang/Thread.java 1 Jul 2006 11:58:39 - 1.30 +++ java/lang/Thread.java 1 Jul 2006 12:54:07 - @@ -147,8 +147,8 @@ /** The next thread number to use. */ private static int numAnonymousThreadsCreated; - /** The next thread ID to use. */ - private static long nextThreadId = 1; + /** Used to generate the next thread ID to use. */ + private static long totalThreadsCreated; /** The default exception handler. */ private static UncaughtExceptionHandler defaultHandler; @@ -367,7 +367,7 @@ synchronized (Thread.class) { -this.threadId = nextThreadId++; +this.threadId = ++totalThreadsCreated; } priority = current.priority; @@ -414,7 +414,7 @@ contextClassLoaderIsSystemClassLoader = true; synchronized (Thread.class) { - this.threadId = nextThreadId++; + this.threadId = ++totalThreadsCreated; } }
RE: [cp-patches] FYI: Fix thread ID start value
Andrew John Hughes wrote: > No problem; the new name makes things a bit clearer too. Really, > though, according to the specification, the ids should be reused after > the thread terminates (which both Tom's original solution and > this patch don't handle). I don't know how necessary this is though, > given that you'd have to have 2^63 - 1 threads to outrun available ids. The spec allows the ids to be reused, but it does not require it. We could add code to handle overflow, but it doesn't seem likely that any real application will ever create more than 2^63 - 1 threads. On my current system it would take about half a million years to instantiate that many thread objects ;-) Regards, Jeroen
RE: [cp-patches] RFC: patch to make gconf as default preference backend
Mario Torre wrote: > This patch makes gconf the default backend. > > The patch works adding a new configure option that let the user to > specify a default implementation (like FileBased or GConfBased ones). > > If the user does not provides this option, than the preference backend > is FileBased (current default). > > Only if the GConf backend is built, than it is used, unless the flag > specify a different default. > > To make this possible, I have added a new field to > gnu.classpath.Configuration.in, this is inherited from the > configure.ac. We're trying to move away from gnu.classpath.Configuration, so this is not ideal. Also, why are you doing this: +System.setProperty("java.util.prefs.PreferencesFactory", + Configuration.DEFAULT_PREFS_PEER); in java.util.prefs.Preferences? I would expect that to be in gnu.classpath.SystemProperties, because this way there is no point to having a system property (as it gets overwritten anyway). How about simply changing the default factory in Preferences.getFactory() to try GConf first and if it doesn't exist fall back to the file based implementation? Your objection that this is inefficient because of the exception doesn't really hold water, as this is only done once (the cached factory is used on subsequent calls). Regards, Jeroen
RE: [cp-patches] RFC: patch to make gconf as default preferencebackend
Mario Torre wrote: > Ops, this had to be System.get(...) > > Rereading the code, this (few lines later) makes more sense: > >String className = > System.getProperty("java.util.prefs.PreferencesFactory", > + > Configuration.DEFAULT_PREFS_PEER); OK. I see what you mean now. > > I would expect that to be in gnu.classpath.SystemProperties, because > > this way there is no point to having a system property (as it gets > > overwritten anyway). > > The fact is that in SystemProperties there are no security checks, but > maybe I have misunderstood how it works. If it is safe, it is better > (and clear) to put it there. What I was suggesting was putting the setProperty("java.util.prefs.PreferencesFactory", Configuration.DEFAULT_PREFS_PEER) in SystemProperties, but I've now read the Sun documentation and I think that there is a better solution: > Andrew suggested me to look at resources/META-INF. Exactly. When configure runs and the GConf preferences backend is specified, create a file in resource/META-INF/services with the name java.util.prefs.PreferencesFactory that contains the class name of the GConf preferences factory. Then you can use gnu.classpath.ServicesFactory to load the provider. > The point here, is to allow some flexibility, GConf, Memory and File > based are our actual backends, but few may be introduced later (an > example would be a backend that uses the default KDE > preference system, a MySQL or PostgreSQL may also came at a later point, > and may be fine, especially for enterprise usage). Absolutely, but I think in these cases people will most likely specify the system property on the command line to pick the required preferences factory. Regards, Jeroen
[cp-patches] RE: patch to make gconf as default preference backend, second try
Mario Torre wrote: > This patch makes the gconf backend the default. > > The configure part of the patch is the same as the one > discussed early, but now the backend name is stored under > META-INF and loaded at runtime using ServiceFactory. > > A new file is introduced in the META-INF directory that is > used to build the actual real resource file, so there is a change in > copy-vmresources.sh to avoid the copy of this new file into the meta > directory. Thanks! This patch looks good to me. However, someone who knows more about ./configure than me should make sure this works and check it in. Regards, Jeroen
[cp-patches] FYI: Removed GTK drop target code from java/awt/Component.java
Hi, I commented out the GTK specific code in java/awt/Component.java. Component cannot have dependencies on any specific type of peer. Lillian could you please find a generic way to do what is required? Regards, Jeroen 2006-08-05 Jeroen Frijters <[EMAIL PROTECTED]> * java/awt/Component.java (setDropTarget): Commented out GTK specific code. Index: java/awt/Component.java === RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v retrieving revision 1.142 diff -u -r1.142 Component.java --- java/awt/Component.java 3 Aug 2006 08:08:14 - 1.142 +++ java/awt/Component.java 5 Aug 2006 09:23:24 - @@ -39,7 +39,7 @@ package java.awt; -import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer; +//import gnu.java.awt.dnd.peer.gtk.GtkDropTargetContextPeer; import java.awt.dnd.DropTarget; import java.awt.event.ActionEvent; @@ -700,9 +700,10 @@ public void setDropTarget(DropTarget dt) { this.dropTarget = dt; -if (dropTarget != null) - dropTarget.getDropTargetContext().addNotify( -new GtkDropTargetContextPeer(this)); +// XXX this is bogus, Component cannot have a dependency on GTK +// if (dropTarget != null) +// dropTarget.getDropTargetContext().addNotify( +// new GtkDropTargetContextPeer(this)); } /**
RE: [cp-patches] RFC: refactoring gnu.java.nio and kqueue Selectors
Tom Tromey wrote: > Casey> - Adds a NativeFD interface to all our Channel > implementations that > Casey> returns the native file descriptor integer. The plan > here would be that > Casey> a Selector implementation could work generically given > that you register > Casey> a Channel that implements NativeFD. > > I think this is the only problematic bit. AIUI we've been careful > until now to keep the 'fd == int' identity hidden in the VM layer. > That makes it all a bit more palatable to VMs on non-posixy platforms; > IKVM comes to mind. Yeah, in general int handles aren't great for me, but in this case I'm not convinced that it's worthwhile to design a more abstract VM layer. Sun already designed these APIs with a provider model (like the regular sockets) and like the regular sockets I just replaced all of the *Impl classes (although for nio I also had to replace some other classes, which wasn't ideal I guess.) One small point regarding this though, I think it's better to move around references to NativeFD and do the getNativeFD call that returns the int as late as possible (i.e. close to the native method invocation). That will at least make it easier to replace NativeFD with another class, should anyone want to do so. And it doesn't hurt perf or make the code any less clear (arguably more clear). Regards, Jeroen
RE: [cp-patches] RFC: refactoring gnu.java.nio and kqueue Selectors
Casey Marshall wrote: > On reflection, it actually seems like a better idea to > augment VMChannel > for this purpose (and refactor VMPlainSocketImpl) instead. Right now > VMChannel takes a Channel object, and extracts the native file > descriptor integer, and uses it internally. Instead, each > Channel object > could just create a VMChannel instance, delegate its method > calls to it, > and in our RI we'll use native FD integers under the hood. > > Some of the methods I was adding to VMChannel almost support this, > anyway, like this: > > > public int accept() throws IOException > > { > > return accept(nfd.getNativeFD()); > > } > > > > public static native int accept(int native_fd) throws IOException; > > We could instead make accept() return a new VMChannel, make the native > method private, and in our reference implementation, use an integer > native file descriptor. Most of the methods in VMChannel > support this at > least partially -- there is a plain call that doesn't use any > descriptor > integer, and a call that takes a FD int as an argument, and the former > passes a private integer instance variable to the latter. > We'd just need to make the FD ones private in the RI. > > Then we can add a getNativeFD() call to VMChannel, that platform > specific code, like the kqueue Selector, can call. VMs that don't use > integers as file descriptors can then throw > UnsupportedOperationException for that method. > > Does this sound like it will work? I think so. > I don't know if we usually define VM > classes as classes to be instantiated, instead of being all static > methods, but I can't think of any drawback of doing that. I have done that in at least one other instance (VMThread) and I think it works well. Regards, Jeroen
[cp-patches] RE: FYI: Removed GTK drop target code from java/awt/Component.java
Lillian Angel wrote: > On Sat, 2006-08-05 at 11:28 +0200, Jeroen Frijters wrote: > > Hi, > > > > I commented out the GTK specific code in java/awt/Component.java. > > Component cannot have dependencies on any specific type of peer. > > > > Lillian could you please find a generic way to do what is required? > > > > Right now, its not possible to do it another way. I have removed this > code and added a comment else where. Thanks for pointing this out. Thanks, but shouldn't setDropTarget check if peer == null and in that case store the drop target and call its addNotify in Component.addNotify? Regards, Jeroen
[cp-patches] RE: FYI: Removed GTK drop target code from java/awt/Component.java
Jeroen Frijters wrote: > Lillian Angel wrote: > > On Sat, 2006-08-05 at 11:28 +0200, Jeroen Frijters wrote: > > > Hi, > > > > > > I commented out the GTK specific code in java/awt/Component.java. > > > Component cannot have dependencies on any specific type of peer. > > > > > > Lillian could you please find a generic way to do what is > required? > > > > > > > Right now, its not possible to do it another way. I have > removed this > > code and added a comment else where. Thanks for pointing this out. > > Thanks, but shouldn't setDropTarget check if peer == null and > in that case store the drop target and call its addNotify in > Component.addNotify? Oh I see it already does that, in that case I would think that all that is needed is an extra "if (peer != null)" around the dropTarget.addNotify() in setDropTarget. Regards, Jeroen
[cp-patches] FYI: ObjectInputStream bug fix
Hi, An IKVM user reported a problem with RMI. I debugged it and it turned out that ObjectInputStream was using the incorrect class loader to try and load the field types. Fixed by the attached patch (already committed). Note that the ObjectStreamField(String,String) constructor was previously unused, so I did not change it's behavior unintentionally. Regards, Jeroen 2006-08-11 Jeroen Frijters <[EMAIL PROTECTED]> * java/io/ObjectInputStream.java (readClassDescriptor): Use class's class loader to resolve field types. * java/io/ObjectStreamField.java (ObjectStreamField(String,String,ClassLoader)): Removed. (ObjectStreamField(String,String)): Don't try to resolve typename. (resolveType): New method. Index: java/io/ObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v retrieving revision 1.76 diff -u -r1.76 ObjectInputStream.java --- java/io/ObjectInputStream.java 21 May 2006 20:53:14 - 1.76 +++ java/io/ObjectInputStream.java 11 Aug 2006 07:33:25 - @@ -539,8 +539,6 @@ flags, fields); assignNewHandle(osc); -ClassLoader callersClassLoader = currentLoader(); - for (int i = 0; i < field_count; i++) { if(dump) dumpElement(" TYPE CODE="); @@ -560,12 +558,17 @@ class_name = String.valueOf(type_code); fields[i] = - new ObjectStreamField(field_name, class_name, callersClassLoader); + new ObjectStreamField(field_name, class_name); } /* Now that fields have been read we may resolve the class * (and read annotation if needed). */ Class clazz = resolveClass(osc); +ClassLoader loader = clazz.getClassLoader(); +for (int i = 0; i < field_count; i++) + { +fields[i].resolveType(loader); + } boolean oldmode = setBlockDataMode(true); osc.setClass(clazz, lookupClass(clazz.getSuperclass())); classLookupTable.put(clazz, osc); Index: java/io/ObjectStreamField.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectStreamField.java,v retrieving revision 1.20 diff -u -r1.20 ObjectStreamField.java --- java/io/ObjectStreamField.java 13 Sep 2005 21:25:07 - 1.20 +++ java/io/ObjectStreamField.java 11 Aug 2006 07:32:58 - @@ -111,28 +111,10 @@ { this.name = name; this.typename = typename; -try - { -type = TypeSignature.getClassForEncoding(typename); - } -catch(ClassNotFoundException e) - { - } } - - /** - * There are many cases you can not get java.lang.Class from typename - * if your context class loader cann not load it, then use typename to - * construct the field. - * - * @param name Name of the field to export. - * @param typename The coded name of the type for this field. - * @param loader The class loader to use to resolve class names. - */ - ObjectStreamField (String name, String typename, ClassLoader loader) + + void resolveType(ClassLoader loader) { -this.name = name; -this.typename = typename; try { type = TypeSignature.getClassForEncoding(typename, true, loader); @@ -141,7 +123,7 @@ { } } - + /** * This method returns the name of the field represented by the * ObjectStreamField instance.
[cp-patches] RFC: RMI Class loading patch
Hi, I did some RMI debugging and I found that we're using the wrong class loader in a couple of cases. The attached patch cleans up the code a little and uses the caller's class loader instead of the thread's context class loader in a couple of places. I would appreciate it if someone with more RMI knowledge could review this. Note that I removed VMObjectInputStream.currentClassLoader() and added VMStackWalker.firstNonNullClassLoader(). They are not identical, because VMObjectInputStream.currentClassLoader() used to return the thread context class loader if it couldn't find any non-null class loader on the stack, but firstNonNullClassLoader() doesn't do this. I could think of no good reason for the old behavior, so I removed it. Thanks, Jeroen Index: gnu/java/rmi/server/RMIClassLoaderImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java,v retrieving revision 1.1 diff -u -r1.1 RMIClassLoaderImpl.java --- gnu/java/rmi/server/RMIClassLoaderImpl.java 28 Sep 2005 19:51:31 - 1.1 +++ gnu/java/rmi/server/RMIClassLoaderImpl.java 13 Aug 2006 11:22:24 - @@ -1,5 +1,5 @@ /* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ package gnu.java.rmi.server; +import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -186,6 +187,7 @@ { defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null, defaultAnnotation); +// XXX using getContextClassLoader here *cannot* be right cacheLoaders.put (new CacheKey (defaultAnnotation, Thread.currentThread().getContextClassLoader()), defaultClassLoader); @@ -216,47 +218,53 @@ ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException { -ClassLoader loader; -if (defaultLoader == null) - loader = Thread.currentThread().getContextClassLoader(); -else - loader = defaultLoader; - -//try context class loader first try { -return Class.forName(name, false, loader); +if (defaultLoader != null) +return Class.forName(name, false, defaultLoader); } catch (ClassNotFoundException e) { -// class not found in the local classpath + } + +return Class.forName(name, false, getClassLoader(codeBase)); + } + + public Class loadProxyClass(String codeBase, String[] interfaces, + ClassLoader defaultLoader) + throws MalformedURLException, ClassNotFoundException + { +Class clss[] = new Class[interfaces.length]; + +for (int i = 0; i < interfaces.length; i++) + { +clss[i] = loadClass(codeBase, interfaces[i], defaultLoader); } -if (codeBase.length() == 0) //=="" +// Chain all class loaders (they may differ). +ArrayList loaders = new ArrayList(clss.length); +ClassLoader loader = null; +for (int i = 0; i < clss.length; i++) { -loader = defaultClassLoader; +loader = clss[i].getClassLoader(); +if (! loaders.contains(loader)) + { +loaders.add(0, loader); + } } -else +if (loaders.size() > 1) { -loader = getClassLoader(codeBase); +loader = new CombinedClassLoader(loaders); } -if (loader == null) +try { -//do not throw NullPointerException -throw new ClassNotFoundException ("Could not find class (" + name + - ") at codebase (" + codeBase + ")"); +return Proxy.getProxyClass(loader, clss); + } +catch (IllegalArgumentException e) + { +throw new ClassNotFoundException(null, e); } - -return Class.forName(name, false, loader); - } - - public Class loadProxyClass(String codeBase, String[] interfaces, - ClassLoader defaultLoader) - throws MalformedURLException, ClassNotFoundException - { -// FIXME: Implement this. -return null; } /** @@ -272,6 +280,9 @@ public ClassLoader getClassLoader(String codebase) throws MalformedURLException { +if (codebase == null || codebase.length() == 0) + return Thread.currentThread().getContextClassLoader(); + ClassLoader loader; CacheKey loaderKey = new CacheKey (codebase, Thread.currentThread().getContextClassLoader()); Index: gnu/java/rmi/server/RMIObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/gnu/java/rmi/serve
RE: [cp-patches] Re: RFC: RMI Class loading patch:Why thread contextclass loader
Audrius Meskauskas wrote: > In the case when the thread is created and started inside the > bootstrap classes, it may be no any user class on the stack. > Without using thread context class loader, it may not be possible > to locate any class of the user application that is currently > running (the class name is frequently specified via system > properties). The CORBA implementation can instantiate the user > - defined interceptor, helper and holder classes only with the > help of the thread context class loader, as it is doing > instantiation from the threads running with no user classes > on the stack. > > If you want to remove the context class loader somewhere, > please be sure what the similar situation will never be the case. The way I understand it, RMI code already delegates to the thread context class loader, so it doesn't need to do so twice by way of the passed in "default" class loader. Thanks, Jeroen
RE: [cp-patches] FYI: ZipFile performance improvement
Roman Kennke wrote: > Here comes a significant performance improvement for Zipfile, done by > Ingo. It avoids expensive UTF8 decoding when possible (most > cases, for ASCII) and optimizes readLeShort() and readLeInt() for the > case when the buffer has enough bytes. Mauve shows no regressions. This looks like it isn't thread safe: + UTF8DECODER.reset(); + char [] characters = UTF8DECODER.decode(bufferBuffer).array(); Regards, Jeroen
RE: [cp-patches] FYI: java.io fixlets
Roman Kennke wrote: > - Creates a local copy of the channels field in > FileDescriptor.valid() to improve threading safety. Why is this necessary? channel is final so it can never become null after it has been checked. Regards, Jeroen
RE: [cp-patches] RFC: Object de-/serialization improvement
Roman Kennke wrote: > Friedjof hacked up the Object de-/serialization code for improved > performance. It is now an order of magnitude faster. Thanks. Most of it looks good. A few comments: This looks funny: + {System.err.println("1"); I think this is bad style: +catch (IllegalArgumentException _) + { +InvalidClassException e = new InvalidClassException + ("writing fields of class " + osc.forClass().getName()); +e.initCause(_); I would only use _ if the exception object is not used. This test is wrong: + || (l.getClass().getClassLoader() == null /* application loader */); If an application instantiates URLClassLoader, it should still be garbage collectable. I think that he should consider using a cache that uses weak references instead of this test. Regards, Jeroen
RE: [cp-patches] RFC: File/VMFile improvement
Hi Roman, The attached patch file is empty. Regards, Jeroen > -Original Message- > From: [EMAIL PROTECTED] > [mailto:[EMAIL PROTECTED] On Behalf Of Roman Kennke > Sent: Tuesday, August 15, 2006 17:31 > To: Roman Kennke > Cc: classpath-patches@gnu.org > Subject: Re: [cp-patches] RFC: File/VMFile improvement > > Hi again, > > > we are having problems here with java.io.File on Windows CE. Which > > handles files different again than other Windows and of > course different > > than Unix. I could have hacked some more special casing in > there. But > > I'd like to propose to pull some more methods into VMFile. > See ChangeLog > > and attached patch. Basically this moves the impl of > getAbsolutePath(), > > isAbsolute() and toURL() to VMFile. > > The last patch here had a mistake. Here comes the corrected one. > > > 2006-08-15 Roman Kennke <[EMAIL PROTECTED]> > > * java/io/File.java > (getAbsolutePath): Fetch absolute path from > VMFile.getAbsolutePath(). Moved actual impl to there. > (isAbsolute): Let VMFile determine the absoluteness. > (toURL): Let VMFile convert the filename. > * vm/reference/java/io/VMFile.java > (getAbsolutePath): New method. > (isAbsolute): New method. > (toURL): New method. > > > /Roman >
RE: [cp-patches] RFC: Object de-/serialization improvement
Roman Kennke wrote: > > This test is wrong: > > + || (l.getClass().getClassLoader() == null /* > application loader > > */); > > > > If an application instantiates URLClassLoader, it should still be > > garbage collectable. > > > > I think that he should consider using a cache that uses > weak references > > instead of this test. > > AFAICS, the test is maybe a little aggressive and disallows > caching for classes that could even be cached (correct me if I'm wrong). No, it assumes that class loaders that are loaded by the boot class loader are cacheable, but that's not the case. For example, an application can instantiate a URLClassLoader and that would satify the above caching test. > I'd rather avoid dealing with WeakReferences unless > really needed. Yeah, it may not be ideal either. Hmm, maybe we should add a caching mechanism to ClassLoader? Regards, Jeroen
RE: [cp-patches] RFC: File/VMFile improvement
Roman Kennke wrote: > Jeroen Frijters schrieb: > > Hi Roman, > > > > The attached patch file is empty. > > Ugh. My bad. Here it is. Thanks. Looks like a good change to me. Regards, Jeroen
RE: [cp-patches] RFC: Object de-/serialization improvement
Roman Kennke wrote: > What about > > || (l == VMClassLoader.getSystemClassLoader()) > > instead ? You shouldn't call VMClassLoader.getSystemClassLoader() (it creates a new instance of the system class loader), but apart from that comparing against the system class loader would work, but I'd much rather see a solution that allows caching for other classes as well. I really would like to explore the option of adding a field to ClassLoader a little more (and hear other people's opinions about that). Regards, Jeroen
RE: [cp-patches] RFC: File/VMFile improvement
Casey Marshall wrote: > Tom Tromey wrote: > > It seems to me that this is an area we haven't handled very > well: this > > isn't really a "VM" thing per se -- the code could very well be > > written in pure java -- but rather a platform thing. > > > > I agree that adding special cases in File just makes the code uglier > > and uglier. But, we could delegate to a pure java "platform" class, > > with instances for "posixy", Windows, Windows CE, etc, and share the > > code across all VMs. > > > > We do something vaguely similar to this in libgcj (though in the > > specific case of File we put the platform stuff in native code). > > > > FWIW I agree. Some of us were chatting about this on IRC, and not only > are these "VM" interfaces more often than not platform interfaces (or > with some things, all they rely on is JNI and standard C), but they do > lead to performance hits (witness our direct ByteBuffer). > > I think putting some design thought into this is a good idea, because > right now I don't think we have any clear idea about what the scope or > purpose of VM/platform interfaces are. Right now, it looks like it's > just an ad-hoc catch-all for anything that can't be done in > pure Java -- you slap a VM class on it, and hack up the core class. I disagree. In most cases the VM decides what platforms to support and how to do this, so it does make some sense to move this stuff into the VM interface. This combined with the fact that native methods are very inconvenient for some VMs (like IKVM), we decided to add this extra indirection layer where the VM can decide to do things differently. I realise that for gcj people it may look like there is a significant difference between (e.g.) VMFile and VMThread, but other VMs replace both these classes. BTW, if there are specific cases (like ByteBuffer you mention), I'm more than willing to discuss alternatives to find a better alternative to suites everyone. I think that in many cases the VM interface design suffers from the fact that not enough VM implementers participate in the design. Regards, Jeroen
RE: [cp-patches] RFC: File/VMFile improvement
Hi Casey, I just about exploded when I read the first part of your message ;-) But at the end of your message I discovered that we completely misunderstood each other and that we agree much more than we disagree. With that in mind, here are my responses including to the parts that I initially found so inflammatory. (I know I'm an idiot for writing a response without having first read the entire message, but I can't help being passionate about this stuff.) Casey Marshall wrote: > OK. But I could argue back that VMs for whom native methods don't work > are broken as far a Java goes. True, but totally irrelevant. I said "native methods are very inconvenient for some VMs". IKVM supports native methods just fine, but that doesn't mean that they are a good idea. > I think you're saying that because platform details, like how files > and sockets work, are easier for you to implement "in the VM layer," > that they're necessarily VM-specific, and not platform-specific. > I couldn't disagree more with that. No, I'm saying that not all VMs are like the traditional C based VMs. BTW, this is not just IKVM, there are other Classpath VMs that also prefer to write their "native" code in Java. > There's also no rule saying that you have to use Classpath's > version of a class in your VM/system. That's true and sometimes I do decide to specialize a class (for example with the java.util.concurrent stuff) if the cost of using a VM interface is too high, but we all benefit if we share code. > > I realise that for gcj people it may look like there is a > > significant difference between (e.g.) VMFile and VMThread, but other > > VMs replace both these classes. > > Yeah, if I were writing a VM for Windows, I'd re-implement both. That has nothing to do with it. Just so you know, the *same* IKVM *binaries* run on Windows/Linux/MacOSX. The platform I code against is .NET/Mono, not the OS. That's also the reason why native code makes no sense for me. > If we keep the VM* interface thing, I think a better design is to stop > passing the core class to a static VM method, with the native state > inside the core class, and just make these VM classes > instance classes, with the native state associated with the instance. I thought that we already do that in most cases where it makes sense. > An example I'm thinking of is VMPlainSocketImpl. > PlainSocketImpl has an int field for the native file descriptor (and that > makes just plain no sense, either way), and passes itself to > VMPlainSocketImpl methods, which rips the descriptor integer out of that > instance. I think it's better to make VMPlainSocketImpl an instance class, > and keep the native state in that instance; in our default implementation, > this would be an integer file descriptor, and we'd have method pairs like so > in the VM class: I totally agree, but do you know why VMPlainSocketImpl is such a mess? Because it wasn't designed, someone just blindly applied the idea that native methods should be moved to the VM class. When VMPlainSocketImpl was introduced I should have stepped in and proposed something like what you just did, but I didn't because IKVM had already specialized the entire PlainSocketImpl class, so I was lazy and let it slide. > So the *interface* for the VM class is the public instance method, and > is the only one a VM writer needs to implement. Our default > implementation then just implements the function in the obvious, fast > way for POSIX. Maybe you can explain why passing an object to a static > method makes more sense than that (I can't see how; all it adds is a > litany of JNI calls to *every* method call). I think you *completely* misunderstood my position, as this is not at all what I was advocating. I completely agree with the VMPlainSocketImpl design you just proposed. Regards, Jeroen
[cp-patches] FYI: RMI class loading patch
Hi, I committed my RMI class loading patch. Regards, Jeroen 2006-08-17 Jeroen Frijters <[EMAIL PROTECTED]> * gnu/java/rmi/server/RMIClassLoaderImpl.java (loadClass): Rewritten to use getClassLoader. (loadProxyClass): Implemented. (getClassLoader): Fixed support for null or empty codebase. * gnu/java/rmi/server/RMIObjectInputStream.java (resolveClass): Use user class loader as default class loader. (resolveProxyClass): Delegate to RMIClassLoader.loadProxyClass. * gnu/javax/rmi/CORBA/UtilDelegateImpl.java (loadClass): Simplified and use user class loader instead of context class loader as default. * java/io/ObjectInputStream.java (currentLoader): Use VMStackWalker.firstNonNullClassLoader(). * vm/reference/gnu/classpath/VMStackWalker.java (firstNonNullClassLoader): New method. * vm/reference/java/io/VMObjectInputStream.java (loaderAction, currentClassLoader): Removed. Index: gnu/java/rmi/server/RMIClassLoaderImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java,v retrieving revision 1.1 diff -u -r1.1 RMIClassLoaderImpl.java --- gnu/java/rmi/server/RMIClassLoaderImpl.java 28 Sep 2005 19:51:31 - 1.1 +++ gnu/java/rmi/server/RMIClassLoaderImpl.java 13 Aug 2006 11:22:24 - @@ -1,5 +1,5 @@ /* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ package gnu.java.rmi.server; +import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -186,6 +187,7 @@ { defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null, defaultAnnotation); +// XXX using getContextClassLoader here *cannot* be right cacheLoaders.put (new CacheKey (defaultAnnotation, Thread.currentThread().getContextClassLoader()), defaultClassLoader); @@ -216,47 +218,53 @@ ClassLoader defaultLoader) throws MalformedURLException, ClassNotFoundException { -ClassLoader loader; -if (defaultLoader == null) - loader = Thread.currentThread().getContextClassLoader(); -else - loader = defaultLoader; - -//try context class loader first try { -return Class.forName(name, false, loader); +if (defaultLoader != null) +return Class.forName(name, false, defaultLoader); } catch (ClassNotFoundException e) { -// class not found in the local classpath + } + +return Class.forName(name, false, getClassLoader(codeBase)); + } + + public Class loadProxyClass(String codeBase, String[] interfaces, + ClassLoader defaultLoader) + throws MalformedURLException, ClassNotFoundException + { +Class clss[] = new Class[interfaces.length]; + +for (int i = 0; i < interfaces.length; i++) + { +clss[i] = loadClass(codeBase, interfaces[i], defaultLoader); } -if (codeBase.length() == 0) //=="" +// Chain all class loaders (they may differ). +ArrayList loaders = new ArrayList(clss.length); +ClassLoader loader = null; +for (int i = 0; i < clss.length; i++) { -loader = defaultClassLoader; +loader = clss[i].getClassLoader(); +if (! loaders.contains(loader)) + { +loaders.add(0, loader); + } } -else +if (loaders.size() > 1) { -loader = getClassLoader(codeBase); +loader = new CombinedClassLoader(loaders); } -if (loader == null) +try { -//do not throw NullPointerException -throw new ClassNotFoundException ("Could not find class (" + name + - ") at codebase (" + codeBase + ")"); +return Proxy.getProxyClass(loader, clss); + } +catch (IllegalArgumentException e) + { +throw new ClassNotFoundException(null, e); } - -return Class.forName(name, false, loader); - } - - public Class loadProxyClass(String codeBase, String[] interfaces, - ClassLoader defaultLoader) - throws MalformedURLException, ClassNotFoundException - { -// FIXME: Implement this. -return null; } /** @@ -272,6 +280,9 @@ public ClassLoader getClassLoader(String codebase) throws MalformedURLException { +if (codebase == null || codebase.length() == 0) + return Thread.currentThread().getContextClassLoade
[cp-patches] FYI: Serialization implementation for javax/naming/CompoundName.java
Hi, I implemented serialization support for javax.naming.CompoundName. Regards, Jeroen 2005-09-08 Jeroen Frijters <[EMAIL PROTECTED]> * javax/naming/CompoundName.java (readObject, writeObject): New methods. ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] RE: FYI: Serialization implementation for javax/naming/CompoundName.java
Again, with the patch this time. > -Original Message- > From: Jeroen Frijters > Sent: Thursday, September 08, 2005 10:33 > To: Classpath-Patches > Subject: FYI: Serialization implementation for > javax/naming/CompoundName.java > > Hi, > > I implemented serialization support for javax.naming.CompoundName. > > Regards, > Jeroen > > 2005-09-08 Jeroen Frijters <[EMAIL PROTECTED]> > > * javax/naming/CompoundName.java > (readObject, writeObject): New methods. > Index: javax/naming/CompoundName.java === RCS file: /cvsroot/classpath/classpath/javax/naming/CompoundName.java,v retrieving revision 1.9 diff -u -r1.9 CompoundName.java --- javax/naming/CompoundName.java 2 Jul 2005 20:32:45 - 1.9 +++ javax/naming/CompoundName.java 8 Sep 2005 08:16:53 - @@ -38,6 +38,9 @@ package javax.naming; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Enumeration; import java.util.NoSuchElementException; @@ -48,9 +51,6 @@ * @author Tom Tromey ([EMAIL PROTECTED]) * @date May 16, 2001 * - * FIXME: must write readObject and writeObject to conform to - * serialization spec. - * * FIXME: this class is underspecified. For instance, the `flat' * direction is never described. If it means that the CompoundName * can only have a single element, then the Enumeration-based @@ -467,6 +467,25 @@ this.trimBlanks = Boolean.valueOf (mySyntax.getProperty ("jndi.syntax.trimblanks", "false")).booleanValue (); + } + + private void readObject(ObjectInputStream s) +throws IOException, ClassNotFoundException + { +mySyntax = (Properties) s.readObject(); +int count = s.readInt(); +elts = new Vector(count); +for (int i = 0; i < count; i++) + elts.addElement((String) s.readObject()); + } + + private void writeObject(ObjectOutputStream s) +throws IOException + { +s.writeObject(mySyntax); +s.writeInt(elts.size()); +for (int i = 0; i < elts.size(); i++) +s.writeObject(elts.elementAt(i)); } // The spec specifies this but does not document it in any way (it ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Proxy serialization fixes
Hi, I fixed serialization/deseriazation of Proxy instances. Together with my previous patch (javax.naming.CompoundName serialization) this allows a JNDI lookup against JBoss to work now. I don't know anything about JNDI, RMI or JBoss, so I don't know whether you can do anything useful now, but it's a first step. Regards, Jeroen 2005-09-08 Jeroen Frijters <[EMAIL PROTECTED]> * java/io/ObjectInputStream.java (readObject): Removed println and fixed Proxy class descriptor deserialization. (resolveProxyClass): Use Class.forName() instead of calling ClassLoader.loadClass() directly. * java/io/ObjectOutputStream.java (writeClassDescriptor): Added support for serializing Proxy class descriptor. Index: java/io/ObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v retrieving revision 1.62 diff -u -r1.62 ObjectInputStream.java --- java/io/ObjectInputStream.java 13 Aug 2005 18:02:38 - 1.62 +++ java/io/ObjectInputStream.java 8 Sep 2005 08:16:49 - @@ -199,7 +199,6 @@ for (int i = 0; i < n_intf; i++) { intfs[i] = this.realInputStream.readUTF(); - System.out.println(intfs[i]); } boolean oldmode = setBlockDataMode(true); @@ -219,6 +218,10 @@ is_consumed = false; ObjectStreamClass superosc = (ObjectStreamClass)readObject(); osc.setSuperclass(superosc); + osc.firstNonSerializableParentConstructor = +superosc.firstNonSerializableParentConstructor; + osc.fieldMapping = new ObjectStreamField[0]; + osc.realClassIsSerializable = true; ret_val = osc; break; } @@ -874,7 +877,7 @@ } else for (int i = 0; i < intfs.length; i++) - clss[i] = cl.loadClass(intfs[i]); + clss[i] = Class.forName(intfs[i], false, cl); try { return Proxy.getProxyClass(cl, clss); Index: java/io/ObjectOutputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectOutputStream.java,v retrieving revision 1.57 diff -u -r1.57 ObjectOutputStream.java --- java/io/ObjectOutputStream.java 10 Jul 2005 18:29:07 - 1.57 +++ java/io/ObjectOutputStream.java 8 Sep 2005 08:16:53 - @@ -412,37 +412,53 @@ protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException { -realOutput.writeByte(TC_CLASSDESC); -realOutput.writeUTF(osc.getName()); -realOutput.writeLong(osc.getSerialVersionUID()); -assignNewHandle(osc); - -int flags = osc.getFlags(); - -if (protocolVersion == PROTOCOL_VERSION_2 - && osc.isExternalizable()) - flags |= SC_BLOCK_DATA; - -realOutput.writeByte(flags); - -ObjectStreamField[] fields = osc.fields; -realOutput.writeShort(fields.length); - -ObjectStreamField field; -for (int i = 0; i < fields.length; i++) +if (osc.isProxyClass) { - field = fields[i]; - realOutput.writeByte(field.getTypeCode ()); - realOutput.writeUTF(field.getName ()); - - if (! field.isPrimitive()) - writeObject(field.getTypeString()); +realOutput.writeByte(TC_PROXYCLASSDESC); + Class[] intfs = osc.forClass().getInterfaces(); + realOutput.writeInt(intfs.length); + for (int i = 0; i < intfs.length; i++) + realOutput.writeUTF(intfs[i].getName()); + +boolean oldmode = setBlockDataMode(true); +annotateProxyClass(osc.forClass()); +setBlockDataMode(oldmode); +realOutput.writeByte(TC_ENDBLOCKDATA); + } +else + { +realOutput.writeByte(TC_CLASSDESC); +realOutput.writeUTF(osc.getName()); +realOutput.writeLong(osc.getSerialVersionUID()); +assignNewHandle(osc); + +int flags = osc.getFlags(); + +if (protocolVersion == PROTOCOL_VERSION_2 + && osc.isExternalizable()) +flags |= SC_BLOCK_DATA; + +realOutput.writeByte(flags); + +ObjectStreamField[] fields = osc.fields; +realOutput.writeShort(fields.length); + +ObjectStreamField field; +for (int i = 0; i < fields.length; i++) + { + field = fields[i]; + realOutput.writeByte(field.getTypeCode ()); + realOutput.writeUTF(field.getName ()); + + if (! field.isPrimitive()) + writeObject(field.getTypeString()); + } + +boolean oldmode = setBlockDataMode(true); +annotateClass(osc.forClass()); +setBlockDataMode(oldmode); +realOutput.writeByte(TC_ENDBLOCKDATA); } - -boolean oldmode = setBlockDataMode(true); -annotate
[cp-patches] FYI: Small Proxy fix
Hi, I committed the attached patch to fix the class name of proxies that implement only public interfaces (the name was "null$Proxy0", but it should be "$Proxy0"). Regards, Jeroen 2005-09-09 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/reflect/Proxy.java (pack): Initialize field. Index: java/lang/reflect/Proxy.java === RCS file: /cvsroot/classpath/classpath/java/lang/reflect/Proxy.java,v retrieving revision 1.21 diff -u -r1.21 Proxy.java --- java/lang/reflect/Proxy.java5 Sep 2005 07:11:24 - 1.21 +++ java/lang/reflect/Proxy.java9 Sep 2005 12:06:53 - @@ -617,7 +617,7 @@ * The package this class is in including the trailing dot * or an empty string for the unnamed (aka default) package. */ -String pack; +String pack = ""; /** * The interfaces this class implements. Non-null, but possibly empty. ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Moved System.loadLibrary() calls from ObjectInputStream/ObjectOutputStream to VM classes
Hi, I committed the attached patch to move the System.loadLibrary calls to the VM classes. Regards, Jeroen 2005-09-09 Jeroen Frijters <[EMAIL PROTECTED]> * java/io/ObjectInputStream.java: Removed static initializer. * java/io/ObjectOutputStream.java: Removed static initializer. * vm/reference/java/io/VMObjectInputStream.java: Added static initializer. (oisClass, vmoisClass): Removed unused fields. * vm/reference/java/io/VMObjectStreamClass.java: Added static initializer. Index: java/io/ObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v retrieving revision 1.63 diff -u -r1.63 ObjectInputStream.java --- java/io/ObjectInputStream.java 8 Sep 2005 08:40:57 - 1.63 +++ java/io/ObjectInputStream.java 9 Sep 2005 12:06:51 - @@ -39,7 +39,6 @@ package java.io; -import gnu.classpath.Configuration; import gnu.java.io.ObjectIdentityWrapper; import java.lang.reflect.Array; @@ -1909,14 +1908,6 @@ for (int i = 0; i < depth; i++) System.out.print (" "); System.out.print (Thread.currentThread() + ": "); - } - - static - { -if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary ("javaio"); - } } // used to keep a prioritized list of object validators Index: java/io/ObjectOutputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectOutputStream.java,v retrieving revision 1.58 diff -u -r1.58 ObjectOutputStream.java --- java/io/ObjectOutputStream.java 8 Sep 2005 08:40:57 - 1.58 +++ java/io/ObjectOutputStream.java 9 Sep 2005 12:06:51 - @@ -39,7 +39,6 @@ package java.io; -import gnu.classpath.Configuration; import gnu.java.io.ObjectIdentityWrapper; import gnu.java.lang.reflect.TypeSignature; import gnu.java.security.action.SetAccessibleAction; @@ -1583,12 +1582,4 @@ private boolean dump = false; private static final boolean DEBUG = false; - - static - { -if (Configuration.INIT_LOAD_LIBRARY) - { -System.loadLibrary("javaio"); - } - } } Index: vm/reference/java/io/VMObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/io/VMObjectInputStream.java,v retrieving revision 1.3 diff -u -r1.3 VMObjectInputStream.java --- vm/reference/java/io/VMObjectInputStream.java 2 Jul 2005 20:33:08 - 1.3 +++ vm/reference/java/io/VMObjectInputStream.java 9 Sep 2005 12:06:58 - @@ -39,6 +39,7 @@ package java.io; +import gnu.classpath.Configuration; import gnu.classpath.VMStackWalker; import java.lang.reflect.Constructor; import java.security.AccessController; @@ -46,8 +47,13 @@ final class VMObjectInputStream { - private static Class oisClass = ObjectInputStream.class; - private static Class vmoisClass = VMObjectInputStream.class; + static + { +if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javaio"); + } + } // PrivilegedAction needed for Class.getClassLoader() private static PrivilegedAction loaderAction = new PrivilegedAction() Index: vm/reference/java/io/VMObjectStreamClass.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/io/VMObjectStreamClass.java,v retrieving revision 1.3 diff -u -r1.3 VMObjectStreamClass.java --- vm/reference/java/io/VMObjectStreamClass.java 2 Jul 2005 20:33:08 - 1.3 +++ vm/reference/java/io/VMObjectStreamClass.java 9 Sep 2005 12:06:58 - @@ -1,5 +1,5 @@ /* VMObjectStreamClass.java -- VM helper functions for ObjectStreamClass - Copyright (C) 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,10 +38,19 @@ package java.io; +import gnu.classpath.Configuration; import java.lang.reflect.Field; final class VMObjectStreamClass { + static + { +if (Configuration.INIT_LOAD_LIBRARY) + { + System.loadLibrary("javaio"); + } + } + /** * Returns true if CLAZZ has a static class initializer * (a.k.a. ). ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: Fix to javax/security/auth/login/Configuration.java
Hi, I committed the attached patch to fix a NPE in LoginContext (it calls the package private getConfig() method, but if the config field hadn't previously been initialized that would return null). Regards, Jeroen 2005-09-09 Jeroen Frijters <[EMAIL PROTECTED]> * javax/security/auth/login/Configuration.java (getConfiguration): Call getConfig() instead of doing the work. (getConfig): Instantiate the configuration provider. Index: javax/security/auth/login/Configuration.java === RCS file: /cvsroot/classpath/classpath/javax/security/auth/login/Configuration.java,v retrieving revision 1.3 diff -u -r1.3 Configuration.java --- javax/security/auth/login/Configuration.java2 Jul 2005 20:32:46 - 1.3 +++ javax/security/auth/login/Configuration.java9 Sep 2005 12:06:55 - @@ -67,29 +67,7 @@ SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission (new AuthPermission ("getLoginConfiguration")); -if (config == null) - { -String conf = (String) AccessController.doPrivileged - (new PrivilegedAction() -{ - public Object run() - { -return Security.getProperty ("login.configuration.provider"); - } -}); -try - { -if (conf != null) - config = (Configuration) Class.forName (conf).newInstance(); -else - config = new NullConfiguration(); - } -catch (Exception x) - { -config = new NullConfiguration(); - } - } -return config; +return getConfig(); } public static synchronized void setConfiguration (Configuration config) @@ -115,6 +93,28 @@ */ static Configuration getConfig() { +if (config == null) + { +String conf = (String) AccessController.doPrivileged + (new PrivilegedAction() +{ + public Object run() + { +return Security.getProperty ("login.configuration.provider"); + } +}); +try + { +if (conf != null) + config = (Configuration) Class.forName (conf).newInstance(); +else + config = new NullConfiguration(); + } +catch (Exception x) + { +config = new NullConfiguration(); + } + } return config; } } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] Patch: FYI: BorderLayout -vs- 1.5
Tom Tromey wrote: > (vgap, hgap, north, south, east, west): Reordered > fields to conform to serialization spec. Field order is not significant for serialization (even in the absence of a serialVersionUID field). Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] [generics] Copied org/omg/PortableServer/portable/Delegate.java
Hi, org/omg/PortableServer/portable/Delegate.java was missing on the generics branch, so I copied it over. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] [generics] Removed java/lang/MalformedParameterizedTypeException.java
Hi, I removed java/lang/MalformedParameterizedTypeException.java, I think someone accidentally added it to the wrong directory. Regards, Jeroen 2005-09-25 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/MalformedParameterizedTypeException.java: Removed. ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] [generics] Removed generics from VMSystem interface
Hi, As previously discussed, I've applied the attached patch to remove the generic type from the VMSystem.environ() call, to make it easier to have a common VMSystem for the trunk and the generics branch. Regards, Jeroen 2005-09-25 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/System.java, vm/reference/java/lang/VMSystem.java: Removed generic type from VMSystem.environ() signature. Index: java/lang/System.java === RCS file: /cvsroot/classpath/classpath/java/lang/System.java,v retrieving revision 1.38.2.13 diff -u -r1.38.2.13 System.java --- java/lang/System.java 20 Sep 2005 18:46:28 - 1.38.2.13 +++ java/lang/System.java 26 Sep 2005 11:09:19 - @@ -495,7 +495,7 @@ sm.checkPermission(new RuntimePermission("getenv.*")); if (environmentMap == null) { - List environ = VMSystem.environ(); + List environ = (List)VMSystem.environ(); Map variables = new EnvironmentMap(); for (String pair : environ) { Index: vm/reference/java/lang/VMSystem.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMSystem.java,v retrieving revision 1.10.2.6 diff -u -r1.10.2.6 VMSystem.java --- vm/reference/java/lang/VMSystem.java2 Aug 2005 20:12:48 - 1.10.2.6 +++ vm/reference/java/lang/VMSystem.java26 Sep 2005 11:09:25 - @@ -143,7 +143,7 @@ * * @return a list of 'name=value' pairs. */ - static native List environ(); + static native List environ(); /** * Gets the value of an environment variable from the current ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] [generics] Partial implementation of generic signature parsing
Hi, I started implementing the parsing of the new Signature attribute that describes the 1.5 generic signatures. Not everything is there yet, but I will continue to flesh out the implementation. Regards, Jeroen 2005-09-25 Jeroen Frijters <[EMAIL PROTECTED]> * gnu/java/lang/reflect/ClassSignatureParser.java, gnu/java/lang/reflect/GenericSignatureParser.java, gnu/java/lang/reflect/MethodSignatureParser.java: New files. * java/lang/Class.java (constructor): Changed type to generic type. (cast, getEnumConstants): Added cast. (getGenericInterfaces, getGenericSuperclass, getTypeParameters): Implemented. * vm/reference/java/lang/VMClass.java (getSimpleName, getDeclaredAnnotations, getCanonicalName, getEnclosingClass, getEnclosingConstructor, getEnclosingMethod, isAnonymousClass, isLocalClass, isMemberClass): Removed generic types from signatures. (getGenericInterfaces, getGenericSuperclass, getTypeParameters): Removed. (getClassSignature): New method. * vm/reference/java/lang/reflect/Constructor.java (getTypeParameters): Implemented. * vm/reference/java/lang/reflect/Method.java (getTypeParameters, getSignature): New methods. Index: java/lang/Class.java === RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.22.2.18 diff -u -r1.22.2.18 Class.java --- java/lang/Class.java20 Sep 2005 18:46:27 - 1.22.2.18 +++ java/lang/Class.java26 Sep 2005 11:21:02 - @@ -39,6 +39,7 @@ package java.lang; import gnu.classpath.VMStackWalker; +import gnu.java.lang.reflect.ClassSignatureParser; import java.io.InputStream; import java.io.Serializable; @@ -124,7 +125,7 @@ final transient Object vmdata; /** newInstance() caches the default constructor */ - private transient Constructor constructor; + private transient Constructor constructor; /** * Class is non-instantiable from Java code; only the VM can create @@ -1298,7 +1299,7 @@ */ public T cast(Object obj) { -return VMClass.cast(obj, this); +return (T)VMClass.cast(obj, this); } /** @@ -1368,7 +1369,7 @@ */ public T[] getEnumConstants() { -return VMClass.getEnumConstants(this); +return (T[])VMClass.getEnumConstants(this); } /** @@ -1602,7 +1603,15 @@ */ public Type[] getGenericInterfaces() { -return VMClass.getGenericInterfaces(this); +if (isPrimitive()) + return new Type[0]; + +String sig = VMClass.getClassSignature(this); +if (sig == null) + return getInterfaces(); + +ClassSignatureParser p = new ClassSignatureParser(this, sig); +return p.getInterfaceTypes(); } /** @@ -1636,7 +1645,18 @@ */ public Type getGenericSuperclass() { -return VMClass.getGenericSuperclass(this); +if (isArray()) + return Object.class; + +if (isPrimitive() || isInterface() || this == Object.class) + return null; + +String sig = VMClass.getClassSignature(this); +if (sig == null) + return getSuperclass(); + +ClassSignatureParser p = new ClassSignatureParser(this, sig); +return p.getSuperclassType(); } /** @@ -1653,7 +1673,12 @@ */ public TypeVariable>[] getTypeParameters() { -return VMClass.getTypeParameters(this); +String sig = VMClass.getClassSignature(this); +if (sig == null) + return (TypeVariable>[])new TypeVariable[0]; + +ClassSignatureParser p = new ClassSignatureParser(this, sig); +return p.getTypeParameters(); } /** Index: vm/reference/java/lang/VMClass.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMClass.java,v retrieving revision 1.10.2.9 diff -u -r1.10.2.9 VMClass.java --- vm/reference/java/lang/VMClass.java 7 Aug 2005 18:34:13 - 1.10.2.9 +++ vm/reference/java/lang/VMClass.java 26 Sep 2005 11:21:10 - @@ -325,7 +325,7 @@ * @param klass the class whose simple name should be returned. * @return the simple name for this class. */ - static String getSimpleName(Class klass) + static String getSimpleName(Class klass) { if (isArray(klass)) { @@ -387,7 +387,7 @@ * @return the annotations directly defined by the specified class. * @since 1.5 */ - static native Annotation[] getDeclaredAnnotations(Class klass); + static native Annotation[] getDeclaredAnnotations(Class klass); /** * @@ -424,7 +424,7 @@ * class doesn't have a canonical name. * @since 1.5 */ - static String getCanonicalName(Class klass) + static String getCanonicalName(Class klass) { if (isArray(klass)) { @@ -452,7 +452,7 @@ * a top-level class. * @since 1.5 */ - static native Class getEnclosing
[cp-patches] FYI: Fixed bug 24122
Hi, I checked in the attached patch to fix bug 24122. Regards, Jeroen 2005-09-30 Jeroen Frijters <[EMAIL PROTECTED]> Fixes Bug 24122 * gnu/xml/transform/TransformerImpl.java (writeStreamResult): Added call to connection.setDoInput(false). Index: gnu/xml/transform/TransformerImpl.java === RCS file: /cvsroot/classpath/classpath/gnu/xml/transform/TransformerImpl.java,v retrieving revision 1.5 diff -u -r1.5 TransformerImpl.java --- gnu/xml/transform/TransformerImpl.java 9 Jul 2005 20:38:35 - 1.5 +++ gnu/xml/transform/TransformerImpl.java 30 Sep 2005 07:09:59 - @@ -1,5 +1,5 @@ /* TransformerImpl.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -505,6 +505,12 @@ { URL url = new URL(systemId); URLConnection connection = url.openConnection(); +// We need to call setDoInput(false), because our +// implementation of the file protocol allows writing +// (unlike Sun), but it will fail with a FileNotFoundException +// if we also open the connection for input and the output +// file doesn't yet exist. +connection.setDoInput(false); connection.setDoOutput(true); out = connection.getOutputStream(); } ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] [generics] Finished generics signature parsing
Hi, I finished the generics signature parsing support code. Next up, changing the vm\reference reflection classes to make use of it. Regards, Jeroen 2005-09-30 Jeroen Frijters <[EMAIL PROTECTED]> * gnu/java/lang/reflect/FieldSignatureParser.java: New file. * gnu/java/lang/reflect/ClassSignatureParser.java, gnu/java/lang/reflect/GenericSignatureParser.java, gnu/java/lang/reflect/MethodSignatureParser.java: Finished implementation. Index: gnu/java/lang/reflect/ClassSignatureParser.java === RCS file: /cvsroot/classpath/classpath/gnu/java/lang/reflect/Attic/ClassSignatureParser.java,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 ClassSignatureParser.java --- gnu/java/lang/reflect/ClassSignatureParser.java 26 Sep 2005 11:43:40 - 1.1.2.1 +++ gnu/java/lang/reflect/ClassSignatureParser.java 28 Sep 2005 10:37:32 - @@ -1,4 +1,4 @@ -/* Class.java -- Representation of a Java class. +/* ClassSignatureParser.java Copyright (C) 2005 Free Software Foundation @@ -69,20 +69,24 @@ } interfaceTypes = new Type[interfaces.size()]; interfaces.toArray(interfaceTypes); +end(); } public TypeVariable[] getTypeParameters() { +TypeImpl.resolve(typeParameters); return typeParameters; } public Type getSuperclassType() { +superclassType = TypeImpl.resolve(superclassType); return superclassType; } public Type[] getInterfaceTypes() { +TypeImpl.resolve(interfaceTypes); return interfaceTypes; } } Index: gnu/java/lang/reflect/FieldSignatureParser.java === RCS file: gnu/java/lang/reflect/FieldSignatureParser.java diff -N gnu/java/lang/reflect/FieldSignatureParser.java --- /dev/null 1 Jan 1970 00:00:00 - +++ gnu/java/lang/reflect/FieldSignatureParser.java 28 Sep 2005 10:49:13 - @@ -0,0 +1,103 @@ +/* FieldSignatureParser.java + Copyright (C) 2005 + Free Software Foundation + +This file is part of GNU Classpath. + +GNU Classpath 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 2, or (at your option) +any later version. + +GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.java.lang.reflect; + +import java.lang.reflect.GenericSignatureFormatError; +import java.lang.reflect.Type; + +public final class FieldSignatureParser extends GenericSignatureParser +{ +private Type type; + +public FieldSignatureParser(Class container, String signature) +{ +super(container, container.getClassLoader(), signature); + +switch (peekChar()) +{ +case 'L': +case '[': +case 'T': +type = readFieldTypeSignature(); +break; +case 'Z': +consume('Z'); +type = boolean.class; +break; +case 'B': +consume('B'); +type = byte.class; +break; +case 'S': +consume('S'); +type = short.class; +break; +case 'C': +consume('C'); +type = char.class; +break; +case 'I': +
[cp-patches] [generics] Generic reflection implementation
Hi, I committed the attached patch. Regards, Jeroen 2005-10-01 Jeroen Frijters <[EMAIL PROTECTED]> * vm/reference/java/lang/reflect/Constructor.java (getSignature): New method. (getGenericExceptionTypes): New method. (getGenericParameterTypes): New method. * vm/reference/java/lang/reflect/Field.java (getGenericType): New method. (getSignature): New method. * vm/reference/java/lang/reflect/Method.java (getSignature): New method. (getGenericExceptionTypes): New method. (getGenericParameterTypes): New method. (getGenericReturnType): New method. Index: vm/reference/java/lang/reflect/Constructor.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Constructor.java,v retrieving revision 1.11.2.8 diff -u -r1.11.2.8 Constructor.java --- vm/reference/java/lang/reflect/Constructor.java 28 Sep 2005 17:50:21 - 1.11.2.8 +++ vm/reference/java/lang/reflect/Constructor.java 1 Oct 2005 09:56:40 - @@ -252,10 +252,10 @@ /** * Returns an array of TypeVariable objects that represents * the type variables declared by this constructor, in declaration order. - * An array of size zero is returned if this class has no type + * An array of size zero is returned if this constructor has no type * variables. * - * @return the type variables associated with this class. + * @return the type variables associated with this constructor. * @throws GenericSignatureFormatError if the generic signature does * not conform to the format specified in the Virtual Machine * specification, version 3. @@ -268,5 +268,51 @@ return p.getTypeParameters(); } + /** + * Return the String in the Signature attribute for this constructor. If there + * is no Signature attribute, return null. + */ private native String getSignature(); + + /** + * Returns an array of Type objects that represents + * the exception types declared by this constructor, in declaration order. + * An array of size zero is returned if this constructor declares no + * exceptions. + * + * @return the exception types declared by this constructor. + * @throws GenericSignatureFormatError if the generic signature does + * not conform to the format specified in the Virtual Machine + * specification, version 3. + * @since 1.5 + */ + public Type[] getGenericExceptionTypes() + { +String sig = getSignature(); +if (sig == null) + return getExceptionTypes(); +MethodSignatureParser p = new MethodSignatureParser(this, sig); +return p.getGenericExceptionTypes(); + } + + /** + * Returns an array of Type objects that represents + * the parameter list for this constructor, in declaration order. + * An array of size zero is returned if this constructor takes no + * parameters. + * + * @return a list of the types of the constructor's parameters + * @throws GenericSignatureFormatError if the generic signature does + * not conform to the format specified in the Virtual Machine + * specification, version 3. + * @since 1.5 + */ + public Type[] getGenericParameterTypes() + { +String sig = getSignature(); +if (sig == null) + return getParameterTypes(); +MethodSignatureParser p = new MethodSignatureParser(this, sig); +return p.getGenericParameterTypes(); + } } Index: vm/reference/java/lang/reflect/Field.java === RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/reflect/Field.java,v retrieving revision 1.9.2.3 diff -u -r1.9.2.3 Field.java --- vm/reference/java/lang/reflect/Field.java 28 Sep 2005 17:50:22 - 1.9.2.3 +++ vm/reference/java/lang/reflect/Field.java 1 Oct 2005 09:56:49 - @@ -1,5 +1,5 @@ /* java.lang.reflect.Field - reflection of Java fields - Copyright (C) 1998, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,8 @@ package java.lang.reflect; +import gnu.java.lang.reflect.FieldSignatureParser; + /** * The Field class represents a member variable of a class. It also allows * dynamic access to a member, via reflection. This works for both @@ -586,4 +588,29 @@ */ public native void setDouble(Object o, double value) throws IllegalAccessException; + + /** + * Return the generic type of the field. If the field type is not a generic + * type, the method returns the same as getType(). + * + * @throws GenericSignatureFormatError if the generic signature does + * not conform to the format specified in the Virtual Machine + * specification, version 3. + * @since 1.5 + */ + public Type getGenericType() + { +String signature = g
[cp-patches] FYI: Fixed URLClassLoader regression (on Windows)
Hi, I committed the attached patch to fix a regression introduced in the previous URLClassLoader change. Regards, Jeroen 2005-10-01 Jeroen Frijters <[EMAIL PROTECTED]> * java/net/URLClassLoader.java (Resource.name): Removed field. (JarURLResource.name): Added field. (FileResource.getURL): Use File.toURL() instead of doing it in a way that breaks on Windows. Index: java/net/URLClassLoader.java === RCS file: /cvsroot/classpath/classpath/java/net/URLClassLoader.java,v retrieving revision 1.38 diff -u -r1.38 URLClassLoader.java --- java/net/URLClassLoader.java17 Sep 2005 04:22:08 - 1.38 +++ java/net/URLClassLoader.java1 Oct 2005 10:57:09 - @@ -235,12 +235,10 @@ abstract static class Resource { final URLLoader loader; -final String name; -Resource(URLLoader loader, String name) +Resource(URLLoader loader) { this.loader = loader; - this.name = name; } /** @@ -391,11 +389,13 @@ static final class JarURLResource extends Resource { private final JarEntry entry; +private final String name; JarURLResource(JarURLLoader loader, String name, JarEntry entry) { - super(loader, name); + super(loader); this.entry = entry; + this.name = name; } InputStream getInputStream() throws IOException @@ -496,7 +496,7 @@ RemoteResource(RemoteURLLoader loader, String name, URL url, InputStream stream, int length) { - super(loader, name); + super(loader); this.url = url; this.stream = stream; this.length = length; @@ -539,7 +539,7 @@ { File file = new File(dir, name).getCanonicalFile(); if (file.exists() && !file.isDirectory()) - return new FileResource(this, file.getPath(), file); + return new FileResource(this, file); } catch (IOException e) { @@ -553,9 +553,9 @@ { final File file; -FileResource(FileURLLoader loader, String name, File file) +FileResource(FileURLLoader loader, File file) { - super(loader, name); + super(loader); this.file = file; } @@ -573,8 +573,7 @@ { try { - return new URL(loader.baseURL, name, - loader.classloader.getURLStreamHandler("file")); + return file.toURL(); } catch (MalformedURLException e) { ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] Stupid spec constant values
Mark Wielaard wrote: > The RCSID fields really serve no good purpose and I would just propose > we remove these fields and ask for a japi override mode to > ignore them. > I bet the value of these fields even changes between minor releases. They never change. They only exist because of an historical accident, way back. I don't have a strong opinion on whether we should copy them or not, but I certainly have no objection against it (and I'd like the Japi scores to be as high as reasonably possible). > The LoaderHandler.packagePrefix is also a bit subtle. The > only way I can see why/how people are using it is to check whether > a LoaderHandler is actually the system LoaderHandler implementation. > So changing it to something that isn't actually the package that we > define it in might break code (not seen actual code that does that > though). This one is very subtle. Since it is a compile time constant, the compiler will inline the value, so if a piece of code is compiled against GNU Classpath and then run on Sun's JDK (or vice versa) you get incorrect results. So I'd argue for changing our constants to match Sun's. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] Stupid spec constant values
Stuart Ballard wrote: > On 10/5/05, Jeroen Frijters <[EMAIL PROTECTED]> wrote: > > They never change. They only exist because of an historical > accident, > > way back. I don't have a strong opinion on whether we > should copy them > > or not, but I certainly have no objection against it (and > I'd like the > > Japi scores to be as high as reasonably possible). > > They do change - if you look in the japi results they're different in > different versions (I checked 1.2, 1.4 and 1.5). Not that it matters much, but I didn't see any changes from 1.3 to 1.4 to 1.5, and given the fact that the dates are both in 1997, I assumed it was just a historical thing. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: prevent URL degeneration
Robert Schuster wrote: > 2005-10-07 Robert Schuster <[EMAIL PROTECTED]> > > * java/net/URLStreamHandler.java: > (toExternalForm): Remove superfluous leading slashes from URL > paths. This patch introduces several Mauve regressions for me (on Windows): FAIL: gnu.testlet.java.net.URL.URLTest: new URL(string) (number 1) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(string) (number 19) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(string) (number 31) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(string) (number 40) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 29) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 33) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 37) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 41) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 45) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 49) FAIL: gnu.testlet.java.net.URL.URLTest: new URL(protocol, host, file) (number 53) I also disagree with it on principle grounds. We should match the JDK in cases like this, not try to do the "right thing". It's very easy to break applications that depend on the JDK URL implementation and it is not reasonable to expect them to be fixed if the JDK is never going to get fixed (which I can assure you, it isn't). Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: prevent URL degeneration - v3
Robert Schuster wrote: > However I consider these tests wrong because they violate the > URL spec. Some people (like me) believe it is more important, in some cases, to be compatible with the reference implementation than to the spec. > proto:p1/p2 > > is not the same as > > proto://p1/p2 > > Furthermore this is exactly the bug which causes trouble in > our XML parser and since the other implementation contains it > too I send Sun a problem report. > > I am going to fix these tests afterwards. Obviously they will > then fail on Sun-based VMs until they fix the problem, too. It's highly unlikely Sun will fix their code, see also: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737160 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4110155 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4447088 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5014591 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5018803 Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR classpath/24104 et al. ...
David Daney wrote: > This is the new version of my HTTP patch. It keeps promoting (near) > silence from the approvers, and I keep finding and fixing new bugs. > Also it has been about a week and I fixed another bug, so I thought I > would post the current version. Thanks for this rewrite. I reviewed the patch and it looks good. I have two small nitpicks: +if (-1 == r) In Java this isn't really needed (as you can't accidentally do an assign here anyway), so it is uncommon to put the constant first. LimitedLengthInputStream shouldn't have a finalize(). > OK to commit? I vote yes. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR classpath/24104 et al. ...
David Daney wrote: > Jeroen Frijters wrote: > > David Daney wrote: > > > > LimitedLengthInputStream shouldn't have a finalize(). > > Let's consider the case where a client program did not read > the entire body of the response: > > As implemented in the patch, the finalize is indeed needed to > clean up the mess and return the connection to the connection > pool. I understand that was the motivation, but I just don't agree with it. Even *if* you wanted to do this, you should use a PhantomReference to keep track of the lifetime of the LimitedLengthInputStream instead of a finalize method. > However I have been going back and forth on this matter, and > now am of the opinion that if a client does not read the entire body > that the connection should just be abandoned and not returned to the > pool. Think of the case where you only read a little bit from the > head of a very large response body. In this case do you want the > runtime to read and throw away the rest of the body (which could > have unbounded size) just so it can reuse the connection? > I am starting to think not. Exactly. Another issue is that finalize (or the PhantomReference solution) introduces non-determinisme that IMO simply does nobody any favors. > > I vote yes. > > Thanks for the vote, but what I really am looking for is official > permission. There is no official owner. If nobody complains in a couple of days, just go ahead and commit. As long as you don't commit too close to a snapshot release date, any left over issues will get worked out. In any case, I believe your implementation is a big step forward. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR classpath/24104 et al. ...
David Daney wrote: > A finalizer is simple and gets the job done. Finalizers are anything but simple. They really should only be used to free native resources (as a last resort), not for any type of Java clean up. Blocking and locking should be avoided in a finalizer. Typically there is only one finalizer thread and you don't want to hog that by blocking on I/O. I wrote about how finalize should be used on my blog: http://weblog.ikvm.net/permalink.aspx?guid=3E0ABC11-F486-4366-9127-CF38B B6C3EF1 Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] [PATCH] Fix PR classpath/24086, PR classpath/24091, PR classpath/24104 et al. ...
Boehm, Hans wrote: > Blocking on IO indeed seems dubious. But finalizers almost > always need to acquire at least one lock. Agreed, but outside of the lock needed to protect the finalizable resource it's probably best to avoid taking other locks, because it is very easy to introduce potential deadlocks that way. > In the example in your blog, the finalize method should be > synchronized (or start with synchronized(this) {} ) to > guarantee reachability of the object while one of the other > synchronized methods is running. Huh? finalize calls the synchronized close method, so it doesn't need to be synchronized. > If you follow the (admittedly baroque) rules, there are safe ways to > clean up Java resources with finalizers as well, though > clearly not when timing matters. > > And you actually need to follow very similar rules for java.lang.ref. Well at the very least the fact that you control the threading with a reference queue makes things a little easier. For example, the I/O blocking issue is not a problem if you can do it in your own thread. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: java/io/ObjectInputStream.java
Hi, I committed the attached patch to fix proxy deserialization (bug 24422). Regards, Jeroen 2005-10-18 Jeroen Frijters <[EMAIL PROTECTED]> * java/io/ObjectInputStream.java (parseContent): Removed bogus println and fixed bug #24422. Index: java/io/ObjectInputStream.java === RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v retrieving revision 1.69 diff -u -r1.69 ObjectInputStream.java --- java/io/ObjectInputStream.java 12 Oct 2005 19:41:42 - 1.69 +++ java/io/ObjectInputStream.java 18 Oct 2005 07:17:29 - @@ -221,7 +221,6 @@ for (int i = 0; i < n_intf; i++) { intfs[i] = this.realInputStream.readUTF(); - System.out.println(intfs[i]); } boolean oldmode = setBlockDataMode(true); @@ -229,6 +228,21 @@ setBlockDataMode(oldmode); ObjectStreamClass osc = lookupClass(cl); + if (osc.firstNonSerializableParentConstructor == null) +{ + osc.realClassIsSerializable = true; + osc.fields = osc.fieldMapping = new ObjectStreamField[0]; + try +{ + osc.firstNonSerializableParentConstructor = +Object.class.getConstructor(new Class[0]); +} + catch (NoSuchMethodException x) +{ + throw (InternalError) +new InternalError("Object ctor missing").initCause(x); +} +} assignNewHandle(osc); if (!is_consumed) ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
[cp-patches] FYI: java/lang/reflect/Proxy.java fix
Hi, There was a bootstrap / system class loader confusion bug in Proxy. I committed the attached patch to fix it. Regards, Jeroen 2005-10-21 Jeroen Frijters <[EMAIL PROTECTED]> * java/lang/reflect/Proxy.java (ProxyType.ProxyType): Don't replace null with system class loader. (ProxyType.hashCode): Handle null loader. Index: java/lang/reflect/Proxy.java === RCS file: /cvsroot/classpath/classpath/java/lang/reflect/Proxy.java,v retrieving revision 1.24 diff -u -r1.24 Proxy.java --- java/lang/reflect/Proxy.java26 Sep 2005 18:44:38 - 1.24 +++ java/lang/reflect/Proxy.java21 Oct 2005 00:03:52 - @@ -413,8 +413,6 @@ */ ProxyType(ClassLoader loader, Class[] interfaces) { - if (loader == null) - loader = ClassLoader.getSystemClassLoader(); this.loader = loader; this.interfaces = interfaces; } @@ -426,8 +424,7 @@ */ public int hashCode() { - //loader is always not null - int hash = loader.hashCode(); + int hash = loader == null ? 0 : loader.hashCode(); for (int i = 0; i < interfaces.length; i++) hash = hash * 31 + interfaces[i].hashCode(); return hash; ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: implementation of getPackage for the vm reference
Nicolas Geoffray wrote: > This patch was written when we wanted to test our vm and gnu > classpath with jonas. > Jonas complained (crashed) because it got a null package for a system > class. This patch corrects the issue, and should be adequate for all vms. Looks good, but you should use SystemProperty.getProperty() instead of System.getProperty(). Using System.getProperty() does a security check and that is not correct in this case. I don't think this is very important, but getPackages() should return all packages, not just the ones that have already been specifically requested. Since there is no VM independent way of enumerating all the packages in the boot class loader we probably shouldn't worry about it too much. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: implementation of getPackage for the vm reference
Jeroen Frijters wrote: > Nicolas Geoffray wrote: > > This patch was written when we wanted to test our vm and gnu > > classpath with jonas. > > Jonas complained (crashed) because it got a null package > for a system > > class. This patch corrects the issue, and should be > adequate for all vms. > > Looks good, but you should use SystemProperty.getProperty() > instead of System.getProperty(). Using System.getProperty() > does a security check and that is not correct in this case. > > I don't think this is very important, but getPackages() > should return all packages, not just the ones that have > already been specifically requested. Since there is no VM > independent way of enumerating all the packages in the boot > class loader we probably shouldn't worry about it too much. After looking at it some more, I think the patch is actually incorrect. There should be no need to introduce the new VMClassLoader.getVMPackage() method. VMClassLoader.getPackage() should actually be doing that work and Class.getPackage() should be calling VMClassLoader.getPackage if cl is null. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: implementation of getPackage for the vmreference
Nicolas Geoffray wrote: > That's what I thought too in the first place, but the > ClassLoader.getPackage calls the parent loader's getPackage > method. If the parent is null, then it calls > VMClassLoader.getPackage(). > > If VMClassLoader.getPackage had to add the package given as > parameter, then all packages (system + applications) would be > defined in VMClassLoader.definedPackages. > > I hope I'm clear enough. > > The suggestion you gave for getPackages (having all bootstrap packages > in VMClassLoader.definedPackages at startup) could remove the > additional VMClassLoader.getVMPackage. Maybe that's a better solution? > (Sun does it) Ah, I see what you mean now. In my VM I also have a full list of the packages defined by the boot class loader, so there my approach does work (I just tested it). I can't think of any other way to solve this, there should be a native method that returns a String[] with the native package names. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: implementation of getPackage for the vmreference
Nicolas Geoffray wrote: > Why should it be native? It might be the same work for all VMs. > Maybe we could add a static initializer to VMClassLoader > that would look for java.boot.class.path property and fill > the packages (eg the directories) it finds in the > definedPackages hashmap. I just assumed it would have to be native, but I don't really know which VMs use VMClassLoader as-is (I don't use it, for example). If a non-native implementation that works for everyone (that uses the reference VMClassLoader) is possible, then that would obviously be the best option. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches
RE: [cp-patches] RFC: implementation of getPackage for the vmreference
Nicolas Geoffray wrote: > Mark are you OK with the changes? I would like to see this go in before 0.19. After 0.19 (based on feedback from other VM implementers) we should consider making getBootPackages native so that they will be able to use the reference VMClassLoader as is. Regards, Jeroen ___ Classpath-patches mailing list Classpath-patches@gnu.org http://lists.gnu.org/mailman/listinfo/classpath-patches