Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Java以编程方式安装所有Java JVM(不是默认安装的)?_Java_Jvm - Fatal编程技术网

如何使用Java以编程方式安装所有Java JVM(不是默认安装的)?

如何使用Java以编程方式安装所有Java JVM(不是默认安装的)?,java,jvm,Java,Jvm,有人知道如何通过编程方式安装所有JVM,而不是使用Java安装默认JVM吗 例如,在用户的机器上安装了两个JVM: JDK 5 JDK 6 >java JavaFinder C:\Program Files (x86)\Java\jre6\bin\java.exe: Version: 1.6.0_31 Bitness: 32-bits C:\Program Files\Java\jre6\bin\java.exe: Version: 1.6.0_31 Bitness:

有人知道如何通过编程方式安装所有JVM,而不是使用Java安装默认JVM吗

例如,在用户的机器上安装了两个JVM:

JDK 5
JDK 6
>java JavaFinder

C:\Program Files (x86)\Java\jre6\bin\java.exe:
  Version: 1.6.0_31
  Bitness: 32-bits

C:\Program Files\Java\jre6\bin\java.exe:
  Version: 1.6.0_31
  Bitness: 64-bits

D:\Dev\Java\jdk1.6.0_31\bin\java.exe:
  Version: 1.6.0_31
  Bitness: 64-bits

C:\Windows\system32\java.exe:
  Version: 1.6.0_31
  Bitness: 64-bits

C:\Windows\SysWOW64\java.exe:
  Version: 1.6.0_31
  Bitness: 32-bits
我需要知道安装的所有版本,以便切换默认使用的版本,然后通过编程调用javac,使用特定的JDK版本编译一些源代码

我一直在网上寻找一些信息,我发现:

但是我找不到我要找的东西。

安装的内容非常模糊-即使JRE和JDK附带了安装程序,实际上我们只需要将JRE或JDK的文件复制到机器上,就可以立即使用它

所以一般来说,如果这个名为java/java.exe的可执行文件真的是JRE的一部分,那么您必须在本地机器上找到所有java或java.exe可执行文件,并调用java-version来调用see1

刚才看到,您请求使用JVM并希望调用编译器。。如果您正在查找JDK,请使用上面的方法查找所有javac/javac.exe。他们也有一个版本选项


1这种方法没有风险,也没有乐趣,请仔细看看肖恩的评论!如果你不能信任机器或它的用户,那么你可能想测试,如果可执行文件是脚本/批处理或二进制文件-即使二进制文件也可以擦除你的磁盘,甚至原始的javac可执行文件也可以替换为一些恶意代码…

我不确定这是否回答了你的问题,但是,您可以使用族版本控制功能控制小程序或WebStart应用程序将在哪个主要JRE版本上运行。这允许您指定运行小程序的主要Java版本。您应该能够从那里导出javac的位置

…使用特定的JDK版本编译一些源代码

在最新的JDK中使用,用户可以使用-source、-target和-bootclasspath的适当选项。最后两个是javac的一部分


至于查找JDK,请弹出一个JFileChooser,将当前JRE的路径作为默认目录。如果用户无法从那里导航到JDK,那么他们是否应该编写代码是值得怀疑的。

要查找安装的Java版本,比查找javac.exe更好的方法是检查注册表。Java创建注册表项HKEY\U LOCAL\U MACHINE\Software\JavaSoft\Java Runtime Environment,字符串CurrentVersion设置为版本号,例如1.5或1.6

您可以使用该信息查找JVM:

HKEY\U LOCAL\U MACHINE\Software\JavaSoft\Java运行时环境\1.5\JavaHome=C:\Program Files\Java\j2re1.5 HKEY\U LOCAL\U MACHINE\Software\JavaSoft\Java运行时环境\1.5\RuntimeLib=C:\Program Files\Java\j2re1.4.2\bin\client\jvm.dll 您可以在此处看到更多信息:


我不熟悉从Java访问注册表,但您始终可以运行regedit的命令行界面并解析结果,这就是我所做的。

基本上没有办法枚举所有JVM,即使不是从Java代码。考虑不同的平台,不同的JDK供应商,将JDK捆绑在其他产品中,从数据库到飞行模拟器和视频渲染引擎。 大多数JDK都是指向另一个的简单链接,例如指向已安装的v.6的v.1.2。常见的问题是如何获得一个版本:java-version 但我们有几点:

对于Windows,请查看注册表HKEY\U LOCAL\U MACHINE\Software\JavaSoft\。还考虑WOW432节点模式的64位OS。检查在Java上创建软件的主要供应商的产品。 MacOSX/System/Library/Frameworks/JavaVM.framework/Versions+OpenJDK Linux和其他一些Unix-whichJava、/etc/alternations/JavaRPM-qa | grepJava等。
我快速检查了windows注册表,该键似乎提供了系统上安装的各种Java版本

