Class UberJarBuilder

All Implemented Interfaces:
Generator, Renamable, ResourceProvider, ResourceRetriever

public class UberJarBuilder extends LibraryBuilder

A Generator for uber jars.

Depending on the request, the generator provides one of two resource types.

  1. A JarFile. This type of resource is also returned if a more general ResourceType such as ClasspathElement is requested.

  2. An AppJarFile. When this special JarFile type is requested, the generator requires a main class to be configured.

The generator takes the following approach:

  • Request resources of type ClasspathElement with all intents from the added providers. Add the class and resource trees to the sources to be processed. JAR files are handled differently depending on their origin. The content of JAR files that are not retrieved from a Maven repository is added to the sources to be processed. For MvnRepoJarFiles (i.e. JAR files from a Maven repository) only the MvnRepoResource reference is collected.
  • Use all MvnRepoResources obtained in the previous step for a dependency resolution. Add the content from the resulting JAR files to the sources to be processed.
  • Add resources from the sources to the uber jar. Merge the files in META-INF/services/ that have the same name by concatenating them.
  • Filter out any other duplicate files under META-INF. These files often contain information related to the origin jar that is not applicable to the uber jar.
  • Filter out any module-info.class entries.

The resource type of the uber jar builder's output is one of the resource types of its inputs, because uber jars can also be used as ClasspathElement. Therefore, you cannot add a uber jar builder to the project like this:

    generator(UberJarBuilder::new).addFrom(this); // Circular dependency

This would add the project as provider and thus make the uber jar builder's result a uber jar builder's source (via Project.resources). Instead use the following approach:

    generator(UberJarGenerator::new)
        .addFrom(providers().select(Forward, Expose, Supply));

This requests the same providers from the project as Project.resources would, but allows the uber jar builder's LibraryBuilder.addFrom(org.jdrupes.builder.api.ResourceProvider...) method to filter out the uber jar builder itself from the providers. The given intents can vary depending on the requirements.

If the generated uber jar should not be visible to the project's other generators, you can also add it like this:

    dependency(new UberJarGenerator(this).addFrom(
        providers(EnumSet.of(Forward, Expose, Supply))), Intent.Forward)

In most cases, the simplest solution is to generate the uber jar in a separate project, typically the parent project. This cleanly separates the generation of class and resource trees and library jars from the generation of the uber jar.