Details
Description
When a plugin contains an Immutable class (annotated with @Immutable), an application with this plugin installed sometimes fails to compile, giving this stacktrace:
[groovyc] org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
[groovyc] General error during canonicalization: Explicit constructors not allowed for @Immutable class: ImmutableExample
[groovyc]
[groovyc] java.lang.RuntimeException: Explicit constructors not allowed for @Immutable class: ImmutableExample
[groovyc] at org.codehaus.groovy.transform.ImmutableASTTransformation.createConstructor(ImmutableASTTransformation.java:308)
[groovyc] at org.codehaus.groovy.transform.ImmutableASTTransformation.visit(ImmutableASTTransformation.java:117)
[groovyc] at org.codehaus.groovy.transform.ASTTransformationVisitor.visitClass(ASTTransformationVisitor.java:129)
...
This only happens the first time you compile the application, and only when another plugin is also installed. I have been able to reproduce it with the shiro plugin and with the spring-security-core plugin.
Steps to reproduce:
1. create a new plugin 'immutable-bug-plugin'
2. in this plugin, create a Groovy class 'ImmutableExample', annotated with @Immutable. The class should be under src/groovy
3. in this same plugin, create a service, 'ImmutableService'. In a service method, a new instance of the ImmutableExample class should be created, for example: def example = new ImmutableExample('hello', 'world')
4. create a new application 'immutable-bug-demo'
5. in the BuildConfig, add an inline dependency to the plugin you just created: grails.plugin.location.'immutable-bug-plugin'='../immutable-bug-plugin'
6. install the shiro plugin in the application
7. execute 'grails run-app': the compilation will fail
8. execute 'grails run-app' again: the compilation will succeed
A sample plugin and application was attached to this issue.
-
Hide
- grails-immutable-bug.zip
- 29/Jan/11 4:28 PM
- 216 kB
- Jurgen Lust
-
- grails-immutable-bug/grails-immutable-bug.ipr 12 kB
- grails-immutable-bug/grails-immutable-bug.iws 31 kB
- grails-immutable-bug/.../.classpath 0.7 kB
- grails-immutable-bug/.../.project 0.5 kB
- grails-immutable-bug/.../org.codehaus.groovy.eclipse.preferences.prefs 0.1 kB
- grails-immutable-bug/.../application.properties 0.2 kB
- grails-immutable-bug/.../BootStrap.groovy 0.1 kB
- grails-immutable-bug/.../BuildConfig.groovy 1 kB
- grails-immutable-bug/.../Config.groovy 4 kB
- grails-immutable-bug/.../DataSource.groovy 0.8 kB
- grails-immutable-bug/.../resources.groovy 0.0 kB
- grails-immutable-bug/.../UrlMappings.groovy 0.2 kB
- grails-immutable-bug/.../messages.properties 3 kB
- grails-immutable-bug/.../messages_da.properties 3 kB
- grails-immutable-bug/.../messages_de.properties 4 kB
- grails-immutable-bug/.../messages_es.properties 3 kB
- grails-immutable-bug/.../messages_fr.properties 2 kB
- grails-immutable-bug/.../messages_it.properties 2 kB
- grails-immutable-bug/.../messages_ja.properties 2 kB
- grails-immutable-bug/.../messages_nl.properties 3 kB
- grails-immutable-bug/.../messages_pt_BR.properties 3 kB
- grails-immutable-bug/.../messages_pt_PT.properties 3 kB
- grails-immutable-bug/.../messages_ru.properties 4 kB
- grails-immutable-bug/.../messages_th.properties 5 kB
- grails-immutable-bug/.../messages_zh_CN.properties 2 kB
- grails-immutable-bug/.../shiro.properties 0.0 kB
- grails-immutable-bug/.../error.gsp 2 kB
- grails-immutable-bug/.../index.gsp 4 kB
- grails-immutable-bug/.../main.gsp 0.8 kB
- grails-immutable-bug/.../immutable-bug-demo-grailsPlugins.iml 5 kB
Issue Links
- depends on
-
GRAILS-7981
Upgrade to Groovy 1.8.2
-
Activity
- All
- Comments
- Work Log
- History
- Activity
- Git Commits
This is reproducable every time. I'm on Grails 1.3.7 now and this is very annoying.
This is also affecting the Spring Security Core plugin: when a Groovy class is annotated with @Immutable in a plugin, then the following Exception is thrown when trying to access a secure url in an application using this plugin:
> A NullPointerException is thrown at
> at org.codehaus.groovy.grails.plugins.springsecurity.SpringSecurityUtils.isAjax(SpringSecurityUtils.java:299)
Checking the source code, I noticed that this is caused by the fact that
> ReflectionUtils.getConfigProperty("ajaxHeader");
returns null. So I started experimenting a little bit in the Bootstrap.groovy, and digging through the source code of the Spring Security Core plugin.
ReflectionUtils.getConfigProperty(name) looks like this:
> def value = SpringSecurityUtils.securityConfig
> for (String part in name.split('
.'))
> value
>
So I tried calling both this method, and a copy of its body in Bootstrap.groovy:
> def value = SpringSecurityUtils.securityConfig
> for (String part in "ajaxHeader".split('
.')) {> value = value."$part"> }
> println value
> println ReflectionUtils.getConfigProperty("ajaxHeader")
>
The result was this:
> X-Requested-With
> null
>
So, calling the copy of the method body gave me the correct result, while calling the static method itself returned null.
Removing the @Immutable annotation solves the problem.
I'm using Grails 1.3.7 and spring-security-core 1.1.2
Jurgen,
Is removing the @Immutable annotation a workaround so far?
Which exact classes in Spring Security need to have that annotation removed?
Thanks.
I have the same scenario:
- Foo -class annotated with Immutable under src/groovy
- Bar -service that uses Foo -class
-> Compilation of the plugin fails to the same exception
I'm seeing the same problem, this time with an @Immutable class under grails-app/routes (I'm using the routing plugin).
Please try out the jar here to see if it fixes your problem:
http://snapshots.repository.codehaus.org/org/codehaus/groovy/groovy-all/1.7.11-SNAPSHOT/
I also got hit by this strange problem today.
Plugin-A contains an immutable class:
@Immutable final class MessageKey implements Serializable { Integer tenant String code Locale locale }Plugin-B has an inline dependency on Plugin-A
grails 'clean' followed by 'run-app' in Plugin-B gives the above exception. Repeated 'run-app' still gives the exception.
However 'clean' followed by 'compile' followed by 'run-app' works.
I was under the impression that 'run-app' did a 'compile' automatically.
I'm using Grails 1.3.6