Groovy
  1. Groovy
  2. GROOVY-3925

Multiple GrabResolvers with Grab don't seem to work, and GrabResolve can't be applied to imports

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7-rc-1
    • Fix Version/s: 1.7-rc-2
    • Component/s: Grape
    • Labels:
      None

      Description

      Running the following code:

      @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
      @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
      @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1')
      import groovyx.gpars.actor.PooledActorGroup
      
      println new PooledActorGroup()

      Gives the following error:

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      /Users/tyates/Code/Groovy/chat/chatserver.groovy: 3: unable to resolve class groovyx.gpars.actor.PooledActorGroup
       @ line 3, column 1.
         @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
         ^
      
      1 error

      If I move the GrabResolvers off to a different member, ie:

      @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
      @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
      def dummy() {}
      @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1')
      import groovyx.gpars.actor.PooledActorGroup
      
      println new PooledActorGroup()

      Then the error changes to:

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      /Users/tyates/Code/Groovy/chat/chatserver.groovy: 3: Cannot specify duplicate annotation on the same member : GrabResolver at line: 3 column: 1. File: /Users/tyates/Code/Groovy/chat/chatserver.groovy @ line 3, column 1.
         @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
         ^
      
      1 error

      To get this to work, I need to do the following:

      @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
      def dummy() {}
      @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
      def dummy2() {}
      @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1')
      import groovyx.gpars.actor.PooledActorGroup
      
      println new PooledActorGroup()

      which then gives the output:

      groovyx.gpars.actor.PooledActorGroup@2f2c55e4

      So it seems there may be two problems currently:

      1) You cannot specify multiple GrabResolvers for a single member
      2) You cannot specify GrabResolvers on import statements


      To check that 2 fails, I tried the following:

      @GrabResolver(name='restlet.org', root='http://maven.restlet.org')
      @Grab(group='org.restlet', module='org.restlet', version='1.1.6')
      import org.restlet.data.MediaType
      import org.restlet.resource.StringRepresentation
      
      println new StringRepresentation( "Hi", MediaType.TEXT_PLAIN )

        Issue Links

          Activity

          Hide
          Paul King added a comment - - edited

          Now also in 1.7-rc2

          Show
          Paul King added a comment - - edited Now also in 1.7-rc2
          Hide
          Paul King added a comment -

          Also applied to 1_7_X branch. Both of these should work now:

          @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
          @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
          @Grab('org.codehaus.gpars:gpars:0.9-beta-1')
          import groovyx.gpars.actor.*
          assert Actors.name.contains('groovyx')
          

          and this:

          @Grapes([
            @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2'),
            @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org'),
            @Grab('org.codehaus.gpars:gpars:0.9-beta-1')
          ])
          import groovyx.gpars.actor.*
          assert Actors.name.contains('groovyx')
          
          Show
          Paul King added a comment - Also applied to 1_7_X branch. Both of these should work now: @GrabResolver(name='jboss', root='http: //repository.jboss.org/maven2') @GrabResolver(name='codehaus.snapshot', root='http: //snapshots.repository.codehaus.org') @Grab('org.codehaus.gpars:gpars:0.9-beta-1') import groovyx.gpars.actor.* assert Actors.name.contains('groovyx') and this: @Grapes([ @GrabResolver(name='jboss', root='http: //repository.jboss.org/maven2'), @GrabResolver(name='codehaus.snapshot', root='http: //snapshots.repository.codehaus.org'), @Grab('org.codehaus.gpars:gpars:0.9-beta-1') ]) import groovyx.gpars.actor.* assert Actors.name.contains('groovyx')
          Hide
          Paul King added a comment -

          Fixed in trunk

          Show
          Paul King added a comment - Fixed in trunk
          Hide
          Roshan Dawrani added a comment -

          Regarding @GrabResolver also working on import statements, it seems more due to a compiler bug rather than a designed thing.

          The compiler lets even the following code compile:

          import groovy.beans.*
          
          @Bindable
          import org.codehaus.groovy.classgen.*
          
          class Test {}
          
          println Test
          

          where @Bindable is only supposed to be used on field/type targets and nothing else.

          Show
          Roshan Dawrani added a comment - Regarding @GrabResolver also working on import statements, it seems more due to a compiler bug rather than a designed thing. The compiler lets even the following code compile: import groovy.beans.* @Bindable import org.codehaus.groovy.classgen.* class Test {} println Test where @Bindable is only supposed to be used on field/type targets and nothing else.
          Hide
          Roshan Dawrani added a comment -

          If you are playing with the snapshot versions of the groovy in your talk, then I have done a fix on the trunk
          that allows multiple @GrabResolver (i.e, annotations not having retention policy as RUNTIME). I will be porting
          this fix to 1.7.x and 1.6.x in a bit.

          After the fix, point 1) from the JIRA is taken care of and the following works

          @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
          @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
          def dummy() {}
          @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1')
          import groovyx.gpars.actor.PooledActorGroup
          
          println new PooledActorGroup()
          

          In fact, in the very first example of JIRA, if I re-order annotations a bit, then the following works too:

          @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1')
          @GrabResolver(name='jboss', root='http://repository.jboss.org/maven2')
          @GrabResolver(name='codehaus.snapshot', root='http://snapshots.repository.codehaus.org')
          import groovyx.gpars.actor.PooledActorGroup
          
          println new PooledActorGroup()
          
          Show
          Roshan Dawrani added a comment - If you are playing with the snapshot versions of the groovy in your talk, then I have done a fix on the trunk that allows multiple @GrabResolver (i.e, annotations not having retention policy as RUNTIME). I will be porting this fix to 1.7.x and 1.6.x in a bit. After the fix, point 1) from the JIRA is taken care of and the following works @GrabResolver(name='jboss', root='http: //repository.jboss.org/maven2') @GrabResolver(name='codehaus.snapshot', root='http: //snapshots.repository.codehaus.org') def dummy() {} @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1') import groovyx.gpars.actor.PooledActorGroup println new PooledActorGroup() In fact, in the very first example of JIRA, if I re-order annotations a bit, then the following works too: @Grab(group='org.codehaus.gpars', module='gpars', version='0.9-beta-1') @GrabResolver(name='jboss', root='http: //repository.jboss.org/maven2') @GrabResolver(name='codehaus.snapshot', root='http: //snapshots.repository.codehaus.org') import groovyx.gpars.actor.PooledActorGroup println new PooledActorGroup()
          Hide
          Russel Winder added a comment -

          Tim,

          Let me make you feel better: the hack has saved my talk for tomorrow at Groovy & Grails eXchange 2009. It may be a hack, but it works. You are officially a hero!

          Show
          Russel Winder added a comment - Tim, Let me make you feel better: the hack has saved my talk for tomorrow at Groovy & Grails eXchange 2009. It may be a hack, but it works. You are officially a hero!
          Hide
          Roshan Dawrani added a comment -

          Yes, disallowing duplicate annotations only for Runtime retention policy seems correct to me.

          I will raise a JIRA and fix that bit.

          Show
          Roshan Dawrani added a comment - Yes, disallowing duplicate annotations only for Runtime retention policy seems correct to me. I will raise a JIRA and fix that bit.
          Hide
          Tim Yates added a comment -

          I can only apologise Russel That hack makes me feel unclean when I think that it came from my hands

          Show
          Tim Yates added a comment - I can only apologise Russel That hack makes me feel unclean when I think that it came from my hands
          Hide
          Guillaume Delcroix added a comment -

          Could you file a JIRA issue for we make such an improvement with @GrabResolver?

          Show
          Guillaume Delcroix added a comment - Could you file a JIRA issue for we make such an improvement with @GrabResolver?
          Hide
          Tim Yates added a comment -

          And maybe the GROOVY-3852 issue should only have prevented multiple @Retention(value=RUNTIME) annotations?

          Show
          Tim Yates added a comment - And maybe the GROOVY-3852 issue should only have prevented multiple @Retention(value=RUNTIME) annotations?
          Hide
          Russel Winder added a comment - - edited

          Yes it does. I am successfully using:

          @GrabResolver ( name = 'jboss' , root = 'http://repository.jboss.org/maven2' )
          def dummyA ( ) { }
          @GrabResolver ( name = 'codehaus.snapshot' , root = 'http://snapshots.repository.codehaus.org' )
          def dummyB ( ) { }
          @Grab ( group = 'org.codehaus.gpars' , module = 'gpars' , version = '0.9-SNAPSHOT' )
          
          import groovyx.gpars.actor.Actors
          

          but this workaround really makes me want to . . . , well let's leave it unsaid.

          I think that whatever fix is needed to make to following work really does need putting in place:

          @Grapes ( 
            @GrabResolver ( name = 'jboss' , root = 'http://repository.jboss.org/maven2' ) ,
            @GrabResolver ( name = 'codehaus.snapshot' , root = 'http://snapshots.repository.codehaus.org' ) ,
            @Grab ( group = 'org.codehaus.gpars' , module = 'gpars' , version = '0.9-SNAPSHOT' )
          )
          import groovyx.gpars.actor.Actors
          
          Show
          Russel Winder added a comment - - edited Yes it does. I am successfully using: @GrabResolver ( name = 'jboss' , root = 'http: //repository.jboss.org/maven2' ) def dummyA ( ) { } @GrabResolver ( name = 'codehaus.snapshot' , root = 'http: //snapshots.repository.codehaus.org' ) def dummyB ( ) { } @Grab ( group = 'org.codehaus.gpars' , module = 'gpars' , version = '0.9-SNAPSHOT' ) import groovyx.gpars.actor.Actors but this workaround really makes me want to . . . , well let's leave it unsaid. I think that whatever fix is needed to make to following work really does need putting in place: @Grapes ( @GrabResolver ( name = 'jboss' , root = 'http: //repository.jboss.org/maven2' ) , @GrabResolver ( name = 'codehaus.snapshot' , root = 'http: //snapshots.repository.codehaus.org' ) , @Grab ( group = 'org.codehaus.gpars' , module = 'gpars' , version = '0.9-SNAPSHOT' ) ) import groovyx.gpars.actor.Actors
          Hide
          Tim Yates added a comment -

          I'm 99.8% sure you can use @Grab on an import

          Show
          Tim Yates added a comment - I'm 99.8% sure you can use @Grab on an import
          Hide
          Roshan Dawrani added a comment -

          Also both @Grab and @GrabResolver do not support being specified on import statements

          @Grab/@GrabResolver targets :- CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PARAMETER, TYPE

          So, as far as I understand, the whole behavior is as designed.

          If I see http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/ElementType.html, I don't
          even see any support in JDK for import statements being the target of annotations.

          The only thing to do that is coming out of this JIRA is that there should be a @GrabResolvers and that
          would be a new feature request, I guess.

          Show
          Roshan Dawrani added a comment - Also both @Grab and @GrabResolver do not support being specified on import statements @Grab/@GrabResolver targets :- CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PARAMETER, TYPE So, as far as I understand, the whole behavior is as designed. If I see http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/ElementType.html , I don't even see any support in JDK for import statements being the target of annotations. The only thing to do that is coming out of this JIRA is that there should be a @GrabResolvers and that would be a new feature request, I guess.
          Hide
          Roshan Dawrani added a comment -

          Disallowing duplicate annotations of the same type on one element was done under GROOVY-3852,
          because when done, JVM starts having AnnotationFormatError issues at runtime when annotations
          are accessed.

          Some links about JVM not handling multiple annotations of the same type on same element:

          1)http://stackoverflow.com/questions/1554112/multiple-annotations-of-the-same-type-on-one-element
          2)http://www.docjar.com/html/api/sun/reflect/annotation/AnnotationParser.java.html

          If multiple GrabResolver make sense, then what is needed is a new annotation @GrabResolvers
          that can handle multiple GrabResolver entries.

          Show
          Roshan Dawrani added a comment - Disallowing duplicate annotations of the same type on one element was done under GROOVY-3852 , because when done, JVM starts having AnnotationFormatError issues at runtime when annotations are accessed. Some links about JVM not handling multiple annotations of the same type on same element: 1) http://stackoverflow.com/questions/1554112/multiple-annotations-of-the-same-type-on-one-element 2) http://www.docjar.com/html/api/sun/reflect/annotation/AnnotationParser.java.html If multiple GrabResolver make sense, then what is needed is a new annotation @GrabResolvers that can handle multiple GrabResolver entries.

            People

            • Assignee:
              Paul King
              Reporter:
              Tim Yates
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development