Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WebObjects classloader fun.



On 30/03/2007, at 2:44 PM, Mike Schrag wrote:

Does anyone know much about how webobjects uses the classloader and how the _NSUtilities class cache is initialized and used?

[snip] it appears that _NSUtilities has a static initialiser that pulls in and caches classes rather than asking the current thread context classloader for them when needed [snip]
You are correct ... Frameworks (and your app) are loaded by NSBundle, which traverses all of the classpath and loads the reachable classes into the NSUtilities cache (so you can do things like looking up a component by name -- _NSUtilities.classWithName (..)). You can also override these class names by calling _NSUtilities.setClassForName. If the name was not in the cache, it will Class.forName it and then put the result into the cache. This behavior makes packageless WOComponent name lookups (for instance) very fast in exchange for some kind of weird behavior (like cross- your-fingers-if-you-have-two-classes-with-the-same-name).

That kinda sucks. As it means that I cannot intercept the call to Class.forName() as it doesn't use the thread context class loader, but instead the classloader that loaded _NSUtilities, (ie. the system class loader). This therefore means I either need to bootstrap the application differently so that the classloader chain is setup before _NSUtilities is loaded (like how groovy bootstraps its script files), or I need to dynamically compile every single new or changed .groovy file in the classpath ahead of time so that the system class loader can resolve them, which I think would probably work, but is far more complicated than I was hoping for.


Unfortunately, I don't know of any way to REMOVE an entry from the cache. You can't setClassForName(null, "ClassName") because that tries to put a null key into the cache. If you specifically know the class name, you can replace it yourself -- ERXPatcher is generally just calling setClassForName with classes it replaces

You need to use reflection to do that so you can poke at the underlying dictionary directly, which isn't pretty, but it works.




--
Seeya...Q

Quinton Dolan - email@hidden
Gold Coast, QLD, Australia
Ph: +61 419 729 806


_______________________________________________ Do not post admin requests to the list. They will be ignored. Webobjects-dev mailing list (email@hidden) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/webobjects-dev/email@hidden

This email sent to email@hidden
References: 
 >WebObjects classloader fun. (From: Q <email@hidden>)
 >Re: WebObjects classloader fun. (From: Mike Schrag <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.