4646import java .util .concurrent .Callable ;
4747import java .util .stream .Collectors ;
4848import java .util .stream .Stream ;
49+ import org .apache .logging .log4j .LogManager ;
50+ import org .apache .logging .log4j .Logger ;
4951import org .apache .logging .log4j .converter .plugins .internal .PluginDescriptors .Namespace ;
5052import org .apache .logging .log4j .converter .plugins .internal .PluginDescriptors .PluginDescriptor ;
5153import org .apache .logging .log4j .converter .plugins .internal .ReflectConfigFilter ;
5456import picocli .CommandLine .Command ;
5557import picocli .CommandLine .Option ;
5658import picocli .CommandLine .Parameters ;
59+ import picocli .CommandLine .ScopeType ;
5760
58- @ Command (name = "convertPlugin" )
61+ @ Command (name = "convertPlugin" , mixinStandardHelpOptions = true )
5962public class PluginCacheConverter {
6063
6164 private static final String PLUGIN_DESCRIPTOR_FILE =
6265 "META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat" ;
6366 private static final String PLUGIN_DESCRIPTOR_JSON_FILE = "Log4j2Plugins.json" ;
6467
68+ private static final Logger logger = LogManager .getLogger (PluginCacheConverter .class );
6569 private static final JsonFactory jsonFactory = new ObjectMapper ().getFactory ();
6670
71+ @ Option (
72+ names = {"-o" , "--outputDirectory" },
73+ description = "Directory for the command output" ,
74+ defaultValue = "." ,
75+ scope = ScopeType .INHERIT )
76+ private File outputDirectory ;
77+
6778 public static void main (final String [] args ) {
6879 System .exit (new CommandLine (new PluginCacheConverter ()).execute (args ));
6980 }
7081
7182 @ Command
7283 public void toJson (
73- @ Parameters (description = "Classpath containing Log4j Core plugins" ) final List <String > classPath ,
74- @ Option (names = {"-o" , "--outputDirectory" }) final File outputDirectory )
84+ @ Parameters (
85+ arity = "1..*" ,
86+ description = "Classpath containing Log4j Core plugins" ,
87+ paramLabel = "<classPathElement>" )
88+ final List <String > classPath )
7589 throws IOException {
7690 new PluginDescriptorToJsonConverter (classPath , outputDirectory ).call ();
7791 }
7892
7993 @ Command
80- public void fromJson (
81- @ Parameters (description = "Input `Log4j2Plugins.json` JSON file" ) final File input ,
82- @ Option (names = {"-o" , "--outputDirectory" }) final File outputDirectory )
94+ public void fromJson (@ Parameters (description = "Plugin descriptor in JSON format" ) final File jsonPluginDescriptor )
8395 throws IOException {
84- new JsonToPluginDescriptorConverter (input , outputDirectory ).call ();
96+ new JsonToPluginDescriptorConverter (jsonPluginDescriptor , outputDirectory ).call ();
8597 }
8698
8799 @ Command
88100 public void filterReflectConfig (
89- @ Parameters (description = "Plugin descriptor (as JSON)" ) final File pluginDescriptor ,
90- @ Parameters (description = "Classpath containing GraalVM descriptors" ) final List <String > classPath ,
91- @ Option (names = {"-o" , "--outputDirectory" }) final File outputDirectory )
101+ @ Parameters (description = "Plugin descriptor in JSON format" ) final File jsonPluginDescriptor ,
102+ @ Parameters (
103+ arity = "1..*" ,
104+ description = "Classpath containing GraalVM descriptors" ,
105+ paramLabel = "<classPathElement>" )
106+ final List <String > classPath )
92107 throws IOException {
93- new ReflectConfigTransformer (pluginDescriptor , classPath , outputDirectory ).call ();
108+ new ReflectConfigTransformer (jsonPluginDescriptor , classPath , outputDirectory ).call ();
94109 }
95110
96111 private static Collection <Path > validateClassPath (final Collection <String > classPath ) {
@@ -121,9 +136,9 @@ private static final class PluginDescriptorToJsonConverter implements Callable<@
121136
122137 private final ClassLoader classLoader ;
123138
124- private final @ Nullable Path outputDirectory ;
139+ private final Path outputDirectory ;
125140
126- PluginDescriptorToJsonConverter (final Collection <String > classPath , final @ Nullable File outputDirectory ) {
141+ PluginDescriptorToJsonConverter (final Collection <String > classPath , final File outputDirectory ) {
127142 this .classLoader = AccessController .doPrivileged (
128143 (PrivilegedAction <ClassLoader >) () -> new URLClassLoader (validateClassPath (classPath ).stream ()
129144 .map (p -> {
@@ -134,19 +149,16 @@ private static final class PluginDescriptorToJsonConverter implements Callable<@
134149 }
135150 })
136151 .toArray (URL []::new )));
137- this .outputDirectory = outputDirectory != null ? outputDirectory .toPath () : null ;
152+ this .outputDirectory = outputDirectory .toPath ();
138153 }
139154
140155 @ Override
141156 public @ Nullable Void call () throws IOException {
142- final OutputStream output ;
143- if (outputDirectory != null ) {
144- Files .createDirectories (outputDirectory );
145- output = Files .newOutputStream (outputDirectory .resolve (PLUGIN_DESCRIPTOR_JSON_FILE ));
146- } else {
147- output = System .out ;
148- }
149- try (final JsonGenerator generator = jsonFactory .createGenerator (output )) {
157+ final Path pluginDescriptorPath = outputDirectory .resolve (PLUGIN_DESCRIPTOR_JSON_FILE );
158+ logger .info ("Creating Log4j plugin descriptor file (JSON format): {}" , pluginDescriptorPath );
159+ createParentDirectories (pluginDescriptorPath );
160+ try (final OutputStream output = Files .newOutputStream (pluginDescriptorPath );
161+ final JsonGenerator generator = jsonFactory .createGenerator (output )) {
150162 final PluginDescriptor pluginDescriptor = new PluginDescriptor ();
151163 // Read all `Log4j2Plugins.dat` file on the classpath
152164 for (final URL url : Collections .list (classLoader .getResources (PLUGIN_DESCRIPTOR_FILE ))) {
@@ -156,10 +168,6 @@ private static final class PluginDescriptorToJsonConverter implements Callable<@
156168 }
157169 // Write JSON file
158170 pluginDescriptor .withBuilderHierarchy (classLoader ).toJson (generator );
159- } finally {
160- if (output != System .out ) {
161- output .close ();
162- }
163171 }
164172 return null ;
165173 }
@@ -168,34 +176,26 @@ private static final class PluginDescriptorToJsonConverter implements Callable<@
168176 private static class JsonToPluginDescriptorConverter implements Callable <@ Nullable Void > {
169177
170178 private final Path input ;
171- private final @ Nullable Path outputDirectory ;
179+ private final Path outputDirectory ;
172180
173- JsonToPluginDescriptorConverter (final File input , final @ Nullable File outputDirectory ) {
181+ JsonToPluginDescriptorConverter (final File input , final File outputDirectory ) {
174182 this .input = input .toPath ();
175- this .outputDirectory = outputDirectory != null ? outputDirectory .toPath () : null ;
183+ this .outputDirectory = outputDirectory .toPath ();
176184 }
177185
178186 @ Override
179187 public @ Nullable Void call () throws IOException {
180- final OutputStream output ;
181- if (outputDirectory != null ) {
182- final Path pluginDescriptorPath = outputDirectory .resolve (PLUGIN_DESCRIPTOR_FILE );
183- createParentDirectories (pluginDescriptorPath );
184- output = Files .newOutputStream (pluginDescriptorPath );
185- } else {
186- output = System .out ;
187- }
188- try (final InputStream inputStream = Files .newInputStream (input );
188+ final Path pluginDescriptorPath = outputDirectory .resolve (PLUGIN_DESCRIPTOR_FILE );
189+ logger .info ("Creating Log4j plugin descriptor file (binary format): {}" , pluginDescriptorPath );
190+ createParentDirectories (pluginDescriptorPath );
191+ try (final OutputStream output = Files .newOutputStream (pluginDescriptorPath );
192+ final InputStream inputStream = Files .newInputStream (input );
189193 final JsonParser parser = jsonFactory .createParser (inputStream )) {
190194 final PluginDescriptor pluginDescriptor = new PluginDescriptor ();
191195 // Input JSON
192196 pluginDescriptor .readJson (parser );
193197 // Output `Log4j2Plugins.dat` file
194198 pluginDescriptor .toPluginDescriptor (output );
195- } finally {
196- if (output != System .out ) {
197- output .close ();
198- }
199199 }
200200 return null ;
201201 }
@@ -205,15 +205,13 @@ private static class ReflectConfigTransformer implements Callable<@Nullable Void
205205
206206 private final Path pluginDescriptorPath ;
207207 private final Collection <Path > classPath ;
208- private final @ Nullable Path outputDirectory ;
208+ private final Path outputDirectory ;
209209
210210 ReflectConfigTransformer (
211- final File pluginDescriptorPath ,
212- final Collection <String > classPath ,
213- final @ Nullable File outputDirectory ) {
211+ final File pluginDescriptorPath , final Collection <String > classPath , final File outputDirectory ) {
214212 this .pluginDescriptorPath = pluginDescriptorPath .toPath ();
215213 this .classPath = validateClassPath (classPath );
216- this .outputDirectory = outputDirectory != null ? outputDirectory .toPath () : null ;
214+ this .outputDirectory = outputDirectory .toPath ();
217215 }
218216
219217 void filterReflectConfigInJar (final Path jar , final ReflectConfigFilter filter ) throws IOException {
@@ -226,27 +224,24 @@ void filterReflectConfigInJar(final Path jar, final ReflectConfigFilter filter)
226224 try (final FileSystem fileSystem = FileSystems .newFileSystem (jarFileSystemRoot , Collections .emptyMap ())) {
227225 final Path rootPath = fileSystem .getPath ("/" );
228226 final Path nativeImagePath = rootPath .resolve ("META-INF/native-image" );
229- try (final Stream <Path > paths = Files .walk (nativeImagePath , 3 )) {
230- paths .filter (p ->
231- "reflect-config.json" .equals (p .getFileName ().toString ()))
232- .forEach (p -> filterReflectConfig (rootPath , p , filter ));
227+ if (Files .isDirectory (nativeImagePath )) {
228+ try (final Stream <Path > paths = Files .walk (nativeImagePath , 3 )) {
229+ paths .filter (p -> "reflect-config.json"
230+ .equals (p .getFileName ().toString ()))
231+ .forEach (p -> filterReflectConfig (rootPath , p , filter ));
232+ }
233233 }
234234 }
235235 }
236236
237237 void filterReflectConfig (final Path rootPath , final Path reflectConfig , final ReflectConfigFilter filter ) {
238238 try {
239- final OutputStream output ;
240- if (outputDirectory != null ) {
241- final String relativePath =
242- rootPath .relativize (reflectConfig ).toString ();
243- final Path outputPath = outputDirectory .resolve (relativePath );
244- createParentDirectories (outputPath );
245- output = Files .newOutputStream (outputPath );
246- } else {
247- output = System .out ;
248- }
249- try (final InputStream inputStream = Files .newInputStream (reflectConfig );
239+ final String relativePath = rootPath .relativize (reflectConfig ).toString ();
240+ final Path outputPath = outputDirectory .resolve (relativePath );
241+ logger .info ("Creating GraalVM configuration file: {}" , outputPath );
242+ createParentDirectories (outputPath );
243+ try (final OutputStream output = Files .newOutputStream (outputPath );
244+ final InputStream inputStream = Files .newInputStream (reflectConfig );
250245 final JsonParser parser = jsonFactory .createParser (inputStream );
251246 final JsonGenerator generator = jsonFactory .createGenerator (output )) {
252247 filter .filter (parser , generator );
0 commit comments