• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: WebObjects classloader fun.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WebObjects classloader fun.


  • Subject: Re: WebObjects classloader fun.
  • From: Chuck Hill <email@hidden>
  • Date: Tue, 3 Apr 2007 09:07:26 -0700

Someone has been having fun!


On Apr 3, 2007, at 2:06 AM, Q wrote:


Oh it gets even more fun.
I thought I would post this just for giggles for anyone interested. I don't blog, so this will do.


In order to add true groovy "scripting" support (and maybe even BSF if I can work out how that might work) with rapid turnaround ala WebScript to my WOGroovy framework I needed to work out how WebObjects does it's class loading. In hindsight I probably didn't really need to do this, because the hot class loading in eclipse is acceptable to some degree, but I wanted to see how it might work anyway. And to be honest, hot loading is not the best with classes as dynamic as groovy.

I started by writing a simple class loader wrapper so I could see what's going on. This allowed me to discover that com.webobjects.foundation._NSUtilities does some very funky stuff with partial class name resolution and class caching.


Very, profoundly funky stuff.


(Which prompted my original email asking for help understand what was going on)

Ok, so I asked my friend "Jad" if he knew anything about _NSUtilites that might be useful and with what he told me I got my new best friend GluonJ to watch some function calls that _NSUtilities makes so I could tell what was actually happening when my application failed to load my script code.

So with this information, and some magic fairy dust lifted directly from the now defunct ERXCompilerProxy, I think I have worked out what I needed to do to make it work, unfortunately it means I needed to alter some functionality of _NSUtilities and change how it deals with caching of ClassNotFound exceptions.

Long story short, I now have it working (I think) so that you can do proper rapid turnaround with groovy code.
Here's the catch. To do rapid turnaround you need to use Java 1.5 with a GluonJ based javaagent (included). It may be possible to get around this requirement by writing a custom bootstrap loader that adds the GroovyClassLoader before any of the WebObjects classes are resolved and somehow force the webobjects classes to be loaded higher up the loader chain rather than by the system class loader, but I decided it was easier to write the 3 lines of AOP code and be done with it.


(the updated code has been checked into subversion http:// code.google.com/p/wogroovy/source , if you want to check it out this is the only way for now)

If you have been meaning to have a look at AspectJ, JBoss AOP or similar AOP package for Java, do yourself a favour and look at GluonJ first, you need to use java 1.5, but it only needs a single page of documentation. :)

Thanks for that. I have been meaning to look at GulonJ for a while now. It just got moved higher on the list.




Now that I have got that off my chest I should probably do something useful and get back to work ;)

:-)

Chuck


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).

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.

ms

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40gmail.com


This email sent to email@hidden



-- 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:
40global-village.net


This email sent to email@hidden


--

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems.
http://www.global-village.net/products/practical_webobjects






_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >Re: WebObjects classloader fun. (From: Q <email@hidden>)

  • Prev by Date: Re: Strange Error ???
  • Next by Date: JavaClient & WebClient in one application
  • Previous by thread: Re: WebObjects classloader fun.
  • Next by thread: strange error
  • Index(es):
    • Date
    • Thread