在以前的博客文章中,我介绍了使用Groovy搜索JAR文件以查找JAR中包含的条目(例如.class
文件)以及使用Groovy 查看JAR的清单文件 。 在本文中,我将研究如何使用Groovy在JAR所包含的属性文件中查找特定属性。 这篇文章中的脚本在提供的目录及其子目录中的JAR中搜索包含指定属性的属性文件。
下面的Groovy脚本利用Groovy的多个优点来递归搜索指定目录及其子目录,以查找包含属性文件的JAR文件,该文件包含指定属性。 该脚本输出匹配的JAR及其包含指定属性的属性文件条目。 该脚本还显示了每个匹配的JAR /属性文件中每个属性设置的值。
findPropertiesInJars.groovy
#!/usr/bin/env groovy
/**
* findPropertiesInJars.groovy
*
* findPropertiesInJars.groovy -d <<root_directories>> -p <<properties_to_search_for>>
*
* Script that looks for provided properties (assumed to be in files with
* .properties extension) in JAR files (assumed to have .jar extensions) in the
* provided directory and all of its subdirectories.
*/
def cli = new CliBuilder(
usage: 'findPropertiesInJars.groovy -d <root_directories> -p <property_names_to_search_for>',
header: '\nAvailable options (use -h for help):\n',
footer: '\nInformation provided via above options is used to generate printed string.\n')
import org.apache.commons.cli.Option
cli.with
{
h(longOpt: 'help', 'Help', args: 0, required: false)
d(longOpt: 'directories', 'Directories to be searched', args: Option.UNLIMITED_VALUES, valueSeparator: ',', required: true)
p(longOpt: 'properties', 'Property names to search for in JARs', args: Option.UNLIMITED_VALUES, valueSeparator: ',', required: true)
}
def opt = cli.parse(args)
if (!opt) return
if (opt.h) cli.usage()
def directories = opt.ds
def propertiesToSearchFor = opt.ps
import java.util.zip.ZipFile
import java.util.zip.ZipException
def matches = new TreeMap<String, Set<String>>()
directories.each
{ directory ->
def dir = new File(directory)
propertiesToSearchFor.each
{ propertyToFind ->
dir.eachFileRecurse
{ file->
if (file.isFile() && file.name.endsWith('jar'))
{
try
{
zip = new ZipFile(file)
entries = zip.entries()
entries.each
{ entry->
def entryName = entry.name
if (entryName.contains('.properties'))
{
def fullEntryName = file.canonicalPath + '!/' + entryName
def properties = new Properties()
try
{
def url = new URL('jar:file:' + File.separator + fullEntryName)
def jarConnection = (JarURLConnection) url.openConnection()
properties.load(jarConnection.inputStream)
}
catch (Exception exception)
{
println 'Unable to load properties from ${fullEntryName} - ${exception}'
}
if (properties.get(propertyToFind) != null)
{
def pathPlusMatch = '${file.canonicalPath}\n\t\t${entryName}\n\t\t${propertyToFind}=${properties.get(propertyToFind)}'
if (matches.get(propertyToFind))
{
matches.get(propertyToFind).add(pathPlusMatch)
}
else
{
def containingJars = new TreeSet<String>()
containingJars.add(pathPlusMatch)
matches.put(propertyToFind, containingJars)
}
}
}
}
}
catch (ZipException zipEx)
{
println 'Unable to open JAR file ${file.name}'
}
}
}
}
}
matches.each
{ propertyName, containingJarNames ->
println '\nProperty '${propertyName}' Found:'
containingJarNames.each
{ containingJarName ->
println '\t${containingJarName}'
}
}
当针对JAR运行上述脚本时,它将列出具有属性文件的JAR,这些文件具有指定的属性及其分配的值。 接下来显示的屏幕快照演示了如何在我的计算机上针对Apache Camel发行版运行脚本,以在众多的JAR文件中找到名为“ artifactId”( Maven )的所有属性。
上面的脚本利用了一些Groovy功能。 例如,在整个脚本中,通过使用诸如ZipFile (用于访问JAR内容), Properties (用于访问属性文件的内容), JarURLConnection (也用于访问属性文件的内容)的类,Groovy直接使用Java API和库的能力显而易见。 ), TreeSet (便于排序)和Apache Commons CLI (内置于Groovy中以提供命令行支持)。 Groovy的闭包和简洁的语法也带来了更高的流利性和可读性。
即使Groovy不需要捕获任何异常(无论是检查的还是运行时的),该脚本也会捕获异常。 原因是未捕获的异常将导致脚本终止。 通过在打开每个JAR文件或从属性文件加载过程中捕获任何遇到的异常,在这些情况下的异常将仅阻止该特定JAR或属性文件的加载,而不会阻止其他JAR或属性文件的处理。
该脚本有几个重要的假设。 第一个假设是要搜索的JAR文件具有.jar
扩展名,并且所包含的属性文件具有.properties
扩展名。 该脚本使用内置的CLI支持的单个命令行标志的出色功能, 允许通过使用逗号分隔多个值来搜索多个目录和/或多个属性名称。
有时候,我想知道在应用程序中指定了特定属性的位置,而此脚本使您可以轻松地在应用程序的类路径上的JAR中找到指定该特定属性的位置。
参考:在Inspired by Actual Events博客上,我们的JCG合作伙伴 Dustin Marx 使用Groovy在JAR中查找属性 。
翻译自: https://www.javacodegeeks.com/2013/03/finding-properties-in-jars-with-groovy.html