Skip to content

Commit

Permalink
[MSHADE-307] - adding useDefaultConfiguration flag in ShadeMojo
Browse files Browse the repository at this point in the history
  • Loading branch information
rmannibucau committed Aug 8, 2019
1 parent f122b47 commit 6300425
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ public class ArchiveFilter

private boolean excludeDefaults = true;

public ArchiveFilter()
{
// no-op
}

public ArchiveFilter( Set<String> includes, Set<String> excludes )
{
this.includes = includes;
this.excludes = excludes;
}

public String getArtifact()
{
return artifact;
Expand Down
149 changes: 136 additions & 13 deletions src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
import org.apache.maven.plugins.shade.pom.PomWriter;
import org.apache.maven.plugins.shade.relocation.Relocator;
import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
Expand Down Expand Up @@ -76,8 +78,10 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;

/**
Expand Down Expand Up @@ -490,7 +494,7 @@ public void execute()
replaceFile( finalFile, testJar );
testJar = finalFile;
}

renamed = true;
}

Expand Down Expand Up @@ -752,30 +756,66 @@ private List<Relocator> getRelocators()

private List<ResourceTransformer> getResourceTransformers()
{
final List<ResourceTransformer> resourceTransformers = new LinkedList<>( getDefaultResourceTransformers() );
if ( transformers == null )
{
return Collections.emptyList();
return resourceTransformers;
}
resourceTransformers.addAll( Arrays.asList( transformers ) );
return resourceTransformers;
}

return Arrays.asList( transformers );
private List<ResourceTransformer> getDefaultResourceTransformers()
{
final List<ResourceTransformer> transformers = new LinkedList<>();
if ( missTransformer( ServicesResourceTransformer.class ) )
{
getLog().debug( "Adding ServicesResourceTransformer transformer" );
transformers.add( new ServicesResourceTransformer() );
}
if ( missTransformer( ManifestResourceTransformer.class ) )
{
getLog().debug( "Adding ManifestResourceTransformer transformer" );
transformers.add( new ManifestResourceTransformer() );
}
for ( final ResourceTransformer transformer : ServiceLoader.load( ResourceTransformer.class ) )
{
if ( !missTransformer( transformer.getClass() ) )
{
continue;
}
getLog().debug( "Adding " + transformer.getClass().getName() + " transformer" );
transformers.add( transformer );
}
return transformers;
}

private boolean missTransformer( final Class<?> type )
{
if ( transformers == null )
{
return true;
}
for ( final ResourceTransformer transformer : transformers )
{
if ( type.isInstance( transformer ) )
{
return false;
}
}
return true;
}

private List<Filter> getFilters()
throws MojoExecutionException
{
List<Filter> filters = new ArrayList<>();
List<SimpleFilter> simpleFilters = new ArrayList<>();
List<Filter> filters = new LinkedList<>();
List<SimpleFilter> simpleFilters = new LinkedList<>();
Map<Artifact, ArtifactId> artifacts = null;

if ( this.filters != null && this.filters.length > 0 )
{
Map<Artifact, ArtifactId> artifacts = new HashMap<>();

artifacts.put( project.getArtifact(), new ArtifactId( project.getArtifact() ) );

for ( Artifact artifact : project.getArtifacts() )
{
artifacts.put( artifact, new ArtifactId( artifact ) );
}
artifacts = getArtifactIds();

for ( ArchiveFilter filter : this.filters )
{
Expand Down Expand Up @@ -813,6 +853,51 @@ private List<Filter> getFilters()
}
}

// first check for backward compatibility this is not already configured explicitly
boolean addExclusion = true;
if ( this.filters != null )
{
for ( final ArchiveFilter filter : this.filters )
{
if ( filter.getExcludes() != null
&& filter.getExcludes().contains( "META-INF/*.SF" )
&& filter.getExcludes().contains( "META-INF/*.DSA" )
&& filter.getExcludes().contains( "META-INF/*.RSA" )
&& "*:*".equals( filter.getArtifact() ) )
{
addExclusion = false;
break;
}
}
}
if ( addExclusion )
{
getLog().debug( "Adding META-INF/*.SF, META-INF/*.DSA and META-INF/*.RSA exclusion" );

if ( artifacts == null )
{
artifacts = getArtifactIds();
}
simpleFilters.add( new SimpleFilter(
getMatchingJars( artifacts , new ArtifactId( "*:*" ) ),
new ArchiveFilter(
Collections.<String>emptySet(),
new HashSet<>( Arrays.asList( "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA" ) ) ) ) );
}

for ( final Filter filter : ServiceLoader.load( Filter.class ) )
{
getLog().debug( "Adding " + filter.getClass().getName() + " filter" );
if ( SimpleFilter.class.isInstance( filter ) )
{
simpleFilters.add( SimpleFilter.class.cast( filter ) );
}
else
{
filters.add( filter );
}
}

filters.addAll( simpleFilters );

if ( minimizeJar )
Expand All @@ -832,6 +917,44 @@ private List<Filter> getFilters()
return filters;
}

private Set<File> getMatchingJars( final Map<Artifact, ArtifactId> artifacts, final ArtifactId pattern )
{
final Set<File> jars = new HashSet<File>();

for ( final Map.Entry<Artifact, ArtifactId> entry : artifacts.entrySet() )
{
if ( entry.getValue().matches( pattern ) )
{
final Artifact artifact = entry.getKey();

jars.add( artifact.getFile() );

if ( createSourcesJar )
{
final File file = resolveArtifactSources( artifact );
if ( file != null )
{
jars.add( file );
}
}
}
}
return jars;
}

private Map<Artifact, ArtifactId> getArtifactIds()
{
final Map<Artifact, ArtifactId> artifacts = new HashMap<Artifact, ArtifactId>();

artifacts.put( project.getArtifact(), new ArtifactId( project.getArtifact() ) );

for ( final Artifact artifact : project.getArtifacts() )
{
artifacts.put( artifact, new ArtifactId( artifact ) );
}
return artifacts;
}

private File shadedArtifactFileWithClassifier()
{
Artifact artifact = project.getArtifact();
Expand Down
111 changes: 82 additions & 29 deletions src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
Expand All @@ -41,10 +42,13 @@
import org.apache.maven.plugins.shade.ShadeRequest;
import org.apache.maven.plugins.shade.Shader;
import org.apache.maven.plugins.shade.filter.Filter;
import org.apache.maven.plugins.shade.filter.SimpleFilter;
import org.apache.maven.plugins.shade.relocation.Relocator;
import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
Expand All @@ -60,6 +64,49 @@
public class ShadeMojoTest
extends PlexusTestCase
{

public void testDefaultConfiguration() throws Exception
{
final ShadeMojo shadeMojo = new ShadeMojo();
setProject(shadeMojo);

// default transformers are present
final Method getResourceTransformers = ShadeMojo.class.getDeclaredMethod("getResourceTransformers");
getResourceTransformers.setAccessible(true);
final List<ResourceTransformer> transformers =
List.class.cast(getResourceTransformers.invoke(shadeMojo));
assertEquals(2, transformers.size());
assertTrue(ServicesResourceTransformer.class.isInstance(transformers.get(0)));
assertTrue(ManifestResourceTransformer.class.isInstance(transformers.get(1)));

// default exclusion is present
final Method getFilters = ShadeMojo.class.getDeclaredMethod("getFilters");
getFilters.setAccessible(true);
final List<Filter> filters =
List.class.cast(getFilters.invoke(shadeMojo));
assertEquals(1, filters.size());

final Filter filter = filters.iterator().next();
assertTrue(SimpleFilter.class.isInstance(filter));

final Field jars = filter.getClass().getDeclaredField("jars");
jars.setAccessible(true);
assertEquals(1, Collection.class.cast(jars.get(filter)).size());

final Field excludes = filter.getClass().getDeclaredField("excludes");
excludes.setAccessible(true);
final Collection<String> excludesValues = Collection.class.cast(excludes.get(filter));
assertEquals(3, excludesValues.size());
for ( final String exclude : Arrays.asList( "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA" ) )
{
assertTrue(exclude, excludesValues.contains(exclude) );
}

final Field includes = filter.getClass().getDeclaredField("includes");
includes.setAccessible(true);
assertTrue(Collection.class.cast(includes.get(filter)).isEmpty());
}

public void testShaderWithDefaultShadedPattern()
throws Exception
{
Expand Down Expand Up @@ -124,11 +171,45 @@ public void testShadeWithFilter()
createSourcesJar.setAccessible( true );
createSourcesJar.set( mojo, Boolean.TRUE );

// setup a project
setProject(mojo);

// create and configure the ArchiveFilter
ArchiveFilter archiveFilter = new ArchiveFilter();
Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField( "artifact" );
archiveFilterArtifact.setAccessible( true );
archiveFilterArtifact.set( archiveFilter, "org.apache.myfaces.core:myfaces-impl" );

// add ArchiveFilter to mojo
Field filtersField = ShadeMojo.class.getDeclaredField( "filters" );
filtersField.setAccessible( true );
filtersField.set( mojo, new ArchiveFilter[]{ archiveFilter } );

Field sessionField = ShadeMojo.class.getDeclaredField( "session" );
sessionField.setAccessible( true );
sessionField.set( mojo, mock( MavenSession.class ) );

// invoke getFilters()
Method getFilters = ShadeMojo.class.getDeclaredMethod( "getFilters", new Class[0] );
getFilters.setAccessible( true );
List<Filter> filters = (List<Filter>) getFilters.invoke( mojo);

// assertions - there must be one filter
assertEquals( 2, filters.size() );

// the filter must be able to filter the binary and the sources jar
Filter filter = filters.get( 1 ); // 0 is the built-in META-INF/*
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT.jar" ) ) ); // binary jar
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT-sources.jar" ) ) ); // sources jar
}

private void setProject(final ShadeMojo mojo) throws Exception
{
// configure artifactResolver (mocked) for mojo
ArtifactResolver mockArtifactResolver = new ArtifactResolver()
{
@Override
public ArtifactResult resolveArtifact( ProjectBuildingRequest req, final Artifact art )
public ArtifactResult resolveArtifact(ProjectBuildingRequest req, final Artifact art )
throws ArtifactResolverException
{
return new ArtifactResult()
Expand Down Expand Up @@ -185,34 +266,6 @@ public Artifact getArtifact()
Field projectField = ShadeMojo.class.getDeclaredField( "project" );
projectField.setAccessible( true );
projectField.set( mojo, project );

// create and configure the ArchiveFilter
ArchiveFilter archiveFilter = new ArchiveFilter();
Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField( "artifact" );
archiveFilterArtifact.setAccessible( true );
archiveFilterArtifact.set( archiveFilter, "org.apache.myfaces.core:myfaces-impl" );

// add ArchiveFilter to mojo
Field filtersField = ShadeMojo.class.getDeclaredField( "filters" );
filtersField.setAccessible( true );
filtersField.set( mojo, new ArchiveFilter[]{ archiveFilter } );

Field sessionField = ShadeMojo.class.getDeclaredField( "session" );
sessionField.setAccessible( true );
sessionField.set( mojo, mock( MavenSession.class ) );

// invoke getFilters()
Method getFilters = ShadeMojo.class.getDeclaredMethod( "getFilters" );
getFilters.setAccessible( true );
List<Filter> filters = (List<Filter>) getFilters.invoke( mojo);

// assertions - there must be one filter
assertEquals( 1, filters.size() );

// the filter must be able to filter the binary and the sources jar
Filter filter = filters.get( 0 );
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT.jar" ) ) ); // binary jar
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT-sources.jar" ) ) ); // sources jar
}

public void shaderWithPattern( String shadedPattern, File jar )
Expand Down

0 comments on commit 6300425

Please sign in to comment.