August 6, 2010

JRebel 3.1.2 released

Filed under: news — Jevgeni Kabanov @ 1:20 pm

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.

July 14, 2010

JRebel 3.1.1 “Oogle” Released

Filed under: news — Jevgeni Kabanov @ 11:48 am

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

Filed under: news — Jevgeni Kabanov @ 1:36 pm

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

Filed under: news — Jevgeni Kabanov @ 7:59 pm

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!

Filed under: news — Jevgeni Kabanov @ 9:59 am

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

Filed under: news — Jevgeni Kabanov @ 2:47 pm

Say hello to the last release candidate before the final release hits the virtual shelves on Friday — JRebel 3.0 RC2. The changes mostly include fixes, though some features were tweaked as well. Download it now and tell us if there’s anything wrong with it.

March 29, 2010

JRebel 3.0 RC 1 Released

Filed under: news — Toomas Römer @ 3:05 pm

We’ve started to stabilize the long list of added features and fixes of the milestone releases of the JRebel 3.0 branch. Today we’re happy to bring you the Release Candidate 1. For a full list of changes coming up in the 3.0 release check the full changelog, RC1 changes follow:

  • Added OpenJPA plugin; reloads the EntityManagerFactory on configuration changes (disabled by default)
  • Added support for load time weaving with spring-agent
  • Fixed potential Classloader deadlock on Tomcat 6.0.26
  • Fixed NoSuchMethodError for early Spring 2 versions

Download, test, give feedback and enjoy!

March 17, 2010

JRebel 3.0 M3 Released

Filed under: news — Jevgeni Kabanov @ 5:30 pm

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!

February 15, 2010

JRebel 3.0 M2 Released

Filed under: news — Jevgeni Kabanov @ 6:23 pm

We are excited to announce another milestone on the way to the JRebel 3.0. This release includes the following new features:

  • 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, JBoss Seam, 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.

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; in case you forgot, here they are:

  • 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!

February 11, 2010

Reloading Java Classes 401: HotSwap and JRebel — Behind the Scenes

Filed under: blog,news — Jevgeni Kabanov @ 11:49 am

In this article we’ll review how classes can be reloaded without dynamic class loaders. We will take a look at the JVM HotSwap class reloading support, Instrumentation API and ZeroTurnaround’s JRebel.

Other Articles in the Reloading Java Classes Series

HotSwap and Instrumentation

In 2002, Sun introduced a new experimental technology into the Java 1.4 JVM, called HotSwap. It was incorporated within the Debugger API, and allowed debuggers to update class bytecode in place, using the same class identity. This meant that all objects could refer to an updated class and execute new code when their methods were called, preventing the need to reload a container whenever class bytecode was changed. All modern IDEs (including Eclipse, IDEA and NetBeans) support it. As of Java 5 this functionality is also available directly to Java applications, through the Instrumentation API.

hotswap

Unfortunately, this redefinition is limited only to changing method bodies — it cannot either add methods or fields or otherwise change anything else, except for the method bodies. This limits the usefulness of HotSwap, and it also suffers from other problems:

  • The Java compiler will often create synthetic methods or fields even if you have just changed a method body (e.g. when you add a class literal, anonymous and inner classes, etc).
  • Running in debug mode will often slow the application down or introduce other problems

This causes HotSwap to be used less than, perhaps, it should be.

Why is HotSwap limited to method bodies?

This question has been asked a lot during the almost 10 years since the introduction of HotSwap. One of the most voted for bugs for the JVM calls for supporting a whole array of changes, but so far it has not been implemented.

A disclaimer: I do not claim to be a JVM expert. I have a good general idea how the JVM is implemented and over the years I talked to a few (ex-)Sun engineers, but I haven’t verified everything I’m saying here against the source code. That said, I do have some ideas as to the reasons why this bug is still open (but if you know the reasons better, feel free to correct me).

The JVM is a heavily optimized piece of software, running on multiple platforms. Performance and stability are the highest priorities. To support them in different environments the Sun JVM features:

  • Two heavily optimized Just-In-Time compilers (-client and -server)
  • Several multi-generational garbage collectors

