If you’ve encountered the “cannot wrap … because it is not an executable file” error in Nixpkgs when using makeWrapper
, you’re not alone. I recently faced this issue while working on a Maven Java project using Nix, and I’d like to share the solution that worked for me.
The Problem
The error usually occurs when makeWrapper
is used with a JAR file, and it expects an executable binary. The JAR file is not recognized as an executable, causing the build process to fail.
The Solution
To address this issue, we need to create a wrapper script that invokes the Java runtime with the JAR file. Here’s how you can modify the installPhase
in your Nix derivation:
installPhase = ''
mkdir -p $out/bin
cp target/SomeProgram-${version}-jar-with-dependencies.jar $out/bin/somejar.jar
makeWrapper ${jre}/bin/java $out/bin/somejar.jar --add-flags "-cp $out/bin/somejar.jar org.root.ClassContainingMain"
'';
Complete File
content of build.nix
{ lib
, jre
, maven
, makeWrapper
, stdenv
}:
maven.buildMavenPackage rec {
pname = "someprogram";
version = "2.0-SNAPSHOT";
src = ./.;
mvnHash = "sha256-VHUtiViHzLRDjHtm7eb3E9WnwtjXnHyOIYPr9lL4vyg=";
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin
cp target/SomeProgram-${version}-jar-with-dependencies.jar $out/bin/somejar.jar
makeWrapper ${jre}/bin/java $out/bin/somejar.jar --add-flags "-cp $out/bin/somejar.jar org.root.ClassContainingMain"
'';
meta = with lib; {
description = "Replacing text in AFP and Postscript files";
license = licenses.mit;
};
}
call from flake.nix
packages.<system>.default = pkgs.callPackage ./build.nix {};
or with flake-utils
packages.default = pkgs.callPackage ./build.nix {};