0

I'm having some issues with ProcessBuilder.start();.

Here's an example of what the code looks like:

List<String> listOfStrings = new ArrayList<String>();
myListOfString.add("zip");
myListOfString.add("-r");
myListOfString.add(destinationPath);
myListOfString.add(newFilePath);

File zipFile = new File(workingDirectory, fileName + ".zip");

ProcessBuilder processBuilder = new ProcessBuilder(listOfStrings);
prcoessBuilder.directory(workingDirectory);
try{
  Process p = processBuilder.start();
  ...
  ...
  ...

workingDirectory has been verified to be a working directory using workingDirectory.isDirectory().

The issue occurs at Process p = processBuilder.start(); where it throws an IOException.

Below is the stacktrace:

java.io.IOException: Cannot run program "zip" (in directory "<Path to workingDirectory>"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    ...
    ...
    ...

workingDirectory does not point to a specific file (E.g.: /path/to/, not /path/to/file.zip), however, it is a valid directory. Is that possibly the issue?

I cannot give the exact code due to the nature of the project, but I can't imagine the input matters too much if it's crashing at Process p = processBuilder.start();, however, this is why I'm reaching out so it might be the case.

Let me know if any clarification is needed.

lime
  • 801
  • 8
  • 21
  • @Abra I don't think it's an issue if I share these values. I've updated the question. This method is supposed to create a zip file filled with some information at a specified location. – lime Dec 18 '20 at 13:37
  • [How to create a zip file in Java](https://stackoverflow.com/questions/1091788/how-to-create-a-zip-file-in-java) – Abra Dec 18 '20 at 13:56
  • 1
    Can you share your stacktrace? – akortex Dec 18 '20 at 13:56
  • @akortex91 Updated with stacktrace. I specified some information about `workingDirectory`. Let me know what you think – lime Dec 18 '20 at 14:55

1 Answers1

1

The error message says that Java does not find an executable called zip in the current directory or on the path, which can be seen with:

String systemPath = System.getenv("PATH");
System.out.println("PATH="+systemPath);

Fix your launcher to include the full path to "zip" or fix the PATH used for your Java VM to include a directory that contains zip.

myListOfString.add("/the/path/to/zip");

or something like this (depending on your shell / terminal)

export PATH=/the/path/to:$PATH

As @Abra suggests, there are better ways to ZIP inside Java without relying on ProcessBuilder such as:

public static void zip(Path dir, Path zip) throws IOException
{
    Map<String, String> env = Map.of("create", "true");
    try (FileSystem fs = FileSystems.newFileSystem(zip, env))
    {
        // This predicate processed the action because it makes use of BasicFileAttributes
        // Rather than process a forEach stream which has to call Files.isDirectory(path)
        BiPredicate<Path, BasicFileAttributes> foreach = (p,a) -> {
            copy(p,a, fs.getPath("/"+dir.relativize(p)));
            return false;
        };

        Files.find(dir, Integer.MAX_VALUE, foreach).count();
    }
    System.out.println("ZIPPED "+dir +" to "+zip);
}
private static void copy(Path from, BasicFileAttributes a, Path target)
{
    System.out.println("Copy "+(a.isDirectory() ? "DIR " : "FILE")+" => "+target);
    try
    {
        if (a.isDirectory())
            Files.createDirectories(target);
        else if (a.isRegularFile())
            Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING);
    }
    catch (IOException e)
    {
        throw new UncheckedIOException(e);
    }
}
DuncG
  • 12,137
  • 2
  • 21
  • 33