Re: The BIG Check-In for Multi-App Support

2002-01-30 Thread Ted Husted

Some others have gone fine, but I just moved a production application
over to recent releases of Validator and Tiles and got it working under
the 1.1 pre-BIG-check-in build. 

When I drop in the latest 1.1 Struts JAR, under Resin it comes up with 

500 Servlet Exception

java.lang.NoClassDefFoundError: org/apache/commons/digester/RuleSet
at java.lang.Class.newInstance0(Native Method)
at java.lang.Class.newInstance(Class.java:237)
at java.beans.Beans.instantiate(Beans.java:207)
at java.beans.Beans.instantiate(Beans.java:51)

I also had the same problem with the Velocity tools. OK under the
precheck in build, but now Resin reports the above, and Tomcat reports:

2002-01-30 18:38:19 StandardContext[/velstruts]: Servlet /velstruts
threw load() exception
javax.servlet.ServletException: Error instantiating servlet class
org.apache.struts.action.ActionServlet
at
org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:829)
at
org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3267)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:3384)
at
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:785)
at
org.apache.catalina.core.StandardHost.addChild(StandardHost.java:454)
at org.apache.catalina.core.StandardHost.install(StandardHost.java:712)
at
org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:599)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:777)
at
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:463)
at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:155)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1131)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:612)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1123)
at
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:307)
at
org.apache.catalina.core.StandardService.start(StandardService.java:388)
at
org.apache.catalina.core.StandardServer.start(StandardServer.java:505)
at org.apache.catalina.startup.Catalina.start(Catalina.java:776)
at org.apache.catalina.startup.Catalina.execute(Catalina.java:681)
at org.apache.catalina.startup.Catalina.process(Catalina.java:179)
at java.lang.reflect.Method.invoke(Native Method)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:243)
- Root Cause -
java.lang.NoClassDefFoundError: org/apache/commons/digester/RuleSet
at java.lang.Class.newInstance0(Native Method)
at java.lang.Class.newInstance(Unknown Source)
at
org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:820)
at
org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3267)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:3384)
at
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:785)
at
org.apache.catalina.core.StandardHost.addChild(StandardHost.java:454)
at org.apache.catalina.core.StandardHost.install(StandardHost.java:712)
at
org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:599)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:777)
at
org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:463)
at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:155)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1131)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:612)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1123)
at
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:307)
at
org.apache.catalina.core.StandardService.start(StandardService.java:388)
at
org.apache.catalina.core.StandardServer.start(StandardServer.java:505)
at org.apache.catalina.startup.Catalina.start(Catalina.java:776)
at org.apache.catalina.startup.Catalina.execute(Catalina.java:681)
at org.apache.catalina.startup.Catalina.process(Catalina.java:179)
at java.lang.reflect.Method.invoke(Native Method)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:243)



I'll try to look into this futher, but wanted to pass along the report.

Meanwhile, I've started to move the Artimus example into the
modular/DynaBean format, so we will have a good working example of that.
I'm *very* excited about the module and DynaBean support in the new
controller package. 

-Ted.

--
To unsubscribe, e-mail:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




Re: The BIG Check-In for Multi-App Support

2002-01-18 Thread Martin Cooper

I've finally had a chance to spend a little time looking at this, and it's
*very* cool.

Regarding backward compatibility, I tried running a large, complicated
Struts 1.0 app, complete with customisations of ActionServlet and friends,
on top of the latest nightly build, and saw no problems at all. It worked
flawlessly. Awesome, Craig!

One area that we might give more thought to is that of message resources. In
both Struts 1.0.x and the latest code, the apparent assumption is that each
application has a single source of message resources. (Alternatively, it is
assumed that any other message resources are handled independently of
Struts.) In practise, that is not always the case. Each application may have
multiple sets of message resources, one of which would typically be the
default.

Since the DTD now includes support for (default) message resources, how
about expanding that capability to allow for the definition of multiple
message resources per application, where each non-default resource would
have an identifier (key) associated with it?

--
Martin Cooper


