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.

Sunday, July 13, 2008

Impala 1.0 M2 released

Today I dropped a release of Impala 1.0M2.

It is mostly an incremental release, with a few relatively minor enhancements and bug fixes, but there is one significant feature: a mechanism for allowing module metadata to be contained within the module, instead of being externally specified, as in previous releases. I will post a bit more detail on this feature, as it does make specifying modules more intuitive and concise, as soon as time constraints ease. This change is covered in this issue report, and does involve minor backward incompatible changes.

A total of 20 issues are covered in this release. The full set are covered in this search. Enjoy.

Sunday, May 25, 2008

How lightweight is Impala?

In my last blog, I described a set of criteria which can be used to determine how lightweight a framework or technology is. Let's consider Impala against the criteria described above:

1. How much system resource does the technology use?
Impala adds an almost negligible overhead to a plain Spring application.

2. Do applications need special runtime support to run?
Impala simply runs on the JVM. It's only runtime dependencies are Spring and logging libraries.

3. Are any special build steps required for the application?
No, it can be run from within Eclipse without any build steps.

4. How difficult is it to test applications which use the technology?
The interactive test runner and integration test support make Impala applications easy to test in a very productive way.

5. Can applications be updated dynamically, or do updates require a restart?
Yes.

6. How easy is it to modularise applications which use the technology?
Modularity is built in from the ground up.

7. Do applications require any code generation, either source code or byte code?
None, other than that which is used in the equivalent Spring application.

8. How quick are applications to start?
Not perceptibly slower to start initially than the equivalent plain Spring application, but requiring dramatically fewer restarts.

9. How complex is the technology to understand?
Impala is simple to understand. The developer only needs to have a understanding of the basic principles, architecture and project conventions to get going. Only in very few places is interaction with Impala APIs required.

10. Is any special tool support required to be productive with the technology?

Impala works in a vanilla Eclipse installation without any additional required plugins.

Overall, I'd argue that Impala passes this lightweightness test with flying colours. I'm also pretty convinced that an equivalent comparison with alternative technologies would be less favourable.

See more details on these definitions for lightweightness.

What makes a technology lightweight?

What makes a technology lightweight? Being lightweight is considered a good thing. Lightweight technologies are popular with developers because they are simpler and less cumbersome to work with. The downside, of course, is that lightweight technologies can be less feature rich than their more "heavyweight" alternatives. Whether this matters depends on whether the missing features are actually required, that is, whether the value that these features provides outweigh the overhead that is added.

Plenty of technologies are "sold" on the basis of being lightweight. While most of us have an intuitive idea of what lightweight means, it's quite useful to think of this concept in terms of a more concrete set of questions or criteria. This can be helpful in making comparisons between frameworks and technologies, and indeed for assessing claims made on behalf of particular technologies.

1. How much system resource does the technology use?
This is the most obvious measure of how heavyweight a technology is. What is the memory footprint of an application? A more narrow definition of lightweight vs heavyweight technology is most likely to focus on this aspect of the definition.


2. Do applications need special runtime support to run?
If the technology requires special runtime support, then it automatically becomes more heavyweight. A good example is EJB 2, which requires applications to be run and tested in a container. Even if the container is embeddable in a standard JVM (for example within the IDE), this can make it more difficult to test applications, particularly if tests themselves need to run within the container interactive with the code under test.

3. Are any special build steps required for the application?
If the technologies require artifacts to be packaged in a certain way, then this adds an overhead to the build cycle. A related question is, can applications be run directly in an IDE without an explicit build? The most lightweight technologies by this definition require no build steps at all - you simply fire up the application in your IDE.

4. How difficult is it to test applications which use the technology?
If a technology requires special runtime support (see 2.) or it is complex to set up dependencies for running tests, the barrier to writing effective integration tests is raised, resulting in a reduction in productivity and/or quality.

5. Can applications be updated dynamically, or do updates require a restart?
If every change made requires an application restart, this can make the technology feel more heavyweight, especially if restarts are time consuming.

6. How easy is it to modularise applications which use the technology?
Technologies which allow applications to be packaged and run in a modular way will feel more lightweight than those which require everything to be run up as an amorphous "blob", especially as the application grows in size and the need to be more fine-tuned about what is deployed becomes more obvious.

7. Do applications require any code generation, either source code or byte code?
Applications which require code generation generally involve extra build steps which can complicate the build process and/or slow down the build/test cycle. Byte code generation can hide much of this pain, but does introduce a measure of complexity which can make a technology feel heavyweight.

8. How quick are applications to start?
Technologies that are slow to start are clearly more heavyweight - they are doing more, have more going on behind the scenes, and are using more memory. They also are more likely to leave behind the perception that they are inefficient.

9. How complex is the technology to understand?
The more complex a technology is, the more heavyweight it will feel. One way of thinking of it is this: for each step you take in working with the technology, the more time you will need to spend thinking about what you are doing, relative to simply doing.

10. Is any special tool support required to be productive with the technology?

If special tool support is required to make you productive with a technology, then this technology will feel more heavyweight than one which imposes no such requirements. Now, not only do you need to worry about dependencies in your runtime environment, you need to worry about those in your tooling environment. Also, its slower to get going with the technology to start with.

You can take this methodology further by ranking frameworks and technologies on a scale of 1 to 10 on each of these points. Some frameworks and technologies which purport to be lightweight are actually considerably less so when evaluated against these criteria.

In my next blog, I will evaluate Impala's lightweightness against these criteria.

Wednesday, May 21, 2008

JavaWUG BOF 37: talk on Impala Framework

Just a quick update on my talk at the Java Web User Group in London last night. Thanks for those who made - as always it was an enjoyable evening.

Here's a copy of the presentation.

A main focus of my presentation was a demo based on an Impala version of the Spring Petclinic application - one of the main reference applications bundled with the Spring Framework.

During the demo I introduced a new feature to the application, involving a new database table, some new Hibernate mappings, persistence code, as well as some enhancements to the web presentation layer. The changes were made without having to restart the application during the demo, all updates were made on the fly.

The source code for the demo is available from the Impala subversion repository. The changes made during the demo are in this file.