This is definition document so I don't have to repeat everything on the JIRA tasks
The deployer architecture is made up of the following components:
VDF - Virtual Deployment Framework
The VDF works to abstract
deployments meaning the deployers don't have to deal with
the physical structure/protocol of the deployments.
It is responsible for abstracting away:
copying remote/nested deployments to a temp location
supplying logical urls for users/config/codebase-protectiondomain/etc
supplying physical urls for classloading/debugging/etc
A VDF context identifies a deployment/subdeployment
holding the information that is identifed by the
structural component deployers.
A deployer is made up two components.
1) A structural component that says it recognises a particular
deployment and deconstructs the deployment into its VDF contexts.
2) A deployment component that looks at the deployment
and constructs the objects.
Like the current main deployer it is reponsible for
deploy(URL) and undeploy(URL). It also serves as a registry
for the other deployers.
Any bean that implements the "Deployer interface"
will be registered/unregistered with the MainDeployer
as it is instantiated.
Since the structural components have no dependencies
they can be instantiated early and the deployments
Both the structural and deployment components
of the deployers are stored inside the MainDeployer registry
as a chain in a "priority" order.
For the structural chain, the first deployer in "priority" order
to recognise the deployer wins.
All deployments/subdeployments must be structurally recognised
before the deployment chain is processed.
Each deployer gets to process the deployment in the "priority" order.
The chain is processed depth first, i.e. priority order over all
deployments/subdeployments before moving to the next in the chain
Structural Component More Detail
To construct the VDF context the structural component must be
able to identify:
1) The set of urls that make up the deployment classpath
2) The location of the metadata, e.g. META-INF, WEB-INF, etc.
3) The set of possible subdeployments
Deployment Component More Detail
This does the job of deployment for this VDF context
We want to aim to use the deployment specific
metadata to create microcontainer metadata that can be installed
(instantiated/configured) according to dependencies.
But there are thirdparty components where complete control
of the construction/config is not under IOC/microcontainer control
This has no structural component.
It forms the highest priority (first) deployment component
since very little else can be done reliably until the classes
It takes it info from the urls identified by the structural
deployments in the VDF contexts.
This is the lowest priority (last) structural component.
It takes jars/zips and top level directories (not sub deployments)
and adds the url to the VDF context for classloading.
There is no deployment component.
The priority of this deployer is unimportant.
It takes .bean with a (META-INF/jboss-bean.xml)
or plain -bean.xml files that contain raw microcontainer
config in xml format.
It identifies the root of the .bean archive (or expanded deployment)
as the classloader url.
Any file in the root of the .bean is eligible as a subdeployment.
Parses the -bean.xml and installs it into the microcontainer
A profile serves as a collection of deployments.
The simplest implementation is the current JBoss directory
structure, i.e. a static config and a hot deploy config.
A more useful implementation for production
is a versioned/persistent list of deployments.
The profile feeds URLs to the main deployer.
Hot Deployment Profile
The hot deployment profile will need the mechanisms
to order deployments like current JBoss
Added some tasks for the deployer framework:
Lets say we have:
And just 3 deployers, registered in that priority order:
(C)lassLoadingDeployer -> (B)eanDeployer -> (J)ARDeployer.
After the deployment structure is analyzed (by the bean & jar deployers) we have the corresponding DeploymentContext/subcontexts in place with each one having recorded its own url as a classpath.
How 2nd stage deployment processing would work in this case, wrt depth and priority (.jar comes before .bean, according to suffix rules)
C(c.jar) C(b.bean) C(a.bean)
B(c.jar) B(b.bean) B(a.bean)
J(c.jar) J(b.bean) J(a.bean)
C(c.jar) B(c.jar) J(c.jar)
C(b.bean) B(b.bean) J(b.bean)
C(a.bean) B(a.bean) J(a.bean)
Also, in the 1st case, should the MainDeployer control the traversal, or simply pass the base context to each deployer, and he traverses at will?
Finally, what would the ClassLoadingDeployer do?
Judging from the 3.x/4.x mechanism it seems to be creating a UCL for the base node, then adding the classpath of all subnodes to this UCL. (but processing here is parent first).
Should I just go to the top most deployment, create a plain URLClassLoader, add all classpaths, and point to it from subcontexts?
The second stage deployers still need to ordered, but it may not be the
same order as the structural orders.
The difference is that ALL second stage deployers get to process the deployment.
The second stage deployers create the BeanMetaData and (un)install it to the kernel.
They DO NOT create objects explicitly, except where it would make no difference
to dependency ordering. e.g. There is little point telling the BeanMetaData to
instantatiate a java.lang.Integer through metadata when you can just pass the object
directly as the value (this assumes you have the object already rather than just a string).
So the ordering is less important at the second stage and only becomes relevent
when one deployer wants to process metadata created by a previous deployer.
This response is a repeat of a discussion we had at the end of last year.
It would not be a good idea to have the deployers know their own "next"
since the list can be potentially built and ordered dynamically.
The points you mention are clear more less, i.e. deployers don't know their next, they all process the deployment after the structure has been identified and they don't instantiate objects directly. Their order is decided at registration time.
What I'm trying to understant is, when having a deployment with nested subdeployments, if it is important for any given Deployer to process the deployment & subdeployments completely (either parent first, or depth first), before the next in the chain does the same. (This was the first scenario described)
I couldn't give you an answer to this without looking at use cases.
I would certainly stick to the current rules (deepest first).
My gut fealing is that you pass each deployment/subdeployment
individually down the chain. i.e. assume each deployment is independent.
PRO: We don't want subdeployments manipulating each other's data, they should
refer to each other via by reference/dependency
CON: If they are truly independent why would they be packaged together,
so maybe there are usecases where this tighter coupling is desirable?
Remember, when I talk about coupling I am talking about the metadata
They will of course be tightly coupled by the microcontainer when they are constructed
and wired together from the metadata.
The use case I can think of where coupling of metadata is required is when
the classloader metadata is constructed. Each subdeployment can add
metadata (urls) to the top level metadata that creates the classloader.
This is probably the more common pattern. i.e. Each subdeployment builds
up metadata (e.g. urls) at the top level which is processed last and adds global policy
(e.g. classloader isolation, java2 delegation, etc.)
This is the common behavior mode when there is aggregation:
The use case I can think of where coupling of metadata is required is when the classloader metadata is constructed. Each subdeployment can add metadata (urls) to the top level metadata that creates the classloader.
This is probably the more common pattern. i.e. Each subdeployment builds up metadata (e.g. urls) at the top level which is processed last and adds global policy (e.g. classloader isolation, java2 delegation, etc.)
A given deployment is likely to have configuration of an aspect that needs to be merged into the aggregate view when the deployment is joined to other deployments. In addition to class loading, logging and security are two more examples of aspects that should have an aggregate metadata and behavior. Its also non-deterministic as to what the aggregate behavior should be. In the case of logging it may be that the independent logging configurations should be left as is. An equally valid view is that the logging configuration seen at the root most level takes precedence.
Likewise how the merged security aspect should behave is arbitrary. It can be anything from independent untrusted domains to a global override from the root, to federated domains that have to arrange migration of security contexts based on trust relationships that are described by metadata that has no meaning in absence of aggregation.
In general this kind of problem is a cross cutting concern.
We have some tree of metadata that needs processing by a deployer aspect,
but only some parts of the metadata are relevent to it.
This is usually done by a vistor pattern.
But as we know, patterns are best implemented with aspects.
1) You avoid the boiler plate code
2) You don't need to know ahead of time where the pattern applies
The only problem is that we are now applying an aspect to an aspect :-)
Right, security and logging are aspects which should be applied to the deployment stack, not actually be deployers themselves.