从Java内部确定当前的glibc版本

时间:2019-01-18 00:21:47

标签: java linux glibc

对于在Linux系统上运行的Java应用程序,我如何确定glibc的基础版本?

背景:我想在运行时确定是否可以使用conscrypt,如今看来似乎需要glibc 2.14(https://github.com/google/conscrypt/pull/589),但是我仍然需要优雅地支持在CentOS 6或更高版本上运行其他旧版发行版则退回到标准Java SSL代码。不幸的是(至少就我所能确定的),如果Conscrypt是在较早的发行版上初始化的,则无法捕获并从发生的错误中恢复,但是如果我可以确定glibc版本,则可以选择是否初始化基于此。

2 个答案:

答案 0 :(得分:2)

执行ldd --version并解析响应的版本号的工作示例。

public class Main {

    public static void main(String[] args) throws IOException {
        final ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash").command("ldd --version");
        processBuilder.redirectErrorStream(true);

        final Process process = processBuilder.start();
        final StringBuilder stream = readStream(process.getInputStream());

        final String version = getVersion(stream.toString());

        System.out.println(version);
    }

    /**
     * Read the output stream of the process
     *
     * @param iStream InputStream
     * @return StringBuilder containing the output of the command
     */
    private static StringBuilder readStream(InputStream iStream) throws IOException {
        final StringBuilder builder = new StringBuilder();
        String line;

        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(iStream))) {
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }
        }

        return builder;
    }

    /**
     * Parse the response for the version number.
     *
     * @param input String response of ldd --version
     * @return String of the version, or null if not found
     */
    private static String getVersion(String input) {
        final Pattern pattern = Pattern.compile("[-+]?[0-9]*\\.?[0-9]+");
        final Matcher matcher = pattern.matcher(input);

        return matcher.find() ? matcher.group() : null;
    }
}

答案 1 :(得分:0)

我假设您使用一些预构建的二进制文件。您应该能够捕获java.lang.System.load(String)方法引发的java.lang.UnsatisfiedLinkError异常。如果正确链接了JNI共享对象,那么即使惰性绑定处于活动状态,动态链接程序也会检测到缺少的符号版本(大概为GLIBC_2.14)。

或者,我没有在Conscrypt中看到任何东西可以阻止在CentOS 6上构建(对于C ++ 11编译器使用Developer Toolset software collection)。它涉及到一些问题,但是glibc 2.14依赖性似乎是由预生成二进制文件的方式产生的,并且它不是软件本身固有的。