9

Code is a follows:

class Book
{
     private String title
     Book (String theTitle)
     {
         title=theTitle
     }
     String getTitle()
     {
         return title
     }
}
Book gina=new Book('Groovy in Action')
assert gina.getTitle()=='Groovy in Action'
assert getTitleBackwards(gina)=='noitcA ni yvoorG'
String getTitleBackwards(Book)
{
    title=book.getTitle()
    return title.reverse()
}

When I execute is with Ctrl+R, I get the following compilation error.

1 compilation error:

Invalid duplicate class definition of class Book : The source Book.groovy contains at least two definitions of the class Book. One of the classes is an explicit generated class using the class statement, the other is a class generated from the script body based on the file name. Solutions are to change the file name or to change the class name. at line: 1, column: 1

Can anybody please explain me what is happening here.

Keegan
  • 11,345
  • 1
  • 25
  • 38
learner
  • 2,480
  • 10
  • 50
  • 94
  • I tried to change name of file from Book.groovy to Book-Program.groovy but still it gives error as below. Exception thrown java.lang.ClassFormatError: Illegal class name "Book-Program$getTitleBackwards" in class file Book-Program$getTitleBackwards – learner Jul 20 '15 at 08:18
  • 1
    change the name of the file to something like foo.groovy and it will work. – blackdrag Jul 23 '15 at 13:35
  • `String getTitleBackwards(Book)` should be `String getTitleBackwards(Book book)` also. – Keegan Jan 21 '18 at 15:50

4 Answers4

10

Invalid duplicate class definition of class Book:

The code listing of the OP contains two parts:

  1. The type definition of class Book
  2. A groovy script that acts as a client of the Book type

Groovy treats your *.groovy file as either a script file or as a class definition file. A script file is a file that contains code that is not inside a class definition. When Groovy compiles a script file it implicitly creates a class to hold your code and the implicit class is given the name of the Book.groovy file.

Then, the compiler will try and create an additional class Book for the Book class defined in the groovy script, and the error occurs here because now there a actually two Book class definitions.

Compare: Blog entry with code sample for this error message

A way to define the Book class and the client script in the same file would be to rename the file, e.g. to BookApp.groovy. Caveat: if you do this, the Book type can only be referenced from within the script file, the Book type would not be found by groovy automatically, even if the *.groovy file was found on the class path.

rexford
  • 5,192
  • 5
  • 27
  • 40
1
  1. Groovy console buffers items (sources, classes, variables) internally, second click of "run" can be different that first, I agree. Almost all interpreter windows (in any languages) has similar behaviour
  2. has delicate differences when opening from File, pasting into window without file, in consequence can have name Book or ConsoleScript1 etc ("procedural" use of Groovy has hidden "object" background, hidden/default/generated class names from file etc)

This can be help-full by ad-hoc programming (script mode) but not always is the best for true OOP.

PS. code has few errors, too

Jacek Cz
  • 1,872
  • 1
  • 15
  • 22
0

when I ran into this error, it was because I forgot the word 'import' directly above so rather than :

import io.beapi.api.service.PrincipleService

@RestController
class UserController {

I had this:

io.beapi.api.service.PrincipleService

@RestController
class UserController {

The lack of the word import caused this issue for me. Quick easy fix (once I caught what it was) :)

Orubel
  • 316
  • 4
  • 16
0

You can not add any functions outside the class definition in the file.

This will give you the error.

File: Book.groovy

class Book
{
     private String title
     Book (String theTitle)
     {
         title=theTitle
     }
     String getTitle()
     {
         return title
     }
}
// This function is OUTSIDE the class definition
def someOtherFunction() {
}

This alleviates the error

File: Book.groovy

class Book
{
     private String title
     Book (String theTitle)
     {
         title=theTitle
     }
     String getTitle()
     {
         return title
     }
     // This function is now INSIDE the class definition
     def someOtherFunction() {
     }
}
Chris F
  • 14,337
  • 30
  • 94
  • 192