Latest news

JavaRebel 1.1.2 Released

An incremental update to the stable branch of JavaRebel....

Get a free JavaRebel license

We will give away 50 personal JavaRebel licenses to those who register first. Also personal licenses will be discounted to $49 unt...

JavaRebel offers free licenses to JavaBlackBelt brown belts

JavaRebel offers permanent licenses to all JavaBlackBelt's brown belts. This is a personal 1 seat commercial license that you can ...

Author Archive

JavaRebel offers free licenses to JavaBlackBelt brown belts

Tuesday, July 8th, 2008

JavaRebel offers permanent licenses to all JavaBlackBelt’s brown belts. This is a personal 1 seat commercial license that you can use to speed up your Java development. If you don’t have a brown belt yet, start taking the exams. This is the fifth and currently strongest belt offered so it won’t come easily.

To apply for a free license just send a link to your brown belt profile from the email used at JavaBlackBelt to support[at]zeroturnaround dot com. We’ll get back to you with your license.

JavaBlackBelt is a community for Java & open source skills assessment. It is dedicated to technical quizzes about Java related technologies. Read the full announcement from their news archive.

Zero turnaround with unexploded development

Friday, April 11th, 2008
The latest release of JavaRebel introduced two new approaches for achieving zero turnaround. Firstly if you have deployed your EAR/WAR/JAR as single archives you can still make the application use the classes that you are compiling on-the-fly with your IDE. This is what we are calling unexploded development. The other method is hot JAR replacement which is considered experimental at this point.

In this article we will look at how to setup the development environment to support unexploded development. We will take the Spring Framework sample named PetClinic. We will deploy this to JBoss as a WAR archive and then start modifying the classes in Eclipse IDE and see the changes on-the-fly from the browser.

Before we continue lets look how it works. Once an application is deployed to the container (in this case JBoss) it will start loading the application classes. JBoss is running the JavaRebel agent that will intercept the calls and load those classes from the preconfigured IDE output directory.

Note however, that this means that if a new class is added in the IDE but not present in the JAR files, the JAR files needs to be updated. Why? We are still talking about the classloaders of the container. Container only knows and looks for classes that are present in the EAR/WAR/JAR files and these zip archives are cached. So adding classes still requires the redeployment of the zip archives.

The normal development model in unexploded development looks like this:

  1. Code modifications
  2. Build the archives
  3. Update the EAR/WAR/JAR in the container
  4. Restart the container or redeploy the application
  5. Check the modification

We will change this into:

  1. Code modifications
  2. Background compiling
  3. Check the modification

We assume you have downloaded the Spring Framework (in this case the version number is 2.5.3) and created a Java project from the folder spring-framework/samples/petclinic. We have enabled the IDE to build automatically the source files. Eclipse will by default start building classes to the spring-framework/samples/petclinic/.classes folder.

Lets build the WAR archive. Open up a console and change directory to spring-framework/samples/petclinic. Issue the command ant warfile. It will produce a petclinic.war in spring-framework/samples/petclinic/dist. Copy this file to your JBoss’s deploy folder.

Start the database server for the application. Open up a console and change directory to spring-framework/samples/petclinic/db/hsqldb/ and issue the command server.sh (on Linux) or server.cmd (on Windows). This will start the database server. You should see something like this:

[Server@8813f2]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@8813f2]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@8813f2]: Startup sequence initiated from main() method
[Server@8813f2]: Initiating startup sequence...
[Server@8813f2]: Server socket opened successfully in 4 ms.
, alias=] opened successfully in 259 ms.0, db=file:petclinic
[Server@8813f2]: Startup sequence completed in 268 ms.
[Server@8813f2]: 2008-04-10 16:00:59.471 HSQLDB server 1.8.0 is online
[Server@8813f2]: To close normally, connect and execute SHUTDOWN SQL
[Server@8813f2]: From command line, use [Ctrl]+[C] to abort abruptly

