1

I'm using maven to build an executable JAR and I want to add all dependencies minus a select few to the Class-Path of my MANIFEST.MF. So far I'm using the maven-jar-plugin for this:

<!-- Add dependent JARs to the classpath -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>libraries</classpathPrefix>
                <mainClass>MyMainClass</mainClass>
            </manifest>
            <manifestEntries>
                <Built-By>Me</Built-By>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

This works for adding all dependencies. However, I furthermore want to exclude certain dependencies from being added to the Class-Path. According to the documentation you can use the exclude tag as follows:

<configuration>
    <!-- ... -->
    <excludes>
        <exclude>**selenium*</exclude>
    </excludes>
    <!-- ... -->
</configuration>

I would expect this to exclude any dependency which has selenium in the name but it does not work. For example I would like to exclude libraries/selenium-json-4.0.0-alpha-6.jar from the Class-Path. Even if I specify that exact name it does not exclude anything. I would also like to provide the groupId for exclusion similar to how the maven-dependency-plugin's excludeGroupIds tag works.

How can the desired Class-Path management be done using maven?

I'm also using maven-shade-plugin for building the executable (fat) JAR but its manifest manipulation facilities seem lesser known/documented. Setting the Class-Path using maven-shade-plugin via this answer works but how can I populate my dependencies with exclusions instead of hard-coding everything?

BullyWiiPlaza
  • 17,329
  • 10
  • 113
  • 185

1 Answers1

1

TL;DR

The includes and excludes parameters of the Maven JAR Plugin work on files, not on dependencies.

Longer version

Selenium is typically used as a test dependency. Is Selenium declared as a Maven dependency? If it's only used for tests, I would expect it to have <scope>test</scope>. In that case, it will not end up in the JAR manifest.

If you don't use Selenium as a test dependency and still don't want it to end up in the manifest, you may consider adding <scope>provided</scope>. Provided dependencies don't end up in the JAR manifest either. This would also mean that at runtime, as soon as you invoke a Selenium API it will probably crash...

mthmulders
  • 9,483
  • 4
  • 37
  • 54
  • 1
    Actually, sorry for undoing the accepted answer but I realized that using the `provided` scope also excludes the dependency's classes etc. from being included in the `JAR` and not only the `Class-Path` entries. I want to include the classes etc. but not generate a `Class-Path` entry since the code is already present in the `JAR` and does not need to be referenced externally via the `Class-Path`. You see, I want some dependencies to be merged into the `JAR` and other external dependencies referenced via the `Class-Path`. – BullyWiiPlaza Jun 11 '20 at 14:11
  • So if I understand correctly, you're shading all dependencies into one JAR file? I guess in that case, you shouldn't need to configure set `addClasspath` or `classpathPrefix` for the Maven JAR plugin, since the JAR would contain all dependencies needed. – mthmulders Jun 11 '20 at 14:17
  • No. I'm shading some dependencies into the `JAR` and I'm copying most others into a `libraries` folder so that the main `JAR` can reference them from the `Class-Path`. The latter part should exclude the dependencies which I'm already shading into the `JAR`. – BullyWiiPlaza Jun 11 '20 at 19:42
  • OK, I understand what you want, although I don't understand _why_. But that's less important. Unfortunately, I don't know how to achieve what you want. As to my knowledge, it's a bit uncommon, though. – mthmulders Jun 12 '20 at 06:19
  • I'm doing this for obfuscation and convenience purposes. I want my local maven libraries to be shaded into the `JAR` so I can obfuscate the main JAR and keep the library `JAR`s untouched since they're open source anyway. This way I can reduce the size of the main `JAR` and obfuscation would take much longer when applied to every single dependency and my code at the same time. – BullyWiiPlaza Jun 18 '20 at 18:56