V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Comyn
V2EX  ›  Java

有没有动态切换 jdk 版本的工具

  •  1
     
  •   Comyn · 280 天前 · 4643 次点击
    这是一个创建于 280 天前的主题,其中的信息可能已经有所发展或是发生改变。
    rt
    flutter 有 fvm,node 有 nvm,python 有 pyenv,没见到切换 jdk 的,虽说可以自己写简单的脚本实现
    40 条回复    2023-11-30 15:40:33 +08:00
    DinoStray
        1
    DinoStray  
       280 天前
    sdkman
    molika
        2
    molika  
       280 天前
    limiter
        3
    limiter  
       280 天前
    BiChengfei
        4
    BiChengfei  
       280 天前
    .bash_profile 文件中,设置多个变量,例如
    JAVA_8_HOME = xxxxxxx/jdk8/xxxxx
    JAVA_11_HOME = xxxxxxx/jdk11/xxxxx
    JAVA_17_HOME = xxxxxxx/jdk17/xxxxx
    JAVA_20_HOME = xxxxxxx/jdk20/xxxxx

    JAVA_HOME=JAVA_8_HOME
    PATH=$JAVA_HOME/bin:$PATH
    需要切换 jdk 版本,就改下 JAVA_HOME ,然后应用下就行了
    TaiShang
        5
    TaiShang  
       280 天前   ❤️ 1
    imtianx
        6
    imtianx  
       280 天前
    jenv +1
    wxyrrcj
        7
    wxyrrcj  
       280 天前
    archlinux-java
    chendy
        8
    chendy  
       280 天前
    可能因为一般也没啥切换 jdk 版本的需求吧
    有需求也一个 export JAVA_HOME=xxx 就完事了…
    Oktfolio
        9
    Oktfolio  
       280 天前
    macOS 限定 export JAVA_HOME=$(/usr/libexec/java_home -v 17)
    Radiation
        10
    Radiation  
       280 天前
    我也说一个,jaaba ,https://github.com/shyiko/jabba
    fuis
        11
    fuis  
       280 天前
    alternatives
    archlinux-java
    xgfan
        12
    xgfan  
       280 天前
    asdf
    vituralfuture
        13
    vituralfuture  
       280 天前 via Android
    archlinux 有 archlinux-java 这个命令可以快速切换 jdk
    EastLord
        14
    EastLord  
       280 天前
    jenv
    traffic
        15
    traffic  
       280 天前
    alternatives --config java
    ChicC
        16
    ChicC  
       280 天前
    windows 就 scoop ?
    hiveex
        17
    hiveex  
       280 天前
    jenv
    ysn2233
        18
    ysn2233  
       280 天前
    export JAVA_HOME=xxxxx
    jorneyr
        19
    jorneyr  
       280 天前   ❤️ 1
    java8='export JAVA_HOME="/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home"'

    把这个别名加到 .bash_profile 里,要切换版本的时候执行一下 java8 这个命令就好了。
    arjen
        20
    arjen  
       280 天前
    楼上说的全用过,sdkman !最好用
    maojun
        21
    maojun  
       280 天前 via iPhone
    macOS 自带了一个 java_home 工具
    fanxasy
        22
    fanxasy  
       280 天前
    sdkman + 1 越来越多的 java 相关项目推荐用 sdkman 安装 jdk 了
    Slurp
        23
    Slurp  
       280 天前
    sdkman / jenv / asdf

    另外分享一个在 macOS 上动态更新 jenv 的脚本,需要 jenv 自身、Zsh 、fd ,支持用 .pkg 安装的 JDK 和 brew 装的 openjdk 。

    update-jenvs () {
    eval "$(jenv init -)"
    /bin/rm -rf "~/.jenv"
    local readonly jenv_global="$(jenv global)"
    fd --type directory --regex '.*\.jdk' /Library/Java/JavaVirtualMachines -x jenv add '{}/Contents/Home'
    fd --type directory --regex 'openjdk\.jdk' --exact-depth=4 "$(brew --prefix)/Cellar/" -x jenv add '{}/Contents/Home'
    fd -t=file --glob '*zulu*.pkg' "$(brew --prefix)/Caskroom/" -X rm -rf '{}'
    jenv rehash
    jenv global "$jenv_global"
    }
    james122333
        24
    james122333  
       280 天前 via Android
    很简单 随便写个很不重要的 wrapper 就搞定(不重要分享一下)
    要选项挑选请自行写另外一隻程序
    使用方式就是

    /usr/bin/jdksh -d JAVA_HOME 位置 剩下的 bash 参数...(如-c "java -version")

    #!/usr/bin/env bash

    function err {
    echo "$@" >&2
    }

    function help {
    err "$0 -d JDK_HOME [bash arg...]"
    }

    function check_jdk_home {
    local bins=(java javac)
    if [[ -d "$1" && -x "$1" ]] ; then
    local i
    for i in ${bins[@]}
    do
    if [[ ! -f "$1/bin/$i" || ! -x "$1/bin/$i" ]] ; then
    err "$0: $1/bin/$i program not found!"
    return 1
    fi
    done
    return 0
    fi
    return 1
    }

    function set_jdk_home {
    if [[ -d "$1" && -x "$1" ]] ; then
    cd "$1"
    export JAVA_HOME="$PWD"
    export PATH="$JAVA_HOME"/bin:$PATH
    cd - > /dev/null
    return 0
    fi
    return 1
    }

    function parse_args {
    while let $#
    do
    case "$1" in
    -d)
    shift
    case "$1" in
    ""|-*)
    err "$0: directory not defined!"
    [[ "$1" == -* ]] && continue
    ;;
    esac
    check_jdk_home "$1" && set_jdk_home "$1"
    ;;
    *)
    args[${#args[@]}]="$1"
    ;;
    esac
    shift
    done
    if [[ -z "$JAVA_HOME" ]] ; then
    err "$0: JAVA_HOME not defined!"
    exit 1
    fi
    }

    function main {
    trap help EXIT
    local JAVA_HOME args=()
    parse_args "$@"
    exec bash "${args[@]}"
    }

    main "$@"
    james122333
        25
    james122333  
       280 天前 via Android
    没有 bash 选项就是纯开终端
    james122333
        26
    james122333  
       280 天前 via Android
    local JAVA_HOME 前改成 local JAVA_HOME PATH 更好
    james122333
        27
    james122333  
       280 天前 via Android
    /usr/bin/jdkrun

    #!/usr/bin/env bash

    function err {
    echo "$@" >&2
    }

    function help {
    err "$0 -a(add) [JAVA_HOME]/-r(remove) [JAVA_HOME]/-l(list)/-d [JAVA_HOME] [bash arg...]"
    }

    function parse_config {
    if [[ ! -f "$jdk_versions_file" || ! -r "$jdk_versions_file" ]] ; then
    rm -Rf "$jdk_versions_file"
    : > "$jdk_versions_file"
    else
    local l
    while read -r l
    do
    jdks[${#jdks[@]}]="$l"
    done < "$jdk_versions_file"
    fi
    }

    function list_versions {
    local i=-1
    while let "++i < ${#jdks[@]}"
    do
    echo "${jdks[i]}"
    done
    }

    function check_added_version {
    local i=-1 v="$1"
    v="${v## }"
    v="${v%% }"
    if [[ ! -z "$v" ]] ; then
    while let "++i < ${#jdks[@]}"
    do
    [[ "${jdks[i]%\/}" == "${v%\/}" ]] && return 0
    done
    else
    return 0
    fi
    return 1
    }

    function delete_version {
    local i=-1
    while let "++i < ${#jdks[@]}"
    do
    [[ "${jdks[i]%\/}" != "${1%\/}" ]] && echo "${jdks[i]%\/}"
    done > "${jdk_versions_file}"
    return 1
    }

    function main {
    local jdk_versions_file="$HOME/.jdk_versions" jdks=()
    parse_config
    if [[ "$1" == -d ]] ; then
    shift
    case "$1" in
    ""|-*)
    local i IFS=$'\n'
    select i in ${jdks[@]}
    do
    exec jdksh -d "$i" "$@"
    done
    unset IFS
    ;;
    *)
    if check_added_version "$1" ; then
    local d="$1"
    shift
    exec jdksh -d "$d" "$@"
    else
    err "$0: no such jdk version!"
    return 1
    fi
    ;;
    esac
    return 1
    fi
    case "$#" in
    2)
    case "$1" in
    -a)
    check_added_version "$2" || echo "${2%\/}" >> "${jdk_versions_file}"
    ;;
    -r)
    delete_version "$2"
    ;;
    *)
    help
    ;;
    esac
    ;;
    1)
    case "$1" in
    -a)
    local l
    read -p "Please input JAVA_HOME directory: " -r l
    check_added_version "$l" || echo "${2%\/}" >> "${jdk_versions_file}"
    ;;
    -r)
    local i IFS=$'\n'
    select i in ${jdks[@]}
    do
    delete_version "$i"
    break
    done
    ;;
    -l)
    list_versions
    ;;
    *)
    help
    ;;
    esac
    ;;
    *)
    help
    ;;
    esac
    }

    main "$@"
    james122333
        28
    james122333  
       280 天前 via Android
    倒数 25 行 2 改 l
    james122333
        29
    james122333  
       280 天前 via Android
    以上可以捨弃肥大的工具
    houshuu
        30
    houshuu  
       280 天前 via iPhone
    jenv 好,可以自己加各种 jdk ,比如 idea 内下载的,brew 下载的等等
    random1221
        31
    random1221  
       280 天前
    @james122333 #29
    如何理解你这句话?
    sleepybear1113
        32
    sleepybear1113  
       280 天前
    https://blog.csdn.net/qq_36670734/article/details/123836164

    很久之前写的 Linux 多 Java 直接用的方法

    # 使用 Java 17 来运行 Jar 包
    java17 -jar test-17.jar

    # 使用 Java 8 来运行 Jar 包
    java8 -jar test-8.jar

    # 使用 nohup 不挂断来后台运行 Jar 包
    nohup java17 -jar test-17.jar &
    samli12
        33
    samli12  
       280 天前
    https://modules.readthedocs.io/en/latest/ module file ,想配什么都可以,直接 module load/unload/switch
    cq65617875
        34
    cq65617875  
       279 天前
    anaconda ?
    knightdf
        35
    knightdf  
       279 天前
    jenv 不知道么?
    WispZhan
        36
    WispZhan  
       279 天前
    asdf-vm
    james122333
        37
    james122333  
       279 天前 via Android
    @random1221

    意思是不用使用複杂依赖多或非原生的方式就可以实现
    以上写的脚本也不用写入.bash_profile
    james122333
        38
    james122333  
       279 天前 via Android
    @random1221

    然后不只 java 很多东西都可以这样搞 两个档是可以合并 但脚本会杂一点 我看过 jenv 複杂很多的东西 不够轻量
    awolf
        39
    awolf  
       279 天前
    docker 时代了更加方便了
    yiyiniu
        40
    yiyiniu  
       148 天前
    @Comyn 有工具能动态切换 JDK ,我也有在用,看看这个工具: https://jp.v2ex.com/t/992876
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2768 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 05:37 · PVG 13:37 · LAX 22:37 · JFK 01:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.