В предыдущих публикациях в блоге я рассмотрел Поиск файлов JAR с помощью Groovy, чтобы найти записи (например, .class ), содержащиеся в JAR, и просмотр файла манифеста JAR с помощью Groovy . В этой статье я расскажу об использовании Groovy для поиска определенного свойства в файле свойств, содержащемся в JAR. Сценарий в этом посте ищет файлы JAR в предоставленном каталоге и его подкаталогах для файла свойств, содержащего указанное свойство.
Следующий скрипт Groovy использует несколько преимуществ Groovy для рекурсивного поиска в указанном каталоге и его подкаталогах файлов JAR, содержащих файлы свойств, которые содержат указанное свойство. Сценарий выводит соответствующие файлы JAR и записи их файлов свойств, которые содержат указанное свойство. Сценарий также показывает значение, которое установлено для каждого свойства в каждом соответствующем файле JAR / свойства.
findPropertiesInJars.groovy
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#!/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.Optioncli.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) returnif (opt.h) cli.usage()def directories = opt.dsdef propertiesToSearchFor = opt.psimport java.util.zip.ZipFileimport java.util.zip.ZipExceptiondef 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 на моем компьютере, чтобы найти все свойства с именем ‘artifactId’ ( Maven ) в этих многочисленных файлах JAR.
Приведенный выше скрипт использует несколько возможностей Groovy. Например, способность Groovy напрямую использовать API-интерфейсы и библиотеки Java очевидна по всему сценарию с использованием таких классов, как ZipFile (для доступа к содержимому JAR), Properties (для доступа к содержимому файлов свойств), JarURLConnection (также для доступа к содержимому файлов свойств ), TreeSet (для легкой сортировки) и Apache Commons CLI (встроенный в Groovy для поддержки командной строки). Замыкания и лаконичный синтаксис Groovy также обеспечивают большую беглость и удобочитаемость.
Этот сценарий перехватывает исключения, даже если Groovy не требует перехвата каких-либо исключений (проверенных или во время выполнения). Причина этого в том, что необработанное исключение приведет к завершению скрипта. Улавливая любое обнаруженное исключение во время открытия каждого файла JAR или загрузки из файла свойств, исключение в этих случаях будет препятствовать загрузке только этого конкретного файла JAR или файла свойств, не останавливая обработку других.
Этот сценарий делает пару существенных предположений. Первое предположение состоит в том, что файлы JAR, которые нужно найти, имеют расширение .jar и что содержащиеся в них файлы свойств имеют расширения .properties . Сценарий использует встроенную поддержку CLI — единый флаг командной строки, позволяющий искать несколько каталогов и / или несколько имен свойств, разделяя несколько значений запятыми.
Иногда я хочу узнать, где определенное свойство указано в моем приложении, и этот сценарий позволяет легко найти, где именно это свойство указано в JAR-файлах в пути к классам приложения.
Ссылка: Поиск свойств в JAR с Groovy от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .
