Author Archive

Goodbye, JavaPolis…

Thursday, December 14th, 2006

JavaPolis is almost over and the Aranea team has had a great time! Thanks to all who came to listen to our talk or came up to us in the booth, it was really great to see your interest and to help you out. Thanks a lot to Stephan and the organizers for a great job and we are looking forward to the next time we can met everyone in Antwerp!

In other news we announced integration with Struts, JSF and GWT during the conference and in the next couple of weeks we will setup the subprojects and make them available for testing. The stable releases are expected during January-February, so stay tuned for updates.

Aranea at JavaPolis 2006

Friday, December 8th, 2006

Everyone who will be at JavaPolis 2006 in Antwerp, Belgium from Tuesday, 12th to Friday, 15th December is very welcome to attend both the talk on “Object-Oriented Web Development with Aranea” and visit the booth that we share with ChangeLogic configuration management guys. We will have two of the core Aranea developers on place, so if you have any questions, troubles, comments and offers of help we will be more than glad to hear you out (and help if needed).

One week until JavaPolis

Tuesday, December 5th, 2006

Exactly seven days are left before the largest European Java conference kicks in! As it happens we have both a talk and a booth there, so anyone in the vicinity is very welcome to come by, listen and tell of your experiences with Aranea (even if they are not the best :) ).

As you may remember we promised to announce integration with Struts, JSF and GWT during that time. It seems we will just have to keep our word, as the work is almost complete. Struts integration is up and running, while JSF and GWT are right behind it. This means we’ll be able to demo a working app composed of legacy Struts, standard JSF and cutting-edge GWT right before your eyes during the talk (and during any other time in the booth, if you are interested). The official announcement will come right after JavaPolis, since we have to setup subprojects first.

Zero Turnaround, Revisited

Wednesday, November 22nd, 2006

There has been some amount of discussion on the previous post. What was a bit surprising for me, is that a lot of people think that this isn’t really an issue for Java EE (they should really look at the comments here).

First of all let’s clear up some misunderstandings — we are talking about a development time approach, that allows to see the results of changes to code reflected instantly in the web application. This has nothing to do with production time hot swapping.

Secondly, nowadays compiling isn’t much of a bottleneck, since Eclipse (and similar IDEs) compile application incrementally on-the-fly. So the only thing we need is to actually reload this code in the JVM and we will get instant feedback that speeds up development.

Thirdly, web containers had for quite some time supported reloading classes while preserving the session state. However they do it by restarting the web application, which means all state outside the session (including business and persistence layer configuration, cache, stateful application-level services, compiled statements and so on) will be lost. To speak more specifically in a typical application based on Spring and Hibernate that is deployed to Weblogic (or Tomcat, or whatever else) such restart will take 30s to several minutes depending on the size of the application.

Now this is a really big issue — it means that averaging a restart every five minutes we get 96 restarts a day, which even 30s each gives us 48 minutes spent waiting for the application to reload. And the real numbers are even bigger, both because I chose optimistic numbers and because a developer who waits for a minute loses the context and might easily start reading Slashdot out of boredom. Thus companies are losing hell-of-a-lot of money on their developers just waiting for the application to restart.

So, to get back to the solution proposed in the original post. This was a way to get all of your web layer stuff to reload instantly. This by no means solves all problems, as the business and persistence layer are not covered by this approach. However since a lot of development happens in the web layer it does give a good boost to that (I don’t think I’d lie too much if I say that at least half of the restarts become unnecessary). Moreover there are some possibilities to get the rest of the stuff to reload as well, and Aranea team is working on them as well as some others.

Zero turn-around in Java?

Tuesday, November 21st, 2006

Zero turn-around is one of the selling points of PHP, Ruby, Python and other interpreted languages. Turns out it also works out-of-the-box with Aranea and here we’ll describe how we did it, what are the limitations and show off the compositional nature of Aranea. If you just want to get it to work see the reference manual entry on the topic.

Zero turn-around usually refers to the way changes made to the code are immediately visible in most interpreted languages. Indeed, since there is no compilation and almost no deployment, the time from making a change to seeing it in the browser is a fast as pressing Ctrl + S, Alt + Tab and F5. The situation in the JEE world is different — although compilation is relatively fast, together with deployment, cache reloads and framework initialization it might easily take up to a minute to see a change propagate in a large application.

