geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jan Bartel <j...@mortbay.com>
Subject Re: [webapp deployment] Progress (was Re: [Deployment] Application Deployment Status)
Date Sun, 05 Oct 2003 14:17:36 GMT
Aaron,

>>I agree there may be common code that can be extracted for the 
>>deployment of various j2ee artifacts such as ears and wars. This will 
>>come out as development continues and matures. However, there will 
>>inevitably be differences between deploying say, a war, and a rar. It 
>>seems to me almost as if you are arguing for one big happy generic 
>>"application" deployer rather than specific deployers. If so, then I 
>>don't agree with that approach.
> 
> 
> 	I'm arguing to split it up, so we do much of the common reusable 
> tasks in a central deployer and then dispatch to a specific deployer for 
> the truly custom details.
I am definitely in favour of a central controller, but not a central 
deployer. The DeploymentController that we have now is the only central 
entity that is necessary. In other words, something whose only task is 
to notice that there are things that need to be deployed, undeployed or 
redeployed. The DeploymentController needs to be able to support both 
the geronimo hot deploy directory and also deployments coming from a 
JSR88 tool.

> 
> 
>>1. JSR88 deployment lifecycle vs geronimo hot deploy lifecycle
> 
> 
> 	My feeling is that distribute can be done nearly entirely by the
> common code, with 1 or 2 calls to the WebContainer.  Let's look at the
> case of an EAR.  Something needs to set up a series of ClassLoaders,
> create one MBean for the EAR and another per module, validate all the
> modules, and generate container-specific classes.  There are a number of 
> steps invokving Goals and Tasks and Plans.  I think the application 
> deployer could do everything listed above, with calls to the WebContainer 
> to:
> 
>  - get the AppModule MBean class name (to use for a createMBean task)
>  - validate the application (given URL, DD, etc.)
>  - generate container classes (which I think amounts to precompiling JSPs 
> in the case of a web container)
> 
> 	If there was other web-specific logic, it would presumably happen 
> in the postRegister event on the application MBean.  I think these same 3 
> steps would work for implementing "distribute" for every container type.  
> Most of the container-specific work seems to be in "start", which is 
> implemented by the container-specific app module MBean anyway.
In my reply to Gianny's email, I've said what I think is the biggest 
weakness with the central deployer approach: that is the lack of 
flexibility. To add support for a new deployable type, we'd have to 
modify the central deployer code, adding yet more "if then else" clauses 
each time. By keeping individual deployers (but that reuse common 
deployment code perhaps from a baseclass) we gain a lot of flexibility. 
For example, with individual deployers, we are able to hot deploy a new 
deployer and introduce support for a brand new deployment type into a 
running geronimo instance.


>>2. typed deployers
>>the central deployment mechanism should only be responsible for 
>>detecting things to be deployed, and arranging for distribute(), 
>>start(), undeploy() or whatever to be called on the appropriate 
>>deployer. Typed deployers are necessary because the things that are 
>>being deployed are different. Sure, they might go through a certain 
>>amount of common steps, and these can be abstracted for re-use within 
>>each deployer, but it does not follow that therefore there should only 
>>be one deployer for everything. For example, the web deployer, and only 
>>the web deployer, should be responsible for determining such things as 
>>the context path of a web application. This is very webby specific and 
>>the natural place for this is in a web module. The information that is 
>>used to determine that path can come from many sources: the name of the 
>>directory or war, a tag in an application DD, or an override in a 
>>geronimo-web DD, but the algorithm for choosing is specific to web 
>>deployments only.
> 
> 
> 	I agree with the spirit but potentially disagree with the example.  
> I do not believe that the application deployer should instruct the web
> deployer on how to set up a servlet context or something like that.  As 
> above, though, I think it can take most of the "distribute" work off your 
> hands, except for a couple container-specific callbacks.  And startup is 
> in your court anyway, thanks to JSR-77.
> 	As far as the context root is concerned, I don't want the web
> container groping for content outside the web app -- the last things we
> want is inadvertent dependencies where the web container penetrates its
> interface to root around in the guts of the server or the application.  
> So I thought it would be easy enough for the common deployer to do that
> calculation for you (after all, it has the EAR DD, the file name, etc.).  
> But it doesn't *have* to be done that way -- we could instead pass the EAR
> DD POJOs to the web container along with the WAR DD POJOs and let you do
> the calculation yourself.
I'd much prefer that the interface contract to the deployers contained 
the DD pojos (preferably as part of a DeploymentContext, but that is 
covered in other threads), so that the individual deployer can extract 
whatever information it requires. That allows for maximum flexibility.

