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

    ZipUtil.unzip(warPath, targetExplodedWarRoot, true);
    Predicate<Path> isFile = Files::isRegularFile;
    Predicate<Path> isInWebInfLib =
        path -> path.startsWith(targetExplodedWarRoot.resolve("WEB-INF").resolve("lib"));
    Predicate<Path> isSnapshot = path -> path.getFileName().toString().contains("SNAPSHOT");

    // Non-snapshot layer
    Predicate<Path> isInWebInfLibAndIsNotSnapshot = isInWebInfLib.and(isSnapshot.negate());
    FileEntriesLayer nonSnapshotLayer =
        ArtifactLayers.getDirectoryContentsAsLayer(
            ArtifactLayers.DEPENDENCIES,
            targetExplodedWarRoot,
            isFile.and(isInWebInfLibAndIsNotSnapshot),
            appRoot);

    // Snapshot layer
    Predicate<Path> isInWebInfLibAndIsSnapshot = isInWebInfLib.and(isSnapshot);
    FileEntriesLayer snapshotLayer =
        ArtifactLayers.getDirectoryContentsAsLayer(
            ArtifactLayers.SNAPSHOT_DEPENDENCIES,
            targetExplodedWarRoot,
            isFile.and(isInWebInfLibAndIsSnapshot),
            appRoot);

    // Classes layer.
    Predicate<Path> isClass = path -> path.getFileName().toString().endsWith(".class");
    Predicate<Path> isInWebInfClasses =
        path -> path.startsWith(targetExplodedWarRoot.resolve("WEB-INF").resolve("classes"));
    Predicate<Path> classesPredicate = isInWebInfClasses.and(isClass);
    FileEntriesLayer classesLayer =
        ArtifactLayers.getDirectoryContentsAsLayer(
            ArtifactLayers.CLASSES, targetExplodedWarRoot, classesPredicate, appRoot);

    // Resources layer.
    Predicate<Path> resourcesPredicate = isInWebInfLib.or(isClass).negate();
    FileEntriesLayer resourcesLayer =
        ArtifactLayers.getDirectoryContentsAsLayer(
            ArtifactLayers.RESOURCES,
            targetExplodedWarRoot,
            isFile.and(resourcesPredicate),
            appRoot);

    ArrayList<FileEntriesLayer> layers = new ArrayList<>();
    if (!nonSnapshotLayer.getEntries().isEmpty()) {
      layers.add(nonSnapshotLayer);
    }
    if (!snapshotLayer.getEntries().isEmpty()) {
      layers.add(snapshotLayer);
    }
    if (!resourcesLayer.getEntries().isEmpty()) {
      layers.add(resourcesLayer);
    }
    if (!classesLayer.getEntries().isEmpty()) {
      layers.add(classesLayer);
    }

    return layers;
  }
Constructor for {@link StandardWarExplodedProcessor}.

@param warPath path to WAR file
@param targetExplodedWarRoot path to exploded-war root
@param appRoot the absolute path of the app on the container
jib-cli/src/main/java/com/google/cloud/tools/jib/cli/war/StandardWarExplodedProcessor.java