Repository: GoogleContainerTools/jib
File: jib-cli/src/main/java/com/google/cloud/tools/jib/cli/cli2/Jar.java (Java)

Code before:
    commonCliOptions.validate();
    SingleThreadedExecutor executor = new SingleThreadedExecutor();
    try (TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider()) {

      ConsoleLogger logger =
          CliLogger.newLogger(
              commonCliOptions.getVerbosity(),
              commonCliOptions.getConsoleOutput(),
              spec.commandLine().getOut(),
              spec.commandLine().getErr(),
              executor);

      if (!Files.exists(jarFile)) {
        logger.log(LogEvent.Level.ERROR, "The file path provided does not exist: " + jarFile);
        return 1;
      }
      if (Files.isDirectory(jarFile)) {
        logger.log(
            LogEvent.Level.ERROR,
            "The file path provided is for a directory. Please provide a path to a JAR: "
                + jarFile);
        return 1;
      }

      CacheDirectories cacheDirectories =
          CacheDirectories.from(commonCliOptions, jarFile.getParent());
      Containerizer containerizer = Containerizers.from(commonCliOptions, logger, cacheDirectories);

      JibContainerBuilder containerBuilder =
          JarFiles.toJibContainerBuilder(jarFile, tempDirectoryProvider.newDirectory(), mode);

      containerBuilder.containerize(containerizer);
    } catch (Exception ex) {
      if (commonCliOptions.isStacktrace()) {
        ex.printStackTrace();
      }
      System.err.println(ex.getClass().getName() + ": " + ex.getMessage());
      return 1;
    } finally {
      executor.shutDownAndAwaitTermination(Duration.ofSeconds(3));
    }
    return 0;
  }
}


Review comment (bug):
Technically I think the `jarFile` path (not the parent) can still work. The difference is whether JARs in the same directory will use the same hash directory and share the app cache. Is there a specific reason to use a parent directory?

One thing matters is when that `jarFile` doesn't have a parent directory, which will be a common case, e.g., when doing `jib jar app.jar`. We learned that `jarFile.getParent() == null` in this case. So I think the argument check in `from()` will fail. 

And I just got this question if we can't just use a fixed app cache directory (without hashed sub-directories) shared by every Jib CLI build. But maybe it's good to have a hashed sub-directory per app to avoid generating too many directories in the cache root?

Code after:
    commonCliOptions.validate();
    SingleThreadedExecutor executor = new SingleThreadedExecutor();
    try (TempDirectoryProvider tempDirectoryProvider = new TempDirectoryProvider()) {

      ConsoleLogger logger =
          CliLogger.newLogger(
              commonCliOptions.getVerbosity(),
              commonCliOptions.getConsoleOutput(),
              spec.commandLine().getOut(),
              spec.commandLine().getErr(),
              executor);

      if (!Files.exists(jarFile)) {
        logger.log(LogEvent.Level.ERROR, "The file path provided does not exist: " + jarFile);
        return 1;
      }
      if (Files.isDirectory(jarFile)) {
        logger.log(
            LogEvent.Level.ERROR,
            "The file path provided is for a directory. Please provide a path to a JAR: "
                + jarFile);
        return 1;
      }

      CacheDirectories cacheDirectories =
          CacheDirectories.from(commonCliOptions, jarFile.toAbsolutePath().getParent());
      Containerizer containerizer = Containerizers.from(commonCliOptions, logger, cacheDirectories);

      JibContainerBuilder containerBuilder =
          JarFiles.toJibContainerBuilder(jarFile, tempDirectoryProvider.newDirectory(), mode);

      containerBuilder.containerize(containerizer);
    } catch (Exception ex) {
      if (commonCliOptions.isStacktrace()) {
        ex.printStackTrace();
      }
      System.err.println(ex.getClass().getName() + ": " + ex.getMessage());
      return 1;
    } finally {
      executor.shutDownAndAwaitTermination(Duration.ofSeconds(3));
    }
    return 0;
  }
}