These features make evolving the class schema a considerable challenge. To understand why, we need to look a little closer as to what exactly is necessary to support adding methods and fields (and even more advanced, changing the inheritance hierarchy).

When loaded into the JVM, an object is represented by a structure in memory, occupying a continuous region of memory with a specific size (its fields plus metadata). In order to add a field, we would need to resize that structure, but since nearby regions may already be occupied, we would need to relocate the whole structure to a different region where there is enough free space to fit it in. Now, since we’re actually updating a class (and not just a single object) we would have to do this to every object of that class.

In itself this would not be hard to achieve — Java garbage collectors already relocate objects all the time. The problem is that the abstraction of one “heap” is just that, an abstraction. The actual layout of memory depends on the garbage collector that is currently active and, to be compatible with all of them, the relocation should probably be delegated to the active garbage collector. The JVM will also need to be suspended for the time of relocation, so doing GC at the same time makes sense.

Adding a method does not require updating the object structure, but it does require updating the class structure, which is also present on the heap. But consider this: the moment after a class has been loaded it is essentially is frozen forever. This enables the JIT to perform the main optimization that the JVM does — inlining. Most of the method calls in your application hot spots are eliminated and the code is copied to the calling method. A simple check is inserted to ensure that the target object is indeed what we think it is.

Here’s the punchline: the moment we can add methods to classes this “simple check” is not enough. We would need a considerably more complicated check that needs to ensure not only that no methods with the same name were added to the target class, but also to all it’s superclasses. Alternatively we could track all the inlined spots and their dependencies and deoptimize them when a class is updated. Either way it has a cost in either performance or complexity.

On top of that, consider that we’re talking about multiple platforms with varying memory models and instructions sets that probably require at least some specific handling and you get yourself an expensive problem with not much return on investment.

Introducing JRebel

In 2007, ZeroTurnaround announced the availability of a tool called JRebel (then JavaRebel) that could update classes without dynamic class loaders and with very few limitations. Unlike HotSwap, which is dependent on IDE integration, the tool works by monitoring the actual compiled .class files on disk and updating the classes whenever the files are updated. This means that you can use JRebel with a text editor and command-line compiler if so willing. Of course, it’s also integrated neatly into Eclipse, IntelliJ, and NetBeans. Unlike dynamic classloaders, JRebel preserves the identity and state of all existing objects and classes, allowing developers to continue using their application without delay.

jrebel-agent

How does this work?

For starters, JRebel works on a different level of abstraction than HotSwap. Whereas HotSwap works at the virtual machine level and is dependent on the inner workings of the JVM, JRebel makes use of two remarkable features of the JVM — abstract bytecode and classloaders. Classloaders allow JRebel to recognize the moment when a class is loaded, then translate the bytecode on-the-fly to create another layer of abstraction between the virtual machine and the executed code.

Others have used this features to enable profilers, performance monitoring, continuations, software transactional memory and even distributed heap. Combining bytecode abstraction with classloaders is a powerful combination, and can be used to implement a variety of features even more exotic than class reloading. As we examine the issue closer, we’ll see that the challenge is not just in reloading classes, but also doing so without a visible degradation in performance and compatibility.

As we reviewed in Reloading Java Classes 101 the problem in reloading classes is that once a class has been loaded it cannot be unloaded or changed; but we are free to load new classes as we please. To understand how we could theoretically reload classes, let’s take a look at dynamic languages on the Java platform. Specifically, let’s take a look at JRuby (we’ll simplify a lot, so don’t crucify anyone important).

Although JRuby features “classes”, at runtime each object is dynamic and new fields and methods can be added at any moment. This means that a JRuby object is not much more than a Map from method names to their implementations and from field names to their values. The implementations for those methods are contained in anonymously named classes that are generated when the method is encountered. If you add a method, all JRuby has to do is generate a new anonymous class that includes the body of that method. As each anonymous class has a unique name there are no issues loading it and as a result the application is updated on-the-fly.

