<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d6813476980165976394\x26blogName\x3dThe+Bayesian+Conspiracy\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttps://bayesianconspiracy.blogspot.com/search\x26blogLocale\x3den\x26v\x3d2\x26homepageUrl\x3dhttp://bayesianconspiracy.blogspot.com/\x26vt\x3d-948109813487012623', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

The Bayesian Conspiracy

The Bayesian Conspiracy is a multinational, interdisciplinary, and shadowy group of scientists. It is rumored that at the upper levels of the Bayesian Conspiracy exist nine silent figures known only as the Bayes Council.

This blog is produced by James Durbin, a Bayesian Initiate.

Invalid duplicate class definition

"Invalid duplicate class definition...One of the classes is a 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. "

When I was first learning Groovy I would get this error from time to time. It was puzzling to me because sometimes I'd get this error, and sometimes it would seem like the same situation and I wouldn't. It seemed quite random to me when the error would crop up. When it did, I'd usually just rename the class and go on, resolving to figure it out later. To save you the trouble, here's what is happening.

Groovy has two ways to treat a .groovy file: either as a script, or as a class definition file. If it is a script you can not have a class by the same name as the file. If it is a class definition file you can. It is very easy to tell whether a .groovy file is going to be treated as a script or as a class definition file. If there is any code outside a class statement in the file (other than imports), it is a script. What is happening is that if there is any code to be executed in the file then Groovy needs a containing class for that code. Groovy will implicitly create a containing class with the name of the file. So if you have a file called Grapher.groovy that has some code in it that isn't inside a class definition, Groovy will create an implicit containing class called Grapher. This means that the script file Grapher.groovy can not itself contain a class called Grapher because that would be a duplicate class definition, thus the error. If, on the other hand, all you do in the file Grapher.groovy is define the class Grapher (and any number of other classes), then Groovy will treat that file as simply a collection of class definitions, there will be no implicit containing class, and there is no problem having a class called Grapher inside the class definition file Grapher.groovy.

It's worth mentioning that the script version of Grapher.groovy will be compiled into a class called Grapher that extends groovy.lang.Script. In the other case, when Grapher.groovy merely defines classes, one of which is Grapher, that Grapher class will be compiled into a class that implements groovy.lang.GroovyObject.

I'm sure this is all explained somewhere in the Groovy documentation, but it didn't soak in to me until I read this Nabble post from which I extracted this explanation.

UPDATE: The text of this error message has changed (at least in some cases) to be a bit more informative. Now it reads:

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.
The underlying mechanics behind this error are the same.

Labels:

You can leave your response or bookmark this post to del.icio.us by using the links below.

Post a Comment | Bookmark | Go to end |
  • Anonymous Peter:  

    Thank you. I've been scratching my head about this too....well no need for that anymore. (June 26, 2009 at 12:41 PM) top

  • Blogger OSh:  

    Thanks a lot. I was really confused getting this problem. Your explanation helped. The problem was I occasionally added a line 'package com.xxx.yyy.zzz' outside the class. (May 21, 2010 at 2:34 AM) top

  • Blogger Unknown:  

    Annoying, by convention nice to have same Class/File name.

    Groovy is a great lang, but the gotchas can be a hassle, particulary when error messages have apparently nothing to do with the root cause (not the case here, but in groovlet environment can be completely maddening) (December 20, 2010 at 12:23 PM) top

  • Anonymous Anonymous:  

    If you save your file as UTF-8 and accidentally save it with a Byte Order Mark, you will also get this error. Save as UTF-8 without BOM, and you're good. (February 5, 2013 at 10:50 AM) top

  • Anonymous Anonymous:  

    Nicely explain,Thanks a lot

    This is my mail:
    shoaibista@gmail.com

    plz ping me,,,i would like to ask much more doubts regarding groovy (May 7, 2013 at 12:57 AM) top

  • Anonymous Anonymous:  

    Thank you! I just got this error message.

    I had just changed this file from .java to .groovy, so it was very reasonable to believe that there actually was a duplicate class definition sitting somewhere in my state. I spent several minutes trying to track that down, to no avail.

    That's what I get for taking a Groovy error message at face value -- I should have just Googled it immediately.

    It turns out the culprit was an extraneous } halfway down the page, and Groovy interpreted everything after that as "code outside the class". Of course. (August 25, 2013 at 7:30 PM) top

  • Blogger LaurentDu64:  

    Nice ! Worth reading !
    It's clear and complete.

    Thank you very much. (November 10, 2013 at 12:46 PM) top

  • Blogger Unknown:  

    Thank you for the explanation! It helped to solve my error. (May 8, 2014 at 7:07 AM) top

  • Blogger skuppyJ:  

    Was totally confused. Now, no longer. Thank you. (August 9, 2015 at 8:34 PM) top

  • Blogger smeeb:  

    I lost like an hour on this. One full hour of my life I can never get back.

    In my case I had a simple syntax error in the 'imports' section of my Groovy source file. Instead of:

    import com.example.myapp.MyObject

    I forgot the "import" statement and had:

    com.example.myapp.MyObject

    Sarcastic "thank you" to the Groovy language/compiler. Sincere thank you to all of my fellow victims above that helped clue me that this was a syntax issue and nothing more. Mehhhh (October 22, 2015 at 9:44 AM) top

  • Blogger geezenslaw:  

    What is really confusing is injecting a service into a controller class outside the class name but renaming either the file or the class name does not work. The real solution is to move the def someService back below the class declaration. Thanks to this article for the understanding to guess the solution. (June 21, 2016 at 8:17 AM) top