2

I'm using Maven Shade Plugin to relocate some classes of Apache. The issue which I'm facing is that I have this string as part of my classes:

private static final String ORG_APACHE_HTTP_HTTP_REQUEST = "org.apache.http.HttpRequest"

However the Maven Shade Plugin changes it to

private static final String ORG_APACHE_HTTP_HTTP_REQUEST = "com.company.dependencies.org.apache.http.HttpRequest"

Is there a way for me to exclude my class from being modified by the maven shade plugin?

Current config

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <minimizeJar>false</minimizeJar>
                <relocations>
                    <relocation>
                        <pattern>org.apache</pattern>
                        <shadedPattern>com.company.org.apache</shadedPattern>
                        <excludes>
                            <exclude>com.company.ClassToBeExcluded</exclude>
                        </excludes>
                    </relocation>
                </relocations>
            </configuration>
        </execution>
    </executions>
</plugin>
Alex Vayda
  • 6,154
  • 5
  • 34
  • 50
nadavy
  • 1,755
  • 1
  • 18
  • 33

1 Answers1

2

There are two aspects to this:

  • You have a class: com.company.ClassToBeExcluded
  • This class contains a String with this value: “org.apache.http.HttpRequest”

The shade plugin will attempt to operate on both of these by (a) relocating the class and (b) updating what it presumes is a class reference (albeit embedded in a String).

To prevent the shade plugin from updating the String you have to make the relocation of org.apache.http.HttpRequest a no-op like so:

<relocation>
    <pattern>org.apache.http.HttpRequest</pattern>
    <shadedPattern>org.apache.http.HttpRequest</shadedPattern>
</relocation>

You can, if you want, relocate com.company.ClassToBeExcluded like so …

<relocation>
    <pattern>com.foo.TheClass</pattern>
    <shadedPattern>shaded.com.foo.TheClass</shadedPattern>
</relocation>

… but as long as you tell shade not to relocate org.apache.http.HttpRequest then ORG_APACHE_HTTP_HTTP_REQUEST within that class will not be updated.

Note: org is quite a popular domain name so you might already be relocating it, if so then just make sure that you define the no-op relocation for org.apache.http.HttpRequest above the relocation for org.

I have verified this by creating a class: com.foo.TheClass containing private static final String ORG_APACHE_HTTP_HTTP_REQUEST = "org.apache.http.HttpRequest”. I then ran the shade plugin against the module which contains this class and the class was relocated and ORG_APACHE_HTTP_HTTP_REQUEST was updated. I then added this relocation:

<relocation>
    <pattern>org.apache.http.HttpRequest</pattern>
    <shadedPattern>org.apache.http.HttpRequest</shadedPattern>
</relocation>

… and ran the shade plugin and this class was relocated but ORG_APACHE_HTTP_HTTP_REQUEST was not updated. I also removed the relocation for com.foo.TheClass and re ran the shade plugin and the class was not relocated and ORG_APACHE_HTTP_HTTP_REQUEST was not updated.

This was verified using v3.0.0 of the shade plugin.

Note: this is a bit clunky since you might want to relocate the class but (understandably) not want an internal class attribute to be updated. If this is an issue for you then you might want vote for this issue MSHADE-156.

glytching
  • 44,936
  • 9
  • 114
  • 120