6

I'd like to use maven shade to create a shaded jar, but I'd also like to include a special dependency only in the case of the shaded jar (not in the normal compile dependencies of my project). How can I go about this?

From my understanding the includes/excludes are only whitelists/blacklists so I can't explicitly force something to get included that wasn't included in the actual dependency list.

For more context, I have a JAR dependency which contains a resource that I only want included in one of my shade artifacts, but having that jar on the classpath otherwise would cause errors.

To be clear, I'm looking to generate both a shaded jar, with an additional dependency and a normal jar without it, in one mvn package call.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Hamel Kothari
  • 717
  • 4
  • 11
  • Then fix your error. Honestly, the simpler the better. Using a profile will work but it will make everything more complicated than it needs to be. Avoid workarounds. Make your life easy. – Tunaki Feb 22 '16 at 20:26
  • It's not something you can "fix". These are inherently mutually exclusive configurations contained within the two jars. One of the binaries to be published requires a certain configuration, the other requires another one. Profiles are the solution, not a workaround. – Hamel Kothari Feb 22 '16 at 21:07

1 Answers1

4

Try using a profile, and having your dependency and shade only in that profile. For example:

<profiles>
    <profile>
        <id>shadeProfile</id>
        <dependencies>
            <dependency>
                <groupId>com.example</groupId>
                <artifactId>some-artifact</artifactId>
                <version>1.23</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-shade-plugin</artifactId>
                    <version>2.3</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>shade</goal>
                            </goals>
                            <configuration>
                                <shadedClassifierName>shaded</shadedClassifierName>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Now, when you run mvn -PshadeProfile package it will include the artifact as part of your shaded build, and use the classifier shaded for the new artifact. This way your build can produce your unshaded JAR without the problematic resource, and a shaded JAR with that resource, simply by turning on the profile.

Other projects which depend on this can either depend on the shaded or unshaded artifact, as appropriate, since you are using a classifier to generate both.

dcsohl
  • 7,186
  • 1
  • 26
  • 44
  • Thanks, this is pretty much what I was looking for but is it possible to generate the shaded artifact always, along with the unshaded one and have the shaded one be the only one that includes that dependency. ie. have two profiles (default + shaded) which both always get executed? – Hamel Kothari Feb 22 '16 at 21:11
  • The solution to my question above was to use profiles and set it to be activeByDefault = true. Thanks! – Hamel Kothari Feb 23 '16 at 15:03
  • Glad to hear you figured that part out - not sure I would have figured that would work. I'll have to remember that ... – dcsohl Feb 23 '16 at 16:45