Hello, this is a call for assistance in getting a Java Maven project to build under Nix. The approach taken follows that described here:
https://ryantm.github.io/nixpkgs/languages-frameworks/maven/
The project in question is the agent based transport simulator MATSim example project, which I have forked and to which I have added a flake and a Makefile if you wish to have a hands-on look:
The flake is
{
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "nixpkgs/nixos-unstable";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
# mvn2nix plugin
maven-repository = (pkgs.buildMaven ./project-info.json).repo;
matsim = pkgs.stdenv.mkDerivation rec {
pname = "matsim-example-project";
version = "0.0.1-SNAPSHOT";
src = ./.;
buildInputs = [ pkgs.maven ];
buildPhase = ''
echo "Using repository ${maven-repository}"
mvn --offline -Dmaven.repo.local=${maven-repository} package;
'';
installPhase = ''
install -Dm644 target/${pname}-${version}.jar $out/share/java
'';
};
# double invocation
maven-repository-2 = pkgs.stdenv.mkDerivation {
name = "maven-repository";
buildInputs = [ pkgs.maven ];
src = ./.; # or fetchFromGitHub, cleanSourceWith, etc
buildPhase = ''
mvn package -Dmaven.repo.local=$out
'';
# keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files
# with lastModified timestamps inside
installPhase = ''
find $out -type f \
-name \*.lastUpdated -or \
-name resolver-status.properties -or \
-name _remote.repositories \
-delete
'';
# don't do any fixup
dontFixup = true;
outputHashAlgo = "sha256";
outputHashMode = "recursive";
# replace this with the correct SHA256
# outputHash = pkgs.lib.fakeSha256;
outputHash = "sha256-URq6vNUlF5tttDUeZ97o8IPMZgRMA17MpHmZdeV4wDw=";
};
matsim-2 = pkgs.stdenv.mkDerivation rec {
pname = "matsim-example-project";
version = "0.1.0-SNAPSHOT";
src = ./.;
buildInputs = with pkgs; [ maven jre ];
nativeBuildInputs = with pkgs; [ makeWrapper ];
buildPhase = ''
echo "Using repository ${maven-repository-2}"
mvn --offline -Dmaven.repo.local=${maven-repository-2} package;
# mvn --offline -Dmaven.repo.local=${maven-repository-2} install;
'';
installPhase = ''
mkdir -pv $out/share/java $out/bin
install -Dm644 target/${pname}-${version}.jar $out/share/java
makeWrapper ${pkgs.jre}/bin/java $out/bin/${pname} \
--add-flags "-cp $out/share/java/${pname}-${version}.jar"
'';
};
in rec {
packages.default = packages.matsim;
packages.matsim = matsim;
packages.matsim-2 = matsim-2;
packages.maven-repository = maven-repository;
packages.maven-repository-2 = maven-repository-2;
devShell = pkgs.mkShell {
buildInputs = [
pkgs.maven
pkgs.jre
];
};
}
);
}
The “Double Invocation” method succeeds
nix build .#matsim-2
# update sha
nix build .#matsim-2
(or make matsim-2
), but I would prefer not to have to manually to update the sha for each build.
The “buildMaven with NixOS/mvn2nix-maven-plugin”
mvn org.nixos.mvn2nix:mvn2nix-maven-plugin:mvn2nix
nix build .#matsim
(or make matsim
) fails with
> [ERROR] Failed to execute goal on project matsim-example-project: Could not resolve
dependencies for project org.matsim:matsim-example-project:jar:0.1.0-SNAPSHOT: Failed to
collect dependencies at org.matsim:matsim:jar:15.0 -> org.geotools:gt-main:jar:29.0 ->
org.apache.commons:commons-text:jar:1.10.0: Failed to read artifact descriptor for
org.apache.commons:commons-text:jar:1.10.0: Cannot access osgeo
(https://repo.osgeo.org/repository/release/) in offline mode and the artifact
org.junit:junit-bom:pom:5.9.1 has not been downloaded from it before. -> [Help 1]
which might suggest that the mvn2nix plugin is failing at capturing all of the dependencies.
Any advice, tips, leads on how to proceed are very welcome.