Theoretically, since bytecode translation is usually used to modify the class bytecode, there is no reason why we can’t use the information in that class and just create as many classes as necessary to fulfill its function. We could then use the same transformation as JRuby and split all Java classes into a holder class and method body classes. Unfortunately, such an approach would be subject to (at least) the following problems:

  • Perfomance. Such a setup would mean that each method invocation would be subject to indirection. We could optimize, but the application would be at least an order of magnitude slower. Memory use would also skyrocket, as so many classes are created.
  • Java SDK classes. The classes in the Java SDK are considerably harder to process than the ones in the application or libraries. Also they often are implemented in native code and cannot be transformed in the “JRuby” way. However if we leave them as is, then we’ll cause numerous incompatibility errors, which are likely not possible to work around.
  • Compatibility. Although Java is a static language it includes some dynamic features like reflection and dynamic proxies. If we apply the “JRuby” transformation none of those features will work unless we replace the Reflection API with our own classes, aware of the transformation.

Therefore, JRebel does not take such an approach. Instead it uses a much more complicated approach, based on advanced compilation techniques, that leaves us with one master class and several anonymous support classes backed by the JIT transformation runtime that allow modifications to take place without any visible degradation in performance or compatibility. It also

  • Leaves as many method invocations intact as possible. This means that JRebel minimizes its performance overhead, making it lightweight.
  • Avoids instrumenting the Java SDK except in a few places that are necessary to preserve compatibility.
  • Tweaks the results of the Reflection API, so that we can correctly include the added/removed members in these results. This also means that the changes to Annotations are visible to the application.

Beyond Class Reloading – Archives

Reloading classes is something Java developers have complained about for a long time, but once we solved it, other problems turned up.

The Java EE standard was developed without much concern for development Turnaround (the time it takes between making a change to code and seeing the effects of that change in an application). It expects that all applications and their modules be packaged into archives (JARs, WARs and EARs), meaning that before you can update any file in your application, you need to update the archive — which is usually an expensive operation involving a build system like Ant or Maven. As we discussed in Reloading Java Classes 301 this can be minimized by using exploded development and incremental IDE builds, but for large application this is commonly not a viable option.

To solve this problem in JRebel 2.x we developed a way for the user to map archived applications and modules back to the workspace — our users create a rebel.xml configuration file in each application and module that tells JRebel where the source files can be found. JRebel integrates with the application server, and when a class or resource is updated it is read from the workspace instead of the archive.

workspace-map

This allows for instant updates of not just classes, but any kind of resources like HTML, XML, JSP, CSS, .properties and so on. Maven users don’t even need to create a rebel.xml file, since our Maven plugin will generate it automatically.

Beyond Class Reloading – Configurations and Metadata

En route to eliminating Turnaround, another issue becomes obvious: Nowadays, applications are not just classes and resources, they are wired together by extensive configuration and metadata. When that configuration changes it should be reflected in the running application. However it’s not enough to make the changes to the configuration files visible, the specific framework must reload it and reflect the changes in the application.

conf

To support these kinds of changes in JRebel we developed an open source API that allows our team and third party contributers to make use of JRebel’s features and propagate changes in configuration to the framework, using framework-specific plugins. E.g. we support adding beans and dependencies in Spring on-the-fly as well as a wide variety of changes in other frameworks.

Conclusions

This article sums up the methods to reload Java classes without dynamic class loaders. We also discuss the reasons for HotSwap’s limitations, how JRebel works behind the scenes and the problems that arise when class reloading is solved.

Other Articles in the Reloading Java Classes Series

Older Posts »

Our Customers Say

“For the price, and for how easy it is to get installed and running in a developers’ environment, using JRebel is pretty close to a no-brainer.”

Jim Lesko, GT Nexus

Recent Tweets

RT @nilsga: Top three productivity changes in current project: 1. Use javarebel, 2. Switch to Linux, 3. Two monitors 1 week ago

RT @GabrielKast: java is optional but JRebel is mandatory. Luckily it's only 59$ per year ... Three month of of World of Warcraft! 1 week ago

Olark Livehelp