The problem is that JVM spec clearly states that we can’t just reload code of a single class after it has been loaded into the JVM. HotSpot JVM offers some way by allowing to replace the code of the methods, but so far it forbids to anyhow alter structure and signatures, so it’s only of limited use. What we can do is to load classes using a particular (possibly our own) classloader, and then let it to be garbage collected among with all loaded classes. Then next time an instance is created the class will be loaded anew.

However even this won’t give us the desired result, as any existing instance of a class will still hold on to its previous definition (with the old classloader) and now we might actually have two conflicting class definitions in two different classloaders which can lead to all sorts of trouble. So we also need to somehow reload the object state in a new classloader.

Turns out that we can archive this with serialization — we just need to modify the ObjectInputStream to take a classloader parameter and load the instances using its classes. Thus what we have to do is:

  1. Load the classes using our classloader.
  2. Serialize the state of the instances
  3. Drop the old classloader and create a new one
  4. Deserialize state of the instances in the new classloader

Of course if some objects cannot be serialized (e.g do not implement Serializable or contain non-serializable fields) the whole scheme fails, since we cannot preserve their state.

Before we get to the actual Aranea stuff let’s try to implement the reloading procedure, that takes an object and reloads it using a fresh classloader. We know it should work through serialization, so it should look something like this:

...
private Serializable reload(Serializable child)
  throws Exception {
  return deepCopy(newClassLoader(), child);
}
...

deepCopy should just serialize and deserialize the object. There is one catch though — it should also resolve the classes using our own classloader, so we have to make a subclass of ObjectInputStream:

...
private static class ReloadingObjectInputStream
extends ObjectInputStream {
  private ClassLoader cl;

  public ReloadingObjectInputStream(
      ClassLoader cl,
      InputStream in)
    throws IOException {
    super(in);
    this.cl = cl;
  }

  /*
   * This method is used to resolve the classes
   * when creating object instances.
   */
  protected Class resolveClass(ObjectStreamClass desc)
    throws IOException, ClassNotFoundException {
    String name = desc.getName();
    return cl.loadClass(name);
  }
}
...

The deepCopy() method itself is straightforward and we could have used Apache SerializationUtils methods if it weren’t for the custom ObjectInputStream:

...
private  Serializable deepCopy(
    ClassLoader cl,
    Serializable original) throws Exception {
  //Serialize to a byte array
  ByteArrayOutputStream baos =
    new ByteArrayOutputStream(512);
  ObjectOutputStream out =
    new ObjectOutputStream(baos);
  try {
    out.writeObject(original);
  }
  finally {
    out.close();
  }

  byte[] serialized = baos.toByteArray();

  //Deserialize to an instance
  ByteArrayInputStream bais =
    new ByteArrayInputStream(serialized);

  ReloadingObjectInputStream in =
    new ReloadingObjectInputStream(cl, bais);
  Object obj = in.readObject();

  return (Serializable) obj;
}
...

We could have used just a usual classloader (most common is URLClassLoader) and just point its classpath to the “/WEB-INF/classes”. However there is also a trouble that the same classes are in the classpath of the web application classloader. The Java specification instructs classloaders to try loading classes with the parent classloader first, however in our case we would be able to reload those classes, so we need to invert this preference by delegating to parent only if we cannot find the class in the classpath:

...
private static class ReloadingClassloader
  extends URLClassLoader {

  public ReloadingClassloader(
      URL[] urls,
      ClassLoader parent) {
    super(urls, parent);
  }

  public Class loadClass(String name)
    throws ClassNotFoundException {
    //If already loaded just return
    Class c = findLoadedClass(name);
    if (c != null)
      return c;

    //First try own classpath
    //then delegate to parent
    try {
      return findClass(name);
    }
    catch (ClassNotFoundException e) {
      return super.loadClass(name);
    }
  }
}
...

We create the classloader by putting “/WEB-INF/classes” into the classpath. getEnvironment().getEntry() is just a way in Aranea to look up services, in this case we need a ServletContext:

...
private ClassLoader newClassLoader()
  throws MalformedURLException {
  //Get the ServletContext
  ServletContext sctx =
    (ServletContext) getEnvironment().getEntry(
        ServletContext.class);
  //Return a classloader for "/WEB-INF/classes"
  return new ReloadingClassloader(
      new URL[] {sctx.getResource("/WEB-INF/classes")},
      getClass().getClassLoader());
}
...

