Skip to content

Commit 6300425

Browse files
committed
[MSHADE-307] - adding useDefaultConfiguration flag in ShadeMojo
1 parent f122b47 commit 6300425

File tree

3 files changed

+229
-42
lines changed

3 files changed

+229
-42
lines changed

src/main/java/org/apache/maven/plugins/shade/mojo/ArchiveFilter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ public class ArchiveFilter
3434

3535
private boolean excludeDefaults = true;
3636

37+
public ArchiveFilter()
38+
{
39+
// no-op
40+
}
41+
42+
public ArchiveFilter( Set<String> includes, Set<String> excludes )
43+
{
44+
this.includes = includes;
45+
this.excludes = excludes;
46+
}
47+
3748
public String getArtifact()
3849
{
3950
return artifact;

src/main/java/org/apache/maven/plugins/shade/mojo/ShadeMojo.java

Lines changed: 136 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
import org.apache.maven.plugins.shade.pom.PomWriter;
4141
import org.apache.maven.plugins.shade.relocation.Relocator;
4242
import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
43+
import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
4344
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
45+
import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
4446
import org.apache.maven.project.DefaultProjectBuildingRequest;
4547
import org.apache.maven.project.MavenProject;
4648
import org.apache.maven.project.MavenProjectHelper;
@@ -76,8 +78,10 @@
7678
import java.util.HashMap;
7779
import java.util.HashSet;
7880
import java.util.LinkedHashSet;
81+
import java.util.LinkedList;
7982
import java.util.List;
8083
import java.util.Map;
84+
import java.util.ServiceLoader;
8185
import java.util.Set;
8286

8387
/**
@@ -490,7 +494,7 @@ public void execute()
490494
replaceFile( finalFile, testJar );
491495
testJar = finalFile;
492496
}
493-
497+
494498
renamed = true;
495499
}
496500

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

753757
private List<ResourceTransformer> getResourceTransformers()
754758
{
759+
final List<ResourceTransformer> resourceTransformers = new LinkedList<>( getDefaultResourceTransformers() );
755760
if ( transformers == null )
756761
{
757-
return Collections.emptyList();
762+
return resourceTransformers;
758763
}
764+
resourceTransformers.addAll( Arrays.asList( transformers ) );
765+
return resourceTransformers;
766+
}
759767

760-
return Arrays.asList( transformers );
768+
private List<ResourceTransformer> getDefaultResourceTransformers()
769+
{
770+
final List<ResourceTransformer> transformers = new LinkedList<>();
771+
if ( missTransformer( ServicesResourceTransformer.class ) )
772+
{
773+
getLog().debug( "Adding ServicesResourceTransformer transformer" );
774+
transformers.add( new ServicesResourceTransformer() );
775+
}
776+
if ( missTransformer( ManifestResourceTransformer.class ) )
777+
{
778+
getLog().debug( "Adding ManifestResourceTransformer transformer" );
779+
transformers.add( new ManifestResourceTransformer() );
780+
}
781+
for ( final ResourceTransformer transformer : ServiceLoader.load( ResourceTransformer.class ) )
782+
{
783+
if ( !missTransformer( transformer.getClass() ) )
784+
{
785+
continue;
786+
}
787+
getLog().debug( "Adding " + transformer.getClass().getName() + " transformer" );
788+
transformers.add( transformer );
789+
}
790+
return transformers;
791+
}
792+
793+
private boolean missTransformer( final Class<?> type )
794+
{
795+
if ( transformers == null )
796+
{
797+
return true;
798+
}
799+
for ( final ResourceTransformer transformer : transformers )
800+
{
801+
if ( type.isInstance( transformer ) )
802+
{
803+
return false;
804+
}
805+
}
806+
return true;
761807
}
762808

763809
private List<Filter> getFilters()
764810
throws MojoExecutionException
765811
{
766-
List<Filter> filters = new ArrayList<>();
767-
List<SimpleFilter> simpleFilters = new ArrayList<>();
812+
List<Filter> filters = new LinkedList<>();
813+
List<SimpleFilter> simpleFilters = new LinkedList<>();
814+
Map<Artifact, ArtifactId> artifacts = null;
768815

769816
if ( this.filters != null && this.filters.length > 0 )
770817
{
771-
Map<Artifact, ArtifactId> artifacts = new HashMap<>();
772-
773-
artifacts.put( project.getArtifact(), new ArtifactId( project.getArtifact() ) );
774-
775-
for ( Artifact artifact : project.getArtifacts() )
776-
{
777-
artifacts.put( artifact, new ArtifactId( artifact ) );
778-
}
818+
artifacts = getArtifactIds();
779819

780820
for ( ArchiveFilter filter : this.filters )
781821
{
@@ -813,6 +853,51 @@ private List<Filter> getFilters()
813853
}
814854
}
815855

856+
// first check for backward compatibility this is not already configured explicitly
857+
boolean addExclusion = true;
858+
if ( this.filters != null )
859+
{
860+
for ( final ArchiveFilter filter : this.filters )
861+
{
862+
if ( filter.getExcludes() != null
863+
&& filter.getExcludes().contains( "META-INF/*.SF" )
864+
&& filter.getExcludes().contains( "META-INF/*.DSA" )
865+
&& filter.getExcludes().contains( "META-INF/*.RSA" )
866+
&& "*:*".equals( filter.getArtifact() ) )
867+
{
868+
addExclusion = false;
869+
break;
870+
}
871+
}
872+
}
873+
if ( addExclusion )
874+
{
875+
getLog().debug( "Adding META-INF/*.SF, META-INF/*.DSA and META-INF/*.RSA exclusion" );
876+
877+
if ( artifacts == null )
878+
{
879+
artifacts = getArtifactIds();
880+
}
881+
simpleFilters.add( new SimpleFilter(
882+
getMatchingJars( artifacts , new ArtifactId( "*:*" ) ),
883+
new ArchiveFilter(
884+
Collections.<String>emptySet(),
885+
new HashSet<>( Arrays.asList( "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA" ) ) ) ) );
886+
}
887+
888+
for ( final Filter filter : ServiceLoader.load( Filter.class ) )
889+
{
890+
getLog().debug( "Adding " + filter.getClass().getName() + " filter" );
891+
if ( SimpleFilter.class.isInstance( filter ) )
892+
{
893+
simpleFilters.add( SimpleFilter.class.cast( filter ) );
894+
}
895+
else
896+
{
897+
filters.add( filter );
898+
}
899+
}
900+
816901
filters.addAll( simpleFilters );
817902

818903
if ( minimizeJar )
@@ -832,6 +917,44 @@ private List<Filter> getFilters()
832917
return filters;
833918
}
834919

920+
private Set<File> getMatchingJars( final Map<Artifact, ArtifactId> artifacts, final ArtifactId pattern )
921+
{
922+
final Set<File> jars = new HashSet<File>();
923+
924+
for ( final Map.Entry<Artifact, ArtifactId> entry : artifacts.entrySet() )
925+
{
926+
if ( entry.getValue().matches( pattern ) )
927+
{
928+
final Artifact artifact = entry.getKey();
929+
930+
jars.add( artifact.getFile() );
931+
932+
if ( createSourcesJar )
933+
{
934+
final File file = resolveArtifactSources( artifact );
935+
if ( file != null )
936+
{
937+
jars.add( file );
938+
}
939+
}
940+
}
941+
}
942+
return jars;
943+
}
944+
945+
private Map<Artifact, ArtifactId> getArtifactIds()
946+
{
947+
final Map<Artifact, ArtifactId> artifacts = new HashMap<Artifact, ArtifactId>();
948+
949+
artifacts.put( project.getArtifact(), new ArtifactId( project.getArtifact() ) );
950+
951+
for ( final Artifact artifact : project.getArtifacts() )
952+
{
953+
artifacts.put( artifact, new ArtifactId( artifact ) );
954+
}
955+
return artifacts;
956+
}
957+
835958
private File shadedArtifactFileWithClassifier()
836959
{
837960
Artifact artifact = project.getArtifact();

src/test/java/org/apache/maven/plugins/shade/mojo/ShadeMojoTest.java

Lines changed: 82 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.net.URLClassLoader;
3030
import java.util.ArrayList;
3131
import java.util.Arrays;
32+
import java.util.Collection;
3233
import java.util.LinkedHashSet;
3334
import java.util.List;
3435
import java.util.Set;
@@ -41,10 +42,13 @@
4142
import org.apache.maven.plugins.shade.ShadeRequest;
4243
import org.apache.maven.plugins.shade.Shader;
4344
import org.apache.maven.plugins.shade.filter.Filter;
45+
import org.apache.maven.plugins.shade.filter.SimpleFilter;
4446
import org.apache.maven.plugins.shade.relocation.Relocator;
4547
import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
4648
import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
49+
import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
4750
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
51+
import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
4852
import org.apache.maven.project.MavenProject;
4953
import org.apache.maven.project.ProjectBuildingRequest;
5054
import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
@@ -60,6 +64,49 @@
6064
public class ShadeMojoTest
6165
extends PlexusTestCase
6266
{
67+
68+
public void testDefaultConfiguration() throws Exception
69+
{
70+
final ShadeMojo shadeMojo = new ShadeMojo();
71+
setProject(shadeMojo);
72+
73+
// default transformers are present
74+
final Method getResourceTransformers = ShadeMojo.class.getDeclaredMethod("getResourceTransformers");
75+
getResourceTransformers.setAccessible(true);
76+
final List<ResourceTransformer> transformers =
77+
List.class.cast(getResourceTransformers.invoke(shadeMojo));
78+
assertEquals(2, transformers.size());
79+
assertTrue(ServicesResourceTransformer.class.isInstance(transformers.get(0)));
80+
assertTrue(ManifestResourceTransformer.class.isInstance(transformers.get(1)));
81+
82+
// default exclusion is present
83+
final Method getFilters = ShadeMojo.class.getDeclaredMethod("getFilters");
84+
getFilters.setAccessible(true);
85+
final List<Filter> filters =
86+
List.class.cast(getFilters.invoke(shadeMojo));
87+
assertEquals(1, filters.size());
88+
89+
final Filter filter = filters.iterator().next();
90+
assertTrue(SimpleFilter.class.isInstance(filter));
91+
92+
final Field jars = filter.getClass().getDeclaredField("jars");
93+
jars.setAccessible(true);
94+
assertEquals(1, Collection.class.cast(jars.get(filter)).size());
95+
96+
final Field excludes = filter.getClass().getDeclaredField("excludes");
97+
excludes.setAccessible(true);
98+
final Collection<String> excludesValues = Collection.class.cast(excludes.get(filter));
99+
assertEquals(3, excludesValues.size());
100+
for ( final String exclude : Arrays.asList( "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA" ) )
101+
{
102+
assertTrue(exclude, excludesValues.contains(exclude) );
103+
}
104+
105+
final Field includes = filter.getClass().getDeclaredField("includes");
106+
includes.setAccessible(true);
107+
assertTrue(Collection.class.cast(includes.get(filter)).isEmpty());
108+
}
109+
63110
public void testShaderWithDefaultShadedPattern()
64111
throws Exception
65112
{
@@ -124,11 +171,45 @@ public void testShadeWithFilter()
124171
createSourcesJar.setAccessible( true );
125172
createSourcesJar.set( mojo, Boolean.TRUE );
126173

174+
// setup a project
175+
setProject(mojo);
176+
177+
// create and configure the ArchiveFilter
178+
ArchiveFilter archiveFilter = new ArchiveFilter();
179+
Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField( "artifact" );
180+
archiveFilterArtifact.setAccessible( true );
181+
archiveFilterArtifact.set( archiveFilter, "org.apache.myfaces.core:myfaces-impl" );
182+
183+
// add ArchiveFilter to mojo
184+
Field filtersField = ShadeMojo.class.getDeclaredField( "filters" );
185+
filtersField.setAccessible( true );
186+
filtersField.set( mojo, new ArchiveFilter[]{ archiveFilter } );
187+
188+
Field sessionField = ShadeMojo.class.getDeclaredField( "session" );
189+
sessionField.setAccessible( true );
190+
sessionField.set( mojo, mock( MavenSession.class ) );
191+
192+
// invoke getFilters()
193+
Method getFilters = ShadeMojo.class.getDeclaredMethod( "getFilters", new Class[0] );
194+
getFilters.setAccessible( true );
195+
List<Filter> filters = (List<Filter>) getFilters.invoke( mojo);
196+
197+
// assertions - there must be one filter
198+
assertEquals( 2, filters.size() );
199+
200+
// the filter must be able to filter the binary and the sources jar
201+
Filter filter = filters.get( 1 ); // 0 is the built-in META-INF/*
202+
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT.jar" ) ) ); // binary jar
203+
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT-sources.jar" ) ) ); // sources jar
204+
}
205+
206+
private void setProject(final ShadeMojo mojo) throws Exception
207+
{
127208
// configure artifactResolver (mocked) for mojo
128209
ArtifactResolver mockArtifactResolver = new ArtifactResolver()
129210
{
130211
@Override
131-
public ArtifactResult resolveArtifact( ProjectBuildingRequest req, final Artifact art )
212+
public ArtifactResult resolveArtifact(ProjectBuildingRequest req, final Artifact art )
132213
throws ArtifactResolverException
133214
{
134215
return new ArtifactResult()
@@ -185,34 +266,6 @@ public Artifact getArtifact()
185266
Field projectField = ShadeMojo.class.getDeclaredField( "project" );
186267
projectField.setAccessible( true );
187268
projectField.set( mojo, project );
188-
189-
// create and configure the ArchiveFilter
190-
ArchiveFilter archiveFilter = new ArchiveFilter();
191-
Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField( "artifact" );
192-
archiveFilterArtifact.setAccessible( true );
193-
archiveFilterArtifact.set( archiveFilter, "org.apache.myfaces.core:myfaces-impl" );
194-
195-
// add ArchiveFilter to mojo
196-
Field filtersField = ShadeMojo.class.getDeclaredField( "filters" );
197-
filtersField.setAccessible( true );
198-
filtersField.set( mojo, new ArchiveFilter[]{ archiveFilter } );
199-
200-
Field sessionField = ShadeMojo.class.getDeclaredField( "session" );
201-
sessionField.setAccessible( true );
202-
sessionField.set( mojo, mock( MavenSession.class ) );
203-
204-
// invoke getFilters()
205-
Method getFilters = ShadeMojo.class.getDeclaredMethod( "getFilters" );
206-
getFilters.setAccessible( true );
207-
List<Filter> filters = (List<Filter>) getFilters.invoke( mojo);
208-
209-
// assertions - there must be one filter
210-
assertEquals( 1, filters.size() );
211-
212-
// the filter must be able to filter the binary and the sources jar
213-
Filter filter = filters.get( 0 );
214-
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT.jar" ) ) ); // binary jar
215-
assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT-sources.jar" ) ) ); // sources jar
216269
}
217270

218271
public void shaderWithPattern( String shadedPattern, File jar )

0 commit comments

Comments
 (0)