HKEY\U本地\U机器\SOFTWARE\JavaSoft\Java运行时环境

在进一步的谷歌搜索中,确认这是正确的位置。 请阅读这些文章了解详细信息


在Windows平台上,您可以使用shell查询是否存在已安装的JRE:

java -version:1.6 -version
如果您安装了java版本1.6.0xx,该命令将返回。如果您没有安装它,它会说,找不到符合规范1.6的JRE

这在Linux上似乎不起作用,可能是因为Linux没有安装Java的标准方法。

如前所述,HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java运行时环境应该列出可用的JVM,但我刚刚发现,虽然这个注册表目前只列出了我机器上的64位1.6.0\u 31 JVM,我还在C:\Windows\SysWOW64下安装了一个32位java


因此,注册表上列出的信息并不能说明全部情况,如果您想在64位Windows中运行32位JVM,还应该尝试C:\Windows\SysWOW64。

我最近处理了一个非常类似的情况。下面的代码几乎完全符合您的要求 你需要。它搜索java JRE和JDK,不仅仅是JDK,而且应该很容易根据您的需要进行编辑。注意:仅限windows

/**
 * Java Finder by petrucio@stackoverflow(828681) is licensed under a Creative Commons Attribution 3.0 Unported License.
 * Needs WinRegistry.java. Get it at: https://stackoverflow.com/questions/62289/read-write-to-windows-registry-using-java
 *
 * JavaFinder - Windows-specific classes to search for all installed versions of java on this system
 * Author: petrucio@stackoverflow (828681)
 *****************************************************************************/

import java.util.*;
import java.io.*;

/**
 * Helper class to fetch the stdout and stderr outputs from started Runtime execs
 * Modified from http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
 *****************************************************************************/
class RuntimeStreamer extends Thread {
    InputStream is;
    String lines;

    RuntimeStreamer(InputStream is) {
        this.is = is;
        this.lines = "";
    }
    public String contents() {
        return this.lines;
    }

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader    br  = new BufferedReader(isr);
            String line = null;
            while ( (line = br.readLine()) != null) {
                this.lines += line + "\n";
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();  
        }
    }

    /**
     * Execute a command and wait for it to finish
     * @return The resulting stdout and stderr outputs concatenated
     ****************************************************************************/
    public static String execute(String[] cmdArray) {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process proc = runtime.exec(cmdArray);
            RuntimeStreamer outputStreamer = new RuntimeStreamer(proc.getInputStream());
            RuntimeStreamer errorStreamer  = new RuntimeStreamer(proc.getErrorStream());
            outputStreamer.start();
            errorStreamer.start();
            proc.waitFor();
            return outputStreamer.contents() + errorStreamer.contents();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return null;
    }
    public static String execute(String cmd) {
        String[] cmdArray = { cmd };
        return RuntimeStreamer.execute(cmdArray);
    }
}

/**
 * Helper struct to hold information about one installed java version
 ****************************************************************************/
class JavaInfo {
    public String  path;        //! Full path to java.exe executable file
    public String  version;     //! Version string. "Unkown" if the java process returned non-standard version string
    public boolean is64bits;    //! true for 64-bit javas, false for 32

    /**
     * Calls 'javaPath -version' and parses the results
     * @param javaPath: path to a java.exe executable
     ****************************************************************************/
    public JavaInfo(String javaPath) {
        String versionInfo = RuntimeStreamer.execute( new String[] { javaPath, "-version" } );
        String[] tokens = versionInfo.split("\"");

        if (tokens.length < 2) this.version = "Unkown";
        else this.version = tokens[1];
        this.is64bits = versionInfo.toUpperCase().contains("64-BIT");
        this.path     = javaPath;
    }

    /**
     * @return Human-readable contents of this JavaInfo instance
     ****************************************************************************/
    public String toString() {
        return this.path + ":\n  Version: " + this.version + "\n  Bitness: " + (this.is64bits ? "64-bits" : "32-bits");
    }
}

/**
 * Windows-specific java versions finder
 *****************************************************************************/
public class JavaFinder {