Now we have most of the machinery in place and before we move on to Aranea filter implementation we can spare a thought on the limitations of the solution. Obviously it will only work on serializable classes. What’s more, to get actual gain from it all classes should have serialVersionUID set to some fixed number (e.g. “0″). This should be done so that small changes in the method and class signatures wouldn’t cause a deserialization failure. Even then removing a class (even an inner or anonymous class) will cause serialization to fail as well as changing the field types or order. However it is still much more than HotSwap would allow (at least at the moment).

Now we can go on with implementing the Aranea filter that will do the work. There are several reasons why this solutions suits Aranea so well:

  • Aranea is originally assembled from independent components by containment. Therefore one filter can define the classloader to load its children and do the rest of the tricks.
  • All application widgets in Aranea are serializable and loaded by the parent classloader (most of the filters are configured by Spring and loaded by its classloader).
  • Aranea components can only access their parents through the environment, which can be taken away at any given moment. Moreover parents have references only to their direct children, and can communicate with the indirect children only through messages.

Thus we can create a filter and put it in appropriate place just above the application widgets and we will be able to seamlessly reload all application widgets code.

At the moment we will assume that creating a new classloader and serializing/deserializing does not visibly affect response time in development, so we will just reload all classes before every request. Thus we do not need to check exactly which classes have changed, since any possible changes will be reloaded.

Let’s start by creating the filter service itself. It will have to take the child class name as a string, since we will need to load it reflectively in a freshly created classloader.

public class StandardClassReloadingFilterWidget
    extends BaseApplicationWidget {

  private String childClassName;
  private RelocatableWidget child;

  public void setChildClass(String childClass) {
    this.childClassName = childClass;
  }

  protected void init() throws Exception {
    //Create the classloader and use it
    //to load the child class
    ClassLoader cl = newClassLoader();
    Class childClass = cl.loadClass(childClassName);

    //Create an instance of child class and
    //attach it to the filter
    child =
      new RelocatableDecorator(
          (Widget) childClass.newInstance());
    addWidget("c", child)'
  }
...

Here we create the child widget reflectively in the classloader and add it under a name “c”. The only interesting part is that we also wrap it into a RelocatableDecorator, which we will return to later. Now the next method is called before every request and will do the actual reloading:

...
protected void update(InputData input)
  throws Exception {
  try {
    //Remove all references to parents and
    //reload the child classes
    child._getRelocatable().overrideEnvironment(null);
    child = (RelocatableWidget) reload(child);
  }
  catch (ClassNotFoundException e) {
    log.error("Failed to reload widget classes", e);
  }
  finally {
    //Restore the references to parents
    child._getRelocatable()
      .overrideEnvironment(getEnvironment());
  }

  //Reattach the child new instance to the filter
  _getComposite().attach("c", child);
}
...

Here the point of wrapping the child into the RelocatableDecorator comes out — as all references from children to parents in Aranea have to go through the environment, by removing the environment from the child we also remove all possible links up allowing to serialize children only.

Now the filter is complete (except for the trivial render() method which we leave as an exercise for the reader) and can be tested in e.g. main example or any other Aranea application by adding a similar configuration entry:

<bean id="araneaApplicationStart" singleton="false"
  class="org.araneaframework.framework.filter.StandardClassReloadingFilterWidget">
  <property name="childClass" value="org.araneaframework.example.main.web.DevelWidget"/>
</bean>

Instead of the usual:

<bean id="araneaApplicationStart"
  class="org.araneaframework.example.main.web.LoginWidget"
  singleton="false"/>

You will most probably want to define a different root widget class (in this case DevelWidget), which will start the usual LoginWidget in a StandardFlowContainerWidget. Otherwise you will lose the reloading filter on login.

So, on the plus side we managed to build a useful feature that will save countless developer hours by adding just one filter in a correct place. We also worked through a nice enough example of how to add framework features to Aranea (there definitely are a couple of gotchas here, but they are few and described in the reference manual). The filter can be used to reload widgets and all their helper classes, which makes up basically all of the Aranea application web layer. Since JSPs and most other templating engines can also reload their code easily we get to see all of the changes to the web almost instantly.

On the minus side we are reloading all of the classes in the web layer and serializing/deserializing all of the state on every request, which may become costly for a large application. We could somewhat remedy it by checking that classes have changed before reloading them. Also this trick won’t work for the business layer, since it is usually not serializable and can be referenced from many different places. There are some possible ways around it by they need much more effort and deserve a separate post in the future :)

Aranea 1.0.2 Released

Friday, November 17th, 2006

A bugfix stable release, for detailed description see changelog.

Aranea 1.1M1 is delayed since we are working hard on integration with JSF, GWT and Struts. There is still hope to get at least most of them working by Javapolis and demo it during the presentation.

Aranea 1.0.1 Released

Friday, November 3rd, 2006

In addition to fixes to several bugs that were found in the 1.0 release we have also implemented support for JSP 2.0 and Expression Language by providing a alternative tag library URI:

http://araneaframework.org/tag-library/standard_rt.

To get JSP 2.0 to work just use it instead of the usual URI.

In other news we are working on both new features like AJAX-based partial rendering and integration with other frameworks. We hope to release the 1.1 M1 release in the upcoming weeks including the features we’ve been working on, integration subprojects will come separately from main Aranea releases in their own tempo.

Aranea Kibitzed

Thursday, October 19th, 2006

Our good friends at SourceKibitzer.org have produced software metrics for Aranea framework source code including trends and complexity metrics. We plan to use this tool to finally get a hang of where our source code (which becomes bigger by the hour) is moving :)

Currently they provide basic metrics that give the overall feeling of the project source quality and trends for many Java Open-Source projects. They promise to provide more and more metrics by the moment so definitely keep watch for more interesting stuff.

Aranea Release Party

Friday, October 13th, 2006

And we’re happily celebrating the release in Webmedia’s new and fancy office!

With love from Estonia,
Aranea team and friends :)

Aranea release party!

Aranea 1.0 Final Release Available

Friday, October 13th, 2006

We are glad to announce the immediate availability of Aranea Web Framework 1.0 final release.

Aranea 1.0 is the first stable release of Aranea Web Framework. The API are now fully frozen until 2.x release cycle and documentation includes a 120+ pages Reference Manual, an Introductory Tutorial, a Hands-On Tutorial, Technical Report, Javadoc API and example applications. The framework is widely used in-house in both large and small projects and by now has been successfully deployed to production in most of them.

Aranea is an Open-Source Object-Oriented Web Application Framework that focuses on integration, maintainability and reuse. Our vision of Aranea includes three main themes:

  1. An Object-Oriented Framework. Aranea provides the component model based on static types and usual objects that facilitates applying Object-Oriented design to achieve a high level of maintainability and reuse. It also provides an extensive reusable component library that helps build complex and dynamic user interfaces.
  2. A Lightweight Web Application Integration Platform. Using Aranea component object model it becomes trivial to integrate and assemble seamlessly applications from disparate components. And since a whole application can be considered just a component it is just as simple to integrate whole applications, even dynamically. Aranea can be seen as a viable lightweight alternative to Portlets, especially with remote integration on the way.
  3. A Web Framework Integration Platform. Instead of competing with the numerous web frameworks, we want to harness their power and variety by integrating them with Aranea. We’d like to enable developers to make use of any framework features or components they find useful in their applications and Aranea to serve as glue among the application components. We especially want to support making different components or parts of application using different framework, as different requirements command different approaches.

The next step in Aranea development will focus on the third theme, which at the moment is represented in prototype stage only. Our first candidates for integration are Google Web Toolkit, Java Server Faces and Struts, with the rest to follow later. We expect to present a working integration demo on the JavaPolis 2006 conference in December.

Aranea development is supported by Webmedia, Ltd.

Webmedia is a system development and consultancy company focusing on developing long-term partnerships with corporate customers in public and private sector. Today, Webmedia is one of the largest software development companies in the Baltics, currently employing over 200 people in software development with front offices and development in Estonia, Lithuania and Finland, and an additional development centers in Romania and Serbia. Webmedia sees the software development process as very complex but still dynamic where different competences have to be combined in order to achieve quality applications as well as return on investment. Webmedia offers complete application life-cycle management services.