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

Script subclasses cannot have constructors with arguments

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 4.0.7
    • None
    • Compiler
    • None
    • Patch

    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:

      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()
      

      The error returned is:

      Implicit super constructor NamedScript() is undefined for generated constructor. Must define an explicit constructor.
      

      Ratpack relies on this behavior for its custom text template renderer.
      See how script objects are instantiated in the ScriptEngine#create method.

      I talked this out in the Groovy community Slack with blackdrag (see thread), 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.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              jonnybot jonny
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: