[ 
https://issues.apache.org/jira/browse/GROOVY-7896?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15403584#comment-15403584
 ] 

Jochen Theodorou commented on GROOVY-7896:
------------------------------------------

I don't remember too clearly, so it would have to be confirmed, but afaik the 
grab annotation adds code to the static initializer to cause the download of 
the probably missing jars. This code will also add the extension module. Adding 
the extension module may cause the initialization of classes, but surely means 
the loading of further classes. If you start the program without grab, this can 
very well happen much later. For example if you did not define a static 
initializer, that calls a method, you will probably not get that meta class 
init process executed there. Even in the constructor this may not happen yet. I 
would suggest to dump a stacktrace once initialize is called to see where the 
first call is coming from

> Grape `@Grab` annotation calls zero-arg methods when installing jar with 
> extension module
> -----------------------------------------------------------------------------------------
>
>                 Key: GROOVY-7896
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7896
>             Project: Groovy
>          Issue Type: Bug
>          Components: Grape
>    Affects Versions: 2.4.7
>            Reporter: Ted Naleid
>
> 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:
> {code:title=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;
>     }
> }
> {code}
> and this in resources so it's registered:
> {code:title=META-INF/services/org.codehaus.groovy.runtime.ExtensionModule}
> moduleName=string-ext
> moduleVersion=
> extensionClasses=com.naleid.groovybug.StringExtensions
> {code}
> 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:
> {code:title=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!"
> {code}
> it fails with
> {code}
> 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)
> {code}
> If I remove the {{@Grab}} annotation and instead refer to the jar file via 
> the classpath, it works fine:
> {code}
> groovy -classpath 
> ~/.m2/repository/groovybug/groovybug-ext/1.0/groovybug-ext-1.0.jar 
> demoWorking.groovy
> initialized
> success!
> {code}
> 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: 
> {code:title=ratpackTest.groovy}
> @Grab('io.ratpack:ratpack-rx:1.3.3')
> import ratpack.rx.RxRatpack
> RxRatpack.initialize()
> {code}
> The {{initialize()}} blows up if it has already been called.
> {code}
> 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)
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to