对于在Linux系统上运行的Java应用程序,我如何确定glibc的基础版本?
背景:我想在运行时确定是否可以使用conscrypt,如今看来似乎需要glibc 2.14(https://github.com/google/conscrypt/pull/589),但是我仍然需要优雅地支持在CentOS 6或更高版本上运行其他旧版发行版则退回到标准Java SSL代码。不幸的是(至少就我所能确定的),如果Conscrypt是在较早的发行版上初始化的,则无法捕获并从发生的错误中恢复,但是如果我可以确定glibc版本,则可以选择是否初始化基于此。
答案 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依赖性似乎是由预生成二进制文件的方式产生的,并且它不是软件本身固有的。