groovy

Class reloading of classes through GCL fails when a groovy class is a subclass of another groovy class

Details

  • Type: New Feature New Feature
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 1.0-JSR-6
  • Component/s: groovy-jdk
  • Labels:
    None
  • Testcase included:
    yes
  • Number of attachments :
    1

Description

In order for Grails to support reloading of classes without causing problems with cached instances in application and session scope I need Groovy to support a loadClass method that reloads a class if it has been changed.

Ideally it needs to interact with the GroovyResourceLoader to load resources as Urls if possibly.

Something like

gcl.loadClass(final String name, boolean lookupScriptFiles, boolean preferClassOverScript, boolean resolve, boolean reload)

would be ok.. otherwise maybe a different method

gcl.reloadClassIfNecessary(String name) maybe ?
gcl.reloadClass(String name, boolean force) // for forced reload or false to return current if no changes?

I've attached the test case I used to test this out originally in Grails. It is not Grails specific so you should be able to drop it into groovy and just change the package names

Activity

Hide
Art Gramlich added a comment -

It looks like when a groovy class is a subclass of another groovy class, the reloading doesn't work since it doesn't see the GroovyObject interface. I've created a simple patch to descend the inheritance tree. Seems to work fine with the patch.

Show
Art Gramlich added a comment - It looks like when a groovy class is a subclass of another groovy class, the reloading doesn't work since it doesn't see the GroovyObject interface. I've created a simple patch to descend the inheritance tree. Seems to work fine with the patch.
Hide
Art Gramlich added a comment -

The patch described.

Show
Art Gramlich added a comment - The patch described.
Hide
Art Gramlich added a comment -

It also looks like removeFromCache should be

public void removeFromCache(Class aClass) { cache.remove(aClass.getName()); }

instead of

public void removeFromCache(Class aClass) { cache.remove(aClass); }

Show
Art Gramlich added a comment - It also looks like removeFromCache should be public void removeFromCache(Class aClass) { cache.remove(aClass.getName()); } instead of public void removeFromCache(Class aClass) { cache.remove(aClass); }
Hide
blackdrag blackdrag added a comment -

I now use Class#isAssignableFrom instead of going through the class tree and doing the compares with strings. I think that is good enough, because if the GroovyObject.class of the ClassLoader is the wrong one, then a newly generated class will have also the wrong class. I don't think that is something we should support. It is difficult enough with so many class loaders. The removing of the class works now by name.

Show
blackdrag blackdrag added a comment - I now use Class#isAssignableFrom instead of going through the class tree and doing the compares with strings. I think that is good enough, because if the GroovyObject.class of the ClassLoader is the wrong one, then a newly generated class will have also the wrong class. I don't think that is something we should support. It is difficult enough with so many class loaders. The removing of the class works now by name.

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: