Re: Bug report: java.util.GregorianCalendar
On Friday 29 August 2003 08:58, Ito Kazumitsu wrote: This is my patch for this bug. --- java/util/GregorianCalendar.java.orig Thu Aug 14 13:32:06 2003 +++ java/util/GregorianCalendar.java Fri Aug 29 15:56:51 2003 @@ -264,8 +264,10 @@ // // The additional leap year factor accounts for the fact that // a leap day is not seen on Jan 1 of the leap year. +// And on and after the leap day, the leap day has already been +// included in dayOfYear. int gregOffset = (year / 400) - (year / 100) + 2; - if (isLeapYear (year, true) dayOfYear 31 + 29) + if (isLeapYear (year, true)) --gregOffset; Although I authored this code, I haven't followed the patches for GregorianCalendar lately. I think you are right that the dayOfYear doesn't matter here, but this should also apply for the julian case i.e. outside of the if(gregorian). Also there is almost the same code in getLinearDay that needs fixing too. This function is used when transforming a linear day in day/month/year and it is known whether it is gregorian or julian. A trickier change would subtract year by one at the beginning of the function, replace 1970 by 1969 and get rid of the isLeapYear case. This saves the extra case distinction and isLeapYear call (and makes the code even less understandable). Jochen -- Jochen Hoenicke, University of Oldenburg, 26111 Oldenburg, Germany Email: [EMAIL PROTECTED] Tel: +49 441 798 3124 pgp0.pgp Description: signature ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
jazzlib (java.util.zip implementation in java).
Hello, We (John Leuner and I) have assigned copyright for jazzlib to the FSF, so there shouldn't be any legal obstacle to including the code in classpath anymore. As far as I can see, there is no real java.util.zip implementation in classpath yet, so do you agree if I just commit the content of jazzlib to the classpath repository, overwriting the three small existing classes? The existing classes are just two exceptions and an interface. The other problem is the merge with libgcj as it already contains a working java.util.zip implementation based on CNI. However, the java.util.zip package wasn't merged yet, so there is no need to resolve this now. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: jazzlib (java.util.zip implementation in java).
On Jul 31, Paul Fisher wrote: Jochen Hoenicke wrote: As far as I can see, there is no real java.util.zip implementation in classpath yet, so do you agree if I just commit the content of jazzlib to the classpath repository, overwriting the three small existing classes? That's fine. As you commit files, could you please go through them and clean up the formatting some to match the rest of Classpath? From a quick look over the source this morning, I'm referring to things like spaces between method names and the following parens, and spaces between keywords (if, etc) and their following parens. Okay, I committed the space-changes to the jazzlib repository. There may be a few places left where spacing is not 100% correct, but I think I corrected most. On Jul 31, Aaron M. Renn wrote: Is Jazzlib 100% Java? If so, I would consider it superior to a native implementation, ceteris paribus. Yes it is 100% Java. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: [Classpath] Bug in Double.java
On Jul 16, C. Scott Ananian wrote: On Mon, 16 Jul 2001, Eric Blake wrote: Someone will need to check my work with serialization issues, as I am not very familiar with the process. Basically, my added hashCode() caching will break if a deserialization restores the transient hashCode field to 0 instead of -1. I chose -1 for the non-cached value instead of 0, since new Double(0).hashCode() == 0, but left the cache field transient so it will interoperate with serial streams from other sources. Maybe it's not worth caching the result of hashCode() after all. Fields marked transient are *defined* to be reset to zero after deserialization. Use 0 as your non-cached value; the only harm will be that hashCode will have the same performance as the non-caching version for Double(0) -- it's still better than not caching at all. Another possibility is to add a readObject method, that just calls defaultReadObject() and initializes the transient fields to correct values. See Classpath's implementation of java.util.Locale as an example. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: java.util.zip
John Leuner wrote: Jochen has also completed a pure-java implementation of java.util.zip. I don't know if this will be the preferred implementation for classpath, but I suggest that it at least be a compile-time option. You can get the source and compiled classes at http://jazzlib.sourceforge.net/ Yeah! This is great! I would love to have this as the default implementation in Classpath. Would there be any reason to not make the pure java version the default? I don't see any. The code is functionally equivalent. Bryce McKinlay wrote: I agree, this is very cool. Have you run any tests to compare performance with the JDK's native zlib-based implementation? Reading compressed streams takes ca. 50% more time than with Sun's zlib based implementation. IIRC creating compressed streams was around factor 2 slower. This is with the IBM Java2-1.3 virtual machine and its JIT compiler. Some of this slow down is due to array bound checks in java. I don't know how good the JIT compiler is in inlining short functions, this may also explain some slow-down. Does it pass the ZipVerify test case? (see http://gcc.gnu.org/ml/java/2001-03/msg00374.html) Thanks for the link, I haven't seen this test before. There is a problem with ZipEntry.setExtra(). My version is more stringent at what kind of extra fields it allows. It doesn't allow a NullPointer and it only allows extra fields formed as described in appnotes.iz (zip file format spec). Sun's jdk doesn't care at all about the content but my implementation makes use of it to read the extended timestamp. When changing my implementation to ignore wrong parameters to setExtra() all tests pass. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Changes to TimeZone.java
Hello, I have updated the time zone database in classpath to tzdata2000h. I noticed that Warren changed the automatically generated static constructor. I reflected these changes in my script that creates these lines. I don't have access to libgcj; can someone add the corresponding patch to the libgcj repository? The patch is appended and is also at http://semantik.Informatik.Uni-Oldenburg.DE/~hoenicke/libgcj/TimeZone.java.diff Jochen Changelog entry: 2001-02-20 Jochen Hoenicke [EMAIL PROTECTED] * java/util/TimeZone.java: Rebuild Timezone database from tzdata2000h. Index: TimeZone.java === RCS file: /cvs/gcc/egcs/libjava/java/util/TimeZone.java,v retrieving revision 1.10 diff -u -r1.10 TimeZone.java --- TimeZone.java 2001/01/09 07:07:51 1.10 +++ TimeZone.java 2001/02/21 09:37:05 @@ -84,9 +84,9 @@ // XXX - Should we read this data from a file? tz = new SimpleTimeZone(-11000 * 3600, "MIT"); timezones.put("MIT", tz); -timezones.put("Pacific/Niue", tz); timezones.put("Pacific/Apia", tz); timezones.put("Pacific/Midway", tz); +timezones.put("Pacific/Niue", tz); timezones.put("Pacific/Pago_Pago", tz); tz = new SimpleTimeZone (-1 * 3600, "America/Adak", @@ -100,19 +100,19 @@ timezones.put("Pacific/Johnston", tz); timezones.put("Pacific/Rarotonga", tz); timezones.put("Pacific/Tahiti", tz); +tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas"); +timezones.put("Pacific/Marquesas", tz); tz = new SimpleTimeZone (-9000 * 3600, "AST", Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); timezones.put("AST", tz); -timezones.put("America/Juneau", tz); timezones.put("America/Anchorage", tz); +timezones.put("America/Juneau", tz); timezones.put("America/Nome", tz); timezones.put("America/Yakutat", tz); tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier"); timezones.put("Pacific/Gambier", tz); -tz = new SimpleTimeZone(-8500 * 3600, "Pacific/Marquesas"); -timezones.put("Pacific/Marquesas", tz); tz = new SimpleTimeZone (-8000 * 3600, "PST", Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, @@ -126,10 +126,6 @@ timezones.put("US/Pacific-New", tz); tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn"); timezones.put("Pacific/Pitcairn", tz); -tz = new SimpleTimeZone(-7000 * 3600, "PNT"); -timezones.put("PNT", tz); -timezones.put("America/Dawson_Creek", tz); -timezones.put("America/Phoenix", tz); tz = new SimpleTimeZone (-7000 * 3600, "MST", Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, @@ -143,16 +139,11 @@ timezones.put("America/Mazatlan", tz); timezones.put("America/Shiprock", tz); timezones.put("America/Yellowknife", tz); -tz = new SimpleTimeZone(-6000 * 3600, "America/Regina"); -timezones.put("America/Regina", tz); -timezones.put("America/Belize", tz); -timezones.put("America/Costa_Rica", tz); -timezones.put("America/El_Salvador", tz); -timezones.put("America/Guatemala", tz); -timezones.put("America/Managua", tz); -timezones.put("America/Swift_Current", tz); -timezones.put("America/Tegucigalpa", tz); -timezones.put("Pacific/Galapagos", tz); +tz = new SimpleTimeZone(-7000 * 3600, "PNT"); +timezones.put("PNT", tz); +timezones.put("America/Dawson_Creek", tz); +timezones.put("America/Hermosillo", tz); +timezones.put("America/Phoenix", tz); tz = new SimpleTimeZone (-6000 * 3600, "CST", Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, @@ -161,13 +152,22 @@ timezones.put("America/Cambridge_Bay", tz); timezones.put("America/Cancun", tz); timezones.put("America/Chicago", tz); -timezones.put("America/Iqaluit", tz); timezones.put("America/Menominee", tz); +timezones.put("America/Merida", tz); timezones.put("America/Mexico_City", tz); -timezones.put("America/Pangnirtung", tz); +timezones.put("America/Monterrey", tz); timezones.put("America/Rainy_River", tz); -timezones.put("America/Rankin_Inlet", tz); timezones.put("America/Winnipeg", tz); +tz = new SimpleTimeZone
Re: Why are serialVersionUIDs explicitly set in Exceptions?
On Feb 20, Bryce McKinlay wrote: Eric Arseneau wrote: Since the computed values are the same as the explicitly set ones I am wondering if we could not just remove them. It might hide bugs. What do people think about it? You will find that for now the values may be the same, but if the algorithm changes later, or use on a different VM that the result is not the same. [...] The algorithm for calculating the UID is explicitly specified as part of the serialization specification, isn't it? [...] Yes it is. I don't think that classes that do not have readObject()/writeObject() should have an explicit SerialVersionUID. If a VM is calculating a different UID for the class, then either the serialized form really isn't the same (in which case the UIDs MUST be different), or the serialization implementation is broken. The serialVersionUID doesn't only depend on the serialized fields, but also on the non private methods and non private static/transient fields. So if you add a method, the UID changes, while the serialized form keeps the same. Normally exceptions have a very canonic set of methods, so relying on the default UID is quite safe. But IMHO the existance of an explicit serialVersionUID in a serializable class is a good indicator that someone checked that the serial form is correct. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: java.util.zip
On Nov 16, John Leuner wrote: I should have made it more clear that this is a port to pure java code. My hidden agenda here is to use the code in a future java OS (see http://jos.org), which is why I didn't want to use zlib. IIRC, everything except Deflater and Inflater are already pure java in libgcj. Deflater and Inflater are just interfaces to zlib, so it makes sense for you to rewrite them from scratch. You should borrow some code from zlib, of course. And make sure you have RFC 1950-1952 handy. I will have a look at the libgcj code and Jochen's code, to see what I can borrow / contribute in terms of code and javadoc. You can probably take all other classes in java.zip from libgcj without changes. Regarding javadoc I think there is very little in libgcj. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: java.util.BitSet and synchronization
On Oct 30, Bryce McKinlay wrote: The JCL supplement book says that the BitSet class is now not synchronized, however "all boolean operations that operate on two bit sets still properly handle the case where both bit sets are the same object". Does anyone know what this above statement means? Does this imply that these operations are supposed to synchronize on their argument bitset? I think this just means that e.g. foo.xor(foo) works as expected (as long as foo is not accessed in another thread). But I can't see what is special about it. I have written a not synchronized version long time ago, but I never checked it in. It is a 32 bit version that is faster for 32bit processors (and still 100% compatible). The 64bit code is still in, commented in a special way. It's located at http://www.informatik.uni-oldenburg.de/~delwi/classpath/BitSet.java Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: [Classpath] Compile Errors
On Sep 17, Tom Tromey wrote: Another would be to escape all non-ASCII characters, as you say. This seems safest. I wonder if there is some `recode' invocation you could use to do it automatically. Yes, there is native2ascii which comes with the jdk: native2ascii -encoding ISO8859-1 [infile] [outfile] I just did the conversion for the whole gnu/java/locale directory. Jochen ___ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath
Re: Collection classes as separate package for java 1.1
On Jun 22, Mark Wielaard wrote: On Thu, Jun 22, 2000 at 10:46:05AM -0400, Stuart Ballard wrote: Jochen Hoenicke wrote: Okay, I can do that, but is org.gnu.java.util.collections a good package name? Or do you prefer something like gnu.classpath.collections? Speaking for myself only, I'd suggest putting it in com.sun. I know that it sucks to be writing code in Sun's package domain, but this would let us be a drop-in replacement for Sun's code. Especially for binary-only programs that assume it will be in com.sun... Thoughts? I would like them to be just in java.util where they are now. This shows that you can easily use (finished) parts of Classpath now. And it would indeed really suck to write packages for com.sun. The reasons not to do this are: - Not all VMs/Classloaders allow adding to java.* packages (And for security reasons that might be a very good thing.) Especially Applets! And since you should stick to 1.1 for applets for best compatibility, that is a reason to use the collection package. - Some binary only programs expect them to be in com.sun. (But do we really care about binary only programs?) I don't think there are to many such applications. Sun has hided their collections package quite good :) So if you are really up for a challenge then you could try to generalize your perl script to turn it into a generic package migration tool that dynamically changes classes so they appear in different packages but you have to be carefull to change all fully qualified package names and change the package and import staements. That is probably difficult to do with .java source files. I have an obfuscator that can be used to migrate to different packages :-) (Only .class files are changed) That way you could add a configure option for the actual package --collection-package=some.random.package That is trivial to do. One of the first lines of the perl script is my $destPkg="org.gnu.java.util.collections"; I would love to write some of that. (I really would like to have a flexible package migration tool!) http://jode.sourceforge.net/ contains my obfuscator, that can be used for this purpose. It is probably not as flexible as you want it though; only renaming of complete packages is currently possible. I have absolutely no time right now. But I would like to see the script that you use now. http://www.informatik.uni-oldenburg.de/~delwi/classpath/buildcollections.pl The renaming is almost trivial; the imports are hardcoded. There is also some change to make serialization 1.1 compatible. Jochen
Re: Collection classes as separate package for java 1.1
On Jun 22, Brian Jones wrote: "Jochen Hoenicke" [EMAIL PROTECTED] writes: I have written a small perl script (150 lines) that puts the classpath collection classes into the org.gnu.java.util.collections package. This works well, and I wonder how I should redistribute it to anyone interested. Hey Jochen, Add a phony target to the root Makefile called collection and have it call cd lib $(MAKE) $(AM_MAKEFLAGS) collection (maybe there is a variable for the arg..). In lib/Makefile.am add another phony collection target which zips up the relevant files. You could add a hook to include the source there as well. Okay, I can do that, but is org.gnu.java.util.collections a good package name? Or do you prefer something like gnu.classpath.collections? Jochen
Re: javah for Classpath
I have a java program that produces JNI header files using a bytecode package. The program was hacked together in a day or two and consists of a single java class. So is anybody interested? That bytecode package mentioned above reads class files from any given path (Zip-Files, Directories, even URLs) and provides methods similar to the reflection API to access them. The package is part of my decompiler, but can be used standalone. There are two caveat: First, the package uses some collection classes so it needs 1.2, second, the handling of bytecode instructions will probably change in near future (but javah doesn't need to read instructions). I know, that there is also a gnu.bytecode package as part of kawa. I wrote my own bytecode package, since that package was not usable for me: it missed some public methods to access all information. Jochen
Re: java.util.zip JNI/CNI
On Jun 14, Artur Biesiadowski wrote: Jochen Hoenicke wrote: I have removed the synchronization (though the perl script supports it), since it is unnecessary. The De/Inflater is by design not thread safe, since de/inflate and setInput are distinct functions. The comment I put in the header of the java files documents this. Please only doublecheck it is impossible to crash native code with malicious multithreading. It can fail with any exception, kill thread etc, but crashing a vm would be a security problem. Artur is right here, I didn't think of this. All methods, that call a zlib methods, except init should be synchronized. The native files should be read again with security in mind. We must also check if zstream is null and throw a NullPointerException otherwise. Mark, if you want I can correct this. Jochen
Re: java.util.zip JNI/CNI
On Jun 12, Mark Wielaard wrote: Hi, I just looked at the differences between the java.util.zip implementation of libgcj with CNI and the version that Jochen Hoenicke made with JNI. http://www.Informatik.Uni-Oldenburg.DE/~delwi/classpath/JCL/ Since I know nothing of CNI or JNI I will need to learn a bit more about it. But I thought that it might be a good idea to tell you my first impressions so people can correct me when I am wrong. CNI is readable and JNI is not. This might be because the Perl script that Jochen made inserts a bit more casts and JNI functions then necessary. The JNI is really a bit unreadable. With the unnecessary casts you probably mean jobject to jbytearray, which are all typedefed to the same type in C. But for C++ they are necessary. With CNI a reference to gnu.gcj.RawData is used to hold data that the native code needs. With JNI a reference to a byte[] is used. It seems that a reference to RawData will not be touched by the Garbage collector. I am not sure why that is necessary in this case. This depends on the garbage collector. Some garbage collector may depend that all object fields point to real objects allocated with NewObject. I think many JVMs enforce that. With the byte[] I'm compatible but have a little bit more overhead. Classpath also contains its own native state library (NSA), which uses a hashtable to map objects' internal hashcode to data. This has other disadvantages: It has more runtime overhead, since it has to lookup the hashtable and there may only be one native state per object, so if the super class already uses it, you can't use it. The CNI version does all Nullpointer and array bounds checking in native code. The JNI version does all that checking in java. I am not sure why you would want to do that checking in native code in this case. I like the JNI version more since that does all the sanity checking in a java wrapper and then hands of the checked data to the native code. :-) The CNI version seems to synchronize all the native calls, the JNI version does not. That is how I interpret the first line of every CNI function: JvSynchronize sync (this); I have removed the synchronization (though the perl script supports it), since it is unnecessary. The De/Inflater is by design not thread safe, since de/inflate and setInput are distinct functions. The comment I put in the header of the java files documents this. Jochen
Re: Utility for checking API compatibility with JDK
Hi, On Jun 13, Mark Wielaard wrote: I am working on java.util.zip. The version that you mention can be found at http://www.Informatik.Uni-Oldenburg.DE/~delwi/classpath/JCL/ and is made by Jochen Hoenicke. I want to import the java files from libgcj, make them work with the JNI code from Jochen, document them and then reintegrate them into libgcj. You should use the two java files at the URL above. They should work seamlessly with the other java files from libgcj, since I have started with Tom Tromey's version to produce them. I have not thoroughly tested them, though. And I didn't include any possible changes to libgcj since Dec 22. Reintegration in libgcj shouldn't be too difficult, since I also have the matching CNI files. Jochen
Re: New classes
On May 31, Mark Wielaard wrote: But I think there is a race in Scheduler.run(). IMHO the queue monitor must be kept between queue.top() and queue.sleep(). Otherwise a task may be enqueued in between and the scheduler wouldn't notice since the notify() comes before the sleep(). Good catch. Now that you have pointed it out it seems so obvious. But I always wondered what a good method is to prevent or prove these kinds of race conditions. I don't know an ultimate rule, either. (You say IMHO, is that because you want to be friendly or because you cannot express the proof without any doubt?) The second. I had to be careful, as I only read the important sections of your code. I will change the parameter to the sleep method so it represents the top TimerTask in the queue that you want to sleep on. Then sleep can check if the top task has changed and return immediatly if it has changed and do the real sleep otherwise (which should solve the race since sleep is synchronized). I noticed later that there's a similar issue with the "stop" variable. You should move it to the queue class so that the sleep() method can check it, too. Or maybe you put the whole sleep logic in Queue: You can add a synchronized method to Queue, that sleeps until the first task in the queue becomes ready, or the Timer was canceled. It returns the task and removes it from the queue, or returns null if the Timer was canceled. Jochen
Re: JNI and CNI
On Mar 24, Aaron M. Renn wrote: Hi, I'm looking to import the java.util.zip classes from gcj into Classpath's CVS and immediately hit the JNI v. CNI thing. It looks like the natDeflater.cc and natInflater.cc files that implement the native methods from this package use CNI and thus are Cygnus specific. Did anybody ever resolve anything on this? Yes, I tried to do it via a perl script that translates a special file either to JNI or CNI. This idea wasn't accepted on this list, but you can of course still use the produced JNI and CNI files (they are human readable). I had to do some changes to the java files, since libgcj uses a special object for native references and since JNI forbids to get a permanent pointer to an array. http://www.informatik.uni-oldenburg.de/~delwi/classpath/JCL I'm now going to Berlin for a week, so I can't answer questions immediately. Jochen
Re: java.util: Most Set, Map or List work as expected
On Mar 3, Martin Schroeder wrote: Run the test tools from http://www.javacollections.org/ and weep. Now all collection classes including TreeMap work (at least according to MapBash). TreeMap.java is still a piece of unreadable code with almost no comments, though. Jochen
Re: java.util: Most Set, Map or List work as expected
On Mar 3, Martin Schroeder wrote: (At least not when trying to compile this with Java 1.1.7a). Run the test tools from http://www.javacollections.org/ and weep. These tests (ListBash, MapBash, and SetBash) now succeed for ArrayList, Vector, LinkedList, HashMap, Hashtable, HashSet and TreeSet MapBash fails for TreeMap TreeMap still throws a NullPointerException in rbDeleteFixup. I think it's only a weakness of SetBash, that this error doesn't show up in TreeSet. WeakHashMap also fails, but only because it silently removes unreachable keys. If I keep strong references to the keys, the test succeeds. All classes tested with JDK1.2, and classpath's java.util-Classes in -Xbootclasspath. Jochen
Re: java.lang.NullPointerException at java.util.TreeMap.rbDeleteFixup(TreeMap.java:810)
On Mar 1, Martin Schroeder wrote: I get this crash: java.lang.NullPointerException: at java.util.TreeMap.rbDeleteFixup(TreeMap.java:810) at java.util.TreeMap.rbDelete(TreeMap.java:789) at java.util.TreeMap.remove(TreeMap.java:292) at java.util.TreeMap$TreeMapIterator.remove(TreeMap.java:1165) at java.util.AbstractCollection.removeAll(AbstractCollection.java:226) at de.artcomgmbh.ppdreader.PPD_UI_Frequency.main(PPD_UI_Frequency.java:657) I did a premature fix for this. I think the whole TreeMap.rbDelete routine needs a rewrite, though. I also committed the patch you send in a previous mail. Now on to the next bug report ;-) Jochen
Re: java.util: No Set, Map or List works as expected
On Mar 3, Martin Schroeder wrote: (At least not when trying to compile this with Java 1.1.7a). Run the test tools from http://www.javacollections.org/ and weep. Thanks for the URL, I will look into this over weekend. Jochen
Re: Ideas for faster classes
On Feb 16, Artur Biesiadowski wrote: Jochen Hoenicke wrote: I think the optimum is: shift = 6, data : byte[7808], block:char[1024], flags : byte[158], lowercase,uppercase,numValue : char[158] Total size: 10962 bytes (+/- Unicode Version Number) I have encoded flags directly into data, so it took me an int to do it, and then 4 shift was best - but then it takes about 25kb of data. I think that 15 kb of save is better than one less array access for most calls after all. I have now made the data array a char array (so that I can easily use the string trick). The data array contains the flags directly and a pointer to the lower/upper/numValue arrays. I have further optimized the perl script, so that it merges the blocks, if the head and the tail of two different blocks match. I put the classes at the usual URL. They are currently completely untested, though. http://www.informatik.uni-oldenburg.de/~delwi/classpath Jochen
Re: Ideas for faster classes
On Feb 15, Artur Biesiadowski wrote: Jochen Hoenicke wrote: [...] It is probably slower if many different methods are called on the same character (since I don't have a cached CharAttr), but faster if they are called on similar characters (characters in the same block). Unfortunately cachedBlock in your Character is possibly dangerous - if thread will switch after compares and before return you can get a wrong result. I haven't thought of concurrency, you are right here. But I think there is a simple fix. Just copy it to a local variable, before checking if it's the right block: --- Character.java~ Thu Dec 30 20:02:41 1999 +++ Character.java Wed Feb 16 15:44:18 2000 @@ -577,4 +577,5 @@ private static int getBlock(char ch) { -if (ch = blocks[cachedBlock] ch = blocks[cachedBlock+1]) - return cachedBlock; +int lastCached = cachedBlock; +if (ch = blocks[lastCached] ch = blocks[lastCached+1]) + return lastCached; // simple binary search Maybe later we can do something faster, looking at space/speed benefits - like creating constant size blocks, which would be accesible by just shifting char. Something like charData = data[block[ch11]+(ch0x1f)]; I have tested how big the arrays would be for each shift: shift: 0 data array: 158 block array: 65536 shift: 1 data array: 558 block array: 32768 shift: 2 data array: 1528 block array: 16384 shift: 3 data array: 2944 block array: 8192 shift: 4 data array: 4288 block array: 4096 shift: 5 data array: 6144 block array: 2048 shift: 6 data array: 7808 block array: 1024 shift: 7 data array: 9088 block array: 512 shift: 8 data array: 10496 block array: 256 shift: 9 data array: 13312 block array: 128 shift: 10 data array: 18432 block array:64 shift: 11 data array: 30720 block array:32 shift: 12 data array: 45056 block array:16 shift: 13 data array: 65536 block array: 8 I think the optimum is: shift = 6, data : byte[7808], block:char[1024], flags : byte[158], lowercase,uppercase,numValue : char[158] Total size: 10962 bytes (+/- Unicode Version Number) The data would be accessed with three array accesses, e.g: flags[data[block[ch6] + (ch 0x3f)]] toUpperCase would be: return (char) (ch + uppercase[data[block[ch6] + (ch 0x3f)]]); Jochen
Re: HashMap bucket
On Feb 15, Artur Biesiadowski wrote: HashMap uses array of Bucket objects, which in turn are just wrappers around pointer to Node instance. If I understand this scheme correctly, than for every object put into list, both Bucket instance and Node instance is created, with additional Node for every conflicting hashcode. Would not it be better to use directly array of Nodes ? Saving allocation of one object for each value put in should be a major benefit both in performance and memory for HashMap/Hashtable (and sets which are based on this classes). If nobody have anything against the idea, I'll try to implement the change. I already tried this a few days ago. I have used a linear collision resolution strategy, since that allows complete removing. I also tried a double hash strategy. The files are now at http://www.informatik.uni-oldenburg.de/~delwi/classpath/HashMap There is also a small ad hoc benchmark. IIRC some operations were notably faster than the normal hashcode, the others were about the same speed. Another advantage is, that the iteration over the hash map gets _much_ simpler. I think it would be wise, to implement HashSet in a similar way, but separately, since this is much more space efficient (the value array can be omitted). Feel free to play with these classes if you have some ideas. Jochen
Re: TreeMap / TreeSet
On Feb 10, Romuald Lemarchand wrote: It seems like there is no TreeMap / TreeSet. If nobody works on it, may I do it ? Who should I ask this to ? These classes already exists (in the cvs). They seem to be complete. Here is the way to check out the cvs version: cvs -d :pserver:[EMAIL PROTECTED]:/gd/gnu/anoncvsroot login (no password, press enter) cvs -d :pserver:[EMAIL PROTECTED]:/gd/gnu/anoncvsroot co classpath Ok, so I'm really interested in helping for this project. But I would like to know if any team is interested in me helping : I'm a student and I'm specialized in algorithmics. Your help is appreciated. First you should read the Hacker's Guide if you haven't already. Most classes necessary for 1.1 compatibility are already written. I think the most important thing now, is to get classpath working with japhar and fill in the few missing classes. Another thing to consider is writing more test classes for the mauve project (http://sourceware.cygnus.com/mauve/). Mauve should be the common test suite for free java implementations. There's still much to be done here, since writing test classes is not the most interesting task ;-) Jochen
Re: Proposal for CNI/JNI problems
On Jan 11, Per Bothner wrote: Paul Fisher [EMAIL PROTECTED] writes: While it's important that Classpath continue to support JNI, The first question is why? What is the goal? Presumably, the goal is that Classpath can be used as the standard Java library for non-Gcj JVMs. Yes. The question then is how portable do we need to/want to be? (1) Is it OK to write Classpath in C++ rather than C? [...] (2) Is it OK for Classpath to depend on G++ extensions? [...] I don't feel too good with using C++ in classpath. I can't rationally explain this though. Tom Tromey suggested that the ideal way to let people write code that is both JNI and CNI-compliant is to have a compiler that can read CNI and emit JNI. See: http://sourceware.cygnus.com/ml/java-discuss/1999-q4/msg00570.html My first reaction was that this was too difficult. But it becomes simpler if we remember that JNI is an Application *Binary* Interface. All we need do is have G++ have an option to generate JNI calls. [...] I like this idea (indepent of using it for classpath). I don't know how difficult this is, since I don't know much about the internals of g++. But when I converted the java.util.zip classes, there were some issues that a compiler can't solve: CNI has the method "elements" to access the elements of an array. The corresponding JNI method is "GetTypeArrayElements", but it needs an "ReleaseTypeArrayElements" later. This pair is necessary, to support copying garbage collectors, that may move the array on the fly, or to support jvms that store array elements in a different way (e.g. packing boolean arrays). Under JNI you have to register global references. AFAIK libgcj's garbage collector scans the data area, so one doesn't need to register them under CNI. Another point is how to put pointers to native structures into a classfile. Sun didn't solve it well. If I understand the code in japhar's java/util/zip correctly sun used an int field to store the pointer and later changed it to long to support 64bit architectures. libgcj declares natives fields as "gnu.gcj.RawData", but this is not portable to other jvms, where the garbage collector doesn't know that this class is special. My solution was to put the structure into a java byte array, which imposes a little overhead, but should be portable (and you get it freed automatically). Jochen
Re: KJC and GNU Classpath
On Dec 28, Brian Jones wrote: Vincent GAY-PARA [EMAIL PROTECTED] writes: Hi, At DMS we tried to compile GNU Classpath with KJC (http://www.dms.at/kjc) and we encoutered some problems. WeakHashMap: java/util/WeakHashMap.java:336: Cannot access field "queue" it is in an other package and not a class member [JLS 15.10] This is a problem with how WeakBucket is setup I believe. It doesn't make much sense to me why we would call the super constructor with a package private data member that isn't even initialized in java/lang/ref/Reference.java except in this same constructor. There is also the problem mentioned above of queue being in another package. I think Jochen Hoenicke should look at this. The queue meant here is WeakHashMap.queue, not Reference.queue. Okay, that is a name conflict, but since Reference.queue is private it shouldn't be visible in java.util. jikes and javac don't have problems with this. I may change this, but IMHO this is also a bug in kjc. BTW the conflicts in AbstractList are serious, jikes doesn't compile subList() correctly. Jochen
Re: Ideas for faster classes
This is an answer to an old mail from Artur, but this has never changed since March. On Mar 2, Artur Biesiadowski wrote: Here are few of my ideas about how some classes can be made a lot faster. Maybe I'll implement them, but if not I would like to share them. java.lang.Character I was already talking about it - work directly on array, without CharAttr creation (it is already done in my version) and create compression tables more loosely - do not compress blocks that are too short (like 2-5 lengths) - they should be merged with surrounding explicit info (for better preformance in findBlock) I made a change that does this. It also uses Strings to get the initial data, instead of using various java.io classes. I think it might be bad if the static constructor of a basic class like java.lang.Character uses too many other classes (this might lead to bootstrapping problems). The strings are created by a perl script. See: http://www.informatik.uni-oldenburg.de/~delwi/classpath/ Artur: You should test it for performance. It is probably slower if many different methods are called on the same character (since I don't have a cached CharAttr), but faster if they are called on similar characters (characters in the same block). I think the normal case is that someone parses a string or a file and invokes a few different methods on many different (but often similar) characters. [a nice java.util.Hashtable idea] java.lang.BitSet It might be interesting to implement BitSet to use array of ints instead of array of longs. Of course sun have created API of bitset heavily based on their internal representation - but only serialization and hashcode computation would require hackery. Such BitSet would work a lot faster on 32-bit CPUs. I wonder if it would be possible/reasonable to distribute two versions - and place one that will work faster for target machine (of course both of them would work on every platform). I already did this at that time, but never checked it in. Artur reported that it gave a good speedup for 32-bit CPUs. One problem with this file is that it needs a kind of preprocessor to differ between 32-bit and 64-bit CPUs. I used some perl code that automatically comments out one part of the file. Jochen
Re: Ahhh....Success!
On Dec 29, Chris Toshok wrote: "Aaron M. Renn" wrote: Brian Jones ([EMAIL PROTECTED]) wrote: I may have changed a couple of lib names today without changing the load in the .java file to match. My mistake. I'll fix it tomorrow. Our Java files should be loading names like "javanet". Now this maps to a native library name. In Japhar, supposedly either libjavanet.so or libjaphar_javanet.so work, but I've only ever gotten the latter to do so. I wonder if we are hardcoding a library name someplace in our native code. oh, you know what this might be? Jochen fixed a bug in MapDLLName (or whatever that method is) that gives you the name of the .so to load. that can only return one name, and it returns libjaphar_%s.so. hmm.. i'll take a look at this tomorrow. This was necessary for the jdk1.2 classloader which checks if a library exists (via File.exists) before even calling the native method to load the lib. So for jdk1.2 MapDLLName must even return an existing file name. This problem is because most of the loading process is done in java in jdk1.2, so japhar cannot manipulate it. The 1.2 API, where the classloader (which could be a custom class loader) finds a library and not java.lang.Runtime, makes it really hard to stay with the current multiple name scheme (lib{japhar_,}%s.*). I would propose the following algorithm: System.mapLibraryName returns "lib%s.so", to load custom JNI libs via custom ClassLoaders just the same way it does under sun's jdk. The bootstrap's ClassLoader.findLibrary should then first try to locate libjaphar_%s.*, and if it doesn't succeed lib%s.*. Sadly, that means that japhar doesn't work with the jdk-1.2 java.lang.ClassLoader. Jochen
Re: Coding style etc
On Dec 22, Bryce McKinlay wrote: One issue I'd like to raise is that of coding style. A nice feature of libgcj is that the code is written fairly consistently, where as classpath varies widely between classes and packages that were written by different authors. Although there is no official GNU coding standard for Java, libgcj is written according to what we think such a standard would look like if it existed. There was a discussion on this list about coding style, some time ago. We decided to use GNU coding style (before both GNU and SUN coding style were allowed), but unfortunately many classes were already written with a different coding style at that time. Should classpath's (and libgcj's?) code should be reformatted to adhere to a common style? This could, of course, be easily done using code-formatting tools, and in most cases the changes would be relatively minor. I do think that it would be a significant advantage to achieve some level of consistency before any serious merging work begins. What are the opinions of the classpath developers on this? If there is a code-formatting tool I don't see a reason why we shouldn't convert. We should make sure that nobody has pending changes to that class before converting them, though. Another thing to consider are the copyright notices at the beginning of the file. We should probably make a template of how they should look now and use that for all files. Currently classpath has several different styles of copyright headers. Also, I notice that many parts of classpath are documented with javadoc-style comments while other parts (and libgcj) leave them out or just have minimal comments. The Java APIs are already extensively documented from a variety of sources, so it can be argued that such API documentation is redundant. Personally I think that large comments make the code a bit harder to read and maintain, but I guess that modern editors can be configured to hide javadoc comments so that perhaps isn't a real issue. It is also good to have a free (as in speech) documentation set. Anyway, this is another style difference between the libgcj and some of the classpath code. I don't think that the comments make the code more difficult to read! The only case comments might disturb you, is for simple methods, where the implementation consists of a single line. But if you want to get a overview of the whole class, its much nicer to look at the javadoc generated documentation, than to look at the code. AFAIK, Classpath wants to generate its own documentation. The comments are also useful to document special things (e.g, that the Vector.copyInto() can throw an ArrayIndexOutOfBoundsException, even if that isn't made explicit in the code). It's of course a lot of work to write comments, and so they sometimes were omitted. Jochen
CNI vs JNI [Was: [per@bothner.com: Status of Free Java Environment?]]
On Dec 16, Stuart Ballard wrote: Paul Fisher wrote: The JNI/CNI issue could be solved post agreeing to cooperate. I don't see the JNI/CNI issue to be terribly important. gcj aims to support JNI, but that code needs to be completed. I personally find CNI to be extremely elegant (about 10 lines of JNI code correspond to one line of CNI). Regardless of how cool CNI is, and I'm sure it is, it's not supported by most VMs, and probably won't be, so Classpath can't rely on it (unless we can somehow implement CNI *in* JNI? That would be nice.) JNI is a very abstract interface to the virtual machine. It is made in a way that it should be useful for any Java implementation. To quote from the Introduction of the Java Native Interface Specification: If you are implementing a Java VM, you should implement the JNI. We (Javasoft and the licensees) have tried our best to ensure that the JNI does not impose any overhead or restrictions on your VM implementation, including object representation, garbage collection scheme, and so on. Please let us know if you run into any problems we might have overlooked. CNI is of course much simpler and more efficient than JNI, but it heavily relies on the layout of objects. Also it seems impossible to use a copying or generational garbage collection with CNI, since the native code may directly modify objects. CNI is not even compatible against binary compatible class evolution. I think we should only use JNI in classpath. We don't need another abstraction layer, since JNI is abstract enough. Jochen
Re: Locale observations
On Dec 15, Mark Wielaard wrote: Hi, I looked a bit more at how Locales worked since I had never used them. And noticed the following things: The LocalInformation_nl that I send you has a wrong shortDateFromat (see diff.1) java.util.Calendar wants to get the key "firstDayOfWeek", but the classes in gnu.java.local define it as "firstDayInWeek". (see diff.2) The java.lang.String methods toLowerCase() and toUpperCase() can take a Locale. But they currently don't use it (but use the methods in Character which don't take a Locale). AFAIK the only locale specific thing is that for turkish local, which has two different i's one with dot, and one without. For most locales the unicode uppercase or lowercase is sufficient. The getAvailableLocals() method in java.util.Local should be getAvailableLocales() (see diff.3) I am also not sure that method really does what it should do. But the docuementation is not clear on what it should return since it is not clear what "installed locales" are. For the other classes that implement getAvailableLocales() (or actually don't implement it) wouldn't it be possible to package the locales in a separate jar file and then always load the ResourceBundles through a URLClassLoader (which we should then first implement :) using that jar so we can also search which classes are available in the jar file? You are right, we should only return locales for which we have a localization. But I think we can't use the implementation you suggest. We must call the getResource on the class loader that loaded the class, like ResourceBundle does, to support virtual machines that have their own special class loading mechanism. This means we can't get a list of resource bundles easily. I suggest adding an entry to the root resource bundle, listing the available locales. At the moment all 'functionality' for each local is encoded in one big gnu.java.locale.LocalInformation ListResourceBundle class. The Hacker's Guide says that you should provide a Boolean for every functional area that is supported for the Locale (which isn't done/used at this moment btw). Wouldn't it be easier if there was a seperate class for all the different functional areas? Something like: gnu.locale.java.text.BreakIterator gnu.locale.java.text.Collator gnu.locale.java.text.DateFormat gnu.locale.java.text.DecimalFormat gnu.locale.java.util.Calender gnu.locale.java.util.GregorianCalendar I think it is a good idea to separate them. (I wouldn't separate Calendar and GregorianCalendar though). Since we need to load only the classes for which the program requested some local specific functionality, the overhead should be low enough. I think using gnu.java.locale.DateFormat should be unique, though. I will commit your changes soon and look into cleaning up the resource bundles later. Jochen
Re: Locale observations
On Dec 16, Mark Wielaard wrote: On Thu, Dec 16, 1999 at 11:17:46AM +0100, Jochen Hoenicke wrote: [about getAvailableLocals...] I suggest adding an entry to the root resource bundle, listing the available locales. Would it be an idea to supply a simple properties file (say gnu.locales) with that information? That would make it simpler for people that want to add their own Locales. By providing an extra properties file (with the same name) and their LocaleInformation classes in a directory/zip/jar which people can just add to their classpath (you can then merge those property files by doing a ClassLoader.getResources("gnu.locales")). This sounds like a good idea, but it needs some infrastructure. The format of gnu.locales could be the same as for Properties: gnu/java/locale/DateFormat=en,nl,de_DE,de_AT,ja gnu/java/locale/Calendar=en,nl,de (I assume the LocaleInformation is already splitted up) We could create a gnu/java/locale/AvailableLocale.java which does the gnu.locales merging. The usage could be: public static Locale[] getAvailableLocales() { AvailableLocale.getAvailableLocales("gnu/java/locale/Calendar"); } It may be worthwhile to generalize this interface so that non classpath classes could use it, too. What do you think? Jochen
Re: jikes error...
: From: Brian Jones [EMAIL PROTECTED] : Date: 02 Oct 1999 12:13:35 -0400 : : Hello, I'm working on the GNU Classpath project and having some : trouble using jikes to compile classpath. : : I'm wondering if anyone else has seen the following when using jikes : (1.0.6 in my case)? Am I doing something wrong? : : Compiling java.util.Collection by itself works correctly (javap : results are valid). : : Compiling java.util.* produces an erroneous class... : : lyta:~/classpath/lib$ javap java.util.Collection : Compiled from Collection.java : public abstract synchronized class java.util.Collection extends java.lang.Object : /* ACC_SUPER bit set */ : { : java.util.Collection(); : } Maybe this is the reason: $ cat classpath/java/security/cert/Collection.java package java.util; public abstract class Collection { Collection(){} } This file and Set.java in the same directory should definitely be removed. I have just committed it. Jochen
Initial implementation of java.lang.ref
Hello, I have just committed the jdk 1.2 Reference classes java.lang.ref. They don't have any special functionality. This should be AFAIK implemented by the garbage collection. This should enable us to implement WeakHashtable (even if it doesn't work yet, it will at least compile) and to use References for caches (the java.util.ResourceBundle come into my mind). Jochen
Re: BitSet internally synchronized
: Artur Biesiadowski [EMAIL PROTECTED] writes: : : Are you sure that BitSet should be internally synchronized ? : Paul Fisher [EMAIL PROTECTED] wrote: : Unless the JLS specifies otherwise, Java data structures are generally : assumed to be thread-safe. : : In this case, the example code given for BitSet.hashCode in the JLS is : synchronized, which would seem to imply that BitSets should be : thread-safe. I have written a small test program and the result is 1) For JDK-1.1.7 all Methods in BitSet except size() are synchronized. 2) For JDK-1.2 no Method is synchronized. If no one argues, I will remove the synchronization. Jochen P.S: The test program uses two threads, one that allocates the monitor, while the other calls the method. If the method call doesn't succeed within a given time, it is assumed that the method is synchronized. The test program (a quick hack) can be found at: http://www.Informatik.Uni-Oldenburg.DE/~delwi/classpath/SynchronizedTest.java
Re: Ideas for faster classes
On Tue, 02 Mar 1999 Artur Biesiadowski [EMAIL PROTECTED] wrote: : Here are few of my ideas about how some classes can be made a lot : faster. Maybe I'll implement them, but if not I would like to share : them. : : [...] : : java.util.BitSet : It might be interesting to implement BitSet to use array of ints instead : of array of longs. Of course sun have created API of bitset heavily : based on their internal representation - but only serialization and : hashcode computation would require hackery. Such BitSet would work a lot : faster on 32-bit CPUs. [...] This sounded interesting and since its my class, I have implemented this: http://www.informatik.uni-oldenburg.de/~delwi/classpath/BitSet.java I have only tested this with the blackdown port of JDK1.2. This class uses the new JDK1.2 serialization mechanism (get/putFields) which aren't implemented in classpath, so serialization can't work there. : [...] I wonder if it would be possible/reasonable to : distribute two versions - and place one that will work faster for target : machine (of course both of them would work on very platform). It would be nice to have a simple preprocessor, so we can conditional compile this. Conditional compiling with static final variables doesn't work: class BitSet { if (USE32BIT) public transient int[] bits; else public long[] bits; } Jochen
Re: GNU Classpath: java.util.Properties
: Thanks for the bug report - the Properties class wasn't my work, but : I've included the Classpath mailing list in the recipients of this : message, so whoever wrote it can comment on whether this is a legitimate : bug, and fix it for you. That was my class. I have just commited the change. Thank you for spotting this, Matt. Jochen : Matt Mucklo wrote: : : I've found a possible bug in java.util.Properties.save(). : : It seems that you create a PrintWriter object as the : means to write out to the stream that's passed in. : : Unfortunately, it seems that the PrintWriter object is : buffered. Since you don't close it after returning, the : output has a chance of never getting written out to : the underlying stream. : : A simple solution would be to do a PrintWriter.flush() : call before exiting the method.
java.util commit.
Hello, I just commited my latest changes to java.util. This are mainly comment fixes. I wrote the missing deprecated functions of Date.java and added Random.java. Jochen
Re: Incompatibility of clone in java.util.Vector and other
Brian Jones [EMAIL PROTECTED] writes: "Jochen Hoenicke" [EMAIL PROTECTED] writes: Hello, The clone method in java.util.Vector and some other collection classes is incompatible with the behaviour of the Sun Java methods: When I extend java.util.Vector and clone that class, the result is a java.util.Vector and not the extended class. This is also true, when I clone java.util.Stack. Jochen, If you'd like to submit a diff, I'll add it to the CVS tree. The same for anybody who wants to point out a problem, but thanks very much for the heads up on this. Brian Okay here is a patch for Vector, Hashtable, HashMap and HashSet. I don't have a working japhar, yet, so I can't test if it even compiles. But the patch is quite trivial and should be correct. diff -u classpath/java/util/HashMap.java classpath/java/util/new/HashMap.java --- classpath/java/util/HashMap.javaFri Nov 13 16:39:19 1998 +++ classpath/java/util/new/HashMap.javaSat Nov 14 13:08:42 1998 @@ -212,15 +212,14 @@ */ public Object clone() { - Map.Entry entry; - Iterator it = entrySet().iterator(); - HashMap clone = new HashMap(capacity, loadFactor); - while (it.hasNext()) - { - entry = (Map.Entry) it.next(); - clone.internalPut(entry.getKey(), entry.getValue()); - } - return clone; +try { +HashMap clone = (HashMap) super.clone(); +clone.clear(); +clone.putAll(this); +return clone; +} catch (CloneNotSupportedException ex) { +return null; +} } /** returns a "set view" of this HashMap's keys */ diff -u classpath/java/util/HashSet.java classpath/java/util/new/HashSet.java --- classpath/java/util/HashSet.javaFri Nov 13 16:39:19 1998 +++ classpath/java/util/new/HashSet.javaSat Nov 14 13:07:25 1998 @@ -133,11 +133,13 @@ */ public Object clone() { - Iterator it = iterator(); - HashSet clone = new HashSet(map.capacity, map.loadFactor); - while (it.hasNext()) - clone.internalAdd(it.next()); - return clone; +try { +HashSet clone = (HashSet) super.clone(); +clone.map = (HashMap) map.clone(); +return clone; +} catch (CloneNotSupportedException ex) { +return null; +} } /** diff -u classpath/java/util/Hashtable.java classpath/java/util/new/Hashtable.java --- classpath/java/util/Hashtable.java Fri Nov 13 16:39:43 1998 +++ classpath/java/util/new/Hashtable.java Sat Nov 14 13:06:35 1998 @@ -474,15 +474,14 @@ */ public synchronized Object clone() { - Map.Entry entry; - Iterator it = entrySet().iterator(); - Hashtable clone = new Hashtable(capacity, loadFactor); - while (it.hasNext()) - { - entry = (Map.Entry) it.next(); - clone.internalPut(entry.getKey(), entry.getValue()); - } - return clone; +try { +Hashtable clone = (Hashtable) super.clone(); +clone.clear(); +clone.putAll(this); +return clone; +} catch (CloneNotSupportedException ex) { +return null; +} } /** diff -u classpath/java/util/Vector.java classpath/java/util/new/Vector.java --- classpath/java/util/Vector.java Fri Nov 13 16:40:34 1998 +++ classpath/java/util/new/Vector.java Sat Nov 14 12:59:45 1998 @@ -453,7 +453,14 @@ * Creates a new Vector with the same contents as this one. */ public Object clone() { -return new Vector(this); +try { + Vector clone = (Vector) super.clone(); + clone.elementData = new Object[elementCount]; + System.arraycopy(elementData, 0, clone.elementData, 0, elementCount); + return clone; +} catch (CloneNotSupportedException ex) { + return null; +} } /**