On Aug 14, 2006, at 5:50 PM, Jeremy Boynes wrote:
For TUSCANY-619 I am going to move some of the function currently
in core into separate modules so that we can get the classloader
isolation right.
The goal here is to break the modules down into four categories:
1) core runtime (spi, core) and dependencies
2) extensions (containers, bindings, data-bindings, idl, ...)
3) host implementations
4) api and bootstrap jars
Yes that makes sense and we've been talking about having a separate
API project as well so that can be accommodated with this approach.
Of these, only ones from the last category would appear on an
application's classpath. These would be things like the standard
SCA API classes, Tuscany-specific API classes, and a few classes
that might be needed to boot the SCA runtime. Examples of these
would be the current launcher module and the webapp module I
recently added. These jars will be very small and will really need
to stand on their own (i.e. they will have no dependencies that may
conflict with application code).
The bootstrap code will reflectively load a host implementation
using a isolated classloader and this will go on to boot the core
runtime and then that will load its extensions.
So the simple command line launcher would work like follows:
* launcher.jar is run from the command line.
* It will build a boot classpath comprising all jars in the "boot"
directory. This will be the host and core runtime jars
* It will create a host component (reflectively) and set up any
parameters (such as the path to the install directory)
* It will reflectively invoke the host's boot method
* The host will create the runtime and deploy the system scdl
* The system scdl may define an extension mechanism (e.g. a
DirectoryScanExtender component) and then that would load extensions
* The launcher will locate the application to launch and
reflectively invoke the host's deploy method passing the URL
* The host will construct the SCA config artifacts needed and use
the runtime to deploy the application
* The launcher will invoke the unmanaged application code's main()
method
* When the application exits the launcher will reflectively invoke
the host to shut the runtime down
For the webapp host the behaviour would similar:
* the api and webapp bootstrap jars are added to the webapp
classpath (in WEB-INF/lib or in an appserver directory)
* a context listener is added to web.xml which will fire a
bootstrapper in the webapp module
* the bootstrapper will build a boot classpath from a resource in
the webapp (or possibly from an external directory)
* it will create a host, boot the runtime and deploy the
application in the same way the launcher did
* a TuscanyServlet (from the webapp bootstrap) will locate the
ServletHost and forward requests into the runtime (e.g. for bound
Services)
* when the webapp shuts down, the context listener will shut down
the runtime
Application code will be loaded using a classloader that contains
the following classes:
* ones from the component implementation which will either be the
composite's classloader or a child of it
* classes the implementation chooses to make available (e.g. the JS
container may make the Rhino classes available)
* classes from the Thread context classloader supplied by the host
when it invoked Tuscany
This classloader will also be set as the Thread context
classloader. This means that for normal application code
Thread.getContextClassLoader() == getClass().getClassLoader(). It
also means that, through delegation, classes from the original
Thread context classloader supplied on invocation are available to
host libraries.
Extension code will be loaded using a classloader with the following:
* classes from composite providing the extension
Specifically, the Thread context classloader supplied by the host
will not be modified. This means that extension code can assume
that the Thread context classloader will always refer to
application classes as specified above.
This seems pretty straightforward and in line with other "containers"
I've seen. For integration testing *of extensions* we will probably
need something like a test binding so component types can ensure
interoperability so once you get these changes in place let me know
and I'll start on that. For the majority of application code testing,
I agree with your previous post that nothing other than JUnit or
TestNG should be needed - one of the niceties of dependency
injection ;-).
--
Jeremy
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]