These are some observations I made while trying to kick kaffe until it runs with my company's software which uses a lot of JDK1.2 stuff. Current state: I'm implementing as much of JDK1.2's java.io.* as I need for kaffe, I can't promise a full implementation. The next step will be JDBC 2. ==== paintBorder collision with Swing 1.1.1fcs com/iconsult/tools/engine/Controller.java:17:20:17:29: Warning: Method "void paintBorder(java.awt.Graphics $1);" in class "javax/swing/JComponent" does not override the corresponding method with default access in class "java/awt/Container". Swing's paintBorder collides with paintBorder from Kaffe's AWT implementation and jikes complains about it. This can be taken care of by: ~~/src/kaffe/libraries/javalib$ perl -p -i.bak -e 's|paintBorder|kaffePaintBorder|g' **/*.java (**/*.java is zsh's notion for all .java files in all subdirectories) ==== java.io.File.getCanonicalPath() Should getCanonicalPath be native and use some kind of getpwd? If we got a soft link in our getAbsolutePath() a native implementation would return a drastically different path than this Java implementation. Later note: kaffe's getCanonicalPath() does not remove '.' from the path: import java.io.*; public class file4 { public static void main(String[] args) throws Exception { System.err.println(new File("././././.").getCanonicalPath()); } } [froh] ~/src/kcrash$ /usr/local/pkg/jdk1.2pre-v2/jre/bin/java -cp . file4 /home/froh/src/kcrash [froh] ~/src/kcrash$ kaffe file4 /home/froh/src/kcrash/././././. ***fixed in my version of kaffe's File.java, patch below*** Access to ../../<very very often ..>/../../../boom fails with an index out of bounds exception. ***fixed in my version of kaffe's File.java, patch below*** ===== java.io.File (and probably all other files) This file contains tab characters, but seems to have a convetion of a tab every 4 spaces. Wouldn't it be better to have these expanded to spaces? ==== kaffe.net.DefaultURLStreamHandlerFactory.java The JDK 1.2 doc states: 3.If the previous step fails to find a protocol handler, then the constructor tries to load the class named: sun.net.www.protocol.<protocol>.Handler If this class does not exist, or if the class exists but it is not a subclass of URLStreamHandler, then a MalformedURLException is thrown. Should the DefaultURLStreamHandlerFactory try sun.net... besides com.transvirtual.net... and kaffe.net...? This probably is a borderline case, but I'm just reading Sun's API docs. Doing so might slow things down a little little bit. ==== another buffer overflow ... FileOutputStream has the same buffer overflow that I recently reported for FileInputStream, a range change for the parameters is missing. Interestingly this doesn't really crash kaffe. When a too large size is given and write marches out of mapped memory the write returns with an java.io.IOException("Bad address"). By the way, writing to /dev/zero behaves differently, no wonder since /dev/zero's write should be a no-op ... import java.io.*; public class crash3 { public static void main(String[] args) throws Exception { FileOutputStream fos = new FileOutputStream("veryfunny"); fos.write(new byte[0], 0, 10*1024*1024); System.err.println("You won't see this."); } } ==== File URLs are FTP URLs !?!?! While kaffe's File URLs behave as *I'd* expect (just accessing local files) this seems to be wrong: Have a look at http://www.ncsa.uiuc.edu/demoweb/url-primer.html, that's where Sun's JDK1.2 API doc sends you for information on URLs. Try yourself what the document states, use Netscape to open file://ftp.cdrom.com/ Writing a little test program I verified that Sun's implementation tries to do the same. import java.io.*; import java.net.*; public class file { public static void main(String[] args) throws Exception { InputStream is = new BufferedInputStream(new URL("file://ftp.cdrom.com/README").openStream()); int i; while ((i = is.read())>=0) System.out.print((char)i); } } It tries to activate a ftp client, but never really succeeds on my box. That might be due to my strange internet connection, though. At least now I know how to implement java.io.File.toURL() ;-) ==== At last - a little patch so my stuff doesn't complain when it gets compiled. Note, I forgot to add a XXX FIXME comment to listRoots, there are platforms with more than one "/" as root ... and now it's too late, but I should have put the array in a private static variable, so listRoots doesn't create an object every time. THIS STUFF IS NOT TESTED. I'll do that (and implement the native methods) this weekend, if nobody objects in me building this stuff and send a _real_ patch afterwards. Ah, and of course it would be ridiculous if I'd mind any copyright things on these puny patches, so do with them whatever you want. (That is include them in both versions of kaffe if you want to ...) diff -r -u kaffe/libraries/javalib/java/io/File.java kaffe-other/libraries/javalib/java/io/File.java --- kaffe/libraries/javalib/java/io/File.java Tue Oct 12 21:05:45 1999 +++ kaffe-other/libraries/javalib/java/io/File.java Thu Nov 11 03:30:39 1999 @@ -168,8 +168,11 @@ for (int i = 0; i < len; i++) { String str = tok.nextToken(); if (str.equals("..")) { + if (j>0) j--; - } + } else if (str.equals(".")) { + // do nothing. + } else { array[j] = str; j++; @@ -339,4 +342,65 @@ public String toString() { return path; } + + +//JDK1.2 updates ... + +public java.net.URL toURL() + throws java.net.MalformedURLException +{ + if (isDirectory()) + return new java.net.URL("file", "", getAbsolutePath()+separator); + else + return new java.net.URL("file", "", getAbsolutePath()); +} + +public boolean isHidden() +{ + checkReadAccess(); + return getName().startsWith("."); +} + +public File getAbsoluteFile() { + return new File(getAbsolutePath()); +} + +public File getParentFile() +{ + String p = getParent(); + if (p==null) + return null; + return new File(p); +} + +public File getCanonicalFile() + throws java.io.IOException +{ + return new File(getCanonicalPath()); +} + +public boolean createNewFile() +{ + // XXX FIXME: needs native support + throw new kaffe.util.NotImplemented(); +} + +public boolean setLastModified(long time) +{ + // XXX FIXME: needs native support + throw new kaffe.util.NotImplemented(); +} + +public boolean setReadOnly(long time) +{ + // XXX FIXME: needs native support + throw new kaffe.util.NotImplemented(); +} + +public static File[] listRoots() +{ + return new File[] { new File("/") }; +} + + }