Pass an argument that starts with ‘@’ to jcommander



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?

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:

  1. Use a different command line parser.
  2. Patch the JCommander source so that there is a way to escape the @ mechanism or ask the original author to do so himself.
  3. 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.



Source: stackoverflow