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

Code before:
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/** Class to create a {@link JarProcessor} instance depending on jar type and processing mode. */
public class JarProcessors {
  private static String SPRING_BOOT = "spring-boot";
  private static String STANDARD = "standard";
  private static Integer VERSION_NOT_FOUND = 0;

  /**
   * Creates a {@link JarProcessor} instance based on jar type and processing mode.
   *
   * @param jarPath path to the jar
   * @param temporaryDirectoryProvider temporary directory provider
   * @param mode processing mode
   * @return JarProcessor
   * @throws IOException if I/O error occurs when opening the jar file
   * @throws IncompatibleBaseImageJavaVersionException if the base image java version cannot support
   *     this build
   */
  public static JarProcessor from(
      Path jarPath, TempDirectoryProvider temporaryDirectoryProvider, ProcessingMode mode)
      throws IOException, IncompatibleBaseImageJavaVersionException {
    Integer jarVersion = getVersion(jarPath);
    if (jarVersion > 11) {
      throw new IncompatibleBaseImageJavaVersionException(11, jarVersion);
    }

    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, temporaryDirectoryProvider.newDirectory());
    } else if (jarType.equals(STANDARD) && mode.equals(ProcessingMode.packaged)) {
      return new StandardPackagedProcessor(jarPath);
    } else {
      return new StandardExplodedProcessor(jarPath, temporaryDirectoryProvider.newDirectory());
    }
  }

  /**
   * 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;

Review comment (suggestion):
In build plugins, we catch this exception at a higher stack and provide a detailed error message with an action item. Maybe we can throw an `IllegalStateException`? The message should report the app version, what the problem is, and how to fix.

Code after:
import java.util.jar.JarFile;

/** Class to create a {@link JarProcessor} instance depending on jar type and processing mode. */
public class JarProcessors {
  private static String SPRING_BOOT = "spring-boot";
  private static String STANDARD = "standard";
  private static Integer VERSION_NOT_FOUND = 0;

  /**
   * Creates a {@link JarProcessor} instance based on jar type and processing mode.
   *
   * @param jarPath path to the jar
   * @param temporaryDirectoryProvider temporary directory provider
   * @param mode processing mode
   * @return JarProcessor
   * @throws IOException if I/O error occurs when opening the jar file
   */
  public static JarProcessor from(
      Path jarPath, TempDirectoryProvider temporaryDirectoryProvider, ProcessingMode mode)
      throws IOException {
    Integer jarJavaVersion = getJavaMajorVersion(jarPath);
    if (jarJavaVersion > 11) {
      throw new IllegalStateException(
          "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)) {
      return new SpringBootExplodedProcessor(jarPath, temporaryDirectoryProvider.newDirectory());
    } else if (jarType.equals(STANDARD) && mode.equals(ProcessingMode.packaged)) {
      return new StandardPackagedProcessor(jarPath);
    } else {
      return new StandardExplodedProcessor(jarPath, temporaryDirectoryProvider.newDirectory());
    }
  }

  /**
   * 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())) {