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

Code before:
  private static final String BOOT_INF = "BOOT-INF";

  /**
   * Constructor for {@link SpringBootExplodedProcessor}.
   *
   * @param jarPath path to jar file
   * @param targetExplodedJarRoot path to exploded-jar root
   * @param jarJavaVersion jar java version
   */
  public SpringBootExplodedProcessor(
      Path jarPath, Path targetExplodedJarRoot, Integer jarJavaVersion) {
    this.jarPath = jarPath;
    this.targetExplodedJarRoot = targetExplodedJarRoot;
    this.jarJavaVersion = jarJavaVersion;
  }

  @Override
  public List<FileEntriesLayer> createLayers() throws IOException {
    // Clear the exploded-artifact root first
    if (Files.exists(targetExplodedJarRoot)) {
      MoreFiles.deleteRecursively(targetExplodedJarRoot, RecursiveDeleteOption.ALLOW_INSECURE);
    }

    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      ZipUtil.unzip(jarPath, targetExplodedJarRoot, true);
      ZipEntry layerIndex = jarFile.getEntry(BOOT_INF + "/" + "layers.idx");
      if (layerIndex != null) {
        return createLayersForLayeredSpringBootJar(targetExplodedJarRoot);
      }

      Predicate<Path> isFile = Files::isRegularFile;

      // Non-snapshot layer
      Predicate<Path> isInBootInfLib =
          path -> path.startsWith(targetExplodedJarRoot.resolve(BOOT_INF).resolve("lib"));
      Predicate<Path> isSnapshot = path -> path.getFileName().toString().contains("SNAPSHOT");
      Predicate<Path> isInBootInfLibAndIsNotSnapshot = isInBootInfLib.and(isSnapshot.negate());
      Predicate<Path> nonSnapshotPredicate = isFile.and(isInBootInfLibAndIsNotSnapshot);
      FileEntriesLayer nonSnapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.DEPENDENCIES,
              targetExplodedJarRoot,
              nonSnapshotPredicate,
              JarLayers.APP_ROOT);

      // Snapshot layer
      Predicate<Path> isInBootInfLibAndIsSnapshot = isInBootInfLib.and(isSnapshot);
      Predicate<Path> snapshotPredicate = isFile.and(isInBootInfLibAndIsSnapshot);
      FileEntriesLayer snapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.SNAPSHOT_DEPENDENCIES,

Review comment (suggestion):
```suggestion
      ZipEntry layerIndex = jarFile.getEntry(BOOT_INF + "/layers.idx");
```

Code after:
  private final Path targetExplodedJarRoot;
  private final Integer jarJavaVersion;

  /**
   * Constructor for {@link SpringBootExplodedProcessor}.
   *
   * @param jarPath path to jar file
   * @param targetExplodedJarRoot path to exploded-jar root
   * @param jarJavaVersion jar java version
   */
  public SpringBootExplodedProcessor(
      Path jarPath, Path targetExplodedJarRoot, Integer jarJavaVersion) {
    this.jarPath = jarPath;
    this.targetExplodedJarRoot = targetExplodedJarRoot;
    this.jarJavaVersion = jarJavaVersion;
  }

  @Override
  public List<FileEntriesLayer> createLayers() throws IOException {
    // Clear the exploded-artifact root first
    if (Files.exists(targetExplodedJarRoot)) {
      MoreFiles.deleteRecursively(targetExplodedJarRoot, RecursiveDeleteOption.ALLOW_INSECURE);
    }

    try (JarFile jarFile = new JarFile(jarPath.toFile())) {
      ZipUtil.unzip(jarPath, targetExplodedJarRoot, true);
      ZipEntry layerIndex = jarFile.getEntry(BOOT_INF + "/layers.idx");
      if (layerIndex != null) {
        return createLayersForLayeredSpringBootJar(targetExplodedJarRoot);
      }

      Predicate<Path> isFile = Files::isRegularFile;

      // Non-snapshot layer
      Predicate<Path> isInBootInfLib =
          path -> path.startsWith(targetExplodedJarRoot.resolve(BOOT_INF).resolve("lib"));
      Predicate<Path> isSnapshot = path -> path.getFileName().toString().contains("SNAPSHOT");
      Predicate<Path> isInBootInfLibAndIsNotSnapshot = isInBootInfLib.and(isSnapshot.negate());
      Predicate<Path> nonSnapshotPredicate = isFile.and(isInBootInfLibAndIsNotSnapshot);
      FileEntriesLayer nonSnapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(
              ArtifactLayers.DEPENDENCIES,
              targetExplodedJarRoot,
              nonSnapshotPredicate,
              JarLayers.APP_ROOT);

      // Snapshot layer
      Predicate<Path> isInBootInfLibAndIsSnapshot = isInBootInfLib.and(isSnapshot);
      Predicate<Path> snapshotPredicate = isFile.and(isInBootInfLibAndIsSnapshot);
      FileEntriesLayer snapshotLayer =
          ArtifactLayers.getDirectoryContentsAsLayer(