Home Explore Blog CI



nixpkgs

6th chunk of `doc/languages-frameworks/maven.section.md`
44ca66659e603416fb491fa00dc7e2abe41ee2b229d79db300000001000009e9
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 a Runnable JAR with CLASSPATH or Maven Plugin
Summary
This section details two methods for creating a runnable JAR file in Nix. The first method involves setting up a CLASSPATH environment variable using `makeWrapper`. This is ideal for cases where modifying the project's `pom.xml` is undesirable, such as when providing a derivation for nixpkgs. The classpath is constructed by flattening the Maven repository and concatenating the paths to the JAR files. The second method involves modifying the `pom.xml` file to generate a JAR with a MANIFEST file that includes the CLASSPATH. This approach requires project ownership and allows the classpath to be defined within the Maven project itself.