You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Jeremy Boynes <jb...@apache.org> on 2006/08/15 02:50:50 UTC

Module restructuring for classloader changes

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

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.

--
Jeremy


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: Module restructuring for classloader changes

Posted by Jim Marino <jm...@myromatours.com>.
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: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org