以编程方式列出包含的 Java 个库
Programmatically list included Java libraries
我正在从事一个利用许多 security/utility 库的项目。出于安全原因,我希望能够告知用户我们使用哪些库以及他们的 bin 中 运行 是什么版本。我们的许多用户选择修改我们的代码,所以我更希望它以编程方式进行。
我试图解析 class 路径,但当程序被打包到 jar 中时,这似乎无济于事。我还尝试列出 JAR 中的所有 class 名称,但这并没有传达任何版本信息。
我们所有的库在 jar 文件的名称中都有版本。我愿意制作某种编译时脚本。我们使用 ant 和 intellij 构建。 Ant 是我唯一需要支持的,intellij 让生活更轻松。
如果 jar 在 class 路径中,您可以使用系统属性获取 jar。
String path = System.getProperty("java.class.path");
String[] p;
p = path.split(";");
for(int i=0; i< p.length; i++) {
System.out.println(p[i]);
}
对于上面的示例,我曾经从服务器 return 我所有的网络应用程序库。你可以做类似的事情来得到你想要的罐子。
如果您将它们打包到一个 jar 中,那么您需要从 class 目录本身加载它,您可以尝试 classloader.
ClassLoader loader = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)loader).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
我能够通过解析 META-INF/maven/org/blah/pom.properties 文件来做到这一点。它仅适用于具有 Maven 支持的库(尽管您的项目不需要任何与 Maven 相关的东西)。
private static HashMap<String,String> getVersionMap () {
//Results by <lib name, version>
final HashMap<String,String> resultMap = new HashMap<>();
try {
//Hack to get a ref to our jar
URI jarLocation = new URI("jar:" + SecurityInfo.class.getProtectionDomain().getCodeSource().getLocation().toString());
//This jdk1.7x nio util lets us look into the jar, without it we would need ZipStream
FileSystem fs = FileSystems.newFileSystem(jarLocation, new HashMap<String,String>());
Files.walkFileTree(fs.getPath("/META-INF/maven"), new HashSet<FileVisitOption>(), 3, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toString().endsWith(".properties")) {
try {
List<String> data = Files.readAllLines(file, Charset.defaultCharset());
String id = data.get(4);
id = id.substring(id.lastIndexOf('=') + 1);
String version = data.get(2);
version = version.substring(version.lastIndexOf('=') + 1);
resultMap.put(id, version);
}
catch(Exception ignore) {}
}
return FileVisitResult.CONTINUE;
}
});
} catch(Exception ignore) {
return new HashMap<>();
}
return resultMap;
}
我正在从事一个利用许多 security/utility 库的项目。出于安全原因,我希望能够告知用户我们使用哪些库以及他们的 bin 中 运行 是什么版本。我们的许多用户选择修改我们的代码,所以我更希望它以编程方式进行。
我试图解析 class 路径,但当程序被打包到 jar 中时,这似乎无济于事。我还尝试列出 JAR 中的所有 class 名称,但这并没有传达任何版本信息。
我们所有的库在 jar 文件的名称中都有版本。我愿意制作某种编译时脚本。我们使用 ant 和 intellij 构建。 Ant 是我唯一需要支持的,intellij 让生活更轻松。
如果 jar 在 class 路径中,您可以使用系统属性获取 jar。
String path = System.getProperty("java.class.path");
String[] p;
p = path.split(";");
for(int i=0; i< p.length; i++) {
System.out.println(p[i]);
}
对于上面的示例,我曾经从服务器 return 我所有的网络应用程序库。你可以做类似的事情来得到你想要的罐子。
如果您将它们打包到一个 jar 中,那么您需要从 class 目录本身加载它,您可以尝试 classloader.
ClassLoader loader = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)loader).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
我能够通过解析 META-INF/maven/org/blah/pom.properties 文件来做到这一点。它仅适用于具有 Maven 支持的库(尽管您的项目不需要任何与 Maven 相关的东西)。
private static HashMap<String,String> getVersionMap () {
//Results by <lib name, version>
final HashMap<String,String> resultMap = new HashMap<>();
try {
//Hack to get a ref to our jar
URI jarLocation = new URI("jar:" + SecurityInfo.class.getProtectionDomain().getCodeSource().getLocation().toString());
//This jdk1.7x nio util lets us look into the jar, without it we would need ZipStream
FileSystem fs = FileSystems.newFileSystem(jarLocation, new HashMap<String,String>());
Files.walkFileTree(fs.getPath("/META-INF/maven"), new HashSet<FileVisitOption>(), 3, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.toString().endsWith(".properties")) {
try {
List<String> data = Files.readAllLines(file, Charset.defaultCharset());
String id = data.get(4);
id = id.substring(id.lastIndexOf('=') + 1);
String version = data.get(2);
version = version.substring(version.lastIndexOf('=') + 1);
resultMap.put(id, version);
}
catch(Exception ignore) {}
}
return FileVisitResult.CONTINUE;
}
});
} catch(Exception ignore) {
return new HashMap<>();
}
return resultMap;
}