- Original Message -
From: Craig R. McClanahan [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Saturday, January 12, 2002 4:52 PM
Subject: The BIG Check-In for Multi-App Support


 OK, I think I've got it working now -- the support for multiple Struts
 sub-applications in a single web-app, that is.

 While I'm writing up some documentation for it, here's the key points that
 will help you experiment with it:

 * All of the configuration information about a sub-app is stored
   in the ApplicationConfig object, including a bunch of stuff that
   used to be set with init parameters on the controller servlet.

 * A multi-app environment still runs from a single instance of the
   controller servlet, but you can have multiple struts-config.xml
   files -- one per sub-application.

 * The sub-application that applies to a particular request is based
   on matching an application prefix at the beginning of the
   context-relative URI (similar to the way that a servlet container
   chooses the web app to run based on the context path prefix of the
   request URI.

 * Like a servlet container, there is the notion of a default
   sub-application that is used to process requests not assigned to
   any sub-applicaiton.  The prefix for this application is 
   (i.e. the empty string).

 * All of the context relative values in struts-config.xml are now
   application-relative instead -- in other words, the request URI
   equals context path + application prefix + local value.  This
   works even for the default sub-application, because its prefix is
   a zero-length string.

 * A primary design goal is that the struts-config.xml for an existing
   Struts applicaiton can be used as a sub-application with no changes.
   Failure of this to work should be considered a bug in the current
   implementation, and needs to be fixed.

 * In addition to its other duties, the controller servlet creates
   two request attributes for all requests that flow through the
   controller:

 Action.APPLICATION_KEYWill contain the ApplicationConfig
   instance for the sub-applcation that
   is selected by the current request URI.

 Action.MESSAGES_KEY   Will contain the MessageResources
   instance for the sub-applcation that
   is selected by the current request URI.

 * WARNING:  If you want to use your existing Struts application as a
   sub-application, then *ALL* of the requests must flow through the
   controller servlet -- no direct linking to pages -- in order for the
   above request attributes to always be set.  In a servlet 2.3
   environment, we'd be able to avoid worrying about this by using
   a filter, but that doesn't help under servlet 2.2.

 * A known issue is that sub-apps won't work for path-mapped actions --
   only extension mapped at the moment.  I believe this can be fixed, but
   wanted to focus on getting the basics right first.

 As a quick example of the new approach, assume you have three sub-apps:
   main - Main menu and such (this is the default subapp)
   catalog - The shopping portion of a shopping site - prefix /catalog
   checkout - The checkout portion of a shopping site - prefix /checkout

 You would configure the sub-applicaitons in their own struts-config files,
 and tell the controller servlet about them like this:

   servlet

 servlet-nameaction/servlet-name
 servlet-classorg.apache.struts.action.ActionServlet/servlet-class

 !-- The default sub-application --
 init-param
   param-nameconfig/param-name
   param-value/WEB-INF/struts-config-main.xml/param-value
 /init-param

 !-- The catalog sub-application --
 init-param
   param-nameconfig/catalog/param-name -- Includes prefix! --
   param-value/WEB-INF/struts-config-catalog.xml/param-value
 /init-param

RE: The BIG Check-In for Multi-App Support

2002-01-15 Thread Craig R. McClanahan



On Mon, 14 Jan 2002, Donnie Hale wrote:

 Date: Mon, 14 Jan 2002 23:54:33 -0500
 From: Donnie Hale [EMAIL PROTECTED]
 Reply-To: Struts Developers List [EMAIL PROTECTED]
 To: Struts Developers List [EMAIL PROTECTED]
 Subject: RE: The BIG Check-In for Multi-App Support

 I've finally had a chance to download this check-in. Please note that while
 I've built it, I haven't yet had a chance to test it with anything. Are
 there any examples yet which include all these new features (exceptions,
 roles, multi-apps, etc.)? There's a lot get one's arms around.

 Most importantly, this is great stuff and really appreciated. If one of the
 committers would propose giving Craig a raise, I'd +1 it. ;)

 So... Some general comments and comments from looking at pieces of the code:

 1. I don't know if this is carved in stone yet, but IMHO this is much more
 than a 1.1 release. Perhaps not a 2.0 release, but at least a 1.5 release.
 The implications of a single point release to me are minor functional
 enhancements and bug fixes. These are substantive, major functional
 enhancements which still provide backward compatibility. Again, just my
 opinion...


I don't consider any of it cast in stone.  There are way to many smart
people contributing to the future of Struts for me to have the only good
ideas.

The reason I still want to call the next release 1.1 is this:  despite the
huge number of internal changes, the fundamental APIs for applications
*are* pretty much backwards compatible.  That's a promise that was made
early on in Struts development, and I want to honor that.  Calling it 1.5
or 2.0 would raise concerns in people's minds about compatibility -- even
if those fears turned out to be unfounded.


 2. I'm thrilled to see all the config-related stuff broken out from the
 servlet. I did this myself in some recent attempts at refactoring
 ActionServlet, and the effort was desperately needed to make ActionServlet
 more approachable. Naturally, Craig did a better job than I, as he gave each
 piece of config info its own class. Much more manageable and flexible that
 way.


Besides making things easier to understand, it's already had an additional
benefit -- new configuration parameters can be added with no code changes
to the controller servlet.  In fact, if you're adding a property to an
existing config object, it is just a matter of a getter and setter, and
the automatic introspection logic in Digester takes care of things.

 3. In the DTD, the BeanName entity is being overloaded somewhat in that it's
 used for naming keys to various context attributes as well as for the form
 beans. BeanName is documented as having to be a legal Java identifier since
 it's used in JSPs; not sure off the top of my head if that is a constraint
 on attribute names in the various servlet contexts or not. In any case,
 might I suggest a ContextKey entity be added to the DTD and that used
 where appropriate (data-source.key, action.attribute, etc.).


That definitely sounds like a good idea.  At some point we might add an
XML Schema (or other) validation of the struts-config.xml file that adds
more semantic checks, so it would be good to get the names right now.

 4. Breaking out the request processing into RequestProcessor is also huge.
 ActionServlet plus the config stuff seem like they can now stand alone with
 pluggable request processing easily able to reuse those elements.

Yep.  A subsequent check-in enabled having different RequestProcessor
instances (and even implementation classes) per sub-application.


 5. In the new ActionServlet, doGet and doPost are identical. Would it be
 better to delegate their implementations, simple though they are, to a
 protected overridable method?


When it was a single hard-coded request processor instance, the
implementation was one line each - I guess three lines is enough to make a
subordinate method again.

 6. It's a little confusing seeing member variables of type and name
 FastHashmap actions in both ApplicationConfig and RequestProcessor.
 Perhaps the variable names could be clarified.


In ApplicationConfig, maybe the variable name should be actionConfigs?
That corresponds to what the Map actually contains.

 7. Is the special handling for the default app's ControllerConfig and
 MessageResourcesConfig so that existing web.xml files will still work for
 setting those parameters?


Yes.  It actually took just as long to figure out how to deal with this as
the rest of the design.

 8. ActionForward and ActionMappings both still retain references to
 ActionServlet, and in both cases it seems primarily to allow the user of an
 ActionForward or ActionMappings to get a reference to the servlet. With the
 drastic changes to ActionServlet, what method on ActionServlet would the
 user of an ActionForward or ActionMappings need to call? I guess what I'm
 saying is that it would be nice to deprecate and/or remove those
 getServlet/setServlet methods from those classes if they're not really

RE: The BIG Check-In for Multi-App Support

2002-01-15 Thread Donnie Hale

Craig,

Thanks for the detailed reply. See below.


[snip[
 
  1. I don't know if this is carved in stone yet, but IMHO this
 is much more
  than a 1.1 release. Perhaps not a 2.0 release, but at least a
 1.5 release.
  The implications of a single point release to me are minor functional
  enhancements and bug fixes. These are substantive, major functional
  enhancements which still provide backward compatibility. Again, just my
  opinion...
 

 I don't consider any of it cast in stone.  There are way to many smart
 people contributing to the future of Struts for me to have the only good
 ideas.

 The reason I still want to call the next release 1.1 is this:  despite the
 huge number of internal changes, the fundamental APIs for applications
 *are* pretty much backwards compatible.  That's a promise that was made
 early on in Struts development, and I want to honor that.  Calling it 1.5
 or 2.0 would raise concerns in people's minds about compatibility -- even
 if those fears turned out to be unfounded.

I guess my point was that anything 1.x implies backward compatibility, but
a bigger point change implies somewhat substantive functional changes. To
Ted - going straight from 1.0.1 to 1.5 wouldn't make me wonder about
intervening versions any more than going from 1.2 (or whatever the highest
1.x version of Struts ends up being) to 2.0 will. :)

[snip]

  4. Breaking out the request processing into RequestProcessor is
 also huge.
  ActionServlet plus the config stuff seem like they can now
 stand alone with
  pluggable request processing easily able to reuse those elements.

 Yep.  A subsequent check-in enabled having different RequestProcessor
 instances (and even implementation classes) per sub-application.

I noticed that, and I'm hoping to get a chance to revisit the way I'd like
to see a RequestProcess be designed. I didn't get that far since I was going
about refactoring ActionServlet. But now you've done the dirty work, and
it's checked in!!!



 
  5. In the new ActionServlet, doGet and doPost are identical. Would it be
  better to delegate their implementations, simple though they are, to a
  protected overridable method?
 

 When it was a single hard-coded request processor instance, the
 implementation was one line each - I guess three lines is enough to make a
 subordinate method again.

I think that's a good idea. Someone may want to override both, and it would
be easier to get the super() call right if they just have to override the
subordinate method.



  6. It's a little confusing seeing member variables of type and name
  FastHashmap actions in both ApplicationConfig and RequestProcessor.
  Perhaps the variable names could be clarified.
 

 In ApplicationConfig, maybe the variable name should be actionConfigs?
 That corresponds to what the Map actually contains.

I think that's a good idea.



  7. Is the special handling for the default app's ControllerConfig and
  MessageResourcesConfig so that existing web.xml files will
 still work for
  setting those parameters?
 

 Yes.  It actually took just as long to figure out how to deal with this as
 the rest of the design.

Do you think it's possible to target the eventual deprecation of that
capability - i.e. requiring thos parms to be in struts-config.xml, even for
the default app? I understand the reasoning now, but I think it will be
confusing to newcomers in the future and could cause support issues if
someone drops in a struts-config.xml file with those values set and intends
it to configure the default app.

One other question I forgot to ask - you've marked findDataSource and
destroyDataSources as deprecated. Should that not also make the dataSources
FastHashmap member variable deprecated. It would seem that since the
datasources are stuck straight into the context, Struts can let the
container manage them and eliminate having to manage them itself.



  8. ActionForward and ActionMappings both still retain references to
  ActionServlet, and in both cases it seems primarily to allow
 the user of an
  ActionForward or ActionMappings to get a reference to the
 servlet. With the
  drastic changes to ActionServlet, what method on ActionServlet would the
  user of an ActionForward or ActionMappings need to call? I
 guess what I'm
  saying is that it would be nice to deprecate and/or remove those
  getServlet/setServlet methods from those classes if they're not really
  required, esp. if the best practice way to get to a resource
 is through
  one of the contexts. FWIW...
 

 Deprecation is probably a reasonable idea, but I want to walk through the
 code paths to see if the servlet references are used internally anywhere
 first.

I did searches throughout the base code and didn't come up w/ anything. My
biggest concern, and why deprecation would be preferred, is if there are
derived ActionForward / ActionMapping classes that think they need access to
it. But they're likely broken anyway since, I believe, a lot of the API
they'd expect from 

RE: The BIG Check-In for Multi-App Support

2002-01-14 Thread Donnie Hale

I've finally had a chance to download this check-in. Please note that while
I've built it, I haven't yet had a chance to test it with anything. Are
there any examples yet which include all these new features (exceptions,
roles, multi-apps, etc.)? There's a lot get one's arms around.

Most importantly, this is great stuff and really appreciated. If one of the
committers would propose giving Craig a raise, I'd +1 it. ;)

So... Some general comments and comments from looking at pieces of the code:

1. I don't know if this is carved in stone yet, but IMHO this is much more
than a 1.1 release. Perhaps not a 2.0 release, but at least a 1.5 release.
The implications of a single point release to me are minor functional
enhancements and bug fixes. These are substantive, major functional
enhancements which still provide backward compatibility. Again, just my
opinion...

2. I'm thrilled to see all the config-related stuff broken out from the
servlet. I did this myself in some recent attempts at refactoring
ActionServlet, and the effort was desperately needed to make ActionServlet
more approachable. Naturally, Craig did a better job than I, as he gave each
piece of config info its own class. Much more manageable and flexible that
way.

3. In the DTD, the BeanName entity is being overloaded somewhat in that it's
used for naming keys to various context attributes as well as for the form
beans. BeanName is documented as having to be a legal Java identifier since
it's used in JSPs; not sure off the top of my head if that is a constraint
on attribute names in the various servlet contexts or not. In any case,
might I suggest a ContextKey entity be added to the DTD and that used
where appropriate (data-source.key, action.attribute, etc.).

4. Breaking out the request processing into RequestProcessor is also huge.
ActionServlet plus the config stuff seem like they can now stand alone with
pluggable request processing easily able to reuse those elements.

5. In the new ActionServlet, doGet and doPost are identical. Would it be
better to delegate their implementations, simple though they are, to a
protected overridable method?

6. It's a little confusing seeing member variables of type and name
FastHashmap actions in both ApplicationConfig and RequestProcessor.
Perhaps the variable names could be clarified.

7. Is the special handling for the default app's ControllerConfig and
MessageResourcesConfig so that existing web.xml files will still work for
setting those parameters?

8. ActionForward and ActionMappings both still retain references to
ActionServlet, and in both cases it seems primarily to allow the user of an
ActionForward or ActionMappings to get a reference to the servlet. With the
drastic changes to ActionServlet, what method on ActionServlet would the
user of an ActionForward or ActionMappings need to call? I guess what I'm
saying is that it would be nice to deprecate and/or remove those
getServlet/setServlet methods from those classes if they're not really
required, esp. if the best practice way to get to a resource is through
one of the contexts. FWIW...

Thanks for bearing with me. Please note that I'm not trying to avoid
contributing by bringing up these issues. I want to make sure I don't jump
to any false conclusions before I try to help out.

Thanks again,

Donnie


 -Original Message-
 From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]]
 Sent: Saturday, January 12, 2002 7:53 PM
 To: [EMAIL PROTECTED]
 Subject: The BIG Check-In for Multi-App Support


 OK, I think I've got it working now -- the support for multiple Struts
 sub-applications in a single web-app, that is.

 While I'm writing up some documentation for it, here's the key points that
 will help you experiment with it:

 * All of the configuration information about a sub-app is stored
   in the ApplicationConfig object, including a bunch of stuff that
   used to be set with init parameters on the controller servlet.

 * A multi-app environment still runs from a single instance of the
   controller servlet, but you can have multiple struts-config.xml
   files -- one per sub-application.

 * The sub-application that applies to a particular request is based
   on matching an application prefix at the beginning of the
   context-relative URI (similar to the way that a servlet container
   chooses the web app to run based on the context path prefix of the
   request URI.

 * Like a servlet container, there is the notion of a default
   sub-application that is used to process requests not assigned to
   any sub-applicaiton.  The prefix for this application is 
   (i.e. the empty string).

 * All of the context relative values in struts-config.xml are now
   application-relative instead -- in other words, the request URI
   equals context path + application prefix + local value.  This
   works even for the default sub-application, because its prefix is
   a zero-length string.

 * A primary design goal is that the struts-config.xml

Re: The BIG Check-In for Multi-App Support

2002-01-13 Thread Ted Husted

Craig R. McClanahan wrote:
 Let's get this new code wrinkled out in the short term so that we can move
 towards a 1.1 release as well as the 1.0.1 that was just created.

Cool. I can put this to work right away in the Artimus package, 

http://husted.com/scaffolding/dist/artimus.zip

since it is already designed around the idea of sub apps (even though
we didn't have them yet). 


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Building Java web applications with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




RE: The BIG Check-In for Multi-App Support

2002-01-13 Thread Michael Nash

Craig:

 OK, I think I've got it working now -- the support for multiple Struts
 sub-applications in a single web-app, that is.

I'm happy to hear about this, as it's one of the things we extended in
Struts 1.0 when we connected it with Expresso, as the sub-app concept was
important for Expresso applications, like eForum, ePoll, etc.

I'd like to merge what we did with where you're going, and of course any
bits of what we've done already that are useful you're welcome to as well.

Just some observations on the parallels, for people using both Expresso and
Struts - they're pretty close in most cases, so a merge wouldn't be a
serious impedance mismatch from what I can see:

 * All of the configuration information about a sub-app is stored
   in the ApplicationConfig object, including a bunch of stuff that
   used to be set with init parameters on the controller servlet.

This sounds a lot like what we currently call a Schema object (which is a
misleading name, I know). The relative path to the MessageBundle for the
sub-app lives in the Schema. In Expresso the Schema object also defines the
list of DBObjects, Jobs, and Controllers (Action) objects, so we can do
things like default security, DB creation, etc. Sounds like maybe Schema
extends ApplicationConfig is in the cards...

 * A multi-app environment still runs from a single instance of the
   controller servlet, but you can have multiple struts-config.xml
   files -- one per sub-application.

One of our contributors extended ControllerServlet to simply read all xml's
with the appropriate DTD in  a specific directory, one per sub-app. Might
this be easier than having to least each app in the web.xml? One less thing
to configure? Just thinking out loud... Or does the param to the
ControllerServlet also define the prefix? We do the same kind of thing with
Lo4j config files - put each of them in a specific directory, then read
everything that matches that doctype. Makes configuring a new app pretty
quick and painless.

 * The sub-application that applies to a particular request is based
   on matching an application prefix at the beginning of the
   context-relative URI (similar to the way that a servlet container
   chooses the web app to run based on the context path prefix of the
   request URI.

In Expresso we have a table in the DB that lists all the Schema objects,
and each one has a prefix like this associated with it. It also forms a
prefix for finding related JSP/HTML/doc for the sub-app, so it serves
double-duty in that sense.

 * Like a servlet container, there is the notion of a default
   sub-application that is used to process requests not assigned to
   any sub-applicaiton.  The prefix for this application is 
   (i.e. the empty string).

Great news - we're already on this path, so that's no change at all.

 * All of the context relative values in struts-config.xml are now
   application-relative instead -- in other words, the request URI
   equals context path + application prefix + local value.  This
   works even for the default sub-application, because its prefix is
   a zero-length string.

Ditto, no change here.

 * A known issue is that sub-apps won't work for path-mapped actions --
   only extension mapped at the moment.  I believe this can be fixed, but
   wanted to focus on getting the basics right first.

Has there been any thought to extended path info as parameters? We were
doing this before Expresso 4.0, but dropped it when we integrated Struts
1.0 - does make for cleaner URLs sometimes...

I look forward to seeing this evolve, and helping Expresso evolve with it.
Thanks for the update!

Regards,

Mike


--
To unsubscribe, e-mail:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




RE: The BIG Check-In for Multi-App Support

2002-01-13 Thread Craig R. McClanahan



On Sun, 13 Jan 2002, Michael Nash wrote:

 Date: Sun, 13 Jan 2002 10:44:04 -0500
 From: Michael Nash [EMAIL PROTECTED]
 Reply-To: Struts Developers List [EMAIL PROTECTED],
  [EMAIL PROTECTED]
 To: Struts Developers List [EMAIL PROTECTED]
 Subject: RE: The BIG Check-In for Multi-App Support

 Craig:

  OK, I think I've got it working now -- the support for multiple Struts
  sub-applications in a single web-app, that is.

 I'm happy to hear about this, as it's one of the things we extended in
 Struts 1.0 when we connected it with Expresso, as the sub-app concept was
 important for Expresso applications, like eForum, ePoll, etc.

 I'd like to merge what we did with where you're going, and of course any
 bits of what we've done already that are useful you're welcome to as well.

 Just some observations on the parallels, for people using both Expresso and
 Struts - they're pretty close in most cases, so a merge wouldn't be a
 serious impedance mismatch from what I can see:

  * All of the configuration information about a sub-app is stored
in the ApplicationConfig object, including a bunch of stuff that
used to be set with init parameters on the controller servlet.

 This sounds a lot like what we currently call a Schema object (which is a
 misleading name, I know). The relative path to the MessageBundle for the
 sub-app lives in the Schema. In Expresso the Schema object also defines the
 list of DBObjects, Jobs, and Controllers (Action) objects, so we can do
 things like default security, DB creation, etc. Sounds like maybe Schema
 extends ApplicationConfig is in the cards...


If I was building from scratch, knowing what we know now (how many times
have we said *that* before :-), I probably would have ended up with
something more like this.  I left MessageResources bundles separate,
though, because quite a few apps seem to look them up individually and I
wanted to minimize the backwards-incompatible changes.

However, having the config stuff in a separate object tree has already
helped in one major respect -- adding new configuration parameters doesn't
require any tweaks to the controller servlet any more.  All you do is add
the getter and setter to the appropriate Config bean, and voila ...

  * A multi-app environment still runs from a single instance of the
controller servlet, but you can have multiple struts-config.xml
files -- one per sub-application.

 One of our contributors extended ControllerServlet to simply read all xml's
 with the appropriate DTD in  a specific directory, one per sub-app. Might
 this be easier than having to least each app in the web.xml? One less thing
 to configure? Just thinking out loud... Or does the param to the
 ControllerServlet also define the prefix? We do the same kind of thing with
 Lo4j config files - put each of them in a specific directory, then read
 everything that matches that doctype. Makes configuring a new app pretty
 quick and painless.

It's certainly possible to do all the XML files in directory foo in a
Servlet 2.3 environment, because you can use
ServletContext.getResourcePaths() to identify them in a portable manner.
In a Servlet 2.2 world, though, you have to rely on file i/o for that --
something I'd prefer to avoid since it is not guaranteed to be available
everywhere.

Instead, I used a trick that I've done in other environments -- the prefix
for a subapp is part of the parameter name.  For my example scenario, you
have config (which is backwards compatible :-), config/catalog, and
config/checkout.


  * The sub-application that applies to a particular request is based
on matching an application prefix at the beginning of the
context-relative URI (similar to the way that a servlet container
chooses the web app to run based on the context path prefix of the
request URI.

 In Expresso we have a table in the DB that lists all the Schema objects,
 and each one has a prefix like this associated with it. It also forms a
 prefix for finding related JSP/HTML/doc for the sub-app, so it serves
 double-duty in that sense.


I did a subsequent checkin that lets you configure different
RequestProcessor instances (and even implementation classes) for each
sub-app, in case they need different customizations to the standard
request processing functionality.

  * Like a servlet container, there is the notion of a default
sub-application that is used to process requests not assigned to
any sub-applicaiton.  The prefix for this application is 
(i.e. the empty string).

 Great news - we're already on this path, so that's no change at all.


Great minds and all ... :-)

  * All of the context relative values in struts-config.xml are now
application-relative instead -- in other words, the request URI
equals context path + application prefix + local value.  This
works even for the default sub-application, because its prefix is
a zero-length string.

 Ditto, no change here.

  * A known issue is that sub

The BIG Check-In for Multi-App Support

2002-01-12 Thread Craig R. McClanahan

OK, I think I've got it working now -- the support for multiple Struts
sub-applications in a single web-app, that is.

While I'm writing up some documentation for it, here's the key points that
will help you experiment with it:

* All of the configuration information about a sub-app is stored
  in the ApplicationConfig object, including a bunch of stuff that
  used to be set with init parameters on the controller servlet.

* A multi-app environment still runs from a single instance of the
  controller servlet, but you can have multiple struts-config.xml
  files -- one per sub-application.

* The sub-application that applies to a particular request is based
  on matching an application prefix at the beginning of the
  context-relative URI (similar to the way that a servlet container
  chooses the web app to run based on the context path prefix of the
  request URI.

* Like a servlet container, there is the notion of a default
  sub-application that is used to process requests not assigned to
  any sub-applicaiton.  The prefix for this application is 
  (i.e. the empty string).

* All of the context relative values in struts-config.xml are now
  application-relative instead -- in other words, the request URI
  equals context path + application prefix + local value.  This
  works even for the default sub-application, because its prefix is
  a zero-length string.

* A primary design goal is that the struts-config.xml for an existing
  Struts applicaiton can be used as a sub-application with no changes.
  Failure of this to work should be considered a bug in the current
  implementation, and needs to be fixed.

* In addition to its other duties, the controller servlet creates
  two request attributes for all requests that flow through the
  controller:

Action.APPLICATION_KEYWill contain the ApplicationConfig
  instance for the sub-applcation that
  is selected by the current request URI.

Action.MESSAGES_KEY   Will contain the MessageResources
  instance for the sub-applcation that
  is selected by the current request URI.

* WARNING:  If you want to use your existing Struts application as a
  sub-application, then *ALL* of the requests must flow through the
  controller servlet -- no direct linking to pages -- in order for the
  above request attributes to always be set.  In a servlet 2.3
  environment, we'd be able to avoid worrying about this by using
  a filter, but that doesn't help under servlet 2.2.

* A known issue is that sub-apps won't work for path-mapped actions --
  only extension mapped at the moment.  I believe this can be fixed, but
  wanted to focus on getting the basics right first.

As a quick example of the new approach, assume you have three sub-apps:
  main - Main menu and such (this is the default subapp)
  catalog - The shopping portion of a shopping site - prefix /catalog
  checkout - The checkout portion of a shopping site - prefix /checkout

You would configure the sub-applicaitons in their own struts-config files,
and tell the controller servlet about them like this:

  servlet

servlet-nameaction/servlet-name
servlet-classorg.apache.struts.action.ActionServlet/servlet-class

!-- The default sub-application --
init-param
  param-nameconfig/param-name
  param-value/WEB-INF/struts-config-main.xml/param-value
/init-param

!-- The catalog sub-application --
init-param
  param-nameconfig/catalog/param-name -- Includes prefix! --
  param-value/WEB-INF/struts-config-catalog.xml/param-value
/init-param

!-- The checkout sub-application --
init-param
  param-nameconfig/checkout/param-name -- Includes prefix! --
  param-value/WEB-INF/struts-config-checkout.xml/param-value
/init-param

... other global parameters ...

  /servlet

In such an environment, you might have context-relative request URIs like:

  /index.jsp  Main menu of the entire site
  /logon.do   Log on action (default subapp)

  /catalog/index.jsp  Main menu of the product catalog
  /catalog/addItem.do Add an item to the shopping cart

  /checkout/index.jsp Beginning of the check out area
  /checkout/checkVisa.do  Check the entered VISA credit card number

Application Development Issues:

* As stated above, I tried to maximize backwards compatibility.  The
  following points are things I know about that might impact porting
  of existing Struts apps into being usable in a multi-sub-app
  environment as a sub-application (no change should be required to
  continue use as the default sub-app).

* Applications that are calling Action.getResources() should be modified
  to call Action.getResources(HttpServletRequest) instead.  This allows
  you to pick up the message resources that are unique to this
  sub-application.  Otherwise, the message resources for the default
  sub-app will be used.

*