Home Explore Blog Models CI



nixpkgs

6th chunk of `doc/languages-frameworks/maven.section.md`
bd740dc80238f8d00cfadb9f2666f3738725e494b69fb34c00000001000009e9
The following two methods are more suited to Nix then building an [UberJar](https://imagej.net/Uber-JAR) which may be the more traditional approach.

#### CLASSPATH {#classpath}

This method is ideal if you are providing a derivation for _nixpkgs_ and don't want to patch the project's `pom.xml`.

We will read the Maven repository and flatten it to a single list. This list will then be concatenated with the _CLASSPATH_ separator to create the full classpath.

We make sure to provide this classpath to the `makeWrapper`.

```nix
{
  stdenv,
  maven,
  callPackage,
  makeWrapper,
  jre,
}:
let
  repository = callPackage ./build-maven-repository.nix { };
in
stdenv.mkDerivation (finalAttrs: {
  pname = "maven-demo";
  version = "1.0";

  src = builtins.fetchTarball "https://github.com/fzakaria/nixos-maven-example/archive/main.tar.gz";
  nativeBuildInputs = [ makeWrapper ];
  buildInputs = [ maven ];

  buildPhase = ''
    runHook preBuild

    echo "Using repository ${repository}"
    mvn --offline -Dmaven.repo.local=${repository} package;

    runHook postBuild
  '';

  installPhase = ''
    runHook preInstall

    mkdir -p $out/bin

    classpath=$(find ${repository} -name "*.jar" -printf ':%h/%f');
    install -Dm644 target/maven-demo-${finalAttrs.version}.jar $out/share/java
    # create a wrapper that will automatically set the classpath
    # this should be the paths from the dependency derivation
    makeWrapper ${jre}/bin/java $out/bin/maven-demo \
          --add-flags "-classpath $out/share/java/maven-demo-${finalAttrs.version}.jar:''${classpath#:}" \
          --add-flags "Main"

    runHook postInstall
  '';
})
```

#### MANIFEST file via Maven Plugin {#manifest-file-via-maven-plugin}

This method is ideal if you are the project owner and want to change your `pom.xml` to set the CLASSPATH within it.

Augment the `pom.xml` to create a JAR with the following manifest:

```xml
<build>
  <plugins>
    <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>../../repository/</classpathPrefix>
                    <classpathLayoutType>repository</classpathLayoutType>
                    <mainClass>Main</mainClass>
                </manifest>
                <manifestEntries>
                    <Class-Path>.</Class-Path>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
  </plugins>

Title: Creating Runnable Maven JARs in Nix: CLASSPATH and MANIFEST Methods
Summary
This section presents two Nix-friendly methods for creating runnable Maven JARs, distinct from the traditional UberJar approach. The first, 'CLASSPATH', is ideal for Nixpkgs derivations where modifying `pom.xml` is not feasible. It involves using `makeWrapper` to dynamically construct and set the `CLASSPATH` for the Java executable by flattening the Maven repository to locate all required JARs. The second method, 'MANIFEST file via Maven Plugin', is suited for project owners willing to modify their `pom.xml`. This approach configures the `maven-jar-plugin` to embed classpath information directly into the JAR's manifest file, including a `classpathPrefix` and `mainClass`, allowing Maven itself to handle dependency pathing.