代码之家  ›  专栏  ›  技术社区  ›  Matt Sheppard

从Java中确定当前glibc版本

  •  2
  • Matt Sheppard  · 技术社区  · 7 年前

    对于在linux系统上运行的java应用程序,如何确定glibc的底层版本?

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

    2 回复  |  直到 7 年前
        1
  •  2
  •   Chris    7 年前

    执行工作示例 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;
        }
    }
    
        2
  •  0
  •   Florian Weimer    7 年前

    我假设你使用了一些预先构建的二进制文件。你应该能抓住 java.lang.UnsatisfiedLinkError 由引发的异常 java.lang.System.load(String) 方法。如果JNI共享对象链接正确,动态链接器将检测丢失的符号版本(可能 GLIBC_2.14 )即使惰性绑定处于活动状态。

    或者,我在地窖里看不到任何东西可以阻止在CentOS 6上建造 Developer Toolset software collection 对于C++ 11编译器。这有点复杂,但是glibc 2.14的依赖性似乎来自于预构建的二进制文件的生成方式,而不是软件本身固有的。