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>