7777import org .eclipse .aether .graph .DependencyNode ;
7878import org .eclipse .aether .resolution .ArtifactRequest ;
7979import org .eclipse .aether .resolution .ArtifactResolutionException ;
80- import org .eclipse .aether .resolution .ArtifactResult ;
8180
8281import static org .apache .maven .plugins .shade .resource .UseDependencyReducedPom .createPomReplaceTransformers ;
8382
@@ -393,6 +392,37 @@ public class ShadeMojo extends AbstractMojo {
393392 @ Parameter (defaultValue = "false" )
394393 private boolean skip ;
395394
395+ /**
396+ * Extra JAR files to infuse into shaded result. Accepts list of files that must exists. If any of specified
397+ * files does not exist (or is not a file), Mojo will fail.
398+ * <p>
399+ * Extra JARs will be processed in same way as main JAR (if any) is: applied relocation, resource transformers
400+ * but <em>not filtering</em>.
401+ * <p>
402+ * Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more
403+ * just a feature to be able to slightly "differentiate" shaded JAR from main only.
404+ *
405+ * @since 3.6.0
406+ */
407+ @ Parameter
408+ private List <File > extraJars ;
409+
410+ /**
411+ * Extra Artifacts to infuse into shaded result. Accepts list of GAVs in form of
412+ * {@code <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>} that will be resolved. If any of them
413+ * cannot be resolved, Mojo will fail.
414+ * <p>
415+ * The artifacts will be resolved (not transitively), and will be processed in same way as dependency JARs
416+ * are (if any): applied relocation, resource transformers and filtering.
417+ * <p>
418+ * Note: this feature should be used lightly, is not meant as ability to replace dependency hull! It is more
419+ * just a feature to be able to slightly "differentiate" shaded JAR from main only.
420+ *
421+ * @since 3.6.0
422+ */
423+ @ Parameter
424+ private List <String > extraArtifacts ;
425+
396426 @ Inject
397427 private MavenProjectHelper projectHelper ;
398428
@@ -444,6 +474,17 @@ public void execute() throws MojoExecutionException {
444474
445475 artifacts .add (project .getArtifact ().getFile ());
446476
477+ if (extraJars != null && !extraJars .isEmpty ()) {
478+ for (File extraJar : extraJars ) {
479+ if (!Files .isRegularFile (extraJar .toPath ())) {
480+ throw new MojoExecutionException (
481+ "Failed to create shaded artifact: parameter extraJars contains path " + extraJar
482+ + " that is not a file (does not exist or is not a file)" );
483+ }
484+ artifacts .add (extraJar );
485+ }
486+ }
487+
447488 if (createSourcesJar ) {
448489 File file = shadedSourcesArtifactFile ();
449490 if (file .isFile ()) {
@@ -680,15 +721,40 @@ private void processArtifactSelectors(
680721 Set <File > sourceArtifacts ,
681722 Set <File > testArtifacts ,
682723 Set <File > testSourceArtifacts ,
683- ArtifactSelector artifactSelector ) {
724+ ArtifactSelector artifactSelector )
725+ throws MojoExecutionException {
684726
685727 List <String > excludedArtifacts = new ArrayList <>();
686728 List <String > pomArtifacts = new ArrayList <>();
687729 List <String > emptySourceArtifacts = new ArrayList <>();
688730 List <String > emptyTestArtifacts = new ArrayList <>();
689731 List <String > emptyTestSourceArtifacts = new ArrayList <>();
690732
691- for (Artifact artifact : project .getArtifacts ()) {
733+ ArrayList <Artifact > processedArtifacts = new ArrayList <>();
734+ if (extraArtifacts != null && !extraArtifacts .isEmpty ()) {
735+ processedArtifacts .addAll (extraArtifacts .stream ()
736+ .map (org .eclipse .aether .artifact .DefaultArtifact ::new )
737+ .map (RepositoryUtils ::toArtifact )
738+ .collect (Collectors .toList ()));
739+
740+ for (Artifact artifact : processedArtifacts ) {
741+ try {
742+ org .eclipse .aether .artifact .Artifact resolved =
743+ resolveArtifact (RepositoryUtils .toArtifact (artifact ));
744+ if (resolved .getFile () != null ) {
745+ artifact .setFile (resolved .getFile ());
746+ }
747+ } catch (ArtifactResolutionException e ) {
748+ throw new MojoExecutionException (
749+ "Failed to create shaded artifact: parameter extraArtifacts contains artifact "
750+ + artifact .getId () + " that is not resolvable" ,
751+ e );
752+ }
753+ }
754+ }
755+ processedArtifacts .addAll (project .getArtifacts ());
756+
757+ for (Artifact artifact : processedArtifacts ) {
692758 if (!artifactSelector .isSelected (artifact )) {
693759 excludedArtifacts .add (artifact .getId ());
694760
@@ -802,7 +868,7 @@ private void copyFiles(File source, File target) throws IOException {
802868 }
803869
804870 private File resolveArtifactForClassifier (Artifact artifact , String classifier ) {
805- org . eclipse . aether . artifact . Artifact coordinate = RepositoryUtils . toArtifact ( new DefaultArtifact (
871+ Artifact toResolve = new DefaultArtifact (
806872 artifact .getGroupId (),
807873 artifact .getArtifactId (),
808874 artifact .getVersionRange () == null
@@ -812,24 +878,26 @@ private File resolveArtifactForClassifier(Artifact artifact, String classifier)
812878 artifact .getType (),
813879 classifier ,
814880 artifact .getArtifactHandler (),
815- artifact .isOptional ()));
816-
817- ArtifactRequest request = new ArtifactRequest (
818- coordinate , RepositoryUtils .toRepos (project .getRemoteArtifactRepositories ()), "shade" );
819-
820- Artifact resolvedArtifact ;
881+ artifact .isOptional ());
821882 try {
822- ArtifactResult result = repositorySystem .resolveArtifact (session .getRepositorySession (), request );
823- resolvedArtifact = RepositoryUtils .toArtifact (result .getArtifact ());
883+ org .eclipse .aether .artifact .Artifact resolved = resolveArtifact (RepositoryUtils .toArtifact (toResolve ));
884+ if (resolved .getFile () != null ) {
885+ return resolved .getFile ();
886+ }
887+ return null ;
824888 } catch (ArtifactResolutionException e ) {
825889 getLog ().warn ("Could not get " + classifier + " for " + artifact );
826890 return null ;
827891 }
892+ }
828893
829- if (resolvedArtifact .isResolved ()) {
830- return resolvedArtifact .getFile ();
831- }
832- return null ;
894+ private org .eclipse .aether .artifact .Artifact resolveArtifact (org .eclipse .aether .artifact .Artifact artifact )
895+ throws ArtifactResolutionException {
896+ return repositorySystem
897+ .resolveArtifact (
898+ session .getRepositorySession (),
899+ new ArtifactRequest (artifact , project .getRemoteProjectRepositories (), "shade" ))
900+ .getArtifact ();
833901 }
834902
835903 private List <Relocator > getRelocators () {
0 commit comments