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

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

  •  1
     
  •   Comyn · 2023-07-21 14:26:12 +08:00 · 5321 次点击
    这是一个创建于 525 天前的主题,其中的信息可能已经有所发展或是发生改变。
    rt
    flutter 有 fvm,node 有 nvm,python 有 pyenv,没见到切换 jdk 的,虽说可以自己写简单的脚本实现
    40 条回复    2023-11-30 15:40:33 +08:00
    DinoStray
        1
    DinoStray  
       2023-07-21 14:27:24 +08:00
    sdkman
    molika
        2
    molika  
       2023-07-21 14:28:02 +08:00
    limiter
        3
    limiter  
       2023-07-21 14:28:12 +08:00
    BiChengfei
        4
    BiChengfei  
       2023-07-21 14:36:49 +08:00
    .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  
       2023-07-21 14:37:19 +08:00   ❤️ 1
    imtianx
        6
    imtianx  
       2023-07-21 14:43:28 +08:00
    jenv +1
    wxyrrcj
        7
    wxyrrcj  
       2023-07-21 14:45:44 +08:00
    archlinux-java
    chendy
        8
    chendy  
       2023-07-21 14:48:47 +08:00
    可能因为一般也没啥切换 jdk 版本的需求吧
    有需求也一个 export JAVA_HOME=xxx 就完事了…
    Oktfolio
        9
    Oktfolio  
       2023-07-21 14:49:25 +08:00
    macOS 限定 export JAVA_HOME=$(/usr/libexec/java_home -v 17)
    Radiation
        10
    Radiation  
       2023-07-21 14:50:08 +08:00
    我也说一个,jaaba ,https://github.com/shyiko/jabba
    fuis
        11
    fuis  
       2023-07-21 15:00:10 +08:00
    alternatives
    archlinux-java
    6IbA2bj5ip3tK49j
        12
    6IbA2bj5ip3tK49j  
       2023-07-21 15:02:12 +08:00
    asdf
    vituralfuture
        13
    vituralfuture  
       2023-07-21 15:13:40 +08:00 via Android
    archlinux 有 archlinux-java 这个命令可以快速切换 jdk
    EastLord
        14
    EastLord  
       2023-07-21 15:17:44 +08:00
    jenv
    traffic
        15
    traffic  
       2023-07-21 15:54:29 +08:00
    alternatives --config java
    ChicC
        16
    ChicC  
       2023-07-21 15:58:13 +08:00
    windows 就 scoop ?
    hiveex
        17
    hiveex  
       2023-07-21 15:59:48 +08:00
    jenv
    ysn2233
        18
    ysn2233  
       2023-07-21 16:25:59 +08:00
    export JAVA_HOME=xxxxx
    jorneyr
        19
    jorneyr  
       2023-07-21 16:46:55 +08:00   ❤️ 1
    java8='export JAVA_HOME="/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home"'

    把这个别名加到 .bash_profile 里,要切换版本的时候执行一下 java8 这个命令就好了。
    arjen
        20
    arjen  
       2023-07-21 19:04:11 +08:00
    楼上说的全用过,sdkman !最好用
    maojun
        21
    maojun  
       2023-07-21 20:14:00 +08:00 via iPhone
    macOS 自带了一个 java_home 工具
    fanxasy
        22
    fanxasy  
       2023-07-21 23:10:48 +08:00
    sdkman + 1 越来越多的 java 相关项目推荐用 sdkman 安装 jdk 了
    Slurp
        23
    Slurp  
       2023-07-22 02:03:58 +08:00
    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  
       2023-07-22 05:01:22 +08:00 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  
       2023-07-22 05:04:42 +08:00 via Android
    没有 bash 选项就是纯开终端
    james122333
        26
    james122333  
       2023-07-22 05:13:20 +08:00 via Android
    local JAVA_HOME 前改成 local JAVA_HOME PATH 更好
    james122333
        27
    james122333  
       2023-07-22 07:33:13 +08:00 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  
       2023-07-22 07:49:38 +08:00 via Android
    倒数 25 行 2 改 l
    james122333
        29
    james122333  
       2023-07-22 08:02:45 +08:00 via Android
    以上可以捨弃肥大的工具
    houshuu
        30
    houshuu  
       2023-07-22 08:33:12 +08:00 via iPhone
    jenv 好,可以自己加各种 jdk ,比如 idea 内下载的,brew 下载的等等
    random1221
        31
    random1221  
       2023-07-22 10:06:29 +08:00
    @james122333 #29
    如何理解你这句话?
    sleepybear1113
        32
    sleepybear1113  
       2023-07-22 10:11:34 +08:00
    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  
       2023-07-22 10:12:04 +08:00
    https://modules.readthedocs.io/en/latest/ module file ,想配什么都可以,直接 module load/unload/switch
    cq65617875
        34
    cq65617875  
       2023-07-22 14:15:53 +08:00
    anaconda ?
    knightdf
        35
    knightdf  
       2023-07-22 14:18:24 +08:00
    jenv 不知道么?
    WispZhan
        36
    WispZhan  
       2023-07-22 14:29:51 +08:00
    asdf-vm
    james122333
        37
    james122333  
       2023-07-22 16:43:16 +08:00 via Android
    @random1221

    意思是不用使用複杂依赖多或非原生的方式就可以实现
    以上写的脚本也不用写入.bash_profile
    james122333
        38
    james122333  
       2023-07-22 17:05:53 +08:00 via Android
    @random1221

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