# Java

# 思路1:jar包+容器java环境

# 概述

需要在运行环境下安装java,如果涉及到的服务比较多需要一个个安装环境还是比较麻烦的。

简单来说就是把java代码打包成jar文件,sh运行java命令并传参,最后 python调用 sh 命令。

# 示例

java主函数:

image

  1. 生成 Class文件

    javac PhoneDecode.java
    
  2. 打包成jar文件并添加清单(其中--main-class后跟类名)

    jar --create --verbose --file PhoneDecode.jar --main-class PhoneDecode *.class
    
  3. python通过 subprocess.getoutput(java -jar PhoneDecode.jar $1$2) 获取解密手机号

    subprocess.getoutput("java -jar PhoneDecode.jar $1 $2")
    

# 思路2:打成二进制

这个思路适用于大部分语言。

java打二进制包可能会出现各种各样的依赖问题。尝试过native-image​、install4j​都有问题,终放弃。

# 思路3:jar包+便携式java环境

# 概述

参考Linux配置Java环境,仔细研究一下linux下java环境的安装过程,可以发现就是解压jdk并把jdk下的一些路径加到环境变量中去以保证java的正常运行,对于jdk文件夹我们可以下载下来并挂载进容器,关于环境变量的设置则可以在shell脚本中来实现。

这样做就不用重新打镜像(尤其是需要修改的镜像比较多的时候),并且我们可以把要运行的jar包和jdk环境放在一个目录下,使用一个shell脚本作为调用的入口,整体体验下来和打成二进制包没有太大差异。

# 示例

假设当前目录是/data/test

最终目录结构:

.
├── java
│ ├── _init.sh
│ └── jdk1.8.0_221
│ ├── bin
│ ├── COPYRIGHT
│ ├── include
│ ├── javafx-src.zip
│ ├── jre
│ ├── lib
│ ├── LICENSE
│ ├── man
│ ├── README.html
│ ├── release
│ ├── src.zip
│ ├── THIRDPARTYLICENSEREADME-JAVAFX.txt
│ └── THIRDPARTYLICENSEREADME.txt
├── pub.sh
└── sofa.jar

  1. 将java程序打成jar包

  2. 下载需要的jdk_xxxxx.tar.gz

  3. 创建java​​文件夹并将jdk​​解压到java​文件​​夹​下

  4. java​文件夹下创建_init.sh​文件并写入

    • 自动找到脚本所在目录下的jdk并根据这个jdk设置需要的环境变量
    #!/bin/bash
    
    # 获取脚本所在的目录
    JAVA_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    
    # 查找脚本所在目录下以 "jdk" 开头的目录
    jdkp=""
    for dir in "$JAVA_SCRIPT_DIR"/*; do
      if [ -n "$jdkp" ]; then
        echo "JDK found, exiting loop"
        break
      fi
      if [[ -d "$dir" && $(basename "$dir") == *jdk* ]]; then
        jdkp="$dir"
        break
      fi
    done
    
    if [ -z "$jdkp" ]; then
      echo "Error: not found dir for JDK"
      exit 1
    fi
    
    echo "JDK dir: $jdkp"
    
    JAVA_HOME="$jdkp"
    CLASSPATH="$JAVA_HOME/lib:$JAVA_HOME/jre/lib"
    PATH=""
    PATH="$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin"
    export PATH CLASSPATH JAVA_HOME
    
  5. 将jar包上传到test目录下

  6. 创建入口shell脚本

    • 在脚本的开头source​java目录下的_init.sh​脚本即可正常使用java​命令
    #!/bin/bash
    
    rlp="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    . "$rlp"/java/_init.sh
    
    while getopts "t" opt; do
      case $opt in
        t)
          # 执行测试,使用预定义的数据
          java -jar "$rlp"/sofa.jar pub 192.168.0.15 9603 com.alipay.test.demo.service:1.0@DEFAULT 223.104.68.55:9090?xx=re
          exit 0
          ;;
        \?)
          echo "无效的选项: -$OPTARG"
          exit 1
          ;;
      esac
    done
    
    # 获取四个参数
    shift $((OPTIND-1))
    sofa_host="$1"
    sofa_port="$2"
    id="$3"
    url="$4"
    
    # 执行带参数的命令
    java -jar "$rlp"/sofa.jar pub "$sofa_host" "$sofa_port" "$id" "$url"
    
  7. 将整个/data/test​挂载进容器并假设路径不变

  8. 在项目需要的地方通过调用命令行即可执行java程序

    subprocess.getoutput("java -jar /data/test/pub.jar -t")