DWR

Hassle using DWR in modular web applications

Details

  • Type: Improvement Improvement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: 2.0.2
  • Fix Version/s: 3.0.1
  • Component/s: Core
  • Description:
    Hide
    This issue is continuation of thread in user mailing list. Just to recapitulate:

    I submited an issue DWR-174 (
    http://getahead.org/bugs/browse/DWR-174?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
    ) that is resolved by now - but only in its easiest way. I would like
    to propose more general solution, but that means some discussion in
    advance.

    I will describe the situation we have in our projects. We build
    modular web systems in which we use DWR for AJAX. Most of our modules
    are based on Spring nowadays and are assembled together at runtime
    leveraging hierarchical tree of Spring application contexts.

    We want to provide AJAX support for each module and the problem is as follows:

    * each module has to have its own namespace (in Spring it is ensured
    by having application context for each module) - in DWR it means it
    has to have its own SpringContainer for each module configured in
    comformity with its Spring app context
    * DWR requests has to furthermore analyzed to select appropriate
    target module - this could be easily done by parsing requestPath - but
    the problem is DWR could make its own redirects that will break url
    logic
    * to support older modules we have to provide DWR support using
    standard DefaultContainer

    We have implemented a solution to this, but it could be hardly called
    clean. It involves using custom servlet that internally holds pool of
    DwrServlets and DwrSpringServlets and that performs the selection
    logic and delegates servlet processing onto chosen dwr servlet.

    Additionally there has been problems with redirects executed inside
    Dwr UrlProcessors - to address this issue we had to wrap HttpRequest
    to imitate correct request url (namely overriding getPathInfo() and
    getServletPath() method) in order to ensure all fired redirects will
    contain url with module selectors in path we use in delegation servlet
    to select appropriate DWR delegate.

    I hope I described the matter compherensible and I wonder whether we
    are alone or whether there is anybody fighting the same.

    Do you thing there is a chance to have this issue addresed by the DWR
    library itself? Waht it would involve?
    Show
    This issue is continuation of thread in user mailing list. Just to recapitulate: I submited an issue DWR-174 ( http://getahead.org/bugs/browse/DWR-174?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ) that is resolved by now - but only in its easiest way. I would like to propose more general solution, but that means some discussion in advance. I will describe the situation we have in our projects. We build modular web systems in which we use DWR for AJAX. Most of our modules are based on Spring nowadays and are assembled together at runtime leveraging hierarchical tree of Spring application contexts. We want to provide AJAX support for each module and the problem is as follows: * each module has to have its own namespace (in Spring it is ensured by having application context for each module) - in DWR it means it has to have its own SpringContainer for each module configured in comformity with its Spring app context * DWR requests has to furthermore analyzed to select appropriate target module - this could be easily done by parsing requestPath - but the problem is DWR could make its own redirects that will break url logic * to support older modules we have to provide DWR support using standard DefaultContainer We have implemented a solution to this, but it could be hardly called clean. It involves using custom servlet that internally holds pool of DwrServlets and DwrSpringServlets and that performs the selection logic and delegates servlet processing onto chosen dwr servlet. Additionally there has been problems with redirects executed inside Dwr UrlProcessors - to address this issue we had to wrap HttpRequest to imitate correct request url (namely overriding getPathInfo() and getServletPath() method) in order to ensure all fired redirects will contain url with module selectors in path we use in delegation servlet to select appropriate DWR delegate. I hope I described the matter compherensible and I wonder whether we are alone or whether there is anybody fighting the same. Do you thing there is a chance to have this issue addresed by the DWR library itself? Waht it would involve?
  1. AbstractDwrServlet.java
    (2 kB)
    Jan Novotný
    20/Feb/08 12:20 PM
  2. DefaultContainerManager.java
    (5 kB)
    Jan Novotný
    20/Feb/08 12:20 PM
  3. DwrServlet.java
    (2 kB)
    Jan Novotný
    20/Feb/08 12:20 PM
  4. DwrSpringServlet.java
    (3 kB)
    Jan Novotný
    20/Feb/08 12:20 PM
  5. SpringContainerManager.java
    (3 kB)
    Jan Novotný
    20/Feb/08 12:20 PM

Activity

Hide
Jan Novotný added a comment - 20/Feb/08 12:19 PM

Jose Noheda:

Hi,

I'm not sure I've understood completely. Here's more or less what I'm imaging:

You have several DwrSpringServlets each one with a Spring application context injected.
You have several DwrServlets each with some remoted objects
Each servlet is mapped to a different URL
You have some kind of servlet that redirects (filter that forwards?) the processing to the correct servlet (I don't really understand why)
You need that DWR supports internally the handling of many servlets and/or different kind of configurations with one entry point

Can you clarify if that's correct? I would really need an example web.xml with three or so servlet definitions (and mappings) and one sample flow (of a client call).

Regards,

Jan Novotny:

Hello,

You are correct in most of points. I realized, that I omit to
mention that in web.xml there is only one registered servlet. As I
wrote application is assembled in runtime - so you can enable /
disable certain modules without restarting webapp context and
application will respond immediately.
It means, that our servlet must somehow react on live application
reassembly, free internal pool of servlets and initialize new ones for
current application assembly.

Web.xml part example:

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>com.fg.webapp.cps.v1.modules.dwr.DwrDelegationServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>

Then I could call:

http://server/context/dwr/moduleA_Id/
And I expect that DWR will display debug page containing
description of AJAX API of my module A

http://server/context/dwr/moduleB_Id/
And I expect that DWR will display debug page containing
description of AJAX API of my module B

BTW: these urls would trigger the issue with redirect, because
when accessing debug page in this way DWR calls redirect to different
internal url that really shows the debug page ...

Then imagine, that I will disable moduleA and enable moduleC at
runtime. Spring gets refreshed, my DwrDelegationServlet get notifiead
about it too, and reinitializes its own pool of DWR servlets (means
its containers). Then when I try to access:

http://server/context/dwr/moduleA_Id/
I will get HTTP 404

but when accessing
http://server/context/dwr/moduleC_Id/
I expect correct debug page of moduleC AJAX API

Did I make it more clear by this description?

Jose Noheda:

Hi,

It's a little bit complicated.

I could think of a solution for the Spring part. We could modify the DwrSpringServlet and SpringContainer so they accept a collection of application contexts instead of just one. That would reduce the number of servlets. Then we would need to add hot configuration capabilities to add or remove contexts during runtime. The first task is more or less easy. The second is not.

But even then you would have to keep your frontend servlet and all the DwrServlets plus this servlet with the Spring configuration. All in all, you haven't advanced that much. That means that the problem spans well beyond the Spring configuration so unless Joe considers it important enough...I see it difficult.

If you are interested just in the Spring side create a Jira issue attaching a sample project (I wouldn't be able to replicate your environment really) and I'll take a look at it.

Regards,

Jan Novotný:

I propose slightly different approach and that is - one more level
of abstraction. If you look at the Servlet code (DwrServlet and
DwrSpringServlet) there is a lot of code that could be united and
reused. What about introducing something like ContainerManager, that
would take care of Dwr containers initialization and other operations
connected with the container ... then there could be much simplier
servlets, that woud be furthermore better extensible / changeable with
custom servlets just because there would be no bigger logic in them.
Please see attached Java classes - please, and keep in mind, that
this is only a proposal - it might not word in this state - I wrote it
just to outline solution. While writing this abstraction I realized,
that existing servlet might not behave the same - for example shutdown
hook killing comet polls was only inside DwrServlet but not in
DwrSpringServlet. So I think, that this abstraction could moreover
facilitate keeping servlet logic in sync.
If described approach is in the DWR, I could easily write my own
servlet maintaining set of different ContainerManagers even combining
Spring ones with Default ones without any problem. Internal logic is
in ContainerManagers so that I would not have to fear that I will
break anything. So first part of my problem would have been solved by
this.
What do you say to this proposal?

The second part connected with sending http redirect form inside
UrlProcessor is harder to solve. Could there be any interceptor or
UrlPaths resolver, that would abstract this?

Show
Jan Novotný added a comment - 20/Feb/08 12:19 PM Jose Noheda: Hi, I'm not sure I've understood completely. Here's more or less what I'm imaging: You have several DwrSpringServlets each one with a Spring application context injected. You have several DwrServlets each with some remoted objects Each servlet is mapped to a different URL You have some kind of servlet that redirects (filter that forwards?) the processing to the correct servlet (I don't really understand why) You need that DWR supports internally the handling of many servlets and/or different kind of configurations with one entry point Can you clarify if that's correct? I would really need an example web.xml with three or so servlet definitions (and mappings) and one sample flow (of a client call). Regards, Jan Novotny: Hello, You are correct in most of points. I realized, that I omit to mention that in web.xml there is only one registered servlet. As I wrote application is assembled in runtime - so you can enable / disable certain modules without restarting webapp context and application will respond immediately. It means, that our servlet must somehow react on live application reassembly, free internal pool of servlets and initialize new ones for current application assembly. Web.xml part example: <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <servlet-class>com.fg.webapp.cps.v1.modules.dwr.DwrDelegationServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> Then I could call: http://server/context/dwr/moduleA_Id/ And I expect that DWR will display debug page containing description of AJAX API of my module A http://server/context/dwr/moduleB_Id/ And I expect that DWR will display debug page containing description of AJAX API of my module B BTW: these urls would trigger the issue with redirect, because when accessing debug page in this way DWR calls redirect to different internal url that really shows the debug page ... Then imagine, that I will disable moduleA and enable moduleC at runtime. Spring gets refreshed, my DwrDelegationServlet get notifiead about it too, and reinitializes its own pool of DWR servlets (means its containers). Then when I try to access: http://server/context/dwr/moduleA_Id/ I will get HTTP 404 but when accessing http://server/context/dwr/moduleC_Id/ I expect correct debug page of moduleC AJAX API Did I make it more clear by this description? Jose Noheda: Hi, It's a little bit complicated. I could think of a solution for the Spring part. We could modify the DwrSpringServlet and SpringContainer so they accept a collection of application contexts instead of just one. That would reduce the number of servlets. Then we would need to add hot configuration capabilities to add or remove contexts during runtime. The first task is more or less easy. The second is not. But even then you would have to keep your frontend servlet and all the DwrServlets plus this servlet with the Spring configuration. All in all, you haven't advanced that much. That means that the problem spans well beyond the Spring configuration so unless Joe considers it important enough...I see it difficult. If you are interested just in the Spring side create a Jira issue attaching a sample project (I wouldn't be able to replicate your environment really) and I'll take a look at it. Regards, Jan Novotný: I propose slightly different approach and that is - one more level of abstraction. If you look at the Servlet code (DwrServlet and DwrSpringServlet) there is a lot of code that could be united and reused. What about introducing something like ContainerManager, that would take care of Dwr containers initialization and other operations connected with the container ... then there could be much simplier servlets, that woud be furthermore better extensible / changeable with custom servlets just because there would be no bigger logic in them. Please see attached Java classes - please, and keep in mind, that this is only a proposal - it might not word in this state - I wrote it just to outline solution. While writing this abstraction I realized, that existing servlet might not behave the same - for example shutdown hook killing comet polls was only inside DwrServlet but not in DwrSpringServlet. So I think, that this abstraction could moreover facilitate keeping servlet logic in sync. If described approach is in the DWR, I could easily write my own servlet maintaining set of different ContainerManagers even combining Spring ones with Default ones without any problem. Internal logic is in ContainerManagers so that I would not have to fear that I will break anything. So first part of my problem would have been solved by this. What do you say to this proposal? The second part connected with sending http redirect form inside UrlProcessor is harder to solve. Could there be any interceptor or UrlPaths resolver, that would abstract this?
Hide
Jose Noheda added a comment - 04/Jun/08 8:23 AM

I will start working in this issue in the near future but the setup seems complex. Could you provide a sample project with 2 or 3 contexts that isn't working right now? And how do you expect it to work?

Show
Jose Noheda added a comment - 04/Jun/08 8:23 AM I will start working in this issue in the near future but the setup seems complex. Could you provide a sample project with 2 or 3 contexts that isn't working right now? And how do you expect it to work?

People

Dates

  • Created:
    20/Feb/08 12:16 PM
    Updated:
    13/Apr/11 12:09 PM