    /**
     * @return: A list of javaExec paths found under this registry key (rooted at HKEY_LOCAL_MACHINE)
     * @param wow64  0 for standard registry access (32-bits for 32-bit app, 64-bits for 64-bits app)
     *               or WinRegistry.KEY_WOW64_32KEY to force access to 32-bit registry view,
     *               or WinRegistry.KEY_WOW64_64KEY to force access to 64-bit registry view
     * @param previous: Insert all entries from this list at the beggining of the results
     *************************************************************************/
    private static List<String> searchRegistry(String key, int wow64, List<String> previous) {
        List<String> result = previous;
        try {
            List<String> entries = WinRegistry.readStringSubKeys(WinRegistry.HKEY_LOCAL_MACHINE, key, wow64);
            for (int i = 0; entries != null && i < entries.size(); i++) {
                String val = WinRegistry.readString(WinRegistry.HKEY_LOCAL_MACHINE, key + "\\" + entries.get(i), "JavaHome", wow64);
                if (!result.contains(val + "\\bin\\java.exe")) {
                    result.add(val + "\\bin\\java.exe");
                }
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return result;
    }

    /**
     * @return: A list of JavaInfo with informations about all javas installed on this machine
     * Searches and returns results in this order:
     *   HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment (32-bits view)
     *   HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment (64-bits view)
     *   HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit     (32-bits view)
     *   HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit     (64-bits view)
     *   WINDIR\system32
     *   WINDIR\SysWOW64
     ****************************************************************************/
    public static List<JavaInfo> findJavas() {
        List<String> javaExecs = new ArrayList<String>();

        javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment", WinRegistry.KEY_WOW64_32KEY, javaExecs);
        javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Runtime Environment", WinRegistry.KEY_WOW64_64KEY, javaExecs);
        javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit",     WinRegistry.KEY_WOW64_32KEY, javaExecs);
        javaExecs = JavaFinder.searchRegistry("SOFTWARE\\JavaSoft\\Java Development Kit",     WinRegistry.KEY_WOW64_64KEY, javaExecs);

        javaExecs.add(System.getenv("WINDIR") + "\\system32\\java.exe");
        javaExecs.add(System.getenv("WINDIR") + "\\SysWOW64\\java.exe");

        List<JavaInfo> result = new ArrayList<JavaInfo>();
        for (String javaPath: javaExecs) {
            if (!(new File(javaPath).exists())) continue;
            result.add(new JavaInfo(javaPath));
        }
        return result;
    }

    /**
     * @return: The path to a java.exe that has the same bitness as the OS
     * (or null if no matching java is found)
     ****************************************************************************/
    public static String getOSBitnessJava() {
        String arch      = System.getenv("PROCESSOR_ARCHITECTURE");
        String wow64Arch = System.getenv("PROCESSOR_ARCHITEW6432");
        boolean isOS64 = arch.endsWith("64") || (wow64Arch != null && wow64Arch.endsWith("64"));

        List<JavaInfo> javas = JavaFinder.findJavas();
        for (int i = 0; i < javas.size(); i++) {
            if (javas.get(i).is64bits == isOS64) return javas.get(i).path;
        }
        return null;
    }

    /**
     * Standalone testing - lists all Javas in the system
     ****************************************************************************/
    public static void main(String [] args) {
        List<JavaInfo> javas = JavaFinder.findJavas();
        for (int i = 0; i < javas.size(); i++) {
            System.out.println("\n" + javas.get(i));
        }
    }
}

在Windows命令提示符中,您可以运行以下两个命令,也可以作为批处理文件一起运行。这将查看Windows添加/删除程序注册表项,并报告通过安装/卸载链接找到的JAVA版本,以及文件夹路径和其他一些内容

wmic product where "name LIKE '%%java%%'" get * /format:textvaluelist > temp_javavers.txt 

notepad.exe temp_javavers.txt

什么操作系统,因为这将依赖于操作系统在本地计算机上查找所有java或java.exe可执行文件,并调用java版本,这太可怕了。你不能在整个系统中到处执行二进制文件!如果某个聪明人将一个名为java的shell脚本放在某个地方,其内容为rm-rf/怎么办?@Sean Patrick Floyd-但这是一个普遍的难题:除非您不知道所有原始java/javac可执行文件的校验和,否则您必须执行该可执行文件才能看到它是否真的是java/javac二进制文件。。。要知道,测试可能会炸毁你的系统或添加一些微小的恶意软件。这个建议非常古老,只适用于小程序。请检查此处以了解指定的详细信息。对于applet,我倾向于使用它来确保最少的Java可用性。deployJava.js还可用于编写JWS应用程序的启动按钮。@java.sun.com页面列出了Windows和Solaris的信息,但没有列出Mac或Unix的信息。这里有一页关于。在Unix上,可能需要检查JVM本身的文件夹;我不确定。我只是注意到使用32位java.exe运行此程序会将我发送到注册表的另一个部分,并显示C:\program Files x86\java\jre6\bin\java.exe。当这个问题得到解决时,我会修正并更新我的帖子。你不应该在Java pat hs字符串中使用反斜杠。始终使用斜杠。在后台,文件系统实现将自动转换目录分隔符。