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
}
}
}
}