"pre"-patch for JDK 1.2 compatible java.io.File, lots of notes on Kaffe

Frohwalt Egerer froh at iconsult.com
Wed Nov 10 18:44:35 PST 1999





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("/") };
+}
+
+
 }


More information about the kaffe mailing list