[ https://issues.apache.org/jira/browse/GROOVY-11154?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
jonny updated GROOVY-11154: --------------------------- Description: Prior to the fix for GROOVY-9857, subclasses of {{Script}} could have constructor arguments and still be used (with a little help from {{InheritConstructors}} and {{DefaultGroovyMethods#newInstance}}). For example, the following script executes find in Groovy 3.x, but fails after Groovy 4.0.7: {code} import groovy.transform.InheritConstructors import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.classgen.GeneratorContext import org.codehaus.groovy.control.CompilationFailedException import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.control.customizers.CompilationCustomizer import org.codehaus.groovy.runtime.DefaultGroovyMethods abstract class NamedScript extends Script { NamedScript(String name) { } } def compilerConfig = new CompilerConfiguration() compilerConfig.setScriptBaseClass(NamedScript.class.getName()) compilerConfig.addCompilationCustomizers(new CompilationCustomizer(CompilePhase.CONVERSION) { @Override void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { classNode.addAnnotation(new AnnotationNode(new ClassNode(InheritConstructors.class))) } }) def classLoader = new GroovyClassLoader(new GroovyClassLoader(), compilerConfig) def parsedClass = classLoader.parseClass('println "Foo"') DefaultGroovyMethods.newInstance(parsedClass, "dummy").run() {code} The error returned is: {noformat} Implicit super constructor NamedScript() is undefined for generated constructor. Must define an explicit constructor. {noformat} Ratpack relies on this behavior for its custom text template renderer. See how script objects are instantiated in the [ScriptEngine#create|https://github.com/ratpack/ratpack/blob/503060ab2351a49f6e96416d588607ff7ef63028/ratpack-groovy/src/main/java/ratpack/groovy/script/internal/ScriptEngine.java#L51] method. I talked this out in the Groovy community Slack with [~blackdrag] (see [thread|https://groovy-community.slack.com/archives/C2NEFCM55/p1691783910137829]), who suggested that we should skip the check for constructors for Script subclasses as a bugfix in Groovy 4, with a potentially breaking change in Groovy 5 to make constructor generation for Script subclasses happen in the same place as any other class. was: Prior to the fix for GROOVY-9857, subclasses of {{Script}} could have constructor arguments and still be used (with a little work). For example, the following script executes find in Groovy 3.x, but fails after Groovy 4.0.7: {code} import groovy.transform.InheritConstructors import org.codehaus.groovy.ast.AnnotationNode import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.classgen.GeneratorContext import org.codehaus.groovy.control.CompilationFailedException import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.control.customizers.CompilationCustomizer import org.codehaus.groovy.runtime.DefaultGroovyMethods abstract class NamedScript extends Script { NamedScript(String name) { } } def compilerConfig = new CompilerConfiguration() compilerConfig.setScriptBaseClass(NamedScript.class.getName()) compilerConfig.addCompilationCustomizers(new CompilationCustomizer(CompilePhase.CONVERSION) { @Override void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException { classNode.addAnnotation(new AnnotationNode(new ClassNode(InheritConstructors.class))) } }) def classLoader = new GroovyClassLoader(new GroovyClassLoader(), compilerConfig) def parsedClass = classLoader.parseClass('println "Foo"') DefaultGroovyMethods.newInstance(parsedClass, "dummy").run() {code} The error returned is: {noformat} Implicit super constructor NamedScript() is undefined for generated constructor. Must define an explicit constructor. {noformat} Ratpack relies on this behavior for its custom text template renderer. See how script objects are instantiated in the [ScriptEngine#create|https://github.com/ratpack/ratpack/blob/503060ab2351a49f6e96416d588607ff7ef63028/ratpack-groovy/src/main/java/ratpack/groovy/script/internal/ScriptEngine.java#L51] method. I talked this out in the Groovy community Slack with [~blackdrag] (see [thread|https://groovy-community.slack.com/archives/C2NEFCM55/p1691783910137829]), who suggested that we should skip the check for constructors for Script subclasses as a bugfix in Groovy 4, with a potentially breaking change in Groovy 5 to make constructor generation for Script subclasses happen in the same place as any other class. > Script subclasses cannot have constructors with arguments > --------------------------------------------------------- > > Key: GROOVY-11154 > URL: https://issues.apache.org/jira/browse/GROOVY-11154 > Project: Groovy > Issue Type: Bug > Components: Compiler > Affects Versions: 4.0.7 > Reporter: jonny > Priority: Major > > Prior to the fix for GROOVY-9857, subclasses of {{Script}} could have > constructor arguments and still be used (with a little help from > {{InheritConstructors}} and {{DefaultGroovyMethods#newInstance}}). > For example, the following script executes find in Groovy 3.x, but fails > after Groovy 4.0.7: > {code} > import groovy.transform.InheritConstructors > import org.codehaus.groovy.ast.AnnotationNode > import org.codehaus.groovy.ast.ClassNode > import org.codehaus.groovy.classgen.GeneratorContext > import org.codehaus.groovy.control.CompilationFailedException > import org.codehaus.groovy.control.CompilePhase > import org.codehaus.groovy.control.CompilerConfiguration > import org.codehaus.groovy.control.SourceUnit > import org.codehaus.groovy.control.customizers.CompilationCustomizer > import org.codehaus.groovy.runtime.DefaultGroovyMethods > abstract class NamedScript extends Script { > NamedScript(String name) { > } > } > def compilerConfig = new CompilerConfiguration() > compilerConfig.setScriptBaseClass(NamedScript.class.getName()) > compilerConfig.addCompilationCustomizers(new > CompilationCustomizer(CompilePhase.CONVERSION) { > @Override > void call(SourceUnit source, GeneratorContext context, ClassNode > classNode) throws CompilationFailedException { > classNode.addAnnotation(new AnnotationNode(new > ClassNode(InheritConstructors.class))) > } > }) > def classLoader = new GroovyClassLoader(new GroovyClassLoader(), > compilerConfig) > def parsedClass = classLoader.parseClass('println "Foo"') > DefaultGroovyMethods.newInstance(parsedClass, "dummy").run() > {code} > The error returned is: > {noformat} > Implicit super constructor NamedScript() is undefined for generated > constructor. Must define an explicit constructor. > {noformat} > Ratpack relies on this behavior for its custom text template renderer. > See how script objects are instantiated in the > [ScriptEngine#create|https://github.com/ratpack/ratpack/blob/503060ab2351a49f6e96416d588607ff7ef63028/ratpack-groovy/src/main/java/ratpack/groovy/script/internal/ScriptEngine.java#L51] > method. > I talked this out in the Groovy community Slack with [~blackdrag] (see > [thread|https://groovy-community.slack.com/archives/C2NEFCM55/p1691783910137829]), > who suggested that we should skip the check for constructors for Script > subclasses as a bugfix in Groovy 4, with a potentially breaking change in > Groovy 5 to make constructor generation for Script subclasses happen in the > same place as any other class. -- This message was sent by Atlassian Jira (v8.20.10#820010)