JRebel 3.1.2 incorporates improved support for OSGi (all containers), JBoss 6 and Freemarker as well as a host of fixes. See the full change log or download right away.
August 6, 2010
July 22, 2010
“Copy-on-Iterate” Java Idiom considered broken
This is a story of an interesting support request handled by our guru Lauri Tulmin. The inquiry was about a rare occurring ArrayIndexOutOfBoundsException that JRebel seemed to cause in Wicket. After some investigation he discovered that the root exception was thrown from the following Wicket code:
private final Map<IModifiable, Entry> modifiableToEntry = new ConcurrentHashMap(); public void start(Duration pollFrequency) { this.task = new Task("ModificationWatcher"); this.task.run(pollFrequency, new ICode() { public void run(Logger log) { Iterator iter = new ArrayList( ModificationWatcher.this.modifiableToEntry.values()).iterator(); while (iter.hasNext())
Specifically the exception was thrown from the constructor of ArrayList. How was that possible?
Let’s take a step back and review the reasons for this code. One issue with collections is that when iterating a ConcurrentModificationException is thrown if a collection is changed (usually by a different thread). This is done to protect the Iterator from unpredictable behaviour. A common idiom to avoid it is to copy the collection before iteration like that:
for(Iterator i = new ArrayList(collection).iterator(); i.hasNext();) {...}
Note that the collection must either to be synchronized or otherwise suitable for a multi-threaded environment.
This idiom is a very common one, as easily proven by a simple Google Code search. In fact we used it several times in the JRebel code and is present in several places in Wicket as well. So how could this cause an ArrayIndexOutOfBoundsException?
When Lauri investigated in depth he found out that this idiom is inherently unsafe in a multi-threaded environment (even when the underlying collection is synchronized!). The reason for that is the way ArrayList was constructed before Java 1.6. In my 1.5 Java SDK source code it looks like this:
public ArrayList(Collection<? extends E> collection) { int size = collection.size(); firstIndex = 0; array = newElementArray(size + (size / 10)); collection.toArray(array); lastIndex = size; modCount = 1; }
The issue is that there is a race condition between the time the size is recorded and the collection.toArray(array) is called. During that time it is conceivable (and indeed possible) that the size of the collection is changed by a different thread. If the size is now bigger, the array copying in toArray() fails with the dreaded ArrayIndexOutOfBoundsException. When researching the issue further we found that the constructor in Java 1.6 ArrayList has been changed to avoid this issue, so at least on Oracle Java 1.6 or later you are safe. Unfortunately I couldn’t find a specific bug referring to that issue, so likely as not it’s an accidental fix.
So what should you do to avoid this issue? One way is to put the synchronized block around the whole loop, but this requires that you only access that collection from other threads in the same synchronized block. An easier solution is to use the toArray()method like this:
for (Iterator i = Arrays.asList(collection.toArray()).iterator(); i.hasNext();)
July 14, 2010
JRebel 3.1.1 “Oogle” Released
This minor release includes a score of improvements across the board. Among the most important is that the Google App Engine support is now out of the beta and Google Web Toolkit support has been substantially improved, and the only reason we still keep it in beta is because we don’t have a full automated test harness for it yet. We have also tested JRebel with Tomcat 7 and Jetty 7.1 and can now declare them officially supported. Beta support for serializing added fields has been added, but is still disabled by default. Please add -Drebel.serialization=true and let us know how it works for you. Also we worked some of our magic with AspectJ and Groovy, so those of you who had issues should definitely upgrade to this version. See full changelog for details, or grab the download!
June 1, 2010
JRebel 3.1 — ORM Goodness
With the support for all Java EE standards this release of JRebel will help you reach a new level of productivity. Whatever change you make to your code, whether it’s a class, resource, configuration or a component, you can immediately see it in your application, with no need to build or redeploy. Although we’re still waiting on usage stats to confirm it, we estimate that JRebel 3.1 will eliminate up to 95% of builds/redeploys that you have to do without it on a common Java EE project.
The first thing you’ll notice after downloading the new 3.1 release, is the support for reloading JPA entities and configuration on all containers. Hibernate and OpenJPA plugins are now enabled by default, but for TopLink/EclipseLink we’re waiting for more user feedback, so go ahead and fire it up. JRebel also fully support reloading native entities and configuration for Hibernate and TopLink.
The second is the support for EJB interface changes and JSP scriptlet changes in GlassFish. Changes to EJB interfaces and scriptlets are now reloaded instantly on all major containers. New features include a spanking new iBatis plugin, beta support for the Geronimo container and a host of others.
Download it while it’s hot!
May 1, 2010
JRebel 3.0.1 Released
The first update to the 3.x line includes better handling of JDK proxies, support for Spring dm Server 2.x, advanced scriptlet support for WebSphere and Resin and more. Remember that the advanced scriptlet support is only available with the Enterprise Add-On, which is a free upgrade for all current users –- as long as you upgrade before June 1st.
Pick up the new version at our download page, with or without the Enterprise Add-On.
April 16, 2010
JRebel 3.0 Released!
This is exciting — Today is the day that we get to announce the culmination of 8 months of development effort, fine-tuning, bug fixing, and, awesome awesome awesome feature-adding (don’t just take our word for it, check out the buzz on Twitter). Today we announce the release of JRebel 3.0!
JRebel has matured a lot with this release. Adding to the ability to reload classes, it now integrates tightly with all common Enterprise stacks, allowing seamless reloading of almost all changes across the board. We’re talking about preventing 100% of your incremental builds and over 90% of the redeploys that you had to do during the day. Keep your focus, stay in flow, and have more fun delivering more features, with less defects, faster — just by taking your time back from an antiquated process.
Here’s the exciting part — the new features:
- Better Java EE support
- EJB — JRebel now includes plugins for JBoss (4.x, 5.x), Oracle Weblogic (8.x, 9.x, and 10.x) and IBM WebSphere (6.1 and 7.0) that support changing the Local/Remote EJB interface in EJB 1.x, 2.x and 3.x. It also supports on-the-fly dependency injection for @EJB annotation in JBoss. Unfortunately we don’t support EJB interface changes on IBM WebSphere 6.0 or earlier and require the EJB 3.0 Feature Pack to be installed on IBM WebSphere 6.1, even if you use EJB 1.x or 2.x.
- JSP <scriptlet>-s — Now when you change your Java code (e.g. add a new class or method) it can be immediately used in the Java code snippets in the JSP.
- JSF — Plugin for Mojarra that supports changes to configuration and annotations, and other JSF implementations are on the way.
- CDI — Plugin for Weld that supports changes to annotations.
- JPA — Plugin for OpenJPA that supports changes to entities and configuration. We’re considering this beta for this release and have it disabled by default. Other JPA implementation are on the way.
- Framework support
- Seam — Supports changes to annotations.
- Hibernate — Supports changes to entities, annotations and configuration. This rocks, but we’re taking it easy and considering it beta. It’s disabled by default.
- Support for adding static fields and changing enums. Previously when you added a static field to your class you’d see a discouraging warning in the console and get an exception when trying to access the field. Now JRebel will happily print “Reinitialized class” and your application will continue working as if nothing happened. To top it off you can also change Java 1.5 enums in any way you like and they’ll continue working!
- Startup time improvements. We significantly improved class/resource lookup overhead with caching and better server integration. Our nightly users are reporting up to 2x improvements in startup time.
- 25%-30% less memory use. It is not uncommon to need a lot of PermGen heap with JRebel enabled, so we optimized memory use and will continue to drive it down in the upcoming milestones.
- Better Proxy Support JRebel now integrates tightly with Javassist and CgLib, providing much better compatibility with changes to class signature in some advanced cases, e.g. JBoss Seam.
- rebel.xml Editor. A GUI editor for creating JRebel configuration files is now available and will soon be integrated in the IDEs. This makes it easier to setup your project and get started with JRebel.
We’re also happy to announce the release of the JRebel Enterprise Add-On. It’s meant for larger enterprises working with a more diverse set of applications, and preferences towards more centralized management. It supports older or discontinued technologies, which often require more maintenance and have longer restart & redeploy times. The Enterprise Add-On will be a free upgrade for all current users – as long as you upgrade before June 1st.
You can try JRebel free for 30 days, with or without the Enterprise Add-On from the same place where everyone else gets the new version.. right here! Download JRebel
April 13, 2010
JRebel 3.0 RC2 Available
March 30, 2010
March 17, 2010
JRebel 3.0 M3 Released
We are excited to announce the last milestone on the way to the JRebel 3.0. This release includes the following exciting new features:
- More EJB Support. JRebel now includes plugins for IBM WebSphere 6.1 and 7.0 that support changing the Local/Remote EJB interface in EJB 1.x, 2.x and 3.x. Unfortunately we don’t support EJB interface changes on IBM WebSphere 6.0 or earlier and require the EJB 3.0 Feature Pack to be installed on IBM WebSphere 6.1 even if you use EJB 1.x or 2.x.
- Better Proxy Support. JRebel now integrates tightly with Javassist and CgLib, providing much better compatibility with changes to class signature in some advanced cases, e.g. JBoss Seam.
- Hibernate Plugin. Now when you change your database schema the ORM follows. JRebel will recreate the SessionFactory automatically. Unfortunately this may take some time, so you’ll have to wait for it to finish, but it’s still much faster than a full redeploy.
- Mojarra JSF Plugin. Supports reloading JSF annotations and XML configuration on the fly.
- Seam Plugin. Supports reloading the Seam annotations on the fly.
- Weld Plugin. Supports reloading the Weld annotations on the fly.
- rebel.xml Editor. A GUI editor for creating the JRebel configuration files is now available and will soon be integrated in the IDEs.
- We also added support for reloading property resource bundles on IBM JVM, improved startup behaviour to prevent deadlocks and improved expression language support.
In addition to that there are numerous fixes and minor features that you can see in the changelog. And it includes the features introduced in 3.0 M1 and 3.0 M2; in case you forgot, here they are:
- Advanced EJB Support. JRebel now includes plugins for JBoss 4.x, 5.x and Oracle Weblogic 8.x, 9.x and 10.x that support changing the Local/Remote EJB interface in EJB 1.x, 2.x and 3.x. It also supports on-the-fly dependency injection for @EJB annotation in JBoss. In the coming milestones we’ll add support for IBM WebSphere and more comprehensive support for the EJB 3.x features
- Startup time improvements. We significantly improved class/resource lookup overhead with caching and better server integration. Our nightly users are reporting up to 2x improvements in startup time.
- More integration. We added or improved plugins for Guice 2.x, Groovy, Wicket 1.4, Google App Engine, AspectJ, Struts 1 and Spring MVC. With every new plugin we are a step closer to our vision of seamless updates to your application, no matter what are you changing. Expect even more integration in the next JRebel release.
- Support for adding static fields and changing enums. Previously when you added a static field to your class you’d see a discouraging warning in the console and get an exception when trying to access the field. Now JRebel will happily print “Reinitialized class” and your application will continue working as if nothing happened. To top it off you can also now change Java 1.5 enums in any way you like and they should just continue working. This feature is still a tad experimental, so please help us out to smooth it out!
- Full JSP <scriptlet> support. Now when you change your Java code (e.g. add a method) it can be immediately used in the Java code snippets in the JSP.
- 25%-30% less memory use. It is not uncommon to need a lot of PermGen heap with JRebel enabled. Now we optimized the memory use and will continue to drive it down in the upcoming milestones.
Download and enjoy!
March 9, 2010
RJC501: How Much Does Turnaround Cost?
Over the Reloading Java Classes (RJC) article series, we’ve examined how class reloading happens, from objects and classloaders to application servers and solutions that reduce Turnaround. It’s been pretty in-depth, so we’d like to take a step back, move to more shallow ground, and take a look at why we would want class reloading to work in the first place. What are the real costs of missing class reloading on Java teams?
As we discover, this is a challenging question to answer — but we’ll give it a shot here, using the attempts of others to guide us.
Other Articles in the Reloading Java Classes Series
- RJC101: Objects, Classes and ClassLoaders
- RJC201: How do Classloader leaks happen?
- RJC301: Classloaders in Web Development — Tomcat, GlassFish, OSGi, Tapestry 5 and so on
- RJC401: HotSwap and JRebel — Behind the Scenes
- RJC501: How Much Does Turnaround Cost?
The Easily-Measurable Cost of Turnaround: Builds and Redeploys
Last year we ran two surveys asking developers how much time they spend building and redeploying their application. Although we’ve been talking with developers about this for a long time, and everyone understands that some amount of time is spent on builds and redeploys, it was still surprising to see the results – including actual numbers of minutes, days, and weeks spent on the process. For example, during an average hour of coding developers spend:
- An average of 6 minutes building the application [Source: The Build Tool Report].
- An average of 10.5 minutes redeploying the application [Source: The Java EE Container Redeploy & Restart Report].
To be fair, there are large deviations on both sides of these averages — the survey data we used only came from 600 and 1100 respondents respectively, and they used a variety of technologies which you can read about in the reports themselves. Some folks don’t spend as much as the averages, while others spend much more, and your project could be anywhere in that range.
Given that, the averages should apply pretty nicely to Java EE development as an industry (with the usual disclaimer of “lies, damn lies and statistics”). Let’s take a look at an awful scenario — where everyone in the industry is right on the average:
- Build (6 mins) + Redeploy (10.5 mins) = 16.5 minutes per hour of development or 27.5% of coding time
- Assuming that developers only code 5 hours per day x 5 days per week x 48 weeks a year = 1200 coding hours a year
- 1200 hours * 27.5% = 330 hours a year or 330/40 = 8.25 full-time work-weeks a year spent on turnaround, per developer
- Assuming $20/h average salary, this adds up to 330 * 20 = $6600 per developer per year [Source: conservative estimation backed by http://www.worldsalaries.org/computerprogrammer.shtml]
- Larry Ellison recently quoted the number of Java developers around the world at 9 million.
If you’d like to work out the time or cash spent annually by the industry on Turnaround, these are some numbers you can start with.
Context Switching
Programming is complicated. In fact it’s so complicated that most people are not capable of doing it. Those who are capable must mentally juggle a lot of context while writing code.. context including specifications, GUI considerations, relevant library calls, relevant application classes, methods and variables and so on.
This information is held in the the working (aka short-term) memory. Since the working memory is not meant for long term storage, switching away from a current task means that you will start losing the context surrounding the code, and then spend time trying to get back into it. The rest of the article will discuss how quickly context is lost, how long it takes to restore it, and what effect it has on the quality of your work.
How quickly does working memory degrade?
In 1959, an article titled, “Short-Term Retention of Individual Verbal Items” by L. Peterson and M. Peterson appeared in the Journal of Experimental Psychology [Source: http://www-test.unifr.ch/psycho/site/assets/files/Allg/ExU/Peterson_1959.pdf]. It showed that on average, after only 3 seconds, about half of our working memory is lost. The following graph plots the amount of working memory preserved after every subsequent 3 seconds:
After 15 seconds, less than 10% of the original memory is preserved. While these results may not be directly applicable to the programming context, it is clear that memory degradation occurs after seconds, not minutes. Translated, it means that short distractions cause dramatic losses in working memory.
How long it takes to restore context after an interruption?
Although there’s not a direct answer to that question, going through the relevant literature gives us some clues:
[…] the recovery time after a phone call is at least 15 minutes. [...] If more than 10 interrupts occur during a day, the time between the interrupts becomes too short to accomplish product development work.
To take a call you need to completely switch away from your working environment and focus on the conversation. Other interrupts are less disruptive than that:
Recovering from an email interrupt, and returning to work at the same work rate as before the interrupt — 64 seconds.
Instant message — 11 to 25 seconds.
FYI – These quotes are not based on software developers, but rather more generic office workers. Take that as you’d like. Since context recovery is a process, it takes some time to get back to maximum speed after an interrupt:
The trouble is, getting into “the zone” is not easy. When you try to measure it, it looks like it takes an average of 15 minutes to start working at maximum productivity. [...] The other trouble is that it’s so easy to get knocked out of the zone. Noise, phone calls, going out for lunch, having to drive 5 minutes to Starbucks for coffee, and interruptions by coworkers [...] all knock you out of the zone.
So what about development Turnaround — should that be considered an interrupt and how much does it add to the cost?
From experience, any pause will cause the working memory to start fading, and longer pauses will cause developers to multi-task (even if the other task is reading Slashdot). This will mean that the context surrounding a particular task is at least partially lost and needs to be restored. A longer pause means more memory degradation, increased likelihood of a task switch, and the assumption that recovery time is also longer. Just to illustrate, let’s assume that it takes 50% of the length of the pause to recover the context after getting back to work. In that case, the total cost of turnaround for a java developer dealing with average build and redeploy delays looks something like:
- 16.5 (mins per hour spent on Build & Redeploy phases) + 50% = 24.75 minutes per hour of development or 41.25% of coding time
- 1200 (coding hours per year) * 41.25% = 495 hours per year spent on Turnaround (divide that by 40 hours per week to get 12.375 full-time work-weeks a year spent on turnaround)
- Assuming a $20/h average salary this adds up to 495 * 20 = $9900 per developer per year
These numbers make a lot of assumptions. I’m not convinced that the average hourly wage of someone reading this blog is $20. I’m also not convinced that these numbers make an air-tight argument — but the point here is: the social cost of Turnaround is more than just the time spent on building, redeploying, & restarting.
Finally, I’m not convinced that developers keep all the code they wrote on a day full of distractions – I get the feeling that long turnaround times, distractions, and interruptions have a negative effect on code quality, and on the mental abilities of other developers. Though we couldn’t find data measuring this specifically, there is some indication that this impact is also not trivial, and I’d like to finish with it:
In a series of tests carried out by Dr Glenn Wilson, Reader in Personality at the Institute of Psychiatry, University of London, an average worker’s functioning IQ falls ten points when distracted by ringing telephones and incoming emails. This drop in IQ is more than double the four point drop seen following studies on the impact of smoking marijuana. Similarly, research on sleep deprivation suggests that an IQ drop of ten points is equal to missing an entire night of sleep. This IQ drop was even more significant in the men who took part in the tests.
Many programmers appear to be continually frustrated in attempts to work. They are plagued by noise and interruption, and pessimistic that the situation will ever be improved. The data recorded about actual interruptions supports the view that the so-called “work-day” is made up largely of frustration time.
What are your thoughts on all this?
Resources
- Concerning Interruptions – Stephen B. Jenkins, Institute for Aerospace Research, National Research Council of Canada
- Interruptions.net Literature — comprehensive index of published papers concerning interruptions









