如何使用64位浏览器和64位java插件在64位Linux上获取32位JRE路径

如何使用64位浏览器和64位java插件在64位Linux上获取32位JRE路径,java,linux,ubuntu,applet,32bit-64bit,Java,Linux,Ubuntu,Applet,32bit 64bit,我的应用程序由三个组件组成: 小程序 Java程序(myapp.jar) JNI库(myjni.so) 请注意,JNI库是为32位而构建的。在32位操作系统上,小程序使用java.home属性获取JRE路径。一旦applet获得JRE路径,它就会像这样启动JAR JRE-path myapp.jar 现在我需要在64位Linux上运行这个应用程序。这里我有两个选择: 构建64位的JNI库。 这是不可能的,因为所有依赖的库都需要为64位构建。(这是我这边的一个限制) 要求用户安装32位JVM 现

我的应用程序由三个组件组成:

  • 小程序
  • Java程序(myapp.jar)
  • JNI库(myjni.so)
  • 请注意,JNI库是为32位而构建的。在32位操作系统上,小程序使用
    java.home
    属性获取JRE路径。一旦applet获得JRE路径,它就会像这样启动JAR

    JRE-path myapp.jar
    
    现在我需要在64位Linux上运行这个应用程序。这里我有两个选择:

  • 构建64位的JNI库。 这是不可能的,因为所有依赖的库都需要为64位构建。(这是我这边的一个限制)
  • 要求用户安装32位JVM 现在的问题是如何将32位JRE路径设置为
    java。home
    属性给出了64位JRE路径。(因为浏览器和插件是64位的)。一个选项是使用
    updatealternations–list java
    命令获取所有JRE安装路径。然后,对于每个安装路径,运行
    JRE path-d32–version
    命令,查看它是否支持32位JVM
    • 如果它支持32位JVM,则使用该JRE路径来启动JAR文件
    • 如果所有java安装都不支持32位JVM,则显示消息以安装32位JVM
  • 问题:

  • 上述解决方案有什么问题吗?(我需要在Ubuntu、Redhat和OpenSuse上使用此解决方案)
  • 在64位Linux上获得32个JRE路径是否有更好的解决方案

  • 使用选项1。构建一个32位和64位JNI库并加载相关的。因此,基于32位或64位虚拟机

    您可以为sun JDK使用
    sun.arch.data.model
    系统属性

    您可以对IBMWebSphereVM使用
    com.ibm.vm.bitmode

    或者在
    os.arch
    系统属性中查找子字符串
    64
    (在基于intel的64位虚拟机上是x86_64/amd64)

    由于您无法构建
    .so
    及其所有相关
    .a
    .so
    文件的64位变体(这实际上是很好的软件配置管理实践),因此下面的shell脚本应该是一个不错的尝试。如果在调用结束时脚本以
    66
    退出,则没有有效的32位java

    #!/bin/bash -p
    
    # attempt to find a 32bit VM
    # uses a dummy class file (it's just an empty file)
    
    trap 'rm -f /tmp/testclass$$.class /tmp/jlocations.$$' EXIT HUP
    
    touch /tmp/testclass$$.class
    
    tryj() {
        while read java; do
            errout=$($java -cp /tmp -d32 testclass$$ 2>&1)
            if grep -q 'java.lang.ClassFormatError' <<<$errout; then
                # good VM - run with this
                rm -f /tmp/testclass$$.class /tmp/jlocations.$$
                # echo $java "$@"
                exec $java "$@"
            fi
        done </tmp/jlocations.$$
        return 1
    }
    
    # try update-alternatives - debian/ubuntu
    update-alternatives --list java > /tmp/jlocations.$$ 2>/dev/null
    
    tryj "$@"
    
    # Try alternatives - redhat
    alternatives --list java > /tmp/jlocations.$$ 2>/dev/null
    
    tryj "$@"
    
    # then try locate - generic linux/unix
    locate java | grep 'bin/java$' > /tmp/jlocations.$$
    
    tryj "$@"
    
    # if we had no luck, then use find - this will be sloooooooooow
    find / -wholename '*/bin/java' >/tmp/jlocations.$$ 2>/dev/null
    tryj "$@"
    
    exit 66
    
    #/bin/bash-p
    #尝试查找32位虚拟机
    #使用虚拟类文件(它只是一个空文件)
    陷阱'rm-f/tmp/testclass$$.class/tmp/jlocations.$$'退出HUP
    touch/tmp/testclass$$.class
    tryj(){
    读java的时候,做些什么
    errout=$($java-cp/tmp-d32测试类$$2>&1)
    如果grep-q'java.lang.ClassFormatError'/dev/null
    tryj“$@”
    #然后尝试查找通用linux/unix
    找到java | grep'bin/java$'>/tmp/jlocations$$
    tryj“$@”
    #如果我们运气不好,那么使用find-这将是slooooow
    查找/-wholename'*/bin/java'>/tmp/jlocations.$$2>/dev/null
    tryj“$@”
    66号出口
    
    如何将本机库推送到客户端?我想您的小程序是用可信证书签名的,对吗?是的,小程序是用可信证书签名的。本机库是用java传递机制推送到客户端的。无法使用选项1。这是因为myjni.so依赖于其他静态和共享库。所以我需要编译so64位模块。同样是那些模块,另一组库等等。简而言之,我需要为64位构建整个堆栈。然后选项1不是一个真正的选项。在我的ubuntu系统上,我甚至没有安装32位jre变体的选项-我必须手动安装,这意味着它不会出现在
    更新选项中de>output。我将在答案中添加一个选项,该选项使用shell脚本,利用
    locate
    尝试查找java的副本,如果找不到,则返回使用find