Run a program from maven using jbang

I’d like to use quarkus and I wanted to follow this Get Started - Quarkus. As I understand, to install quarkus, I need to use jbang that will pick the CLI program in Maven’s repository. However, if I do:

$ nix-shell -p jbang
$ jbang app install --fresh --force quarkus@quarkusio
[jbang] Command installed: quarkus
$ quarkus --version
quarkus: command not found

How could I solve this problem?

Seems like doing $ export PATH=~/.jbang/bin/:$PATH solves the problem. Couldn’t we configure nix-shell to do that automatically?

Can I somehow specify in a nix-shell “install jbang and from jbang install quarkus”? For now I’m doing this:

{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  packages = with pkgs; [ jbang ];
  shellHook = ''
    echo ">>>> Making sure quarkus is installed"
    jbang app install --fresh --force quarkus@quarkusio
    echo ">>>> Updating PATH"
    export PATH=~/.jbang/bin/:$PATH
    echo ">>>> You can start the debug mode via 'quarkus dev' (this project was created via 'quarkus create')."

but it does not seem to be really optimized (and there is no guarantee that the quarkus version will match between multiple users I guess)

If you use JBang, it will install whatever version it decides to. You can just get quarkus directly from Github
Releases · quarkusio/quarkus · GitHub
That way you can build a normal Nix package.

Thanks. So basically, JBang is the quick and dirty, and packaging is the clean and long approach. So I tried to write this:

# This method is the simplest, but not the cleanest (download the whole maven dependency in one output)
{ stdenv, maven, lib, fetchFromGitHub }:
stdenv.mkDerivation rec {
  name = "quarkus-${version}";
  version = "2.10.1.Final";

  src = fetchFromGitHub {
    owner = "quarkusio";
    repo = "quarkus";
    rev = "${version}";
    sha256 = "sha256-OUxVkKFqAEwWQiwvVJfetHC0nEPARvYXpeu8bKSVu7M=";

  buildInputs = [ maven ];

  buildPhase = ''
    mvn package -Dmaven.repo.local=$out -Dmaven.test.skip=true
  # keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside
  installPhase = ''
    find $out -type f \
      -name \*.lastUpdated -or \
      -name -or \
      -name _remote.repositories \

  # don't do any fixup
  dontFixup = true;
  outputHashAlgo = "sha256";
  outputHashMode = "recursive";
  # replace this with the correct SHA256
  outputHash = lib.fakeSha256;

  meta = {
    description = "";
    homepage =;

    # license = stdenv.lib.licenses.;
    # maintainers = [ stdenv.lib.maintainers. ];
    # platforms = stdenv.lib.platforms.;

unfortunately a test appears to fail (gRPC - Stubs for health and reflection ), but I can’t find how to disable tests (sorry, I’m very new to the Java ecosystem). Using -Dmaven.test.skip=true does not solve the problem.

See this question where I give the precise error Can't package Quarkus

Building Java programs with Nix is a nightmare. I got the compiled jar to work with this self-contained example:


{ pkgs ? <nixpkgs>
  quarkus-cli = { stdenv, fetchurl, writeScript, bash, openjdk }: 
    stdenv.mkDerivation rec {
      pname = "quarkus-cli";
      version = "2.10.1.Final";

      src = fetchurl {
        url = "${pname}-${version}.tar.gz";
        sha256 = "0cl641g5vgw94ac7sj8mhz21s6rkjdfjdzhh02dq64cd5cxwcmc5";

      launcher = writeScript pname ''
        #! ${bash}/bin/bash

        export CLASSPATH=@LIB@/${pname}-${version}-runner.jar

        exec ${openjdk}/bin/java $JAVA_OPTS -classpath $CLASSPATH"quarkus" -Dapp-pid="$$" -Dapp.repo="@LIB@" -Dapp.home="@OUT@" -Dbasedir="@OUT@" io.quarkus.cli.Main "$@"

      installPhase = '' 
        mkdir -p $out/{lib,bin}

        cp ./lib/${pname}-${version}-runner.jar $out/lib
        cp ${launcher} $out/bin/${pname}
        substituteInPlace $out/bin/${pname} --replace @LIB@ $out/lib --replace @OUT@ $out
  (import pkgs {}).callPackage quarkus-cli {}
1 Like

Thanks a lot!! (your trick with @OUT@ is also funny) Too bad compiling is not easy (I’ll read now the other conversation for that) But your solution is actually more interesting from a practical point of view as it does not compile anything and is therefore close to instantaneous. Note however that to make it work, you need to have export JAVA_HOME="${openjdk}" before the exec, otherwise the application won’t compile when running it with quarkus-cli dev.