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

Code before:
                tempDirectoryPath,
                isClassFile,
                APP_ROOT.resolve(RelativeUnixPath.get("explodedJar")))
            .setName("Classes")
            .build();
    FileEntriesLayer resourcesLayer =
        addDirectoryContentsToLayer(
                FileEntriesLayer.builder(),
                tempDirectoryPath,
                isResourceFile,
                APP_ROOT.resolve(RelativeUnixPath.get("explodedJar")))
            .setName("Resources")
            .build();

    // Get dependencies from Class-Path in the jar's manifest and create a FileEntriesLayer.Builder
    // with these dependencies as entries.
    List<Path> dependencies = new ArrayList<>();
    JarFile jarFile = new JarFile(jarPath.toFile());
    String classPath = jarFile.getManifest().getMainAttributes().getValue("Class-Path");
    if (classPath != null) {
      for (String dependency : Splitter.on(" ").split(classPath)) {
        Path depPath = Paths.get(dependency);
        dependencies.add(depPath);
      }
    } else {
      throw new IllegalStateException("Class path is not specified.");
    }
    FileEntriesLayer.Builder dependenciesLayerBuilder = FileEntriesLayer.builder();
    dependencies.forEach(
        path ->
            dependenciesLayerBuilder.addEntry(
                path, APP_ROOT.resolve(RelativeUnixPath.get("dependencies")).resolve(path)));
    dependenciesLayerBuilder.setName("Dependencies");

    layers.add(classesLayer);
    layers.add(resourcesLayer);
    layers.add(dependenciesLayerBuilder.build());

    return layers;
  }

  private static FileEntriesLayer.Builder addDirectoryContentsToLayer(
      FileEntriesLayer.Builder builder,
      Path sourceRoot,
      Predicate<Path> pathFilter,
      AbsoluteUnixPath basePathInContainer)
      throws IOException {
    try (Stream<Path> fileStream = Files.walk(sourceRoot)) {
      ImmutableList<Path> directoryPaths =
          fileStream
              .filter(path -> !path.equals(sourceRoot))

Review comment (bug):
Do we have to fail here? Would this code path also handle the shaded jar style jars (which may not have `Class-Path` entries)?

Code after:
          Splitter.onPattern("\\s+")
              .splitToList(classPath.trim())
              .stream()
              .map(Paths::get)
              .collect(Collectors.toList());
      FileEntriesLayer.Builder dependenciesLayerBuilder =
          FileEntriesLayer.builder().setName("dependencies");
      dependencies.forEach(
          path ->
              dependenciesLayerBuilder.addEntry(
                  path, APP_ROOT.resolve(RelativeUnixPath.get("dependencies")).resolve(path)));
      layers.add(dependenciesLayerBuilder.build());
    }

    Predicate<Path> isClassFile = path -> path.getFileName().toString().endsWith(".class");
    Predicate<Path> isResourceFile = isClassFile.negate();

    // Determine class and resource files in the directory containing jar contents and create
    // FileEntriesLayer for each type of layer (classes or resources), while maintaining the
    // file's original project structure.
    FileEntriesLayer classesLayer =
        addDirectoryContentsToLayer(
            "classes",
            localExplodedJarRoot,
            isClassFile,
            APP_ROOT.resolve(RelativeUnixPath.get("explodedJar")));
    FileEntriesLayer resourcesLayer =
        addDirectoryContentsToLayer(
            "resources",
            localExplodedJarRoot,
            isResourceFile,
            APP_ROOT.resolve(RelativeUnixPath.get("explodedJar")));

    layers.add(resourcesLayer);
    layers.add(classesLayer);
    return layers;
  }

  private static FileEntriesLayer addDirectoryContentsToLayer(
      String layerName,
      Path sourceRoot,
      Predicate<Path> pathFilter,
      AbsoluteUnixPath basePathInContainer)
      throws IOException {
    FileEntriesLayer.Builder builder = FileEntriesLayer.builder().setName(layerName);
    new DirectoryWalker(sourceRoot)
        .filterRoot()
        .filter(path -> Files.isDirectory(path) || pathFilter.test(path))
        .walk(
            path -> {
              AbsoluteUnixPath pathOnContainer =