groovy
  1. groovy
  2. GROOVY-5020

invoking groovy with -D seems to mess up main's args in some cases

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.8.2
    • Fix Version/s: None
    • Labels:
      None
    • Environment:
      Ubuntu 11.04 amd64, 64-bit sun java

      java version "1.6.0_27"
      Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
      Java HotSpot(TM) 64-Bit Server VM (build 20.2-b06, mixed mode)
    • Number of attachments :
      0

      Description

      Put this code in A.groovy

      class A
      {
          public static void main(String[] args) {
      	args.each { println it }
          }
      }
      

      Run

      groovy -Da=b A.groovy -no-file
      

      Actual output:

      -n
      o-file
      

      Expected output:

      -no-file
      

      Omitting the -Da=b causes the arguments to be processed correctly. It appears that groovy's startup script is calling java correctly. In other words, running this command:

      /opt/jdk/bin/java -classpath /opt/groovy/lib/groovy-1.8.2.jar -Dscript.name=/opt/groovy/bin/groovy -Dprogram.name=groovy -Dgroovy.starter.conf=/opt/groovy/conf/groovy-starter.conf -Dgroovy.home=/opt/groovy -Dtools.jar=/opt/jdk/lib/tools.jar org.codehaus.groovy.tools.GroovyStarter --main groovy.ui.GroovyMain --conf /opt/groovy/conf/groovy-starter.conf --classpath . -Da=b A.groovy -no-file

      results in the same output.

        Issue Links

          Activity

          Hide
          blackdrag blackdrag added a comment -

          this sounds like a bug in CLI to me actually

          Show
          blackdrag blackdrag added a comment - this sounds like a bug in CLI to me actually
          Hide
          Roshan Dawrani added a comment -

          Investigated this behavior a bit. The reason for the behavior you are seeing is that command line argument "-no-file" happens to clash with "-n" option supported by Groovy for doing some line numbers stuff, and the behavior is really controlled by commons-cli's PosixParser and not Groovy itself (even in a Java program using commons-cli to parse command line with similar options, you would have the same issue). (If ur arg was named 'no-file' and not '-no-file', it wouldn't confuse the PosixParser.)

          So, below is a piece of code that shows the relevant behavior reproduced (you can try it in groovyconsole locally). I have added another "-z" in the supported command line options to show that whatever command line switches clash with what Groovy uses will have this issue - because '-no-file' and '-zoo' confuse the cli parser because it supports '-n' and '-z' options.

          import org.apache.commons.cli.*
          
          private Options buildOptions() {
              Options options = new Options()
              options.addOption(OptionBuilder.withLongOpt("define").withDescription("define a system property").hasArg(true).withArgName("name=value").create('D'))
              options.addOption(OptionBuilder.hasArg(false).withDescription("process files line by line using implicit 'line' variable").create('n'))
              options.addOption(OptionBuilder.hasArg(false).withDescription("another dummy option -z").create('z'))
              options
          }
          
          def parseAndShowWhatPosixParserComesUpWith(args) {
              CommandLineParser parser = new PosixParser()
              CommandLine cmd = parser.parse(buildOptions(), args, true)
              println cmd.args
          }
          // Confused Posix parser gives back [A.groovy, -n, o-file] because it supports '-n'
          parseAndShowWhatPosixParserComesUpWith(["-Da=b", "A.groovy", "-no-file"] as String[]) 
          
          // Posix parser gives back [A.groovy, -no-file]
          parseAndShowWhatPosixParserComesUpWith(["A.groovy", "-no-file"] as String[]) 
          
          // Confused Posix parser gives back [A.groovy, -z, oo] because it supports '-z'
          parseAndShowWhatPosixParserComesUpWith(["-Da=b", "A.groovy", "-zoo"] as String[]) 
          
          // Posix parser correctly gives [A.groovy, foo] because it supports no '-f'
          parseAndShowWhatPosixParserComesUpWith(["-Da=b", "A.groovy", "-foo"] as String[]) 
          
          Show
          Roshan Dawrani added a comment - Investigated this behavior a bit. The reason for the behavior you are seeing is that command line argument "-no-file" happens to clash with "-n" option supported by Groovy for doing some line numbers stuff, and the behavior is really controlled by commons-cli's PosixParser and not Groovy itself (even in a Java program using commons-cli to parse command line with similar options, you would have the same issue). (If ur arg was named 'no-file' and not '-no-file', it wouldn't confuse the PosixParser.) So, below is a piece of code that shows the relevant behavior reproduced (you can try it in groovyconsole locally). I have added another "-z" in the supported command line options to show that whatever command line switches clash with what Groovy uses will have this issue - because '-no-file' and '-zoo' confuse the cli parser because it supports '-n' and '-z' options. import org.apache.commons.cli.* private Options buildOptions() { Options options = new Options() options.addOption(OptionBuilder.withLongOpt( "define" ).withDescription( "define a system property" ).hasArg( true ).withArgName( "name=value" ).create('D')) options.addOption(OptionBuilder.hasArg( false ).withDescription( "process files line by line using implicit 'line' variable" ).create('n')) options.addOption(OptionBuilder.hasArg( false ).withDescription( "another dummy option -z" ).create('z')) options } def parseAndShowWhatPosixParserComesUpWith(args) { CommandLineParser parser = new PosixParser() CommandLine cmd = parser.parse(buildOptions(), args, true ) println cmd.args } // Confused Posix parser gives back [A.groovy, -n, o-file] because it supports '-n' parseAndShowWhatPosixParserComesUpWith([ "-Da=b" , "A.groovy" , "-no-file" ] as String []) // Posix parser gives back [A.groovy, -no-file] parseAndShowWhatPosixParserComesUpWith([ "A.groovy" , "-no-file" ] as String []) // Confused Posix parser gives back [A.groovy, -z, oo] because it supports '-z' parseAndShowWhatPosixParserComesUpWith([ "-Da=b" , "A.groovy" , "-zoo" ] as String []) // Posix parser correctly gives [A.groovy, foo] because it supports no '-f' parseAndShowWhatPosixParserComesUpWith([ "-Da=b" , "A.groovy" , "-foo" ] as String [])
          Hide
          blackdrag blackdrag added a comment -

          I assume the parser would have to know the command line is split in two and not supposed to process after a certain point. I always assumed the parser does know this actually, but this does not look like it. The question is what we should do about this. If we could give in our own parser, we could avoid these problems maybe.

          Show
          blackdrag blackdrag added a comment - I assume the parser would have to know the command line is split in two and not supposed to process after a certain point. I always assumed the parser does know this actually, but this does not look like it. The question is what we should do about this. If we could give in our own parser, we could avoid these problems maybe.
          Hide
          Roshan Dawrani added a comment -

          Well, CLI's PosixParser does try not to process the command line after a certain point, but does it in a buggy way. That's what is causing the problem here.

          With a one-liner fix in org.apache.commons.cli.PosixParser, I am able to get this example working here. For the same code, as above, it then outputs:

          [A.groovy, -no-file]
          [A.groovy, -no-file]
          [A.groovy, -zoo]
          [A.groovy, -foo]
          

          I am not so sure that because of a bug in CLI, we should make its parser a part of Groovy codebase. Do you see more value in doing that compared to using it as a 3rd party lib that has served us well so far and may bring improved versions tomorrow?

          In any case, I will try to raise it as an issue on commons-cli and see if they confirm it a bug.

          Show
          Roshan Dawrani added a comment - Well, CLI's PosixParser does try not to process the command line after a certain point, but does it in a buggy way. That's what is causing the problem here. With a one-liner fix in org.apache.commons.cli.PosixParser, I am able to get this example working here. For the same code, as above, it then outputs: [A.groovy, -no-file] [A.groovy, -no-file] [A.groovy, -zoo] [A.groovy, -foo] I am not so sure that because of a bug in CLI, we should make its parser a part of Groovy codebase. Do you see more value in doing that compared to using it as a 3rd party lib that has served us well so far and may bring improved versions tomorrow? In any case, I will try to raise it as an issue on commons-cli and see if they confirm it a bug.
          Hide
          Paul King added a comment -

          I did the same experiment with the same result. I also noticed that they had a similar issue reported earlier that was marked as closed and in 1.3-SNAPSHOT they have deprecated PosixParser and recommend using a new DefaultParser. The error doesn't display using the DefaultParser.

          Show
          Paul King added a comment - I did the same experiment with the same result. I also noticed that they had a similar issue reported earlier that was marked as closed and in 1.3-SNAPSHOT they have deprecated PosixParser and recommend using a new DefaultParser. The error doesn't display using the DefaultParser.
          Hide
          Paul King added a comment -

          And as a final check, swapping our build over to use 1.3-SNAPSHOT and switching all occurrences of PosixParser to DefaultParser gives us a clean build apart from CliBuilderTest#testPosixBizarreness which was in some sense documenting some weird behavior in the PosixParser which was different to all the other parsers - so in fact if that goes away, it would be a good thing. So, an alternative to them fixing the PosixParser would be having them release 1.3 since we can't release to maven central while referencing SNAPSHOT artifacts as a general rule.

          Show
          Paul King added a comment - And as a final check, swapping our build over to use 1.3-SNAPSHOT and switching all occurrences of PosixParser to DefaultParser gives us a clean build apart from CliBuilderTest#testPosixBizarreness which was in some sense documenting some weird behavior in the PosixParser which was different to all the other parsers - so in fact if that goes away, it would be a good thing. So, an alternative to them fixing the PosixParser would be having them release 1.3 since we can't release to maven central while referencing SNAPSHOT artifacts as a general rule.
          Hide
          blackdrag blackdrag added a comment -

          I am closing this issue for now. Instead please look at GROOVY-5282, which we use as a reminder to update to cli 1.3 once it is available

          Show
          blackdrag blackdrag added a comment - I am closing this issue for now. Instead please look at GROOVY-5282 , which we use as a reminder to update to cli 1.3 once it is available

            People

            • Assignee:
              blackdrag blackdrag
              Reporter:
              Jay Berkenbilt
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: