To make sure that we are on the same page:
environment.systemPackages includes openjdk. However, the JAVA_HOME environment variable is not set. While this isn't a problem for scripts run through nix-shell -i bash, it breaks scripts that aren't. Possibly part of the reason for this is my use of ZSH as a default shell.
JAVA_HOME should be set.
It is not set.
echo $JAVA_HOME.
Notice that it isn't set.
This is quite likely to be an ZSH issue. The exact same (simple) script fails if I use -i zsh, whereas it works with -i bash.
Nope. Not an ZSH issue. I'm not sure why I got the behaviour above earlier, but now I can't reproduce it.
Ha! I've got jdk
on my systemPackages
, but my $JAVA_HOME
is not set, neither in zsh
nor in bash
.
With nix-shell -p jdk
, it is set. I didn't even know about that hook. How is it not present for systemPackages
?
@bendlas Good question! :)
I've got a temporary fix in the PR referenced above, but if you're comfortable enough with applying that locally then you can probably just use nix-shell until it's fixed properly. Whatever "properly" turns out to mean.
Just to clarify, when you use nix-shell -p
the packages gets added to your shell dependencies and their respective setup-hooks are introduced into the environment. When they are aggregated into a profile they are not dependencies of your shell. I'm not convinced that it is a good idea to introduce the setup-hook when added to a profile but I also don't think that your issue is unreasonable.
I'll take that up on the mailing list.
The issue is, though, that if JAVA_HOME isn't set then a lot of Java applications just won't work... And every other distribution does set the variable by default, so we should too.
I'm not sure how to deal with upgrades. Possibly it'll need another symlink in /run. Anyway, mailing list...
JAVA_HOME
should not be set globally. There should be some java wrapper which sets it to whatever value of JAVA_HOME
is desirable for that application.
As a concrete test case: env | grep -q JAVA_HOME
should return an exit status of 1 regardless of how it is installed in any shell like zsh or bash.
Would like to know if there is a well documented workaround for this somewhere, trying to install sbt-ensime
and it complains with this error, not sure if this is something that can be fixed the "nix way"... correct me if I'm wrong please.
I am not convinced that nix shouldn't handle environment variables for user profiles, but maybe I could be convinced. A common situation, not unrelated to the current issue, is that apparently nix-shell
has some downsides for graphical applications (not speaking from personal experience, but citing someone who seems to know more about nix than me):
And another nitpick. You'll soon find very incovenient to launch IDE from shell every time. It seems a good idea to specify, that some package is used for development, but nix-shell doesn't work well for non-cli applications. Not to mention occasional problems with Nix GC and nix-shell. You'd better install IDE globally or per-user, it is better long-term solution.
nix-env
already defines our environment by defining what is effectively in our PATH
, so why not allow it to define other parts of our environment, rather than having to devise our own solutions on a case-by-case basis? I'm not saying it will work for everything, but I would think it could easily work for common cases such as this.
@roman My solution for now, which may be an OK way to do this:
I have the following script, nix-env-dynamic.sh
:
#!/bin/bash
export JAVA_HOME=$(readlink -e $(type -p javac) | sed -e 's/\/bin\/javac//g')
export IDEA_JDK=/usr/lib/jvm/zulu-8-amd64
ln -sfT $JAVA_HOME $ENVSDIR/JDK
A couple of extra lines there to make intellij happy - first to give it its own JVM that works well with it, and second, to provide a linked path I can easily fine for the current nix JDK, since IntelliJ doesn't like to use the environment's JAVA_HOME
to find JDKs.
I have a docker container running nix/nixpkgs that has its entrypoint do some configuration to .bashrc
; the related part for this is shown next, but I assume most aren't using docker, so just add it to your .bashrc
normally in that case (e.g. source $HOME/workspace/nix-env-dynamic.sh
)
SET_DYNAMIC_ENV="source $HOME/workspace/nix-env-dynamic.sh"
grep -q -F "${SET_DYNAMIC_ENV}" $HOME/.bashrc || printf "\n$SET_DYNAMIC_ENV\n" >> $HOME/.bashrc
That said, I'd like to do as little bash/perl programming as possible - I suspect you can relate ;). So, I still think it might be nice for Nix to handle this at some level.
@bbarker this saves you the sed
command and the which
dependency:
export JAVA_HOME="${$(readlink -e $(type -p java))%*/bin/java}"
@NeQuissimus I'm so inured to which
that I hadn't even thought of it as a dependency, but I can see that it is probably not something used much in Nix - I feel sed
is probably more standard. I couldn't quite get your command to work and am not good enough with bash to easily fix, so I went with replacing which
with type -p
- thanks!:
export JAVA_HOME=$(readlink -e $(type -p javac) | sed -e 's/\/bin\/javac//g')
On NixOS
programs.java.enable = true;
now sets up JAVA_HOME
system-wide.
Most helpful comment
On NixOS
now sets up
JAVA_HOME
system-wide.