groovy
  1. groovy
  2. GROOVY-3233

The main(args) entry point cannot be found when a class file has multiple classes and the first class extends another class.

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.6-rc-1
    • Fix Version/s: None
    • Component/s: Compiler
    • Labels:
      None
    • Environment:
      Groovy Version: 1.6-RC-1 JVM: 1.6.0_11. WinXP
    • Number of attachments :
      0

      Description

      Running the classes shown below results in:
      groovy -cp ..\main\groovy ..\main\groovy\MainInvokeSub.groovy
      Caught: groovy.lang.GroovyRuntimeException: This script or class could not be run.
      It should either:

      • have a main method,
      • be a JUnit test, TestNG test or extend GroovyTestCase,
      • or implement the Runnable interface.

      However, if the 'extends MainInvokeBase' is removed or if the second class is commented out, it does run.
      The only "spec" I could find about the expected behavior is in the GINA book.

      file: MainInvokeBase.groovy
      class MainInvokeBase {
      }

      file: MainInvokeSub.groovy
      class MainInvokeSub extends MainInvokeBase{
      static main(args)

      { println "Hello world!" }


      }

      def class SecondClass{
      }

        Activity

        Hide
        blackdrag blackdrag added a comment -

        and switching the order of the classes in MainInvokeSub does not help?

        Show
        blackdrag blackdrag added a comment - and switching the order of the classes in MainInvokeSub does not help?
        Hide
        josef betancourt added a comment -

        No, that did not help:

        file: MainInvokeSub.groovy
        def class SecondClass{
        }

        class MainInvokeSub extends MainInvokeBase{
        static main(args)

        { println "Hello world!" }


        }

        Show
        josef betancourt added a comment - No, that did not help: file: MainInvokeSub.groovy def class SecondClass{ } class MainInvokeSub extends MainInvokeBase{ static main(args) { println "Hello world!" } }
        Hide
        Roshan Dawrani added a comment -

        I looked into it a bit and I know what is causing it but I have no idea how to fix it.

        The reason re-ordering of the classes in the source file is not having any effect is that ACG sorts the classes that it generates (needSortedInput() for classgen returns true) and the sorting is by the length of the hierarchy of the class (its distance from java.lang.Object).

        So, when MainInvokeSub does not extend MainInvokeBase, length of type hierarchy of MainInvokeSub and SecondClass is same and you get back MainInvokeSub as the class to run from the source file, if it is present first in the source file.

        But when MainInvokeSub extends MainInvokeBase, its type hierarchy is longer than SecondClass's and after sorting in ACG SecondClass comes ahead in order and becomes the class to run (by being the first class to be pushed from ACG to GroovyClassLoader$ClassCollector), and running it fails because it does not have any main method, etc.

        Any suggestion on what I can explore to fix it?

        Show
        Roshan Dawrani added a comment - I looked into it a bit and I know what is causing it but I have no idea how to fix it. The reason re-ordering of the classes in the source file is not having any effect is that ACG sorts the classes that it generates (needSortedInput() for classgen returns true) and the sorting is by the length of the hierarchy of the class (its distance from java.lang.Object). So, when MainInvokeSub does not extend MainInvokeBase, length of type hierarchy of MainInvokeSub and SecondClass is same and you get back MainInvokeSub as the class to run from the source file, if it is present first in the source file. But when MainInvokeSub extends MainInvokeBase, its type hierarchy is longer than SecondClass's and after sorting in ACG SecondClass comes ahead in order and becomes the class to run (by being the first class to be pushed from ACG to GroovyClassLoader$ClassCollector), and running it fails because it does not have any main method, etc. Any suggestion on what I can explore to fix it?
        Hide
        Roshan Dawrani added a comment -

        A little clarification - to avoid one potential round-trip of comments

        I did not mean that classnodes are sorted by ACG itself. I meant that they are sorted in classgen phase because ACG.needSortedInput() returns true.

        Show
        Roshan Dawrani added a comment - A little clarification - to avoid one potential round-trip of comments I did not mean that classnodes are sorted by ACG itself. I meant that they are sorted in classgen phase because ACG.needSortedInput() returns true.

          People

          • Assignee:
            Unassigned
            Reporter:
            josef betancourt
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: