Announcement Announcement Module
Collapse
No announcement yet.
Extending Web Applications Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Extending Web Applications

    I posted this on another forum it was suggested to me that I post it here:

    http://forum.springsource.org/showthread.php?p=260708

    So, here goes:

    I'm not sure where the best place to post this message is, but since the most recent line of research I've been doing has lead me to OSGi and Spring dm (which is close, but still not quite there), this looks like the right place to post.

    I've got some real-world scenarios that the OSGi platform seems very well suited to, but, from what I can tell from research, still does not quite hit the mark. Let me mention a few, and then talk about at least as far as I've gotten. Maybe there is already some technology that solves these problems, or maybe this is "in the works" but not built yet.

    Scenarios:
    1) Customization: Web application A is deployed. Customer 1 likes it plain. Customer 2 wants a couple of stylesheet tweaks for branding. Customer 3 wants a little bit of the business logic changed. So the end result are three new virtual applications that are the result of A merged with a set of changes for each customer.
    2) Modules: Web application A is deployed. Optional application module B is developed and needs to be plugged into A, not just adding new files, but also making small tweaks to some of the existing files (adding menus, adding fields to existing pages, adding additional workflow, new pages to wizards, etc). So when B is deployed, the end result is a new virtual applicaiton that merges A and B together.
    3) Patches: Web application A is deployed. Bugs are found. A patch (call it P1) that contains just the patched files is plugged in. The new application (that results of merging A with P1) is tested and something isn't working. The patch is then unplugged and reworked until it is gotten right.

    I was pretty excited to read about dyamic modules, and learn about OSGi fragments as a way to solve some of these problems. As it turns out, I don't think dynamic modules or fragments can solve any of these.

    For example:

    Case #1 sure seems to call for fragments. However, in order to get this to work, you'd need multiple copies of the base application A deployed 3 times, each one modified by a different fragment and accessible by a different hostname (or context path or something). Having multiple copies of the base application is not very efficient (you end up with multiple copies of JSP classes compiled, multiple classloaders, one for each app, loading all the classes for the app, etc). What you really want to be able to merge a set of fragments with a web application "virtually" so you really only have one base set of classes and instances loaded in memory.

    Case #2 sure seems like fragments would come to the rescue here as well. However, since fragments can't override content in the base (just add to it) it can't be done. Instead you would have to munge the original application to add the ability to "configure" it to add in the extra stuff needed to handle the presence or absense of module B. That's fine if you are the primary owner of the base application. But what if you really just wanted to overlay your new module B on top of some existing web bundle, maybe one that was produced by someone else, to get your new extended application without having to modify the base code (i.e. treat it as a 3rd party/vendor provided module)?

    Case #3 also seems like dynamic modules would come to the rescue. Unfortunately again, fragments can't override content in the base, so you can't augment an OSGi module with a fragment that merges with it to produce a patched module. It seems OSGi CAN handle this through simply upgrading to the latest version of the modules with the "update" functionality, and if that doesn't work, you can always roll back. But it seems that's not the "traditional" patching model (where the patch is placed ahead of everything else in the lookup path so its stuff comes first, and if you want to unpatch, you just remove it from the lookup path and the original versions of stuff will be found).

    All the problems seem to be related, and it seems like a single solution might be able to address all 3 of these issues. OSGi and fragments sure seem to be "close" to the solution, but not quite. So, is there a solution, using Spring, OSGi, or some other technology to any of these problems? If the answer to these is that there really is no good standardized solution to these problems that exists now, then is there anything that might be already specified and not built, or even some upcoming specifications that might help solve these problems?

    The response was to look at Spring Slices. So we did. It is a very cool technology, and definitely close to what we're thinking we'd like to do, but not quite. Slices requires partitioning of the application modules via a sub-context path. As well, the slices really do not know and cannot interact with each other.

    What we're thinking is a bit more general purpose... slice-like modules that would plug-in and basically provide classes and resources that come ahead of the WAR in the search path. Some resources would override, some resources could merge (css, web.xml, etc), some could extend the parent resources.

    Thoughts on what we might want to look into? Maybe we could talk in more detail about what we wanted to do, and how Slices might be adapted to fit a more general problem? I think possibly an adaption of this technology could be used for customization, modules, and patches.

    Thanks in advance!

    -J.C.

  • #2
    Great questions, J.C.!

    Originally posted by jchamlin View Post
    I've got some real-world scenarios that the OSGi platform seems very well suited to, but, from what I can tell from research, still does not quite hit the mark. Let me mention a few, and then talk about at least as far as I've gotten. Maybe there is already some technology that solves these problems, or maybe this is "in the works" but not built yet.

    Scenarios:
    1) Customization: Web application A is deployed. Customer 1 likes it plain. Customer 2 wants a couple of stylesheet tweaks for branding. Customer 3 wants a little bit of the business logic changed. So the end result are three new virtual applications that are the result of A merged with a set of changes for each customer.
    2) Modules: Web application A is deployed. Optional application module B is developed and needs to be plugged into A, not just adding new files, but also making small tweaks to some of the existing files (adding menus, adding fields to existing pages, adding additional workflow, new pages to wizards, etc). So when B is deployed, the end result is a new virtual applicaiton that merges A and B together.
    3) Patches: Web application A is deployed. Bugs are found. A patch (call it P1) that contains just the patched files is plugged in. The new application (that results of merging A with P1) is tested and something isn't working. The patch is then unplugged and reworked until it is gotten right.

    I was pretty excited to read about dyamic modules, and learn about OSGi fragments as a way to solve some of these problems. As it turns out, I don't think dynamic modules or fragments can solve any of these.

    For example:

    Case #1 sure seems to call for fragments. However, in order to get this to work, you'd need multiple copies of the base application A deployed 3 times, each one modified by a different fragment and accessible by a different hostname (or context path or something). Having multiple copies of the base application is not very efficient (you end up with multiple copies of JSP classes compiled, multiple classloaders, one for each app, loading all the classes for the app, etc). What you really want to be able to merge a set of fragments with a web application "virtually" so you really only have one base set of classes and instances loaded in memory.
    We'd certainly considered pluggable styling as a use-case for Slices, but hadn't considered that users may want to deploy multiple copies of the same application each with different styling on the same dm Server instance.

    If I've understood you correctly, you'd like to be able to deploy the same application to three different context roots, and then to style the application differently depending on which context root it was accessed via?

    Case #2 sure seems like fragments would come to the rescue here as well. However, since fragments can't override content in the base (just add to it) it can't be done. Instead you would have to munge the original application to add the ability to "configure" it to add in the extra stuff needed to handle the presence or absense of module B. That's fine if you are the primary owner of the base application. But what if you really just wanted to overlay your new module B on top of some existing web bundle, maybe one that was produced by someone else, to get your new extended application without having to modify the base code (i.e. treat it as a 3rd party/vendor provided module)?
    You can do this with fragments and Bundle-ClassPath, although you would have to modify the existing bundle. A host bundle can reference a Jar in its Bundle-ClassPath header that doesn't actually exist in the host. A fragment can then attach to the bundle to provide this Jar. If you specify the Jar before '.' (the default for Bundle-ClassPath) then it can override the bundle's content. This approach is described in section 3.8.1 of the OSGi 4.1 spec.

    Case #3 also seems like dynamic modules would come to the rescue. Unfortunately again, fragments can't override content in the base, so you can't augment an OSGi module with a fragment that merges with it to produce a patched module. It seems OSGi CAN handle this through simply upgrading to the latest version of the modules with the "update" functionality, and if that doesn't work, you can always roll back. But it seems that's not the "traditional" patching model (where the patch is placed ahead of everything else in the lookup path so its stuff comes first, and if you want to unpatch, you just remove it from the lookup path and the original versions of stuff will be found).

    All the problems seem to be related, and it seems like a single solution might be able to address all 3 of these issues. OSGi and fragments sure seem to be "close" to the solution, but not quite. So, is there a solution, using Spring, OSGi, or some other technology to any of these problems? If the answer to these is that there really is no good standardized solution to these problems that exists now, then is there anything that might be already specified and not built, or even some upcoming specifications that might help solve these problems?
    As described above, you can override content with a combination of fragments and Bundle-ClassPath so, hopefully, OSGi can offer you a solution here.

    The response was to look at Spring Slices. So we did. It is a very cool technology, and definitely close to what we're thinking we'd like to do, but not quite. Slices requires partitioning of the application modules via a sub-context path. As well, the slices really do not know and cannot interact with each other.

    What we're thinking is a bit more general purpose... slice-like modules that would plug-in and basically provide classes and resources that come ahead of the WAR in the search path. Some resources would override, some resources could merge (css, web.xml, etc), some could extend the parent resources.

    Thoughts on what we might want to look into? Maybe we could talk in more detail about what we wanted to do, and how Slices might be adapted to fit a more general problem? I think possibly an adaption of this technology could be used for customization, modules, and patches.
    I'm hopeful that you can get pretty close today with the use of Bundle-Classpath and fragment bundles. Your very first requirement isn't something that can be done today with Slices, but it's not beyond the realms of possibility.

    I look forward to your feedback on the fragment and Bundle-ClassPath approach described above. I'd also love to hear some more details on your requirements, particularly those related to Slices, so that we can consider them in our development work.

    Thank again for the thought-provoking questions.

    Andy.

    Comment


    • #3
      Maybe this will help case #1

      As you will see I have a attached a patch which might help you solve #1 of your problems listed (we have a few requirements which are the same)

      basically the patch provides a simple no-obtrusive (albeit not ideal) way of implementing multiple hosts registered to a slice. Basically the slice has to explicitly register itself to the hosts via the slice standard "Slice-Host" manifest entry ie:

      Code:
      Slice-Host: animal.menu.bar;version="[1.0, 2.0)",animal.menu.bar2;version="[1.0,2.0)"
      As for customised theming of a slice from a host without the use of the "host:" url rewiring, see the LayeredSliceHostFilter. It allows a simple way for the host to overwrite resources in a slice by using resources found on the host. I.e if the slice registered to host/slice and uses a resource "images/image.jpg" a host can override the resource by creating the appropriate resource url of "slice/images/image.jpg".

      (NOTE this is a BAD implementation and doesn't resolve url rewriting or anything that Spring MVC provides. In saying that it should (in it's current state) only be used for resources)

      Please note that this is merely a hack to help you get your application prototyping. It should be used in production at your own risk.

      This code has only been tested in the "ideal" cases in which we needed for prototyping, yes it is bad, and yes it isn't done "correctly". But in saying that if any of these solutions can be resolved in slices without this patch I would appreciate someone pointing it out.

      Comment


      • #4
        bjc, this is great stuff, thank you.

        If it's not too much trouble, could I ask that you open one or more stories to capture your requirements, please? I'd like them to be formally tracked so that we can understand them and consider supporting them as we develop Slices.

        Thanks,
        Andy

        Comment


        • #5
          a story has been submitted

          https://issuetracker.springsource.com/browse/DMS-1609

          It outlines (what I believe would be a nicer way of) having multiple hosts registering themselves to a slice. (*NOTE* this is not done in this patch)

          As for the "layered" resources, I don't think that a story needs to be used for this since a slice *should* be implemented to use the "host:" url access which I believe is a cleaner way of doing things.
          Last edited by bjc; Oct 9th, 2009, 12:24 AM.

          Comment

          Working...
          X