Now lets add a configuration option to the JBoss startup script. We presume you have already installed JavaRebel. We will modify the JBoss/bin/run.sh (on Linux) or JBoss/bin/run.cmd (on Windows). First lets find the full path of the folder that your IDE is compiling the classes to. In my case it is /home/demo/projects/spring-framework/samples/petclinic/.classes. Lets add this as a Java -Drebel.dirs option to the JBoss startup script. So JBoss will have the flag -Drebel.dirs=/home/demo/projects/spring-framework/samples/petclinic/.classes on startup in addition to the usual JavaRebel flags. See JBoss installation for details on modifying the startup scripts.

Lets start the server. As the petclinic.war has been copied to the deploy folder, JBoss will deploy the application on startup. Depending on the server port visit http://localhost:PORT/petclinic. You should see the petclinic application homepage.

Petclinick Homepage

Now lets verify that everything got configured correctly. We’ll make a modification to a Petclinic class and see the output. We’ll test this by changing the validation of adding owners. In the browsers naviagate to “Find Owner” » “Add Owner”. Click “Add Owner” without filling any of the fields. You will see a page where it is stated that all fields are required.

PetClinick Required Fields

Open the file org.springframework.samples.petclinic.validation.OwnerValidator in your just configured IDE project. We will modify the validate method. You will see validation rules:

public void validate(Owner owner, Errors errors) {
    if (!StringUtils.hasLength(owner.getFirstName())) {
        errors.rejectValue(“firstName”, “required”, “required”);
    }
    if (!StringUtils.hasLength(owner.getLastName())) {
        errors.rejectValue(“lastName”, “required”, “required”);
    }
    if (!StringUtils.hasLength(owner.getAddress())) {
        errors.rejectValue(“address”, “required”, “required”);
    }
    if (!StringUtils.hasLength(owner.getCity())) {
        errors.rejectValue(“city”, “required”, “required”);
    }
    String telephone = owner.getTelephone();
    if (!StringUtils.hasLength(telephone)) {
        errors.rejectValue(“telephone”, “required”, “required”);
    }
    else {
        for (int i = 0; i <telephone.length(); ++i) {
            if ((Character.isDigit(telephone.charAt(i))) == false) {
                errors.rejectValue(“telephone”, “nonNumeric”, “non-numeric”);
                break;
            }
        }
    }
}

Lets remove the last name, address and city validations. The method will look like this now:

public void validate(Owner owner, Errors errors) {
    if (!StringUtils.hasLength(owner.getFirstName())) {
        errors.rejectValue(“firstName”, “required”, “required”);
    }

    String telephone = owner.getTelephone();
    if (!StringUtils.hasLength(telephone)) {
        errors.rejectValue(“telephone”, “required”, “required”);
    }
    else {
        for (int i = 0; i <telephone.length(); ++i) {
            if ((Character.isDigit(telephone.charAt(i))) == false) {
                errors.rejectValue(“telephone”, “nonNumeric”, “non-numeric”);
                break;
            }
        }
    }
}

Now when you click “Add Owner” button again you will see that the requirement for the last name, address and city are gone now.

PetClinic Less Required Fields

You should also see the line JavaRebel: Reloading class 'org.springframework.samples.petclinic.validation.OwnerValidator'. in JBoss server log.

If the validation rules have been reloaded, you have successfully configured the unexploded development format. You have deployed a WAR file and made the container aware of the location from where to find the modified classes.

If you have multiple locations to look for the classes you can specify a comma separated list of location to the -Drebel.dirs option.

If you have any comments, suggestions or questions don’t hesitate to ask either in the comments section or via support at zeroturnaround dot com

Accepting PayPal payments

Thursday, April 3rd, 2008

As of today we also accept payments made via PayPal. We have added a paypal button to our buy page. The checkout process is the same as before but you will get redirected to the PayPal website for the payment process.

Paypal is a worldwide online payment solution supporting multiple payments methods (credit cards, bank transfers etc.), available in 190 markets and 17 currencies around the world.

JavaRebel Tutorial - Tomcat & Windows

Thursday, April 3rd, 2008

