halcyon / asdf-java

A Java plugin for asdf-vm.
MIT License
454 stars 86 forks source link

JAVA_HOME did not get updated #51

Closed jonatan-ivanov closed 4 years ago

jonatan-ivanov commented 4 years ago

If I switch between java versions, JAVA_HOME did not get updated.

❯ asdf current
java           adopt-openjdk-13.0.2+8 (set by /Users/jivanov/.tool-versions)

❯ java -version
openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment AdoptOpenJDK (build 13.0.2+8)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 13.0.2+8, mixed mode, sharing)

❯ echo $JAVA_HOME
/Users/jivanov/.asdf/installs/java/adopt-openjdk-13.0.2+8

❯ asdf global java adopt-openjdk-8u242-b08

❯ asdf current
java           adopt-openjdk-8u242-b08 (set by /Users/jivanov/.tool-versions)

❯ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_242-b08)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.242-b08, mixed mode)

❯ echo $JAVA_HOME
/Users/jivanov/.asdf/installs/java/adopt-openjdk-13.0.2+8
halcyon commented 4 years ago

You'll need to restart your shell for JAVA_HOME to be updated.

jonatan-ivanov commented 4 years ago

@halcyon Yes, that is the issue, I should not, right? :)

joschi commented 4 years ago

@jonatan-ivanov I think there's currently no hook in asdf which will invoke a plugin when a version was selected (asdf global <plugin> <version> or asdf local <plugin> <version>).

jonatan-ivanov commented 4 years ago

@joschi I'm not very familiar with asdf but isn't exec-env for this? https://asdf-vm.com/#/plugins-create?id=binexec-env The main documentation is not very verbose, this might help a little more: https://github.com/asdf-vm/asdf/blob/master/docs/core-manage-versions.md#shims And here how it's used: https://github.com/asdf-vm/asdf/blob/master/lib/utils.bash#L527-L543

joschi commented 4 years ago

@jonatan-ivanov exec-env controls the environment when a shim is executed (for example $HOME/.asdf/shims/java) but it doesn't change the environment you're calling asdf or the shim from, which would be required to update $JAVA_HOME after changing the version with asdf shell, asdf local, or asdf global.

It's not that it couldn't be added to asdf, but this hook doesn't exist right now, so there's nothing asdf-java could do about it. It has to be added in asdf first.

Related issue: asdf-vm/asdf#384

jonatan-ivanov commented 4 years ago

@joschi Thank you very much!

rubencaro commented 4 years ago

I live with this in my .bashrc as a workaround. It updates JAVA_HOME every time it updates the prompt:

function asdf_update_java_home {
  asdf current java 2>&1 > /dev/null
  if [[ "$?" -eq 0 ]]
  then
      export JAVA_HOME=$(asdf where java)
  fi
}

function prompt_command {
  __vte_prompt_command  # put here whatever previous PROMPT_COMMAND value
  asdf_update_java_home
}

export PROMPT_COMMAND=prompt_command

Maybe you could add this to the README while the hook is not there.

donbeave commented 4 years ago

Zsh users can add this to .zshrc:

# set JAVA_HOME on every change directory
function asdf_update_java_home {
  asdf current java 2>&1 > /dev/null
  if [[ "$?" -eq 0 ]]
  then
      export JAVA_HOME=$(asdf where java)
  fi
}

precmd() { asdf_update_java_home; }
# end set JAVA_HOME

Also, suggest to add it to the README.

rubencaro commented 4 years ago

@halcyon do you prefer a PR adding those to the readme? I could do it.

joschi commented 4 years ago

@rubencaro @donbeave Be aware that it can substantially slow down your shell when asdf is being called before every single command you're running in your shell.

jthegedus commented 4 years ago

@joschi is this something the asdf-direnv plugin can solve? Does it have hooks for this kind of functionality?

rubencaro commented 4 years ago

@rubencaro @donbeave Be aware that it can substantially slow down your shell when asdf is being called before every single command you're running in your shell.

I didn't notice any effect after months using it like that. You should take into account that this will call asdf only when the shell renders the prompt, so right before going idle. It will not slow down execution of every single command :grin:.

Maybe it would be enough to add a warning for that specific usecase (i.e. if somebody needs to render the prompt many times per second ?).

joschi commented 4 years ago

@rubencaro You're right. I mixed up precmd and preexec. 👍

For reference: https://github.com/rothgar/mastering-zsh/blob/master/docs/config/hooks.md#hooks

halcyon commented 4 years ago

@rubencaro @donbeave @joschi @jonatan-ivanov - how would you feel about #76 ?

thuandt commented 4 years ago

@halcyon How about my solution? It worked with both system java and asdf provider java

asdf_update_java_home() {
  # shellcheck disable=SC2046
  JAVA_HOME=$(realpath $(dirname $(readlink -f $(asdf which java)))/../)
  export JAVA_HOME
}
autoload -U add-zsh-hook
add-zsh-hook precmd asdf_update_java_home

https://github.com/thuandt/zsh-config/blob/master/functions.sh#L3-L7 https://github.com/thuandt/zsh-config/blob/master/my-zsh-config.plugin.zsh#L103

halcyon commented 4 years ago

Thank you @thuandt I've integrated your solution into PR #76

donbeave commented 4 years ago

@halcyon LGTM, I just tested zsh script, works perfectly.