1 Reply Latest reply on Apr 23, 2008 5:18 AM by alesj

    Refreshing entries in JARs

    alesj

      Regarding this JIRA issue:
      - http://jira.jboss.com/jira/browse/JBVFS-7

      I created this test:

       public void testEntryModified() throws Exception
       {
       File tmp = File.createTempFile("testJarEntry", ".jar");
       Manifest mf = new Manifest();
       mf.getMainAttributes().putValue("Created-By", getClass().getName() + "." + "testEntryModified");
       FileOutputStream fos = new FileOutputStream(tmp);
       JarOutputStream jos = new JarOutputStream(fos, mf);
       try
       {
       jos.setComment("testJarURLs");
       jos.setLevel(0);
       }
       finally
       {
       jos.close();
       }
       VFS vfs = VFS.getVFS(tmp.toURI());
       VirtualFile metainf = vfs.findChild("META-INF");
       List<VirtualFile> children = metainf.getChildren();
       assertEquals(1, children.size());
      
       fos = new FileOutputStream(tmp);
       jos = new JarOutputStream(fos, mf);
       try
       {
       ZipEntry entry = new ZipEntry("META-INF/some.txt");
       entry.setComment("some_comment");
       entry.setExtra("qwerty".getBytes());
       entry.setSize(1);
       jos.putNextEntry(entry);
       jos.closeEntry();
      
       entry = new ZipEntry("META-INF/other.txt");
       entry.setComment("other_comment");
       entry.setExtra("foobar".getBytes());
       entry.setSize(1);
       jos.putNextEntry(entry);
       jos.closeEntry();
       }
       finally
       {
       jos.close();
       }
      
      // vfs = VFS.getVFS(tmp.toURI());
      // metainf = vfs.findChild("META-INF");
       System.out.println("metainf = " + metainf.hasBeenModified());
       children = metainf.getChildren();
       assertEquals(3, children.size());
       }
      


      Which looks legit, since when I uncomment two lines at the bottom, the new vfs handle picks up all three entries.

      But in our case, where we don't want to create new handle, but use the existing one, where the handle should see that the content has changed and return 3 entries.
      Of course that is not the case. :-(
      And I don't see how you really do this in generic fashion w/o modifying all VFS, e.g. lets say some 4level nested jar is updated.

      Even in this case, where we have just simple jar, updating contents of META-INF handler is far from trivial.
      The handler that maps to META-INF is SynthenticDirEntryHandler, which only gets populated when we iterate over entries of parent jar.
      Meaning we would have to go back and recreate every entry.
      And I don't know how much information that's needed for reconstruction we're holding.

      I'll have a look what can be done if I add some 'reconstruct' method to VirtualFileHandler.

        • 1. Re: Refreshing entries in JARs
          alesj

           

          "alesj" wrote:

          I'll have a look what can be done if I add some 'reconstruct' method to VirtualFileHandler.

          This looks like a huge hassle for something that rarely happens (runtime jar modification), and which has a much nicer workaround (exploded archive).

          The thing is that current JAR handling architecture wasn't designed to handle reconstruction out-of-the-box.
          In case of updating some inner jar, you need to go all the way to root jar, and do the hierarchy creation again, iterating over zip entries, but at the same time keeping the previously created handlers, and correctly modifying them.

          I'm not saying it's impossible, it's mostly what we already do, just need to take existing handlers into consideration.
          But instead of tweaking the existing code, this should probably be done on a clean rewrite.