in src/main/java/org/apache/maven/plugins/ear/EarMojo.java [742:960]
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
}
}
}
}