Peter,
Finally! This is what you wanted considered conversation on?
There are so many ways to answer this. So many choices that mean good and bad news for different parties.
1) WAR should not not able to see or instantiate excalibur (etc) classes by default. It's a security issue and I think everyone agrees that. Given that Jo! (or Tomcat n years from now) could host Cocoon that needs Excalibur (etc) then WAR files as at present must be able to bring their own jars that clash with dopplegangers elsewhee in the VM (different branch).
2) What can the IoC pattern do for us here? Could a Phoenix app that needs Excalibur classes be given a handle to a suitable classloader by asking for it through ComponentManager? This sounds great but I don't think it can work at all. All dependancies are resolved at load time via a zillion findClass() calls. If one is missing (interface or class) it will barf in a very unhelpful way.
3) Home truths. Applications (any) that make an assumption about the parent classloader (being the system one) suck. That is one of three issues with Tomcat running on Phoenix at the present (look back in this list for "StandardClassLoader"). This is a bit of a crux and I'm skimming over it.
4) Aggregation Classloader. Hmmm, not sure that is right anymore.
5) Another IoC solution. Could Phoenix apps be able to see everything as at present (in CL terms). Could they also go back to some componentManager or BlockContext supplied thing and ask for a naked hook to the system class loader (is that not called primordial now?) I.e Phoenix design recognises that Phoenix hosted apps may want to host multiple sub apps that are Pheonix/Avalon/Excalibur/Logkit unaware. Either the block can ask for a single CL that has a parent of the primordial, and with that itself makes multiple classloaders for it's hosted applications. It is not so hard for an app to do this.... Jesktop does. Or it can be more of a factory and generate new ones on request. I'd really prefer the former or a facility for both.
6) Bridging. We're not addressing that in this thread huh? When I get more used to BCEL I think I might be able to make the perfect version tolerate proxy style bridge for SAR to SAR connecting.
7) Hierarchcy in server.xml. Relaing to (5) above. I think this should not be so statically defined. If it is anywhere it is in assembly.xml and a component that can be delivered through compose(..).
In summary, I think we could have a service called :
NonPhoenixClassLoaderEnvironment { ClassLoader getNonPhoenixClassLoader(); }
Phoenix could provide a default implementation of that but other coders could provide alternatives (possibly even chained ones).
Regards,
- Paul H
Currently Phoenix has a relatively simple ClassLoader mechanism. It has the following layout
System ClassLoader <--- Kernel ClassLoader <--- Application ClassLoader (s)
The System ClassLoader includes avalon-framework.jar, phoenix-client.jar and any other jars included in ${phoenix.home}/lib/ (currently xerces and excalibur are required).
This works great if you are just writing normal server applications. The problem arises when you try to write applications that will in turn host other components. For instance a servlet container requires a very specific ClassLoader hierarchy for it to work. For instance the base ClassLoader is meant to only contain a handful of files (including servlet.jar and various other "common" jar files).
However we can only partially implement that at the moment by placing the library files into ${phoenix.home}/lib however even that case we can not remove avalon-framework.jar, phoenix-client.jar, etc as they are required so that Application and Kernel can talk. So in reality it would be difficult to implement a fully compliant EJB, Servlet etc application without writing another ClassLoader (that didn't delegate to top of ClassLoader hierarchy). A few servlet engines already do this but I would prefer if it was easier in Phoenix.
My initial thoughts were to create something like
System ClassLoader <--- Common ClassLoader <--- Kernel ClassLoader <--- Application ClassLoader (s)
where Common ClassLoader contains avalon-framework.jar, phoenix-client.jar, excalibur etc.
That way the Application could create a ClassLoader that delegated to System ClassLoader but wasn't pollutted by Avalon specific jars.
However then I thought that this could be bad because some Applications require that extra elements be added to Common ClassLoader that this wouldn't work. ie A servlet container would still require that servlet.jar be loaded by Application ClassLoader (or one of it's parents) and thus you would still have to stuff the servlet.jar into System ClassLoader for this to work. And this is not a good thing IMHO.
So then I got to thinking about something Paul said. Maybe we could declare ClassLoader hierarhy in the server.xml. However because a hierarchial ClassLoader still wouldn't work we would have to have an Aggregator ClassLoader that aggregated several ClassLoaders together so we could do something like
System ClassLoader <--- Common ClassLoader <--- Kernel ClassLoader <---| | Application ClassLoader (s) Servlet ClassLoader <---|
This way we could get access to the unpolluted ClassLoader to work as base ClassLoader for web application. This would be the same ClassLoader that the Application used to load the servlet interfaces and thus it would be easy to provide implementation in Application space.
As a matter of fact this could be extended so that an arbitrary number of ClassLoaders could be aggregated for application. However this assumes that each ClassLoader aggregated contains separate namespace. ie The same Class can not be available in multiple ClassLoaders for this to work.
To support all this we would need to add an extra method to BlockContext to get named ClassLoader and we would have to enhance server.xml to allow ClassLoader hierarchys to be configured in it (not sure on format).
Thoughts?
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>