Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7896

Grape `@Grab` annotation calls zero-arg methods when installing jar with extension module

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Invalid
    • 2.4.7
    • None
    • Grape
    • None

    Description

      When using @Grab annotation and loading a jar file that extends classes via extension modules, it appears that it is silently calling zero-arg methods on the extension class.

      I've created a test project that shows this issue: https://github.com/tednaleid/groovybug-ext

      Here's the detail. If I have a class that extends String and also has a zero-arg initialize() method that's meant to be called by the user:

      com/naleid/groovybug/StringExtensions.java
      package com.naleid.groovybug;
      
      public abstract class StringExtensions {
      
          private static String append = null;
      
          private StringExtensions() { }
      
          public static void initialize() {
              System.out.println("initialized");
              if (append != null) {
                  throw new RuntimeException("Already initialized");
              }
              append = "foo";
          }
      
          public static String appendFoo(String self) {
              return self + append;
          }
      }
      

      and this in resources so it's registered:

      META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
      moduleName=string-ext
      moduleVersion=
      extensionClasses=com.naleid.groovybug.StringExtensions
      

      If I create a jar out of it, install it in my .m2 directory (linked gradle script does this with ./gradlew install and then run this script:

      demoBug.groovy
      @Grab('groovybug:groovybug-ext:1.0')
      
      import com.naleid.groovybug.StringExtensions
      
      assert "bar ".appendFoo() == "bar null"
      
      StringExtensions.initialize()
      
      assert "bar ".appendFoo() == "bar foo"
      
      println "success!"
      

      it fails with

      Caught: Assertion failed:
      
      assert "bar ".appendFoo() == "bar null"
                    |           |
                    bar foo     false
      
      Assertion failed:
      
      assert "bar ".appendFoo() == "bar null"
                    |           |
                    bar foo     false
      
      	at demoBug.run(demoBug.groovy:12)
      

      If I remove the @Grab annotation and instead refer to the jar file via the classpath, it works fine:

      groovy -classpath ~/.m2/repository/groovybug/groovybug-ext/1.0/groovybug-ext-1.0.jar demoWorking.groovy
      initialized
      success!
      

      The linked project demos the issue. Where I hit it in "real life" was using @Grab on a Ratpack application that has a RxRatpack.initialize() method. This method was already called and it was confusing to have this ratpack script fail:

      ratpackTest.groovy
      @Grab('io.ratpack:ratpack-rx:1.3.3')
      
      import ratpack.rx.RxRatpack
      RxRatpack.initialize()
      

      The initialize() blows up if it has already been called.

      java.lang.IllegalStateException: Cannot install RxJava integration because another execution hook (class rx.plugins.RxJavaObservableExecutionHookDefault) is already installed
      	at ratpack.rx.RxRatpack.initialize(RxRatpack.java:102)
      	at ratpack.rx.RxRatpack$initialize.call(Unknown Source)
      	at ConsoleScript0.run(ConsoleScript0:5)
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            tednaleid Ted Naleid
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: