private void changeManifestClasspath()

in src/main/java/org/apache/maven/plugins/ear/EarMojo.java [662:837]


    private void changeManifestClasspath(
            EarModule module, File original, JavaEEVersion javaEEVersion, Collection<String> outdatedResources)
            throws MojoFailureException {
        final String moduleLibDir = module.getLibDir();
        if (!((moduleLibDir == null) || skinnyModules || (skinnyWars && module instanceof WebModule))) {
            return;
        }

        // for new created items
        FileTime outputFileTime = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp)
                .map(FileTime::from)
                .orElse(null);

        FileSystem fileSystem = null;

        try {
            Path workDirectory;

            // Handle the case that the destination might be a directory (project-038)
            // We can get FileSystems only for files
            if (original.isFile()) {
                fileSystem = FileSystems.newFileSystem(
                        original.toPath(), Thread.currentThread().getContextClassLoader());
                workDirectory = fileSystem.getRootDirectories().iterator().next();
            } else {
                workDirectory = original.toPath();
            }

            // Create a META-INF/MANIFEST.MF file if it doesn't exist (project-038)
            Path metaInfDirectory = workDirectory.resolve("META-INF");
            if (!Files.exists(metaInfDirectory)) {
                Files.createDirectory(metaInfDirectory);
                if (outputFileTime != null) {
                    Files.setLastModifiedTime(metaInfDirectory, outputFileTime);
                }
                getLog().debug(
                                "This project did not have a META-INF directory before, so a new directory was created.");
            }
            Path manifestFile = metaInfDirectory.resolve("MANIFEST.MF");
            if (!Files.exists(manifestFile)) {
                Files.createFile(manifestFile);
                if (outputFileTime != null) {
                    Files.setLastModifiedTime(manifestFile, outputFileTime);
                }
                getLog().debug(
                                "This project did not have a META-INF/MANIFEST.MF file before, so a new file was created.");
            }

            Manifest mf = readManifest(manifestFile);
            Attribute classPath = mf.getMainSection().getAttribute("Class-Path");
            List<String> classPathElements = new ArrayList<>();

            boolean classPathExists;
            if (classPath != null) {
                classPathExists = true;
                classPathElements.addAll(Arrays.asList(classPath.getValue().split(" ")));
            } else {
                classPathExists = false;
                classPath = new Attribute("Class-Path", "");
            }

            if ((moduleLibDir != null) && (skinnyModules || (skinnyWars && module instanceof WebModule))) {
                // Remove modules
                for (EarModule otherModule : getAllEarModules()) {
                    if (module.equals(otherModule)) {
                        continue;
                    }
                    // MEAR-189:
                    // We use the original name, cause in case of outputFileNameMapping
                    // we could not not delete it and it will end up in the resulting EAR and the WAR
                    // will not be cleaned up.
                    final Path workLibDir = workDirectory.resolve(moduleLibDir);
                    Path artifact =
                            workLibDir.resolve(module.getArtifact().getFile().getName());

                    // MEAR-217
                    // If WAR contains files with timestamps, but EAR strips them away (useBaseVersion=true)
                    // the artifact is not found. Therefore, respect the current fileNameMapping additionally.

                    if (!Files.exists(artifact)) {
                        getLog().debug("module does not exist with original file name.");
                        artifact = workLibDir.resolve(otherModule.getBundleFileName());
                        getLog().debug("Artifact with mapping: " + artifact.toAbsolutePath());
                    }

                    if (!Files.exists(artifact)) {
                        getLog().debug("Artifact with mapping does not exist.");
                        artifact = workLibDir.resolve(
                                otherModule.getArtifact().getFile().getName());
                        getLog().debug("Artifact with original file name: " + artifact.toAbsolutePath());
                    }

                    if (!Files.exists(artifact)) {
                        getLog().debug("Artifact with original file name does not exist.");
                        final Artifact otherModuleArtifact = otherModule.getArtifact();
                        if (otherModuleArtifact.isSnapshot()) {
                            try {
                                artifact = workLibDir.resolve(MappingUtils.evaluateFileNameMapping(
                                        ARTIFACT_DEFAULT_FILE_NAME_MAPPING, otherModuleArtifact));
                                getLog().debug("Artifact with default mapping file name: " + artifact.toAbsolutePath());
                            } catch (InterpolationException e) {
                                getLog().warn("Failed to evaluate file name for [" + otherModule
                                        + "] module using mapping: " + ARTIFACT_DEFAULT_FILE_NAME_MAPPING);
                            }
                        }
                    }

                    if (Files.exists(artifact)) {
                        getLog().debug(" -> Artifact to delete: " + artifact);
                        Files.delete(artifact);
                    }
                }
            }

            // Modify the classpath entries in the manifest
            final boolean forceClassPathModification =
                    javaEEVersion.lt(JavaEEVersion.FIVE) || defaultLibBundleDir == null;
            final boolean classPathExtension = !skipClassPathModification || forceClassPathModification;
            for (EarModule otherModule : getModules()) {
                if (module.equals(otherModule)) {
                    continue;
                }
                final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule);
                if (moduleClassPathIndex != -1) {
                    if (otherModule.isClassPathItem()) {
                        classPathElements.set(moduleClassPathIndex, otherModule.getUri());
                    } else {
                        classPathElements.remove(moduleClassPathIndex);
                    }
                } else if (otherModule.isClassPathItem() && classPathExtension) {
                    classPathElements.add(otherModule.getUri());
                }
            }

            // Remove provided modules from classpath
            for (EarModule otherModule : getProvidedEarModules()) {
                final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule);
                if (moduleClassPathIndex != -1) {
                    classPathElements.remove(moduleClassPathIndex);
                }
            }

            if (!skipClassPathModification || !classPathElements.isEmpty() || classPathExists) {
                classPath.setValue(StringUtils.join(classPathElements.iterator(), " "));
                mf.getMainSection().addConfiguredAttribute(classPath);

                // Write the manifest to disk, preserve timestamp
                FileTime lastModifiedTime = Files.getLastModifiedTime(manifestFile);
                try (BufferedWriter writer = Files.newBufferedWriter(
                        manifestFile,
                        StandardCharsets.UTF_8,
                        StandardOpenOption.WRITE,
                        StandardOpenOption.CREATE,
                        StandardOpenOption.TRUNCATE_EXISTING)) {
                    mf.write(writer);
                }
                Files.setLastModifiedTime(manifestFile, lastModifiedTime);
                removeFromOutdatedResources(manifestFile, outdatedResources);
            }

            if (fileSystem != null) {
                fileSystem.close();
                fileSystem = null;
            }
        } catch (ManifestException | IOException | ArchiverException e) {
            throw new MojoFailureException(e.getMessage(), e);
        } finally {
            if (fileSystem != null) {
                try {
                    fileSystem.close();
                } catch (IOException e) {
                    // ignore here
                }
            }
        }
    }