gjar -u doesn't work if the jar file being updated is not on
the same filesystem as /tmp.  This is because the update
process works by creating a new JAR file in /tmp, adding both
the old and new classes to it, and then moving the new one over
the old one.  That final step uses File.renameTo, which in turn
uses the system call rename() which fails with the EXDEV error
code if the filesystems are different.

The existing code ignored the return value (true/false) of the renameTo
operation and so was silently failing to update the JAR file.  Note I
think that there really should be a better way of finding out what went
wrong via the java.io.File API as I had to add a perror line to our native
code to trace this.  But that's one for a Sun JSR...

With this patch, we try to rename (being more efficient), but if this fails,
we copy the file over instead.  Interestingly, the code for copying the file
is used almost verbatim from a file copier I wrote in 2003 before I started
hacking on GNU Classpath... :)

ChangeLog:

2008-06-26  Andrew John Hughes  <[EMAIL PROTECTED]>

        PR classpath/36636:
        * tools/gnu/classpath/tools/jar/Updater.java:
        (run(Main)): Check return value of renameTo, and
        copy file instead if necessary.
        (copyFile(File,File)): New method to copy a file.

-- 
Andrew :)

Support Free Java!
Contribute to GNU Classpath and the OpenJDK
http://www.gnu.org/software/classpath
http://openjdk.java.net
PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
Fingerprint = F8EF F1EA 401E 2E60 15FA  7927 142C 2591 94EF D9D8
Index: tools/gnu/classpath/tools/jar/Updater.java
===================================================================
RCS file: 
/sources/classpath/classpath/tools/gnu/classpath/tools/jar/Updater.java,v
retrieving revision 1.4
diff -u -u -r1.4 Updater.java
--- tools/gnu/classpath/tools/jar/Updater.java  15 May 2006 01:57:29 -0000      
1.4
+++ tools/gnu/classpath/tools/jar/Updater.java  26 Jun 2008 22:18:13 -0000
@@ -38,6 +38,7 @@
 
 package gnu.classpath.tools.jar;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -86,6 +87,32 @@
       }
 
     close();
-    tmpFile.renameTo(parameters.archiveFile);
+    if (!tmpFile.renameTo(parameters.archiveFile))
+      {
+       if (!parameters.archiveFile.delete())
+         throw new IOException("Couldn't delete original JAR file " +
+                               parameters.archiveFile);
+       copyFile(tmpFile, parameters.archiveFile);
+       tmpFile.delete();
+      }
+  }
+
+  private void copyFile(File sourceFile, File destFile) 
+    throws IOException 
+  {
+    BufferedInputStream source =
+      new BufferedInputStream(new FileInputStream(sourceFile));
+    BufferedOutputStream dest =
+      new BufferedOutputStream(new FileOutputStream(destFile));
+    int inputByte;
+    
+    while ((inputByte = source.read()) != -1) 
+      {
+       dest.write(inputByte);
+      }
+        
+    source.close();
+    dest.close();
   }
+
 }

Reply via email to