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?
groovy
migrated from superuser.com Dec 7 at 2:12
This question came from our site for computer enthusiasts and power users.
add a comment |
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?
groovy
migrated from superuser.com Dec 7 at 2:12
This question came from our site for computer enthusiasts and power users.
add a comment |
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?
groovy
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
groovy
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.
add a comment |
add a comment |
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 inExample.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 classmain()
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 staticmain()
method, and it executes it.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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 inExample.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 classmain()
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 staticmain()
method, and it executes it.
add a comment |
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 inExample.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 classmain()
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 staticmain()
method, and it executes it.
add a comment |
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 inExample.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 classmain()
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 staticmain()
method, and it executes it.
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 inExample.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 classmain()
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 staticmain()
method, and it executes it.
edited Dec 7 at 10:08
answered Dec 7 at 9:46
Szymon Stepniak
16.5k83062
16.5k83062
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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