Why does Groovy not execute a class in a program if there is a line of code outside the class?











up vote
1
down vote

favorite












Groovy Version: 2.4.5 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux



I have tried two versions of my Groovy program. The class "Example" runs if I have nothing else in the program (e.g., no 'println "Test"').



Why does the Example class not run if I have a "println" statement?



class Example {
static void main(String args) {
def clos = {println "Hello World"};
clos.call();
}
}

println "Test"


I expect the above program to print this when it is run:




Hello World



Test




Why does the class not execute when there is another line outside of it?










share|improve this question















migrated from superuser.com Dec 7 at 2:12


This question came from our site for computer enthusiasts and power users.



















    up vote
    1
    down vote

    favorite












    Groovy Version: 2.4.5 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux



    I have tried two versions of my Groovy program. The class "Example" runs if I have nothing else in the program (e.g., no 'println "Test"').



    Why does the Example class not run if I have a "println" statement?



    class Example {
    static void main(String args) {
    def clos = {println "Hello World"};
    clos.call();
    }
    }

    println "Test"


    I expect the above program to print this when it is run:




    Hello World



    Test




    Why does the class not execute when there is another line outside of it?










    share|improve this question















    migrated from superuser.com Dec 7 at 2:12


    This question came from our site for computer enthusiasts and power users.

















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      Groovy Version: 2.4.5 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux



      I have tried two versions of my Groovy program. The class "Example" runs if I have nothing else in the program (e.g., no 'println "Test"').



      Why does the Example class not run if I have a "println" statement?



      class Example {
      static void main(String args) {
      def clos = {println "Hello World"};
      clos.call();
      }
      }

      println "Test"


      I expect the above program to print this when it is run:




      Hello World



      Test




      Why does the class not execute when there is another line outside of it?










      share|improve this question















      Groovy Version: 2.4.5 JVM: 1.8.0_151 Vendor: Oracle Corporation OS: Linux



      I have tried two versions of my Groovy program. The class "Example" runs if I have nothing else in the program (e.g., no 'println "Test"').



      Why does the Example class not run if I have a "println" statement?



      class Example {
      static void main(String args) {
      def clos = {println "Hello World"};
      clos.call();
      }
      }

      println "Test"


      I expect the above program to print this when it is run:




      Hello World



      Test




      Why does the class not execute when there is another line outside of it?







      groovy






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 7 at 9:46









      Szymon Stepniak

      16.5k83062




      16.5k83062










      asked Dec 7 at 2:05









      Jermoe

      113




      113




      migrated from superuser.com Dec 7 at 2:12


      This question came from our site for computer enthusiasts and power users.






      migrated from superuser.com Dec 7 at 2:12


      This question came from our site for computer enthusiasts and power users.


























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote













          You need to be aware of a few things. When you create a script (let's call it someScript.groovy) with the following content:



          #!groovy

          println "Test"

          println 21 + 21


          it gets compiled to the following class:



          //
          // Source code recreated from a .class file by IntelliJ IDEA
          // (powered by Fernflower decompiler)
          //

          import groovy.lang.Binding;
          import groovy.lang.Script;
          import org.codehaus.groovy.runtime.InvokerHelper;

          public class someScript extends Script {
          public someScript() {
          }

          public someScript(Binding context) {
          super(context);
          }

          public static void main(String... args) {
          InvokerHelper.runScript(someScript.class, args);
          }

          public Object run() {
          ((someScript)this).println("Test");
          Object var10000 = null;
          ((someScript)this).println(21 + 21);
          return null;
          }
          }


          As you can see, the body of the Groovy script is represented as a method run() in the generated class. When we add a class to this script, let's say the Example class from your question, the body of run() method does not change at all - the class gets compiled to an Example.class bytecode file and that's it:



          //
          // Source code recreated from a .class file by IntelliJ IDEA
          // (powered by Fernflower decompiler)
          //

          import groovy.lang.Closure;
          import groovy.lang.GroovyObject;
          import groovy.lang.MetaClass;
          import org.codehaus.groovy.runtime.DefaultGroovyMethods;
          import org.codehaus.groovy.runtime.GeneratedClosure;

          public class Example implements GroovyObject {
          public Example() {
          MetaClass var1 = this.$getStaticMetaClass();
          this.metaClass = var1;
          }

          public static void main(String... args) {
          class _main_closure1 extends Closure implements GeneratedClosure {
          public _main_closure1(Object _outerInstance, Object _thisObject) {
          super(_outerInstance, _thisObject);
          }

          public Object doCall(Object it) {
          DefaultGroovyMethods.println(Example.class, "Hello World");
          return null;
          }

          public Object call(Object args) {
          return this.doCall(args);
          }

          public Object call() {
          return this.doCall((Object)null);
          }

          public Object doCall() {
          return this.doCall((Object)null);
          }
          }

          Closure clos = new _main_closure1(Example.class, Example.class);
          clos.call();
          }
          }


          When we run Groovy compiler to compile someScript.groovy (groovyc someScript.groovy) and we list generated classes we will see something like this:



          ls -lh *.class
          -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:26 Example.class
          -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:26 'Example$_main_closure1.class'
          -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:26 someScript.class



          NOTE: this Example$_main_closure1.class represents a closure used in Example.main() method




          Now, let's see what happens if we comment (or remove) println statements from the someScript.groovy file and we compile it:



          someScript.groovy



          #!groovy

          class Example {
          static void main(String args) {
          def clos = {println "Hello World"};
          clos.call();
          }
          }

          //println "Test"
          //
          //println 21 + 21


          Compile time:



          > groovyc someScript.groovy

          > ls -lh *.class
          -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:31 Example.class
          -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:31 'Example$_main_closure1.class'


          As you can see, there is no someScript.class class file generated. It happens because the script file we just compiled does not contain any body, but it has the Example class inside. When you run such script Groovy tries to locate the first static main() method to execute it - that is why running the following script produces Hello World output:



          > groovy someScript.groovy 
          Hello World


          Let's go further and add another class on top of the someScript.groovy file:



          someScript.groovy



          #!groovy 

          class Foo {
          static void main(String args) {
          println "Bar"
          }
          }


          class Example {
          static void main(String args) {
          def clos = {println "Hello World"};
          clos.call();
          }
          }

          //println "Test"
          //
          //println 21 + 21


          The body of the script is still commented out. Let's compile and see what class files get generated:



          > groovyc someScript.groovy

          > ls -lh *.class
          -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:35 Example.class
          -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:35 'Example$_main_closure1.class'
          -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:35 Foo.class


          We can see 3 class files, just as expected. Let's see what happens if we run the script with groovy command:



          > groovy someScript.groovy                             
          Bar


          Now as you can see the Foo.main() method got executed because Groovy located this method on top of the script file and it assumed that this is the main method we want to run.



          Let's finalize this with the example containing two classes and script body:



          someScript.groovy



          #!groovy

          class Foo {
          static void main(String args) {
          println "Bar"
          }
          }


          class Example {
          static void main(String args) {
          def clos = {println "Hello World"};
          clos.call();
          }
          }

          println "Test"

          println 21 + 21


          Compile time:



          > groovyc someScript.groovy

          > ls -lh *.class
          -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:39 Example.class
          -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:39 'Example$_main_closure1.class'
          -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:39 Foo.class
          -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:39 someScript.class


          This time a class someScript got generated because the script body is not empty. Last look at the generated someScript.class file:



          //
          // Source code recreated from a .class file by IntelliJ IDEA
          // (powered by Fernflower decompiler)
          //

          import groovy.lang.Binding;
          import groovy.lang.Script;
          import org.codehaus.groovy.runtime.InvokerHelper;

          public class someScript extends Script {
          public someScript() {
          }

          public someScript(Binding context) {
          super(context);
          }

          public static void main(String... args) {
          InvokerHelper.runScript(someScript.class, args);
          }

          public Object run() {
          ((someScript)this).println("Test");
          Object var10000 = null;
          ((someScript)this).println(21 + 21);
          return null;
          }
          }


          As you can see it didn't change compared to our first example (when there were no classes inside the script, but only two println statements), so we can't expect anything else than running someScript.run() method to happen. Let's run the script:



          > groovy someScript.groovy
          Test
          42


          Conclusion




          • When you create a Groovy script its body gets moved and compiled as scriptName.run() method, and it gets executed.

          • If you add a class with a main() method to a Groovy script and you keep script body, added class main() method won't get executed - it only compiles the class, and you can use it explicitly in your script body if needed.

          • If you add a class with a main() method to a Groovy script and you don't put any script body (any statements/expressions outside the class) then Groovy searches for the first static main() method, and it executes it.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53662303%2fwhy-does-groovy-not-execute-a-class-in-a-program-if-there-is-a-line-of-code-outs%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            4
            down vote













            You need to be aware of a few things. When you create a script (let's call it someScript.groovy) with the following content:



            #!groovy

            println "Test"

            println 21 + 21


            it gets compiled to the following class:



            //
            // Source code recreated from a .class file by IntelliJ IDEA
            // (powered by Fernflower decompiler)
            //

            import groovy.lang.Binding;
            import groovy.lang.Script;
            import org.codehaus.groovy.runtime.InvokerHelper;

            public class someScript extends Script {
            public someScript() {
            }

            public someScript(Binding context) {
            super(context);
            }

            public static void main(String... args) {
            InvokerHelper.runScript(someScript.class, args);
            }

            public Object run() {
            ((someScript)this).println("Test");
            Object var10000 = null;
            ((someScript)this).println(21 + 21);
            return null;
            }
            }


            As you can see, the body of the Groovy script is represented as a method run() in the generated class. When we add a class to this script, let's say the Example class from your question, the body of run() method does not change at all - the class gets compiled to an Example.class bytecode file and that's it:



            //
            // Source code recreated from a .class file by IntelliJ IDEA
            // (powered by Fernflower decompiler)
            //

            import groovy.lang.Closure;
            import groovy.lang.GroovyObject;
            import groovy.lang.MetaClass;
            import org.codehaus.groovy.runtime.DefaultGroovyMethods;
            import org.codehaus.groovy.runtime.GeneratedClosure;

            public class Example implements GroovyObject {
            public Example() {
            MetaClass var1 = this.$getStaticMetaClass();
            this.metaClass = var1;
            }

            public static void main(String... args) {
            class _main_closure1 extends Closure implements GeneratedClosure {
            public _main_closure1(Object _outerInstance, Object _thisObject) {
            super(_outerInstance, _thisObject);
            }

            public Object doCall(Object it) {
            DefaultGroovyMethods.println(Example.class, "Hello World");
            return null;
            }

            public Object call(Object args) {
            return this.doCall(args);
            }

            public Object call() {
            return this.doCall((Object)null);
            }

            public Object doCall() {
            return this.doCall((Object)null);
            }
            }

            Closure clos = new _main_closure1(Example.class, Example.class);
            clos.call();
            }
            }


            When we run Groovy compiler to compile someScript.groovy (groovyc someScript.groovy) and we list generated classes we will see something like this:



            ls -lh *.class
            -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:26 Example.class
            -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:26 'Example$_main_closure1.class'
            -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:26 someScript.class



            NOTE: this Example$_main_closure1.class represents a closure used in Example.main() method




            Now, let's see what happens if we comment (or remove) println statements from the someScript.groovy file and we compile it:



            someScript.groovy



            #!groovy

            class Example {
            static void main(String args) {
            def clos = {println "Hello World"};
            clos.call();
            }
            }

            //println "Test"
            //
            //println 21 + 21


            Compile time:



            > groovyc someScript.groovy

            > ls -lh *.class
            -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:31 Example.class
            -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:31 'Example$_main_closure1.class'


            As you can see, there is no someScript.class class file generated. It happens because the script file we just compiled does not contain any body, but it has the Example class inside. When you run such script Groovy tries to locate the first static main() method to execute it - that is why running the following script produces Hello World output:



            > groovy someScript.groovy 
            Hello World


            Let's go further and add another class on top of the someScript.groovy file:



            someScript.groovy



            #!groovy 

            class Foo {
            static void main(String args) {
            println "Bar"
            }
            }


            class Example {
            static void main(String args) {
            def clos = {println "Hello World"};
            clos.call();
            }
            }

            //println "Test"
            //
            //println 21 + 21


            The body of the script is still commented out. Let's compile and see what class files get generated:



            > groovyc someScript.groovy

            > ls -lh *.class
            -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:35 Example.class
            -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:35 'Example$_main_closure1.class'
            -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:35 Foo.class


            We can see 3 class files, just as expected. Let's see what happens if we run the script with groovy command:



            > groovy someScript.groovy                             
            Bar


            Now as you can see the Foo.main() method got executed because Groovy located this method on top of the script file and it assumed that this is the main method we want to run.



            Let's finalize this with the example containing two classes and script body:



            someScript.groovy



            #!groovy

            class Foo {
            static void main(String args) {
            println "Bar"
            }
            }


            class Example {
            static void main(String args) {
            def clos = {println "Hello World"};
            clos.call();
            }
            }

            println "Test"

            println 21 + 21


            Compile time:



            > groovyc someScript.groovy

            > ls -lh *.class
            -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:39 Example.class
            -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:39 'Example$_main_closure1.class'
            -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:39 Foo.class
            -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:39 someScript.class


            This time a class someScript got generated because the script body is not empty. Last look at the generated someScript.class file:



            //
            // Source code recreated from a .class file by IntelliJ IDEA
            // (powered by Fernflower decompiler)
            //

            import groovy.lang.Binding;
            import groovy.lang.Script;
            import org.codehaus.groovy.runtime.InvokerHelper;

            public class someScript extends Script {
            public someScript() {
            }

            public someScript(Binding context) {
            super(context);
            }

            public static void main(String... args) {
            InvokerHelper.runScript(someScript.class, args);
            }

            public Object run() {
            ((someScript)this).println("Test");
            Object var10000 = null;
            ((someScript)this).println(21 + 21);
            return null;
            }
            }


            As you can see it didn't change compared to our first example (when there were no classes inside the script, but only two println statements), so we can't expect anything else than running someScript.run() method to happen. Let's run the script:



            > groovy someScript.groovy
            Test
            42


            Conclusion




            • When you create a Groovy script its body gets moved and compiled as scriptName.run() method, and it gets executed.

            • If you add a class with a main() method to a Groovy script and you keep script body, added class main() method won't get executed - it only compiles the class, and you can use it explicitly in your script body if needed.

            • If you add a class with a main() method to a Groovy script and you don't put any script body (any statements/expressions outside the class) then Groovy searches for the first static main() method, and it executes it.






            share|improve this answer



























              up vote
              4
              down vote













              You need to be aware of a few things. When you create a script (let's call it someScript.groovy) with the following content:



              #!groovy

              println "Test"

              println 21 + 21


              it gets compiled to the following class:



              //
              // Source code recreated from a .class file by IntelliJ IDEA
              // (powered by Fernflower decompiler)
              //

              import groovy.lang.Binding;
              import groovy.lang.Script;
              import org.codehaus.groovy.runtime.InvokerHelper;

              public class someScript extends Script {
              public someScript() {
              }

              public someScript(Binding context) {
              super(context);
              }

              public static void main(String... args) {
              InvokerHelper.runScript(someScript.class, args);
              }

              public Object run() {
              ((someScript)this).println("Test");
              Object var10000 = null;
              ((someScript)this).println(21 + 21);
              return null;
              }
              }


              As you can see, the body of the Groovy script is represented as a method run() in the generated class. When we add a class to this script, let's say the Example class from your question, the body of run() method does not change at all - the class gets compiled to an Example.class bytecode file and that's it:



              //
              // Source code recreated from a .class file by IntelliJ IDEA
              // (powered by Fernflower decompiler)
              //

              import groovy.lang.Closure;
              import groovy.lang.GroovyObject;
              import groovy.lang.MetaClass;
              import org.codehaus.groovy.runtime.DefaultGroovyMethods;
              import org.codehaus.groovy.runtime.GeneratedClosure;

              public class Example implements GroovyObject {
              public Example() {
              MetaClass var1 = this.$getStaticMetaClass();
              this.metaClass = var1;
              }

              public static void main(String... args) {
              class _main_closure1 extends Closure implements GeneratedClosure {
              public _main_closure1(Object _outerInstance, Object _thisObject) {
              super(_outerInstance, _thisObject);
              }

              public Object doCall(Object it) {
              DefaultGroovyMethods.println(Example.class, "Hello World");
              return null;
              }

              public Object call(Object args) {
              return this.doCall(args);
              }

              public Object call() {
              return this.doCall((Object)null);
              }

              public Object doCall() {
              return this.doCall((Object)null);
              }
              }

              Closure clos = new _main_closure1(Example.class, Example.class);
              clos.call();
              }
              }


              When we run Groovy compiler to compile someScript.groovy (groovyc someScript.groovy) and we list generated classes we will see something like this:



              ls -lh *.class
              -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:26 Example.class
              -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:26 'Example$_main_closure1.class'
              -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:26 someScript.class



              NOTE: this Example$_main_closure1.class represents a closure used in Example.main() method




              Now, let's see what happens if we comment (or remove) println statements from the someScript.groovy file and we compile it:



              someScript.groovy



              #!groovy

              class Example {
              static void main(String args) {
              def clos = {println "Hello World"};
              clos.call();
              }
              }

              //println "Test"
              //
              //println 21 + 21


              Compile time:



              > groovyc someScript.groovy

              > ls -lh *.class
              -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:31 Example.class
              -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:31 'Example$_main_closure1.class'


              As you can see, there is no someScript.class class file generated. It happens because the script file we just compiled does not contain any body, but it has the Example class inside. When you run such script Groovy tries to locate the first static main() method to execute it - that is why running the following script produces Hello World output:



              > groovy someScript.groovy 
              Hello World


              Let's go further and add another class on top of the someScript.groovy file:



              someScript.groovy



              #!groovy 

              class Foo {
              static void main(String args) {
              println "Bar"
              }
              }


              class Example {
              static void main(String args) {
              def clos = {println "Hello World"};
              clos.call();
              }
              }

              //println "Test"
              //
              //println 21 + 21


              The body of the script is still commented out. Let's compile and see what class files get generated:



              > groovyc someScript.groovy

              > ls -lh *.class
              -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:35 Example.class
              -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:35 'Example$_main_closure1.class'
              -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:35 Foo.class


              We can see 3 class files, just as expected. Let's see what happens if we run the script with groovy command:



              > groovy someScript.groovy                             
              Bar


              Now as you can see the Foo.main() method got executed because Groovy located this method on top of the script file and it assumed that this is the main method we want to run.



              Let's finalize this with the example containing two classes and script body:



              someScript.groovy



              #!groovy

              class Foo {
              static void main(String args) {
              println "Bar"
              }
              }


              class Example {
              static void main(String args) {
              def clos = {println "Hello World"};
              clos.call();
              }
              }

              println "Test"

              println 21 + 21


              Compile time:



              > groovyc someScript.groovy

              > ls -lh *.class
              -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:39 Example.class
              -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:39 'Example$_main_closure1.class'
              -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:39 Foo.class
              -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:39 someScript.class


              This time a class someScript got generated because the script body is not empty. Last look at the generated someScript.class file:



              //
              // Source code recreated from a .class file by IntelliJ IDEA
              // (powered by Fernflower decompiler)
              //

              import groovy.lang.Binding;
              import groovy.lang.Script;
              import org.codehaus.groovy.runtime.InvokerHelper;

              public class someScript extends Script {
              public someScript() {
              }

              public someScript(Binding context) {
              super(context);
              }

              public static void main(String... args) {
              InvokerHelper.runScript(someScript.class, args);
              }

              public Object run() {
              ((someScript)this).println("Test");
              Object var10000 = null;
              ((someScript)this).println(21 + 21);
              return null;
              }
              }


              As you can see it didn't change compared to our first example (when there were no classes inside the script, but only two println statements), so we can't expect anything else than running someScript.run() method to happen. Let's run the script:



              > groovy someScript.groovy
              Test
              42


              Conclusion




              • When you create a Groovy script its body gets moved and compiled as scriptName.run() method, and it gets executed.

              • If you add a class with a main() method to a Groovy script and you keep script body, added class main() method won't get executed - it only compiles the class, and you can use it explicitly in your script body if needed.

              • If you add a class with a main() method to a Groovy script and you don't put any script body (any statements/expressions outside the class) then Groovy searches for the first static main() method, and it executes it.






              share|improve this answer

























                up vote
                4
                down vote










                up vote
                4
                down vote









                You need to be aware of a few things. When you create a script (let's call it someScript.groovy) with the following content:



                #!groovy

                println "Test"

                println 21 + 21


                it gets compiled to the following class:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Binding;
                import groovy.lang.Script;
                import org.codehaus.groovy.runtime.InvokerHelper;

                public class someScript extends Script {
                public someScript() {
                }

                public someScript(Binding context) {
                super(context);
                }

                public static void main(String... args) {
                InvokerHelper.runScript(someScript.class, args);
                }

                public Object run() {
                ((someScript)this).println("Test");
                Object var10000 = null;
                ((someScript)this).println(21 + 21);
                return null;
                }
                }


                As you can see, the body of the Groovy script is represented as a method run() in the generated class. When we add a class to this script, let's say the Example class from your question, the body of run() method does not change at all - the class gets compiled to an Example.class bytecode file and that's it:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Closure;
                import groovy.lang.GroovyObject;
                import groovy.lang.MetaClass;
                import org.codehaus.groovy.runtime.DefaultGroovyMethods;
                import org.codehaus.groovy.runtime.GeneratedClosure;

                public class Example implements GroovyObject {
                public Example() {
                MetaClass var1 = this.$getStaticMetaClass();
                this.metaClass = var1;
                }

                public static void main(String... args) {
                class _main_closure1 extends Closure implements GeneratedClosure {
                public _main_closure1(Object _outerInstance, Object _thisObject) {
                super(_outerInstance, _thisObject);
                }

                public Object doCall(Object it) {
                DefaultGroovyMethods.println(Example.class, "Hello World");
                return null;
                }

                public Object call(Object args) {
                return this.doCall(args);
                }

                public Object call() {
                return this.doCall((Object)null);
                }

                public Object doCall() {
                return this.doCall((Object)null);
                }
                }

                Closure clos = new _main_closure1(Example.class, Example.class);
                clos.call();
                }
                }


                When we run Groovy compiler to compile someScript.groovy (groovyc someScript.groovy) and we list generated classes we will see something like this:



                ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:26 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:26 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:26 someScript.class



                NOTE: this Example$_main_closure1.class represents a closure used in Example.main() method




                Now, let's see what happens if we comment (or remove) println statements from the someScript.groovy file and we compile it:



                someScript.groovy



                #!groovy

                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                //println "Test"
                //
                //println 21 + 21


                Compile time:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:31 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:31 'Example$_main_closure1.class'


                As you can see, there is no someScript.class class file generated. It happens because the script file we just compiled does not contain any body, but it has the Example class inside. When you run such script Groovy tries to locate the first static main() method to execute it - that is why running the following script produces Hello World output:



                > groovy someScript.groovy 
                Hello World


                Let's go further and add another class on top of the someScript.groovy file:



                someScript.groovy



                #!groovy 

                class Foo {
                static void main(String args) {
                println "Bar"
                }
                }


                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                //println "Test"
                //
                //println 21 + 21


                The body of the script is still commented out. Let's compile and see what class files get generated:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:35 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:35 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:35 Foo.class


                We can see 3 class files, just as expected. Let's see what happens if we run the script with groovy command:



                > groovy someScript.groovy                             
                Bar


                Now as you can see the Foo.main() method got executed because Groovy located this method on top of the script file and it assumed that this is the main method we want to run.



                Let's finalize this with the example containing two classes and script body:



                someScript.groovy



                #!groovy

                class Foo {
                static void main(String args) {
                println "Bar"
                }
                }


                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                println "Test"

                println 21 + 21


                Compile time:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:39 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:39 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:39 Foo.class
                -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:39 someScript.class


                This time a class someScript got generated because the script body is not empty. Last look at the generated someScript.class file:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Binding;
                import groovy.lang.Script;
                import org.codehaus.groovy.runtime.InvokerHelper;

                public class someScript extends Script {
                public someScript() {
                }

                public someScript(Binding context) {
                super(context);
                }

                public static void main(String... args) {
                InvokerHelper.runScript(someScript.class, args);
                }

                public Object run() {
                ((someScript)this).println("Test");
                Object var10000 = null;
                ((someScript)this).println(21 + 21);
                return null;
                }
                }


                As you can see it didn't change compared to our first example (when there were no classes inside the script, but only two println statements), so we can't expect anything else than running someScript.run() method to happen. Let's run the script:



                > groovy someScript.groovy
                Test
                42


                Conclusion




                • When you create a Groovy script its body gets moved and compiled as scriptName.run() method, and it gets executed.

                • If you add a class with a main() method to a Groovy script and you keep script body, added class main() method won't get executed - it only compiles the class, and you can use it explicitly in your script body if needed.

                • If you add a class with a main() method to a Groovy script and you don't put any script body (any statements/expressions outside the class) then Groovy searches for the first static main() method, and it executes it.






                share|improve this answer














                You need to be aware of a few things. When you create a script (let's call it someScript.groovy) with the following content:



                #!groovy

                println "Test"

                println 21 + 21


                it gets compiled to the following class:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Binding;
                import groovy.lang.Script;
                import org.codehaus.groovy.runtime.InvokerHelper;

                public class someScript extends Script {
                public someScript() {
                }

                public someScript(Binding context) {
                super(context);
                }

                public static void main(String... args) {
                InvokerHelper.runScript(someScript.class, args);
                }

                public Object run() {
                ((someScript)this).println("Test");
                Object var10000 = null;
                ((someScript)this).println(21 + 21);
                return null;
                }
                }


                As you can see, the body of the Groovy script is represented as a method run() in the generated class. When we add a class to this script, let's say the Example class from your question, the body of run() method does not change at all - the class gets compiled to an Example.class bytecode file and that's it:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Closure;
                import groovy.lang.GroovyObject;
                import groovy.lang.MetaClass;
                import org.codehaus.groovy.runtime.DefaultGroovyMethods;
                import org.codehaus.groovy.runtime.GeneratedClosure;

                public class Example implements GroovyObject {
                public Example() {
                MetaClass var1 = this.$getStaticMetaClass();
                this.metaClass = var1;
                }

                public static void main(String... args) {
                class _main_closure1 extends Closure implements GeneratedClosure {
                public _main_closure1(Object _outerInstance, Object _thisObject) {
                super(_outerInstance, _thisObject);
                }

                public Object doCall(Object it) {
                DefaultGroovyMethods.println(Example.class, "Hello World");
                return null;
                }

                public Object call(Object args) {
                return this.doCall(args);
                }

                public Object call() {
                return this.doCall((Object)null);
                }

                public Object doCall() {
                return this.doCall((Object)null);
                }
                }

                Closure clos = new _main_closure1(Example.class, Example.class);
                clos.call();
                }
                }


                When we run Groovy compiler to compile someScript.groovy (groovyc someScript.groovy) and we list generated classes we will see something like this:



                ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:26 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:26 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:26 someScript.class



                NOTE: this Example$_main_closure1.class represents a closure used in Example.main() method




                Now, let's see what happens if we comment (or remove) println statements from the someScript.groovy file and we compile it:



                someScript.groovy



                #!groovy

                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                //println "Test"
                //
                //println 21 + 21


                Compile time:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:31 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:31 'Example$_main_closure1.class'


                As you can see, there is no someScript.class class file generated. It happens because the script file we just compiled does not contain any body, but it has the Example class inside. When you run such script Groovy tries to locate the first static main() method to execute it - that is why running the following script produces Hello World output:



                > groovy someScript.groovy 
                Hello World


                Let's go further and add another class on top of the someScript.groovy file:



                someScript.groovy



                #!groovy 

                class Foo {
                static void main(String args) {
                println "Bar"
                }
                }


                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                //println "Test"
                //
                //println 21 + 21


                The body of the script is still commented out. Let's compile and see what class files get generated:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:35 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:35 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:35 Foo.class


                We can see 3 class files, just as expected. Let's see what happens if we run the script with groovy command:



                > groovy someScript.groovy                             
                Bar


                Now as you can see the Foo.main() method got executed because Groovy located this method on top of the script file and it assumed that this is the main method we want to run.



                Let's finalize this with the example containing two classes and script body:



                someScript.groovy



                #!groovy

                class Foo {
                static void main(String args) {
                println "Bar"
                }
                }


                class Example {
                static void main(String args) {
                def clos = {println "Hello World"};
                clos.call();
                }
                }

                println "Test"

                println 21 + 21


                Compile time:



                > groovyc someScript.groovy

                > ls -lh *.class
                -rw-rw-r--. 1 wololock wololock 2,0K 12-07 10:39 Example.class
                -rw-rw-r--. 1 wololock wololock 1,6K 12-07 10:39 'Example$_main_closure1.class'
                -rw-rw-r--. 1 wololock wololock 1,8K 12-07 10:39 Foo.class
                -rw-rw-r--. 1 wololock wololock 1,4K 12-07 10:39 someScript.class


                This time a class someScript got generated because the script body is not empty. Last look at the generated someScript.class file:



                //
                // Source code recreated from a .class file by IntelliJ IDEA
                // (powered by Fernflower decompiler)
                //

                import groovy.lang.Binding;
                import groovy.lang.Script;
                import org.codehaus.groovy.runtime.InvokerHelper;

                public class someScript extends Script {
                public someScript() {
                }

                public someScript(Binding context) {
                super(context);
                }

                public static void main(String... args) {
                InvokerHelper.runScript(someScript.class, args);
                }

                public Object run() {
                ((someScript)this).println("Test");
                Object var10000 = null;
                ((someScript)this).println(21 + 21);
                return null;
                }
                }


                As you can see it didn't change compared to our first example (when there were no classes inside the script, but only two println statements), so we can't expect anything else than running someScript.run() method to happen. Let's run the script:



                > groovy someScript.groovy
                Test
                42


                Conclusion




                • When you create a Groovy script its body gets moved and compiled as scriptName.run() method, and it gets executed.

                • If you add a class with a main() method to a Groovy script and you keep script body, added class main() method won't get executed - it only compiles the class, and you can use it explicitly in your script body if needed.

                • If you add a class with a main() method to a Groovy script and you don't put any script body (any statements/expressions outside the class) then Groovy searches for the first static main() method, and it executes it.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Dec 7 at 10:08

























                answered Dec 7 at 9:46









                Szymon Stepniak

                16.5k83062




                16.5k83062






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53662303%2fwhy-does-groovy-not-execute-a-class-in-a-program-if-there-is-a-line-of-code-outs%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Probability when a professor distributes a quiz and homework assignment to a class of n students.

                    Aardman Animations

                    Are they similar matrix