Question

I am trying to programmatically create a runnable jar file. I am using the following code:

The add method:

private static void add(File source, JarOutputStream target) throws IOException
    {
      BufferedInputStream in = null;
      try
      {
        if (source.isDirectory())
        {
          String name = source.getPath().replace("\\", File.separator);
          if (!name.isEmpty())
          {
            if (!name.endsWith(File.separator))
              name += File.separator;
            JarEntry entry = new JarEntry(name);
            entry.setTime(source.lastModified());
            target.putNextEntry(entry);
            //target.closeEntry();
          }
          for (File nestedFile: source.listFiles())
            add(nestedFile, target);
          return;
        }

        JarEntry entry = new JarEntry(source.getPath().replace("\\", "/"));
        entry.setTime(source.lastModified());
        target.putNextEntry(entry);
        in = new BufferedInputStream(new FileInputStream(source));

        byte[] buffer = new byte[1024];
        while (true)
        {
          int count = in.read(buffer);
          if (count == -1)
            break;
          target.write(buffer, 0, count);
        }
        target.closeEntry();
      }
      finally
      {
        if (in != null)
          in.close();
      }
    }

Its implementation:

try {
            File[] files = new File("tmp").listFiles();
            for (File file : files) {
                System.out.println("Archiving: "+file.getName());
                add(file, target);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            target.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

I am trying to add all of the contents of the tmp directory to my jar, but I do not want to prefix all of the namespaces with tmp.. I tried using this code to iterate through the the files in tmp and add them but I keep getting errors saying "no such file or directory". I am pretty sure that's because it is looking outside the tmp directory. However, when I change it to add(new File("tmp"+File.separator+file.getName()), target); I end up with "tmp" in my namespaces (because I started with the tmp/ directory). Is there a way around this?

Here is an example:

I have a jar file with the Main-Class attribute com.name.proj.ProjDriver When I decompress it into the tmp folder I end up with the file in tmp/com/name/proj/ProjDriver.class. I then recompress my jar using the manifest object from the old jar still specifying the main class as com.name.proj.ProjDriver but now it is actually tmp.com.name.proj.ProjDriver. How can I avoid having tmp. as a prefix for all the namespaces?

Was it helpful?

Solution

Replace your code with this:

private static void add(File source, JarOutputStream target) throws IOException
    {
      BufferedInputStream in = null;
      try
      {
        if (source.isDirectory())
        {
          String name = source.getPath().replace("\\", File.separator);
          if (!name.isEmpty())
          {
            if (!name.endsWith(File.separator))
              name += File.separator;
            JarEntry entry = new JarEntry(name);
            entry.setTime(source.lastModified());
            target.putNextEntry(entry);
            //target.closeEntry();
          }
          for (File nestedFile: source.listFiles())
            try{add(nestedFile, target);}catch(IOException e){System.out.println(e);}
          return;
        }

        JarEntry entry = new JarEntry(source.getPath().replace("tmp\\","").replace("\\", "/"));
        entry.setTime(source.lastModified());
        target.putNextEntry(entry);
        in = new BufferedInputStream(new FileInputStream(source));

        byte[] buffer = new byte[1024];
        while (true)
        {
          int count = in.read(buffer);
          if (count == -1)
            break;
          target.write(buffer, 0, count);
        }
        target.closeEntry();
      }
      finally
      {
        if (in != null)
          in.close();
      }
    }

I have varied this row:

JarEntry entry = new JarEntry(source.getPath().replace("tmp\\","").replace("\\", "/"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top