Everybody does not have a standard installation of a JEE container and a development environment. As JavaRebel installation is a matter of adding -javaagent:path/to/javarebel.jar -noverify flags to the JVM, it can always be installed but exact configurations differ from one development environment to another. Rob Sinner has documented how he configured his environment on Windows running Tomcat as a service to support zeroturnaround with JavaRebel.

JSP Weaver 1.0.2 released

Monday, March 31st, 2008

This is a small bug-fix release of JSP Weaver. All the issues that have been reported have been fixed and some performance optimizations from the development snapshots have also been included. See the changelog for more information:

  • New error screen with source display
  • Updated Commons EL to ZeroTurnaround patched version
  • General performance improvements
  • Fixed issue with boolean tag attributes
  • Fixed issue with c:foreach tag
  • Fixed issue with containers using servlet output stream in included pages
  • Fixed issue with scriptlets ordering in JSP XML format
  • Fixed issue with imports and declared methods in statically included pages
  • Fixed issue with resource paths not ending with slash

Head off to the download section to get the latest version.

Integrating JavaRebel with Spring

Wednesday, March 12th, 2008

We have started working on integrating JavaRebel with the Spring Framework. First we are concentrating on annotation based configuration and then see what can we do with changes in the XML configuration files.

JavaRebel detects added/removed/changed annotations so reloading the changes is a matter of finding the right spots in the code that test for existence of certain classes and their annotations. The simplest solution on failure is to just refresh the context and try one more time. If it fails anyway the extra time relooking is not expensive.

Lets take an example. We are using the Petclinic sample that comes with Spring. Lets add a new controller.

package org.springframework.samples.petclinic.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class NewController {
    public NewController() {}

    @RequestMapping(“/newWelcome.do”)
    public void welcomeHandler() {}
}

And create a newWelcome.jsp also. Lets try to visit the url petClinic/newWelcome.do now. Of course we get an 404. Lets look at the code in DispatcherServlet that looks for the mappings.

Iterator it = this.handlerMappings.iterator();
while (it.hasNext()) {
   // looking for the handler
   …..
   return handler;
}
return null;

Lets make this code refresh the application context if null is returned and after the refresh try one more time.

if (AbstractRefreshableApplicationContext.class.isAssignableFrom(getWebApplicationContext().getClass())) {
 ((AbstractRefreshableApplicationContext)getWebApplicationContext()).refresh();
 // look for the handler again
 // …
}

What does it give us? Adding/changing new controllers is a matter of refreshing the context. Basically all integrations boil down to reiniting some internal state to take into account the changes.

On error we are falling back to give it one more try. Actually this example will find the newly added controller without JavaRebel because the refresh of the context will scan for the new class files. Of course all the other adding/changing/removing classes/methods/annotations etc. will need on-the-fly class reloading.

The status of integrating JavaRebel with different projects can be seen from our Google Code page. If you need help with your own integration just use the forum or drop us a line at support email.

ZT patched Commons-EL - lookup newly added properties

Tuesday, March 4th, 2008

Commons-EL is a widely used JSP 2.0 Expression Language Interpreter from Apache. It lets you easily access and manipulate application data in JSP files without requiring the use of scriptlets. Of course commons-el has caching mechanism in place so that newly added/changed fields are not visible in the EL until application redeploy. We have released a small patch and a custom build of the commons-el that lets you access the newly added/changed fields without the limitations. Hopefully this patch will be accepted to the unplanned commons-el 1.1 version.

JSP Weaver 1.0.1 Released

Friday, February 1st, 2008

This is a small bugfix release addressing the problems with Tomcat 6. Correct interpretation of the JSP Taglibrary descriptor, fixed JSP 2.0 SimpleTag handling and an upgraded XML parser. The new version is available from the download section.

Developing in Exploded Format

Monday, January 28th, 2008

We have had quite many support requests on how to use JavaRebel in different configurations. Either users have one Eclipse project from which they deploy three applications or the other way around, generating one project from multiple projects. Standard approaches (at one point copying or zipping into one archive and deploying) are quite slow in these circumstances and only provide a way to distribute the application and do not concentrate on how to make the developers’ work hours more productive.

