I am using JCommander(version 1.32) to parse command line arguments passed to a java application(let’s call it app
). The problem I have is that one of the arguments I need to pass begins with @
and as can be seen here there is a special syntax for @
. Thus calling the app with app @arg
fails with
Could not read file arg: java.io.FileNotFoundException: arg (No such file or directory).
Reading through this information I tried placing my arguments in a file but apparently the “@ syntax” is recursive thus even when I place @arg
in a file my program fails with the same error.
Is there a way to pass an argument that begins with @
to a program that uses jcommander? Is there a way to disable the @
syntax?
Advertisement
Answer
As a result of the chat discussion about this between OP and myself, we came to the following conclusion:
JCommander calls itself, as part of the way it parses commands – subcommand structures that each have their own parameter definitions.
At the top level it expands the @-parameter and creates a new argument list that includes the contents of the file.
Then, as it calls itself, it parses that argument list again, and therefore expands any parameters beginning with a @
once again.
Luckily, it appears it only does so once, so it is not fully recursive. So the solution for anybody wanting to pass a parameter that begins with @
is to use two indirections. That is, create two files:
file1.txt
@file2.txt
file2.txt
@actualparameter
And then use @file1.txt
on the command line itself.
So this is a possible workaround. Personally, I’m not too happy about creating extra files like that, and I’d suggest one of three other solutions:
- Use a different command line parser.
- Patch the JCommander source so that there is a way to escape the
@
mechanism or ask the original author to do so himself. - As a kludge, prepend a character to any parameter that may begin with a
@
, and then strip that character when I need to use the parameter’s value. At least this doesn’t create two extra files.
Edit: the authors of Jcommander fixed this issue.
There is a new method, according to the comments to this pull request on Jcommander’s github that allows disabling the processing of the @
sign. E.g.
JCommander jc = new JCommander(params); jc.setExpandAmpersat(false);
The method has been added starting with version 1.54.