Monday, September 22, 2008

Is the case for forking Spring building?

SpringSource recently announced a new maintenance policy which I, like many in the developer community, find quite disturbing. The basic idea is that SpringSource will only publish releases to non-paying customers of SpringSource for three months after the initial release. After that, it will be up to the rest of the community to do its own releases, with community releases only coming out every so often.

Reactions to this on The Server Side and other places have been understandably very negative. Personally, I have been less than enthusiastic about some of the developments that have been coming from SpringSource since it got VC funding. See a previous entry.

This time, it has gone to far. By biting the hand that feeds it, it has risked alienating its most loyal users and putting many people off the project altogether. It also really undermines the increasing number of other community projects which are built around Spring, projects like Impala.

As the author of a number of open source projects which despite obvious (to me) technical merits never attracted a very large number of users, I know only too well that users are by far the most precious feature of an open source project, to be valued above all else.

SpringSource has not only begun to ignore it's users, it has shown the willingness to outrage them. This shows an unbelievable arrogance and complacency.

All of this is quite apart from reservations I increasingly have about the direction that SpringSource is taking Spring.
  • The project is no longer open
    if you look at the history of SVN commits in Spring, you will notice that the project has become much less open. Around early 2005 there were plenty of commits going into Spring from individuals who are not SpringSource employees. Now commits to Spring core (the part that most people use) are only being made by SpringSource employees.

    Also, strategically important projects are increasingly developed outside of the public domain - including Spring 3.0, which will be the next major release of the core framework.

  • We should be nervous about future licencing moves
    So far the official line is that none of the none of the licences will be changed for any existing project. It would probably impossible to do this anyway. However, many new projects from SpringSource are no longer coming out with friendly open source licences (specifically ASF 2). How do we know, for example, that Spring 3.0 won't be released as a "new" project with a less friendly licence.

  • Obsession with OSGi
    SpringSource has become obsessed with dragging the entire Java community into using OSGi. Don't get me wrong, I do like OSGi, and hope to support it with Impala, and at some point I am sure that I will be using it in real applications. But it shouldn't be at the exclusion of other things which could be done to make Spring more usable without OSGi. It's exactly for this reason that I started Impala. I wanted modules, reloadability, isolation, etc. but not necessarily with the baggage of OSGi at this point.

  • Key man dependencies
    Every project has it's major contributors, the individuals who do most of the heavy lifting while others go around doing the talking. Spring is no different - as the commit graph shows, this is Juergen Hoeller, and it is very much down to his excellence that Spring is so well regarded. If Juergen decided to go off to pastures new, Spring core would be in a very bad place. For a project which is relied upon by so many around the world, this is not a good thing.
In short, it's hard to like the way that Spring is going. But it's not too late to change. One of two things need to happen:
  • SpringSource needs to take Spring back to where it came from. This doesn't mean winding up the company and going back to working for free. But it needs to reaffirm and re-demonstrate it's commitment to the spirit of open source - openness, transparency and a desire to serve it's users. This probably means lowering it's financial objectives. There's still plenty of money to be made from consulting, training, and from providing value added products and tools. But not when it contravenes the essence of what made Spring popular in the first place.
  • If SpringSource cannot get it's act together, the project should be forked. Because Spring runs on an ASF licence, this is quite feasible. But there are lots of question to answer. Who would be willing to do this? Would they be the right people? And where would they take the project?

    Forking a project could be a dangerous move for the community, but history shows that it won't necessarily fail. Perhaps it's better for the project to take the pain now than to have death by a thousand cuts.
Judging by the strength of ill-feeling regarding SpringSource's latest announcement, I'm sure there must be other people in the wider Spring community thinking the same thing. I wonder if there are people working within SpringSource who feel the same way, or is the gravy train now just moving too fast for them to hop off?

Friday, September 12, 2008

Generic support for dynamically reloadable web frameworks

One little feature that I think we're close to pulling off with Impala is the ability to embed any Servlet-based web application and have it dynamically reloadable as a module. I'm thinking of the likes of Tapestry, Struts, etc.

Up to version 1.0M2, this capability has only really existed for Spring MVC. However, to make Impala really attractive to users of other frameworks, you'd want to support these as well. After all, not every Spring user is also using Spring MVC as the web framework.

More recent changes now allow you to embed any Servlet into a the application context XML belonging to an Impala web module, using code such as:

<bean id = "delegateServlet" class="org.impalaframework.web.integration.ServletFactoryBean">
<property name = "servletName" value = "delegateServlet"/>
<property name = "servletClass" value = "servlet.SomeFrameworkServlet"/>
<property name = "initParameters">
<map>
<entry key="controllerClassName" value = "servlet.ServletControllerDelegate"/>
</map>
</property>
</bean>

Note how the init parameters, the servlet name and the servlet class have been specified, as they would be for entries in web.xml.

The InternalFrameworkIntegrationServlet, whose definition is shown below, is what allows the servlet to "live" within an Impala module. It contains the glue code
that ties an invocation from outside of a module (within the context of a servlet container) to the servlet within the module.

<bean class="org.impalaframework.web.integration.InternalFrameworkIntegrationServletFactoryBean">
<property name = "servletName" value = "myservlet"/>
<property name = "servletClass"
value = "org.impalaframework.web.integration.InternalFrameworkIntegrationServlet"/>
<property name = "delegateServlet" ref = "delegateServlet"/>
</bean>

Finally, to communicate with the module itself, there is the ModuleRedirectingServlet, which simply delegates to the a servlet which is registered in the ServletContext using a name which corresponds with the name of the module (and happens to correspond with the first part of the URL's servlet path).

Here's an example configuration in web.xml:

<servlet>
<servlet-name>module-redirector</servlet-name>
<servlet-class>org.impalaframework.web.integration.ModuleRedirectingServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>module-redirector</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

Together, these offer the capability dynamically embedding applications using arbitrary web frameworks. The idea is that you can register and load a Struts, Webwork, Tapestry or other module after the JVM has started, without impacting any existing code or without having to restart the JVM or reload the entire web application within the application server. A powerful concept.

There are definitely some gotchas to take care of. For one, it relies on object instances being loaded using the classloader obtained via Thread.currentThread().getContextClassLoader(). Also, how can we make sure that objects saved to sessions don't cause ClassCastExceptions when the module is reloaded? Also, how can we make sure that the same result does not occur because of one module attempting to access objects saved to the session by another module? And of course, we'd need to prove it working with real applications based on these frameworks, not example code assuming noddy pseudo frameworks. These kinds of problems will need to be taken care of before the problem can be considered to be fully solved. It should be fun figuring it out, though.

Impala talk at Spring User Group UK

After quite a few weeks of being very busy at work, followed by a few weeks of taking it pretty easy and enjoying the summer, I'm now back to work, and trying to ramp things up a bit with Impala. On Wednesday night I did a talk at the Spring User Group UK on Impala. You can view the talk here - it's a bit grainy, but you can still hear everything. You can view the slides here.

I was given half an hour for the presentation, and I managed to squeeze it into 27 minutes, including a demo. I was pretty happy with the talk - my little example demonstrating creating a new Hibernate entity within a Spring application went without a hitch.

Hope to do a few more talks in the coming months.