In this article we will look at different configurations and see how to configure projects so that we do not spend too much time on building and deploying but developing the applications.

Sample Configuration

We will be developing a web application named WebApp and an accompanying library called OurLib. The WebApp depends on OurLib and we want to take advantage of exploded format in development.

Folder structure

WebApp/

  • src/ - Source files with top level package com
  • bin/ - Eclipse build folder
  • lib/ - Buildtime & runtime libraries
  • tests/ - Tests’ source files
  • etc/ - Configuration files
  • dist/WebApp.war - Distributable artefact generated by build cycle.
  • dist/WebApp/ - Distributable artefact before packing generated by build cycle.

It is better to use a more logical folder structure for web applications. One that has an application folder that can be deployed straight to a container. Then it is easier to separate buildtime and runtime dependencies and limits the need of constructing a special distributable folder during build. In this article will use the given structure though.

OurLib/

  • src/ - Source files with top level package org
  • bin/ - Eclipse build folder
  • lib/ - Buildtime & runtime libraries
  • etc/ - Configuration files
  • dist/OurLib.jar - Distributable artefact

Configuration

We will be deploying the WebApp to a Tomcat web container and Weblogic Server 9.2 . OurLib has to be accessible from the WebApp . We will be using Eclipse for development, Apache Ant as a standard building tool and the developers will be using either Linux or Windows (NTFS filesystem) environment. Eclipse is configured to build files automatically (from the Eclipse menu Project » Build Automatically is checked).

Build Automatically Checkbox

Typical Building

OurLib has a build.xml with target dist. It will produce a single JAR file in the dist folder. The target compiles the source files with the necessary flags, attaches the configuration files and archives into a JAR file.

WebApp has a build.xml with target dist. It will produce a single archive, in this case a WAR file. Consisting of the compiled class files, configuration files, static pages and so forth.

The OurLib.jar ends up in dist/WebApp/WEB-INF/lib either by WebApp’s dist target (has configured the OurLib location) or by OurLib dist target.

The WebApp.war ends up deployed in both application servers. This can be achieved manually (in WebLogic it is dozen of clicks) or automatically through the WebApp build script.

Developers perspective

On every deployment the following tasks happen:

  • Source files are built
    • Longer approach but universal: javac task is invoked to compile the source files
    • Usually quicker: IDE’s output folder is used
  • Built files are aggregated into an archive
    • Involves copying of files
    • Files are zipped into a single archive
  • WAR archive is deployed
    • Archive is copied to the container’s folder
    • Archive is unpacked to a temporary folder
    • Deployment of the temporary folder.

As we can see there is just too much overhead from doing repetitive tasks that we can avoid. I did not include the steps that need to be taken to build the OurLib project or deployment to the other container too. We are compiling code twice, we are packing and unpacking an archive, we are copying files from one location to another, we are losing the session in the web application. Hopefully the deployment cycle is done through the build script. We would otherwise be clicking our way through endless dialogs to make the container understand how certain we are about the redeployment.

How long does it take? Depends on the size of the application. Probably from 30 seconds to some tens of minutes. Even 30 seconds stack up to a lot.

Exploded format

We can lose copying, packing, unpacking from the cycle in different ways. The main difference will be that we will start deploying an application as a folder instead of a WAR archive. To redeploy, one has to touch web.xml or hit Redeploy/Reload in the respected web interface.

With Weblogic deploying in exploded format is done the same way as deploying an archive. Instead of the WAR file you specify a folder. Weblogic will highlight a folder deployable if it has the WAR or EAR folder structure.

With Tomcat it is done by copying the folder to TOMCAT_HOME/webapps.

Application configuration

We need to produce the deployable folder from our project. The structure must be as follows:

  • WEB-INF/
      classes/ - compiled class files
      lib/ - runtime libraries
  • web.xml

This can be achieved by making the build script create the folder structure, copy runtime libraries, compile source files and copy configuration files. The folder can then be deployed to a container. We could have structured the project to include such a folder
and keep the runtime libraries and configuration in such a folder structure already. This time we did not.

