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

Code before:
          "The input JAR ("
              + jarPath
              + ") is compiled with Java "
              + jarJavaVersion
              + ", but the default base image only supports versions up to Java 11. Specify a custom base image with --from.");
    }

    String jarType = determineJarType(jarPath);
    if (jarType.equals(SPRING_BOOT) && mode.equals(ProcessingMode.packaged)) {
      return new SpringBootPackagedProcessor(jarPath);
    } else if (jarType.equals(SPRING_BOOT) && mode.equals(ProcessingMode.exploded)) {
      Path explodedJarRoot = cacheDirectories.getExplodedJarDirectory();
      // Clear the exploded-jar directory first
      if (Files.exists(explodedJarRoot)) {
        MoreFiles.deleteRecursively(explodedJarRoot, RecursiveDeleteOption.ALLOW_INSECURE);
      }

      return new SpringBootExplodedProcessor(jarPath, explodedJarRoot);
    } else if (jarType.equals(STANDARD) && mode.equals(ProcessingMode.packaged)) {
      return new StandardPackagedProcessor(jarPath);
    } else {
      Path explodedJarRoot = cacheDirectories.getExplodedJarDirectory();
      // Clear the exploded-jar directory first
      if (Files.exists(explodedJarRoot)) {
        MoreFiles.deleteRecursively(explodedJarRoot, RecursiveDeleteOption.ALLOW_INSECURE);
      }
      return new StandardExplodedProcessor(jarPath, explodedJarRoot);
    }
  }

  /**
   * Determines whether the jar is a spring boot or standard jar.
   *
   * @param jarPath path to the jar
   * @return the jar type
   * @throws IOException if I/O error occurs when opening the file
   */
  private static String determineJarType(Path jarPath) throws IOException {
    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      if (jarFile.getEntry("BOOT-INF") != null) {
        return SPRING_BOOT;
      }
      return STANDARD;
    }
  }

  /**
   * Determines the java version of JAR. Derives the version from the first .class file it finds in
   * the JAR.
   *
   * @param jarPath path to the jar

Review comment (suggestion):
I wasn't sure who should empty the directory, e.g., if `StandardExplodedProcessor` should clear it instead of `JarProcessors`. I think either makes sense, but if we want the caller to clear it, we should check the precondition inside `StandardExplodedProcessor` to verify that the directory does not exist or is empty.

Otherwise, LGTM, but I'll take a closer look at Monday again.

Code after:
              + jarJavaVersion
              + ", but the default base image only supports versions up to Java 11. Specify a custom base image with --from.");
    }

    String jarType = determineJarType(jarPath);
    if (jarType.equals(SPRING_BOOT) && mode.equals(ProcessingMode.packaged)) {
      return new SpringBootPackagedProcessor(jarPath);
    } else if (jarType.equals(SPRING_BOOT) && mode.equals(ProcessingMode.exploded)) {
      return new SpringBootExplodedProcessor(jarPath, cacheDirectories.getExplodedJarDirectory());
    } else if (jarType.equals(STANDARD) && mode.equals(ProcessingMode.packaged)) {
      return new StandardPackagedProcessor(jarPath);
    } else {
      return new StandardExplodedProcessor(jarPath, cacheDirectories.getExplodedJarDirectory());
    }
  }

  /**
   * Determines whether the jar is a spring boot or standard jar.
   *
   * @param jarPath path to the jar
   * @return the jar type
   * @throws IOException if I/O error occurs when opening the file
   */
  private static String determineJarType(Path jarPath) throws IOException {
    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      if (jarFile.getEntry("BOOT-INF") != null) {
        return SPRING_BOOT;
      }
      return STANDARD;
    }
  }

  /**
   * Determines the java version of JAR. Derives the version from the first .class file it finds in
   * the JAR.
   *
   * @param jarPath path to the jar
   * @return java version
   * @throws IOException if I/O exception thrown when opening the jar file
   */
  @VisibleForTesting
  static Integer getJavaMajorVersion(Path jarPath) throws IOException {
    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      Enumeration<JarEntry> jarEntries = jarFile.entries();
      while (jarEntries.hasMoreElements()) {
        String jarEntry = jarEntries.nextElement().toString();
        if (jarEntry.endsWith(".class") && !jarEntry.endsWith("module-info.class")) {
          URLClassLoader loader = new URLClassLoader(new URL[] {jarPath.toUri().toURL()});
          try (DataInputStream classFile =
              new DataInputStream(loader.getResourceAsStream(jarEntry))) {