从Java中确定当前glibc版本

3
对于在 Linux 系统上运行的 Java 应用程序,如何确定底层的 glibc 版本?
背景:我想在运行时确定是否可以使用 conscrypt,它现在似乎需要 glibc 2.14(https://github.com/google/conscrypt/pull/589),但我仍然需要通过回退到标准 Java SSL 代码来优雅地支持在 CentOS 6 或其他旧发行版上运行。不幸的是(至少据我所知),如果在旧版本上初始化 Conscrypt,则无法捕获和恢复出错,但如果我可以确定 glibc 版本,我可以根据这个选择是否初始化它。

从Java运行ldd --version命令并检查输出。请参阅https://dev59.com/amkw5IYBdhLWcg3ws8xj#20155150。 - undefined
1
有没有官方的格式来解析基于输出的内容?如果没有,那么输出格式是否被认为是稳定的? - undefined
2个回答

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;
    }
}

你必须在Bash中运行命令,而不仅仅是运行命令吗?通过Bash的优势是什么? - undefined
为什么你关心系统的行分隔符呢?逐行处理文本,然后再将其拼接起来再次解析似乎有些多余。使用List<String>会更合理吧?要么直接将输出转储到一个String中,而不需要中间的按行拆分。 - undefined
当然,公平地说,这主要是从我正在进行的一个项目中复制粘贴并稍作修改而来。我没有说它已经准备好投入生产,但它能够满足原帖提出的需求。 - undefined

0

我假设你使用了一些预编译的二进制文件。你应该能够捕获由java.lang.System.load(String)方法抛出的java.lang.UnsatisfiedLinkError异常。如果JNI共享对象链接正确,即使延迟绑定处于活动状态,动态链接器也会检测到缺失的符号版本(可能是GLIBC_2.14)。

另外,我在Conscrypt中没有看到任何东西会阻止在CentOS 6上构建(使用Developer Toolset软件集合提供的C++11编译器)。这可能有点复杂,但glibc 2.14的依赖似乎是预编译二进制文件制作方式导致的,并不是软件本身固有的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接