struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Roughley <>
Subject Re: [s2] A thought - next generation OSGi-based?
Date Fri, 25 Apr 2008 17:25:28 GMT
Maybe I'm overstepping my knowledge from fact, but I thought the benefit 
of OSGi was that you could have completely different implementations 
(i.e. PackageConfig) running on the same JVM, with OSGi providing the 
classloading magic so that the implementations don't collide.

If this is the case, I don't think this would lead to versions in the 
classname as you've shown below, but it may require the core S2/XWork 
JAR to be further split to provide more modularity.  Perhaps even down 
to completely separate implementations.

My question with Don's proposal is with item #4.  Is it new features of 
the same webapp that use new APIs or new webapps that use the new APIs?  
Option one is going to be hard, and may not be possible even with OSGi.  
For option 2, I'm wondering if OSGi is overkill (i.e. would webapps be 
separated enough via the container).  A better question might be is it 
the webapps that need to change the APIs they are using, or is it the 


Brian Pontarelli wrote:
> Yours and mine are the same because you still have implementations 
> inside Struts for some of the API interfaces. For example, 
> org.apache.struts2.config.PackageProvider (yeah, I did move this from 
> XWork to Struts for my example ;), will be an API interface that 
> applications can implement. Struts2 also implements this API.
> Another case is a non-interface POJO like PackageConfig. This class 
> can be instantiated by app1 and then passed back to struts. Likewise, 
> app4 might instantiate a different version and pass it back. You have 
> to separate these into namespaces in order to compile Struts if the 
> versions of PackageConfig are fundamentally different.
> If we take the concrete example of 2.0.* and 2.1 for PackageConfig, 
> one is mutable, the other is immutable with the Builder pattern. 
> However, they have the same package and classname. The issue is that 
> at compile time Struts needs to import and use PackageConfig. The only 
> way I know how to pull this off is extract a common interface (Java 
> interface that is - public interface IPackageConfig) and make adapters 
> OR to separate them into namespaces.
>    org.apache.struts.config.PackageConfig_2_0
>    org.apache.struts.config.PackageConfig_2_1
> Then you can see the ensuing code inside Struts to deal with these:
>    org.apache.struts.config.ConfigurationManager_2_0
>    org.apache.struts.config.ConfigurationManager_2_1
> And then you need some method of determining the version of the API 
> that the application is using and then select a configuration manager 
> based on that.
> Now, there might be some type of tricks and things that OSGi can 
> provide to make this happen, but I'm not familiar enough with advanced 
> bundling and classloading to know how it would work. From what I 
> understand of OSGi, any bundle can only use a version of a dependent 
> bundle that is compatible with the version of that dependent bundle it 
> compiled against.
> For example, if I compiled against log4j 1.0, I can use 1.3 because 
> they are compatible at runtime and compile time. However, I can't use 
> log4j 2.0 because the interfaces changed and things will blow up 
> nicely at runtime. What OSGi does provide is the ability to have one 
> bundle using log4j 1.x and another bundle using log4j 2.x in the same 
> VM. I'm not aware that they have gone any further than that.
> Ian Roughley wrote:
>> Is this the case, or was the thinking more like:
>>                                      - app 1
>>                 - api 1.0 --{
>>                /                     - app 2
>> Struts ---{
>>                \                     - app 4
>>                 - api 2.0 --{
>>                                      - app 3
>> I think this is how I perceived it.  I also agree with Brian that 
>> there will be a burden on s2 to provide the necessary features for 
>> all APIs, but I think it's less of a burden in this layout.
>> /Ian
>> Brian Pontarelli wrote:
>>> Here's a few things I think about when considering API versioning:
>>> 1. How many implementors are there? It sounds like there will be one 
>>> - Struts2
>>> 2. Do you want to allow implementors to implement multiple APIs? 
>>> Sounds like yes.
>>> 3. How much is shared between APIs? Probably a lot.
>>> From what it sounds like, and correct me if I'm wrong, you are 
>>> looking to do something like this:
>>> API 1.0----------\
>>>                 |----------- Struts2
>>> API 2.0----------/
>>> If this is the case, it will require some interesting coding 
>>> tactics. Sun and IBM have some white papers on these types of cases. 
>>> OSGi will shield the two APIs from each other so there aren't any 
>>> conflicts, however, the implementor will have the unfortunate task 
>>> of implementing both. This becomes difficult without proper 
>>> structure at compile time because struts2 will need to implement 
>>> multiple interfaces from both versions and these interfaces might 
>>> overlap.
>>> I've done some of this type of work before and in order to truly 
>>> break compatibility between 1.0 and 2.0, you need namespaces in 
>>> order to allow Struts2 to implement both. Otherwise you get naming 
>>> conflicts that cannot be resolved by the compiler. I've do things 
>>> like this before:
>>> org.apache.struts.api1.SomeInterface
>>> org.apache.struts.api2.SomeInterface
>>> This is the same interface, but breaks compatibility between the API 
>>> versions. Only by separating the namespaces will you be able to 
>>> implement both at compile time. I've also worked with other 
>>> situations like this:
>>> org.apache.struts.api.SomeInterface_1_0
>>> org.apache.struts.api.SomeInterface_2_0
>>> What it comes down to is that if you are going to break 
>>> compatibility at the API level you need to actually create a brand 
>>> new API. When you look at it from this perspective, OSGi really 
>>> isn't needed, just nice to have. Since the two API versions are in 
>>> different namespaces, there aren't any collisions at compile-time or 
>>> runtime, eliminating the need for bundle separation.
>>> Having done some of these types of solutions before, I can attest to 
>>> the pain that they can cause. They can also become complex to 
>>> manage. Which sorta leads back to my original statements about 
>>> compatibility. I'd much rather see something like this:
>>> 1. The APIs locked down
>>> 2. These APIs called Struts3
>>> 3. No APIs break compatibility until Struts4
>>> Therefore, 3.0, 3.1, 3.2, etc are all compatible. Then when Struts4 
>>> start wanting to break compatibility, you branch Struts3, and start 
>>> breaking away on Trunk.
>>> -bp
>>> Don Brown wrote:
>>>> As I learn more and more about OSGi, I wonder if it might be the
>>>> solution to several big problems we seem to have at the moment: poor
>>>> reloadability and the lack of a solid API.  With OSGi, you can drop
>>>> bundles in and out of the system at runtime, even running multiple
>>>> versions of the same bundle side-by-side, but the feature I'm most
>>>> interested in right now is how it would allow us to put in a proper
>>>> API while maintaining full backwards-compatibility.
>>>> Evolving a web framework is hard because apps tend to be written on a
>>>> specific version, and to migrate them to new versions has two
>>>> problems: development may not be continuously funded and the upgrade
>>>> may require too many changes to the application.  On the other hand,
>>>> if you don't evolve your web framework, you quickly go out-of-date and
>>>> lose interest from new developers.  In our case, despite being a
>>>> relatively new framework, we have legacy code around from 2004 that we
>>>> can't just remove, yet we want to provide an attractive, modern, clean
>>>> framework for new development.
>>>> The specific issue it hand that I've been thinking about is how to get
>>>> a proper API into Struts 2 yet keep backwards compatibility, and I
>>>> think OSGi might provide a solution.  What about this:
>>>>  1. Struts 2 and its plugins remain the way they are now - 100%
>>>> backwards-compatibility
>>>>  2. An OSGi plugin provides the platform for the next generation of 
>>>> Struts 2
>>>>  3. A new API bundle is created, implemented by the underlying Struts
>>>> 2 framework
>>>>  4. Old apps can continue to write and deploy code against Struts 2,
>>>> yet new development can start to use the new API
>>>>  5. Later, when we want to write API version 2, we create a new bundle
>>>> that runs side-by-side the old bundle, both implemented by Struts 2
>>>> Basically, OSGi would allow us to write a clean layer on top of a
>>>> framework, much like how Grails builds on Spring, but we get, as a
>>>> side benefit, all the architectural advantages of OSGi for free.
>>>> Furthermore, if we do it right, users don't have to know or care that
>>>> OSGi is under the hood - all they know is they write a jar, drop it in
>>>> a directory or upload it via a form and they just installed part of
>>>> their application at runtime.
>>>> Don
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail:
>>>> For additional commands, e-mail:
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail:
>>> For additional commands, e-mail:
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message