Aaron,

Jan (and Greg),
        This looks cool.

That said, I'd like to work on centralizing some of the deployment
logic. All the work of dealing with deployment plans and tasks is going
to be fairly common across application module types, and we'll need to
bring a lot of it together when we deploy an EAR anyway (arranging
ClassLoaders and identifying context roots and so on).
Firstly, there was a thread about deployment in general and web deployment in particular a few weeks (maybe a month? time flies) ago. The main particpants were Jeremy and myself. We digressed away from a discussion about xml deployment descriptors and got onto topics like the deployment model for web apps, web containers etc.

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.

Also, the JSR-88
model lets you distribute an application to one or more servers without
starting it, and the MBeans need to created at distribute time so they can
be invoked to start it

        So I'd like to build most of that into the application deployer
service, and then have the application deployer call out to the
WebContainer, EJBContainer, etc. at a later stage, more like:

start(String contextRoot, ClassLoader parent, File warDir, (DD POJO));
stop(...)
restart(...)

Does that sound reasonable to you?
Weeeeeell, yes ... and no. Probably mostly no, actually sorry. I think there are various issues here:

1. JSR88 deployment lifecycle vs geronimo hot deploy lifecycle
2. typed deployers
3. ear/war relationship

Starting with 1.:
the deployment model we have now only covers the geronimo hot deploy situation, where essentially we distribute and start a deployable in the one step. We now need to augment that model to cope with the more sophisticated JSR88 lifecycle. In other words, now we have (leaving aside implementation details like goals, plans etc for clarity) the following method on a Deployer:


  deploy (URL url)
  {
      //construct and configure JSR077 components

      //call JSR077 start() on them
  }

Which really consists of something like:

   distribute (URL url)
   {
      //construct and configure JSR077 components
   }

   start (URL url)
   {
      //call JSR077 start() on the components created in
      //the distribute step
   }

So, we should promote these two substeps into the geronimo deployment model to satisfy the JSR88 lifecycle model.

2. 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.

The main reflection of this is that the deployment API should not
be webapp or service specific in any way.

3. 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.

Thus the ear/war deployment scenario I see is:

  + central deployment mechanism passes ear url off to the EarDeployer
    with a (probably) empty DeploymentContext object

  + EarDeployer detects an embedded war, so augments the
    DeploymentContext with appropriate contextual info and
    calls the central deployer mechanism with the url of the war and the
    DeploymentContext

  + the central deployer passes off the the war url and
    DeploymentContext to the war deployer

  + the war deployer does its *normal* thing, using any information
    provided in the DeploymentContext. eg. It is here that the logic is
    implemented to resolve the many ways a context path can be
    specified. The info for this logic is provided by the deployment
    mech, but the logic is in the webapp deployer.



Can you help me define what
the WebContainer interface should look like for that?  For example:

 - Should we always unpack a WAR into a temporary dir before handing it
over, or are you just as happy to get a packed WAR file?
The central deployer can choose to implement a policy of dectecting packed deployables and always unpacking them to a temporary directory. This policy should be configurable.

 - When we go to undeploy or redeploy, can we identify an existing
deployment by its context root or is there something better?
The deployer should only be identifying deployables by their url/uri.


- Do you need to be given the ObjectName for the web application?
I think it is up to the web deployment mechanism itself to work out the ObjectName for one of it's components. It should not be the concern of any other mechanism. Right now, the ObjectName of a WebApplication is created by the WebApplication itself, based on its context path. This is because WebApplications must be typed to the Container in which they reside, and the ObjectName contains this typing information.


 - How can we manage it if two applications claiming the same context root
are distributed (but not started)?  Presumably we need some way for a web
app to "reserve" a context root before its started (we'd like the
distribute to fail if the app couldn't be legitimately started afterward).
Two web deployer should accept distributions of webapps with the same context path. Whether or not that name conflicts with an already started webapp can only be determined at start time of the webapp.

cheers,
Jan

Thanks, Aaron

On Fri, 3 Oct 2003, Jan Bartel wrote:

The "proper" (as opposed to the temporary Jetty integration) webapp deployment mechanism is available now in it's early stage. An integration with this mechanism for the Jetty web container is also available.

To try it:

1. stop geronimo
2. remove the target/geronimo-DEV/deploy/jetty/jetty-service.xml file and replace it with the modules/web/src/dev-jetty-service.xml file
3. start geronimo


You should now be able to deploy packed wars and exploded wars via the normal geronimo deployment mechanism (ie dropping them in the target/geronimo-DEV/deploy directory). At the moment, wars containing uncompiled JSPs won't work, as an enhancement to Jetty is needed to extract a suitable JSP compile classpath from the geronimo classloader hierarchy before Jasper will be able to compile on-the-fly. Greg has this patch nearly ready. One caveat - I haven't had a chance to do much testing on this yet beyond dropping the geronimo-web-console.war into the deploy directory, so expect some surprises. Also be aware that there is no JNDI ENC support from the web deployer yet as there isn't (AFAIK) any datasources, ejbs etc yet within geronimo to put into such an ENC.

One valuable feature of the geronimo web deployment mechanism is that web layer objects such as listeners (aka connectors) and access logs are first class Geronimo services. This means that the configuration for them can be expressed in standard Geronimo mbean config syntax, rather than needing extra web-container specific config files. Here is the dev-jetty-service.xml file which contains all you need to get the Jetty container deployed and serving webapps on port 8088:


<components> <!-- ============================================================ --> <!-- Set up the Jetty-specific jars --> <!-- ============================================================ --> <class-space name="geronimo.system:role=ClassSpace,name=Jetty"> <codebase url="file:lib/"> <archive name="*"/> </codebase> <codebase url="file:../../lib/"> <archive name="geronimo-core-DEV.jar"/> <archive name="geronimo-common-DEV.jar"/> </codebase> </class-space>

  <!-- ============================================================ -->
  <!-- Set up a Jetty container                                     -->
  <!-- ============================================================ -->
  <mbean code="org.apache.geronimo.web.jetty.JettyWebContainer"
         name="jetty:role=WebContainer">
   <attribute type="java.net.URI"
              name="DefaultWebXmlURI">file:web-defaults.xml</attribute>
  </mbean>

  <!-- ============================================================ -->
  <!-- Set up a connector to listen for http requests               -->
  <!-- ============================================================ -->
  <mbean code="org.apache.geronimo.web.jetty.JettyWebConnector"
         name="jetty:role=WebConnector, port=8088">
    <attribute name="Port">8088</attribute>
    <depends name="jetty:role=WebContainer"/>
  </mbean>
</components>


On my list for the very near future is: + support for undeploy + support for webdefaults + support for JSR88 required data for webapps + JNDI ENC + parsing of web.xml and geronimo-web.xml deployment descriptors + support for a geronimo web access log service + testing, testing, testing

The longer term:
+ more testing :-)
+ support for web apps deployed inside an ear
+ support for redeploy
+ support for registering context names with a listener which
  must be deployed on the container before the listener will
  accept connections
+ support for simultaneous deployment of different web containers (eg
  Jetty and Tomcat in parallel)


I will try to update all this on the Geronimo wiki in the next few days. Just thought as the subject came up, I'd give everyone an update on what is happening in web-app deployment land.


cheers
Jan





Reply via email to