Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: 2.0 final
-
Fix Version/s: 2.0.1
-
Component/s: None
-
Labels:
-
Environment:Debian unstable, Java Sun 1.6.0_26-b03
Description
class MyDomain { static myMethod()
{'myMethod'} }
class MyController { def index()
}
Try to change MyDomain.myMethod return value and refresh your index page.
-
Hide
- library-bug-report-17012012.zip
- 17/Jan/12 7:18 AM
- 23 kB
- Peter Ledbrook
-
- grails-app/.../ApplicationResources.groovy 0.1 kB
- grails-app/conf/BootStrap.groovy 0.1 kB
- grails-app/conf/BuildConfig.groovy 2 kB
- grails-app/conf/Config.groovy 4 kB
- grails-app/conf/DataSource.groovy 1 kB
- grails-app/conf/UrlMappings.groovy 0.2 kB
- grails-app/conf/spring/resources.groovy 0.0 kB
- grails-app/.../AuthorController.groovy 0.1 kB
- grails-app/.../BookController.groovy 0.1 kB
- grails-app/domain/.../example/Author.groovy 0.1 kB
- grails-app/domain/.../example/Book.groovy 0.2 kB
- grails-app/i18n/messages.properties 3 kB
- grails-app/.../messages_cs_CZ.properties 3 kB
- grails-app/i18n/messages_da.properties 3 kB
- grails-app/i18n/messages_de.properties 4 kB
- grails-app/i18n/messages_es.properties 3 kB
- grails-app/i18n/messages_fr.properties 2 kB
- grails-app/i18n/messages_it.properties 2 kB
- grails-app/i18n/messages_ja.properties 4 kB
- grails-app/i18n/messages_nl.properties 3 kB
- grails-app/.../messages_pt_BR.properties 3 kB
- grails-app/.../messages_pt_PT.properties 3 kB
- grails-app/i18n/messages_ru.properties 4 kB
- grails-app/i18n/messages_sv.properties 3 kB
- grails-app/i18n/messages_th.properties 6 kB
- grails-app/.../messages_zh_CN.properties 2 kB
- grails-app/views/error.gsp 0.3 kB
- grails-app/views/index.gsp 3 kB
- grails-app/views/layouts/main.gsp 2 kB
- test/unit/.../AuthorControllerTests.groovy 0.3 kB
Activity
- All
- Comments
- Work Log
- History
- Activity
- Git Commits
Ok, found out what the problem really is. I have some fixed roles for my application. Suppose they are 'admin', 'editor' and 'client'. So, instead of looking at the database every time I need them, I've done some caching:
class Role {
String name
private static roleByName
static byName(name)
{ processCache() roleByName[name] } private static processCache() {
if (roleByName) return
roleByName = list().inject([:])
}
}
I'll get weird error messages in development mode if I do that. Using Shiro and another class just for testing, I got this, for instance:
ERROR errors.GrailsExceptionResolver - LazyInitializationException occurred when processing request: [GET] /reloading/main/index
failed to lazily initialize a collection of role: reloading.ShiroUser.permissions, no session or session was closed. Stacktrace follows:
Message: failed to lazily initialize a collection of role: reloading.ShiroUser.permissions, no session or session was closed
Line | Method
->> 77 | isPermitted in ShiroDbRealm$$ENK01yVc
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
237 isPermitted in org.apache.shiro.grails.RealmWrapper 58 isPermitted . . . . in org.apache.shiro.grails.RealmAdapter 222 isPermitted in org.apache.shiro.authz.ModularRealmAuthorizer 113 isPermitted . . . . in org.apache.shiro.mgt.AuthorizingSecurityManager 151 isPermitted in org.apache.shiro.subject.support.DelegatingSubject 511 accessControlMethod in ShiroGrailsPlugin$$ENK01dhI 245 doCall in ShiroGrailsPlugin$_closure3_closure24$$ENK01dhI 13 doCall . . . . . . in ShiroSecurityFilters$_closure1_closure2_closure3$$ENK01kSe 55 doFilter in org.apache.shiro.grails.SavedRequestFilter 359 executeChain . . . in org.apache.shiro.web.servlet.AbstractShiroFilter 275 call in org.apache.shiro.web.servlet.AbstractShiroFilter$1 90 doCall . . . . . . in org.apache.shiro.subject.support.SubjectCallable 83 call in '' 344 execute . . . . . . in org.apache.shiro.subject.support.DelegatingSubject 272 doFilterInternal in org.apache.shiro.web.servlet.AbstractShiroFilter 81 doFilter . . . . . in org.apache.shiro.web.servlet.OncePerRequestFilter 886 runTask in java.util.concurrent.ThreadPoolExecutor$Worker 908 run . . . . . . . . in ''
^ 662run in java.lang.Thread
In my real case, I moved the caching to a service, but still have problems. I changed my code for not caching in development mode to something like this:
class RoleService {
def allRoles, roleByName = [:]
def getAllRoles()
{ processAllRoles() allRoles } private processAllRoles() {
if (allRoles && Environment.current != Environment.DEVELOPMENT) return
//allRoles = ShiroRole.ROLE_NAMES.collect
allRoles = ShiroRole.ROLE_NAMES.collect{roleName -> ShiroRole.withCriteria
{eq 'name', roleName} }
allRoles.each
}
def byName(name)
{ processAllRoles() roleByName[name] }}
If I use the withCriteria to fill "allRoles" I get this message:
No signature of method: security.ShiroRole.withCriteria() is applicable for argument types: () values: [] Possible solutions: withCriteria(groovy.lang.Closure), withCriteria(java.util.Map, groovy.lang.Closure), createCriteria()
If I use the findByName approach, I'll get:
No signature of method: security.ShiroRole.methodMissing() is applicable for argument types: () values: []
If I restart the application, everything goes fine until I touch ShiroRole.groovy.
Humm... I have changed the service to not use caching, and still get the same errors if I touch ShiroRole:
class RoleService {
def getAllRoles() {
ShiroRole.ROLE_NAMES.collect
}
def byName(name)
{ ShiroRole.findByName(name) }}
Any ideas on what could be happening?
This is what I get from the backtrace while calling withCriteria:
2011-12-24 11:15:12,419 ["http-bio-8081"-exec-6] ERROR StackTrace - Full Stack Trace:
java.lang.NullPointerException
at grails.orm.HibernateCriteriaBuilder.invokeMethod(HibernateCriteriaBuilder.java:1515)
at org.grails.datastore.gorm.GormStaticApi.withCriteria(GormStaticApi.groovy:261)
Now, this is really interesting... After setting my vim settings to "set noswapfile" it seems those problems were gone... Why the hell Grails is monitoring my swap files? They are called something like ".AccountController.groovy.swp". Somehow, this seems to be the cause of maybe some race condition in the reloading algorithm.
Any ideas?
Use a different editor for the moment. Textmate doesn't create swp files.
Textmate doesn't run on Linux. But this is no problem, as I've just disabled the swap files for now in gVim. But I'd like to be able to re-enable them some day when this gets fixed.
This is reproducible with vim, and pretty frustrating. More importantly, it could be a more pervasive problem. Anyway, to reproduce with vim:
1. Unpack the attach bug report
2. Start up interactive mode
3. Execute run-app
4. exit
5. Execute run-app a second time
6. Open the application in a browser
7. Try http://localhost:8080/library/book/hello (not implemented yet)
8. Now edit BookController.groovy in vim and add
def hello() {
render "Hello world!"
}
9. Save
10. Refresh the browser.
You should find that BookController has not been reloaded, although there are no error messages.
I have pushed a potential fix, but because i was unable to see Grails monitoring any SWP files whilst debugging nor was I able to reproduce an exceptions or errors I would like someone to verify.
Using Peter's steps I was unable to reproduce any reloading failures with MacVim and :set swapfile
I've made some changes on current Grails 2.0.1 with the swapfiles enabled and I didn't get any further issues with regards to reloading of classes, so I think this bug was really fixed. Thanks!
Unfortunately I can't upgrade to 2.0.1 yet because it broke both mongo and mongo-morphia plugins and I don't know any other plugin for Grails for writing to Mongo, so I'll have to implement my logging to mongo in Groovy by myself before I'm able to upgrade to 2.0.1... ![]()
Never mind, this only seems to happen in my application, not in a newly generated one. It is probably caused by some plugin and I'm investigating which one could be the cause...