Next we will look at some examples of how we can configure the project so that seeing changes made to the source files will not require other operations than just hitting refresh in the browser.

Example

Eclipse is building class files to folder bin. We use dist/WebApp as the folder we deploy to Tomcat or Weblogic. We will use an ANT target that will makes the folder structure of the application (copying the class files from the IDE output location, lib files and configuration files to dist/WebApp respective folders). The very same target can be later used to zip the folder into a WAR file.

On every deploy we save the time of zipping and unzipping our project and depending on the configuration even the compiling. To deploy the application we click reload/redeploy in the application server.

Example With a Twist

We use a set of symlinks to completely lose the copying part and even invoking ANT. We will symlink the IDE’s output folder to dist/WebApp/WEB-INF/classes. The libraries will end up in dist/WebApp/WEB-INF/lib. Either the whole folder or just a subset of the libraries.

Now we have a configuration that requires no copying or invoking ANT. If we need to see the output in the browser we just have to redeploy the application. Now we are only losing the session in the application.

Example Without Redeploy

We will add JavaRebel to the equation and lose the redeployment part. As we are deploying everything as class files we can configure the server to use JavaRebel. See the installation documents for different containers.

Now we have a configuration that requires only a refresh in the browser to see any results.

What about OurLib?

OurLib can be deployed without zipping it into a JAR archive. The easiest way is to just symlink the IDE’s output folder to the WebApp’s deployment folder’s WEB-INF/classes. As we are probably already using a symlink for the WEB-INF/classes we have to make it a bit more granular. So for the WebApp we actually symlink, lets say, the toplevel package. So Webapp’s bin/com gets symlinked to dist/WebApp/WEB-INF/classes/com and OurLib’s bin/org gets symlinked to dist/WebApp/WEB-INF/classes/org.

Symlinks Under Windows

Now if we want to see changes made to the library that we are using in our WebApp we just make a change, save the file (Eclipse is compiling in the background) and hit refresh in the browser.

Summary

Achieving shorter turnaround requires the developers to know the tools available to them. Projects use very different folder structures, build scripts and have different type of dependencies. Still developers can make their life easier with a set of tools and a bit of imagination.

Eclipse

Compiling can be done in the background and the resulted class files can be used for deployment. This is a real time saver.

Custom builders can be defined that run before or after every build. They can be made to copy some deltas or touch configuration files or actually everything. Here is how you create a project builder Ant buildfile.

Different source folder can have different output folders. E.g. the project has different folders for source files and unit tests. They can be compiled into different folders. Project properties » Java Build Path » Source Tab » Allow output folders for source folders checkbox.

Multiple Output Folders

Symbolic Links under Linux & Windows

Projects’ location and structure differ from the deployment counterparts. They can even be in a 1-n relationship. This is where symbolic links come into play. One can link directories or files to other places on the filesystem thus keeping the data in one place but available to different applications. Creating and managing links differ for operating systems, they are even named differently. See Similar Concepts from Wikipedia symlink article for more information. Mind that symbolic links are not something that only Linux users have, Windows has them too (comfortable and secure managing of them requires a freeware application though).

JavaRebel

Developers don’t have to restart a container or redeploy an application to see their code change in action. Make a change, compile the code and JavaRebel will pickup the changes. See the screencast for more information.

JSPWeaver 1.0 released

Tuesday, January 22nd, 2008

JSPWeaver interprets the JSP markup on-the-fly instead of producing and compiling Java code. This reduces JSP reload times in development from tens of seconds to milliseconds.

The final release incorporates performance and stability improvements. JSPWeaver now supports the full JSP standard including common syntax, XML syntax and Java scriplets and is completely container-agnostic.

Installing JSPWeaver is as easy as dropping a JAR into WEB-INF/lib and registering the servlet in web.xml. Download it from ZeroTurnaround and give it a try.

Disclaimer: JSPWeaver is commercial software with a free trial for 21 days and developer seat cost at 49$.