> 
> 	Thinking back, I seem to have overlooked how the ObjectName will 
> be generated.  Personally I would rather have standard application module 
> ObjectNames no matter what container is plugged in, so I'd rather see 
> "geronimo.deployment:role=WebApplication,instance=(unique ID)" instead of 
> "jetty:...".  So I'd prefer to add a 4th method "getUniqueID" to the 3 
> listed above.  But if you feel strongly it could just be "getObjectName" 
> and you can construct a Jetty name instead.
As Gianny has pointed out, JSR77 seems to have something to say about 
acceptable names, so we'll stick to those. I just blindly followed the 
naming precedent that had been set in the "hack" Jetty integration. Now 
I know better :-)


>>3. ear/war relationship
>>wars can be deployed standalone, or bundled as part of an ear. In the 
>>latter case, then some of the deployment information for the war is 
>>contained in the deployment descriptor for the ear, and as you point 
>>out, the classloader hierarchy needs to be established. I think this 
>>should be handled as much as possible via the normal deployment mechanism.
>>
>>To that end, I suggest we augment the signature of the deploy, 
>>distribute, undeploy etc methods with another parameter: 
>>DeploymentContext. This context can contain deployment descriptor POJOs 
>>or xml, or classloader objects or perhaps state information. Anything 
>>that defines the context in which the deployment is taking place.
> 
> 
> 	Well, I agree that we need to get more information to each 
> container.
> 
> 	Let me propose a revised base WebContainer and WebApplication, and
> let me know what you think.  I believe this should leave the bulk of the
> "geronimo kernel"-specific logic in the central deployer, and the bulk of
> the module-specific logic in the container, which seems to me like the
> right split:
> 
> abstract class AbstractWebContainerMBean {
>   // returns i.e. JettyWebApplication
>   public abstract String getModuleMBeanClass()
> 
>   // validates the deployment and returns an ObjectName if valid
>   public abstract ObjectName validateDeployment(URL, EAR-POJOs, WAR-POJOs)
> }
> 
> abstract class AbstractWebApplicationMBean
>   public void setURL(URL)
>   public void setBaseClassLoader(ClassLoader/ClassSpace)
>   public void setEARDeploymentInfo(EAR-POJOs)
>   public void setWARDeploymentInfo(WAR-POJOs)
> 
>   // will be called during distribution process; can precompile JSPs
>   public abstract void generateContainerClasses()
> }
> 
> 	So now the sequence is something like this:
> 
>  - common deployer identifies app and modules
>  - (something) validates EAR
>  - common deployer creates app MBean
>  - for each RAR in EAR:
>    - common deployer calls ConnectorContainer to validate a RAR, gets
>      ObjectName for valid ones
>    - common deployer gets connector MBean class from ConnectorContainer
>    - common deployer creates Connector MBean w/class & ObjectName provided
>    - common deployer sets properties on Connector MBean
>    - common deployer tells Connector MBean to generate custom code
>    - common deployer gets ClassSpace from Connector MBean
>  - for each EJB JAR in EAR:
>    - common deployer calls EJBContainer to validate a JAR, gets
>      ObjectName for valid ones
>    - common deployer gets EJB JAR MBean class from EJBContainer
>    - common deployer creates EJB JAR MBean w/class & ObjectName provided
>    - common deployer sets properties on EJB JAR MBean
>    - common deployer tells EJB JAR MBean to generate custom code
>    - common deployer gets ClassSpace from EJB JAR MBean
>  - for each web app in EAR:
>    - common deployer calls WebContainer to validate a web app, gets
>      ObjectName for valid ones
>    - common deployer gets web MBean class from WebContainer
>    - common deployer creates web app MBean w/class & ObjectName provided
>    - common deployer sets properties on web app MBean
>    - common deployer tells web app MBean to generate custom code

As I mentioned above, one of the major problems with this approach
is the tight coupling between the EARDeployer and every other deployer
in the system. A looser coupling, whereby the EARDeployer, WARDeployer,
RARDeployer, ServiceDeployer and XYZDeployer all re-use common Deployer
code (maybe as a base class or maybe as a delegate), but all communicate 
through a standard set of JSR77/JSR88 style methods (JSR77: start/stop 
etc, JSR88: distribute, undeploy etc) mediated by the 
DeploymentController, gives us:

  - maximum flexibility to easily introduce support for new deployment
    types

  - uniformity of control flows

  - uses existing mechanisms for co-ordinating deployment, eg checking if
    a deployment task can proceed based on the outcome of other tasks,
    suspending deployments for which no appropriate deployer can be
    found, retrying failed deployments etc etc



> Note that all the deployment plans and goals and tasks are managed by 
> the common deployer -- when it says "creates web app MBean" and "sets 
> properties on web app MBean" it really means "registers a task in the 
> deployment plan to..."  So the WebContainer is doing web stuff not 
> deployment plan stuff.
> 
> Then at start time, there are just a bunch of JSR-77 start() commands
> executed, so the detailed startup logic is left to the module.
> 
> You seemed to be saying that there were web-specific steps that either the 
> common deployer would do inappropriately or the web container wouldn't be 
> given the opportunity to do -- would that still be the case?


cheers,
Jan


Mime
View raw message