admin

Nov 112014
 

Note, this tutorial describes the steps that I performed, but I don’t know whether these steps are *the best way* to do it.

Introduction

IDE

IntelliJ and Scala IDE are probably the best known Scala IDEs. Scala IDE is a preconfigured version of Eclipse, and is freely available.
Over the years, IntelliJ gained a lot in popularity and has surpassed NetBeans. IntelliJ comes in two editions: Community Edition (free) and Ultimate Edition (commercial, only free for educational purposes).

SBT

SBT (officially written in lowercase) stands for “Simply Build Tool“, but according to some people, SBT is every but simple, but it is considered to be very powerful.

Although it is possible to use Maven for Scala projects, SBT is considered The Build tool for Scala. Internally SBT uses Apachy Ivy, a tool that has dependency management like Maven and integrates with Apache ANT.

Scala & ScalaTags

Although Scala has a high learning curve, the power/flexibilty of the Scala language makes it suitable to create nice api’s. Some api’s are such clean that instead of creating a text based template framework to write web pages, you can write the web page directly in Scala without sacrificing readability. A big drawback of text based template frameworks is that they usually aren’t object oriented: you pass data from a web controller to a template. Passing data around in code isn’t considered object oriented but more a procedural style of programming. Also, text based template frameworks limit your flexibility in creating all kinds of code structures. ScalaTags is a small and fast library to write HTML is plain Scala, giving you all the flexibility to create your own code structures.

Servlets & Tomcat

Servlets is the standard technology in the Java enterprise world to create web applications. Many Java webframeworks are written upon servlets. Servlets can run in special servlet containers, such as the Tomcat webserver. Jetty is another popular servlet webserver, especially when it comes to embedding webservers in applications instead of the more standalone Tomcat. Note that a relatively high number of Scala web frameworks don’t support servlets, and instead run on embedded fast lightweight webservers, such as Spray and Netty.

Specs/Test setup

The versions of some components probably don’t matter much. But this tutorial might differ for IntelliJ 13. If possible try to have a good combination of Scala, xsbt-web-plugin, Scala plugin. (Not sure which ones are “good” but this one works for me.)

I don’t know if this process differs for IntelliJ Community Edition instead of the Ultimate Edition.

About the tutorial

This tutorial assumes that you haven’t installed Java, Scala, SBT and IntelliJ yet.

If you get strange Scala code warnings, try: “File” > “Invalidate Caches/Restart“.

Light gray indented text in this blog post is background information and is not required to read to follow this tutorial steps.

Install Java

IntelliJ by itself doesn’t require Java to be installed, but your IntelliJ projects do if you want o compile, debug and run them.

Download and install Java SE JDK from the Oracle website.

Install Tomcat

Download and unzip Tomcat as a zip file from from http://tomcat.apache.org. You don’t need a Windows Service, just the zip is enough.

If you want to use a service, then the deployment steps to put your project into Tomcat, differs.

Start IntelliJ

Download and install IntelliJ.

Start IntelliJ. On first run, it will ask you to customize IntelliJ (skin, ui Theme, plugins etc.). I choose “Skip All and Set Defaults” (for the sake of this tutorial).

Configure Java in IntelliJ and info about defaults settings

After starting IntelliJ, it will show the “Welcome to IntelliJ IDEA” start screen, where you can open projects. (If you don’t see the welcome screen, but immediately get a full blown IDE, you can go back to the welcome screen via: “File” > “Close Project“.

JVM based IntelliJ projects usually need a SDK assigned to be able to compile, debug and run applications as well as for “the standard SDK classes resolution“. SDK stands for Software Development Kit. JDK is an SDK.

First we need to add JDK as a SDK to IntelliJ at global (IDE) level. (This is even needed for Scala projects.)

Choose “Configure” > “Project Defaults” > “Project Structure“.

This window shows settings that are by default shared by all projects.

Choose “SDKs” > “+” > “JDK” > and select the root of the directory where you have installed the JDK that you want to use.

(Note that you don’t select a “JRE” but a “JDK“. When installing a JDK, Java by default also installs a JRE.)

Install Scala Plugin

By default, IntelliJ doesn’t install Scala support, so we first have to install the Scala plugin.

Go back to the welcome screen > Choose “Configure” > “Plugins“.

IntelliJ will show all installed plugins.

Choose “Browse repositories” > search for a plugin named “Scala” and install that plugin.

According to the “Scala” plugin description, it also supports SBT. There also exists a third party “SBT” plugin (version 1.6.1, 2014-05-14), but we don’t use that one in this tutorial.

Restart IntelliJ.

(This will probably activate the plugin.)

Creating a SBT project

Choose “Create new Project” > select “Scala” then “SBT” (this will create a “SBT-based Scala project“) > “next” > Choose a “Project name” and “Project location“, for example “scalaweb” and “c:\scalaweb“. The “Project SDK” setting should have a JDK selected, if not, select one. In my case ‘1.8 (java version “1.8.0_25″)‘ is selected. Then choose “Finish” and IntelliJ opens the IDE and the project.

You would probably expect that the project would configure Scala and SBT for you, otherwise it would ask for it, right? Wrong. At this moment, it’s a bit clear what the *correct* workflow is. Currently, the project only consist of some files and has project structure settings with no Scala or SBT configured, and you have access to the “SBT” window (via icon in the lower left > “SBT“).
There are multiple ways to configure SBT/Scala in the project, but each can have different outcomes with possible Scala version conflicts and project errors etc.What works for me is this:

Open /build.sbt and DON’T CLICK in the “Import project: File ‘C:/scalaweb/build.sbt’ seems to be SBT build file, but there is no external project related to it. Import the corresponding project?“. Just leave the “Import project” prompt open for the moment, otherwise it might configure your project to a random Scala version (2.10.4 in my case).

SBT is able to automatically download a specific Scala for you. SBT stores Scala somewhere in the C:\Users\YOUR_USER_NAME\.ivy2\ directory.

Now write the Scala version in build.sbt, so that SBT will use that version and subsequently, the Scala plugin will use that version. In my case, I changed build.sbt to:

name := "YOUR_PROJECT_NAME"

version := "1.0"

scalaVersion := "2.11.4"

(Note that the empty lines are required in SBT.)

After setting the Scala version, click “Import project” button/link from the “Import project” dialog.

The Scala plugin will then perform a lot of magic (see progress in the bottom of IntelliJ), such as letting SBT download the correct Scala version using Ivy. The Ivy repository located in C:\Users\YOUR_USER_NAME\.ivy2\.

Wait till the process is finished.

After the plugin is finished with your project, a number of things have changed in the Project Structure settings:
-A second module was added: “scalaweb-build“, next to the already existing “scalaweb” module. “scalaweb-build” contains SBT specific configuration, while “scalaweb” contains more Scala/Java specific configurations.
-For the modules: source locations were added, compilation output paths changed, SBT Scala libraries added and SBT plugins as library dependencies were added.
-scala-libary was added as a “libary“.
-“Scala compile server” was enabled.

Next, Scala source files should be put in /src/main/scala/, so manually create that directory via IntelliJ.

Enable Servlets for SBT

Next, we need to add the required library dependencies to work with servlets, and we need to configure SBT to generate a war content structure.

While Maven officially supports Java war/web projects, SBT relies on third party plugins. A SBT plugin that is listed at the official SBT website and able to generate war files is “xsbt-web-plugin“.

Install xsbt-web-plugin:

Open /project/plugins.sbt and modify the file to:

logLevel := Level.Warn

addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "1.0.0")

(Empty new line is required.)

Next, add Servlet libary dependencies:

Open /build.sbt and modify the content to:

name := "YOUR_PROJECT_NAME"

version := "1.0"

scalaVersion := "2.11.4"

libraryDependencies ++= Seq(
  "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
)

Everytime you modify /build.sbt, you need to refresh the IntelliJ project:

Hover on the lower left square symbol in IntelliJ > “SBT” > click the refresh button to refresh the SBT project.

Next, we need to configure an IntelliJ “artifact” so that later, we can add the artifact to Tomcat:

Choose “File” > “Project Structure” > “Artifacts” > “+” > “Web application: Exploded” > the artifact will be named “unnamed” by default. Then click the “Output Layout” tab > under “Available Elements” right-click “YOUR_PROJECT_NAME” (in my case “scalaweb“) > “Put into output Root“.
Repeat the same for “scalaweb-build“.
Finish

(Not sure if both “scalaweb” and “scalaweb-build” are required. But couldn’t get it fully working without both, the last time I tried.)

Creating an sample servlet

Under /src/main/scala, create the file “MyServlet.scala” with the following content:

import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

@WebServlet(Array("/"))
class MyServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) {
    val writer = res.getWriter
    writer.write("<html><body>Hello World!</body></html>")
    writer.close()
  }
}

This will create a Servlet that is mapped under the “/” uri.

Starting Tomcat via IntelliJ

Now we can start Tomcat and the project:
Choose “Run” > “Edit Configurations…” > “+” > “Tomcat Server” > “Local“.
Then “Configure” > add the Tomcat server for “Tomcat Home“.
Then “Deployment” tab > “+” of “Deploy at the server startup” > “Artifact” > finish.

Now start the server via: “Run” > “Run ‘unnamed‘” (“unnamed” is the default name of the Tomcat configuration).

Tomcat boots up and should show “Artifact unnamed: Artifact is deployed successfully” in the output.

Try http://localhost:8080/ under a browser to see if you get to see “Hello World!“.

You can close the server using the red square in the left of IntelliJ.

Using ScalaTags

First we need to add a dependency to ScalaTags.
Modify /build.sbt, change:

libraryDependencies ++= Seq(
  "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
)

to

libraryDependencies ++= Seq(
  "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided",
  "com.scalatags" %% "scalatags" % "0.4.2"
)

Because ScalaTags is a dependency that was built with sbt, you can use a double “%%” to let sbt get a version of ScalaTags that was built with the same version of Scala as defined in /build.sbt. If your /build.sbt Scala version is newer than the latest ScalaTags Scala version, then you need to change the version, see: http://www.scala-sbt.org/0.13/docs/Library-Management.html

Remember to reload the project using the SBT window in IntelliJ.

As a ScalaTag example, we’re going to write a Servlet that shows a list of people names (firstname and lastname) followed by a HTML form that allows us to add additional names to the list using a HTTP POST request.

Put the following code in /src/main/scala/MyServlet.scala:

import javax.servlet.annotation.WebServlet
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import scala.collection.mutable.ListBuffer
import scalatags.Text.all._

@WebServlet(Array("/"))
class MyServlet extends HttpServlet {
  private case class Person(firstName: String, lastName: String)

  private val people = ListBuffer[Person]()

  override def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit = {
    renderPage(res)
  }

  override def doPost(req: HttpServletRequest, res: HttpServletResponse): Unit = {
    val firstName = req.getParameter("FirstName")
    val lastName = req.getParameter("LastName")

    if (firstName != null && lastName != null) {
      people += Person(firstName, lastName)
    }

    renderPage(res)
  }

  private def renderPage(res: HttpServletResponse): Unit = {
    val writer = res.getWriter
    writer.write(createTemplate.toString)
    writer.close()
  }

  private def renderPerson(person: Person) =
    div(backgroundColor:="yellow", border:="1px solid black", marginBottom:="5px",
      div("Firstname: ", person.firstName),
      div("Lastname: " , person.lastName)
    )

  private def createTemplate =
    html(
      head(

      ),
      body(
        h1("List of people"),
        for (person <- people) yield renderPerson(person),
        fieldset(legend("Add a new person"),
          form(method:="POST",
            div("Firstname: ", input(`type`:="text", name:="FirstName")),
            div("Lastname: ", input(`type`:="text", name:="LastName")),
            input(`type`:="submit")
          )
        )
      )
    )
}

Try it out and have fun :)

Sep 262013
 

I recently had a case of a hacked website. The hacker gained access to templates and injected the following PHP code:

eval(gzinflate(base64_decode('HJ3HkqNQEkU/ZzqCBd4t8V4YAQI2E..........................NIAWIIgeFb//eeff/79z/8A')));

To evaluate the possible damage the hacker has done, you’ll have to decode the string. The problem is that decoding the string leads to a new encoded string that has to be decoded again, leading to a new encoded string, decoding it again and so forth.

So I wrote some code to decode it.
(My first attempt was to try it in Python, but quickly got encoding problems and ugly Python errors such as “Type str doesn’t support the buffer API”. In the end I always tend to fall back to solid static typed languages, Java in this case.)

Here is the Java code:

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import java.util.zip.ZipException;

import org.apache.commons.codec.binary.Base64;

import com.google.common.io.CharStreams;
import com.google.common.io.Files;

public class GzipBase64Decoder {
	
	public String decode(String gzipBase64Input)  throws Exception {
		String currentDecodedString = gzipBase64Input;
		String previousDecodedString = null;
        int count = 0;
        while (true) {
        	//System.out.println(count);
            InputStream inflInstream = new InflaterInputStream(
                    new ByteArrayInputStream(new Base64().decode(currentDecodedString)),
            		//new ByteArrayInputStream(BaseEncoding.base64().decode(currentDecodedString)),
                    new Inflater(true));
        	try {
                currentDecodedString = CharStreams.toString(new InputStreamReader(inflInstream, "UTF-8"));
                previousDecodedString = currentDecodedString;
                int begin = currentDecodedString.indexOf('\'');
                int end = currentDecodedString.lastIndexOf('\'');

                //System.out.println(currentDecodedString);
                
                if (begin == -1 || begin >= end) {
                	break;
                } else {
                    currentDecodedString = currentDecodedString.substring(begin + 1, end);
                }
                
                
                count++;
        	} catch (ZipException ex) {
        		return previousDecodedString;
        	}
        }
        
        throw new IllegalStateException("Unable to decode input");
	}
	
	public static void main(String[] args) throws Exception {
		String result = new GzipBase64Decoder().decode(InputData.INPUT);
		System.out.println(result);
		
		Files.append(result, new File("x:/db/result.txt"), Charset.defaultCharset());
		
	}
}

class InputData {
	public static final String INPUT = "PASTE THE ENCODED STRING HERE";
}

If uses both Google Guava and Apache Commons as third party utility libraries.
The Java code simply tries to decoded the strings until it cannot be decoded any further.
The input string is put in a separate class for compilation performance reasons. (Due to the length of the encoded string in my case.)
Note that this assumes that all child encoded strings have the same pattern: eval > gzinflate > base64. It also assumes that the encoded string is enclosed by single quotes.

In my case the encoded string was encoded 10 times. In such a low number of encodes, you can also try manually using: www.whitefirdesign.com/tools/deobfuscate-php-hack-code.html
The decoded hacker code resulted in “c99madshell v.2.0 madnet edition”, which can be a big security thread on a server. (More info about cc99madshell, see: www.derekfountain.org/security_c99madshell.php )

 Posted by at 11:02
May 282011
 

This post shows how to render a list of product objects with associated category object using the webframeworks Rails, Wicket, Grails, Play, Tapestry, Lift, Context and JSP/Servlets. I’ve also benchmarked the response times.

INTRODUCTION

More »

The response time of websites is important, not just for the users, but also for SEO (Search Engine Optimalization) of a website. According to Google:

Speeding up websites is important — not just to site owners, but to all Internet users. Faster sites create happy users and we’ve seen in our internal studies that when a site responds slowly, visitors spend less time there. But faster sites don’t just improve user experience; recent data shows that improving site speed also reduces operating costs. Like us, our users place a lot of value in speed — that’s why we’ve decided to take site speed into account in our search rankings. We use a variety of sources to determine the speed of a site relative to other sites.

The response time of a website is the time between the HTTP request send from the webbrowser to the webserver and the corresponding HTTP reponse send from the webserver back to the browser.
There are many factors that determine this response time, such as geographical distance, Internet connection, the speed of the computer the browser is running on, and the performance of the webserver. The webservers performance is usually determined by database queries and the amount of data that has be to send back. But I was wondering how much the rendering performance of webframeworks impact the response time and how they compare to eachother.

In this post I’ll show how each you can render a list of products using each framework. This can be handy if you need a quick look at a framework, and see how it compares codewise to others. For each framework, I’ve measured the response times against the number of concurrent users and the number of product objects to render. I’ve also looked quickly at the memory consumption of each framework.

Please note, I’m not an expert in these frameworks, but I tried to use the most common solutions to render objects.
Also note that this post won’t show which framework is faster in general, it will only tell you which one is faster under the given environment/conditions and the given test case.
Another difficulty is that some frameworks have builtin features that shouldn’t be tested, like automatically opening database connection on each request. Some frameworks might have builtin security features that will increase the response times, or some might have builtin caching enabled by default. I haven’t looked at all these extra features that shouldn’t be part of the test case, so the results will only give a coarse indication of how fast a framework is in the given environment/test-case.

METHODS

More »

Test case

The test only consist of one page that is tested. This page contains a 2 column HTML layout using div tags. One column is the sidebar, the other the content area. The content area needs to render a list of products with it’s associated categories in a HTML table. The page does not contain components that need to be stateful (like forms etc.).
See GitHub for an example.

Each Product (class) contains the following properties:

-name: String
-price: Integer
-description: String
-categories: Hash-based set of Category

Each Category (class) contains the following properties:

-name: String

All solutions use an (static) in-memory List to retrieve products, so no database access was needed or set.

Framework features

For each framework, the page needs to use the following framework features:
-rendering of a list of products, each rendered as a custom component so that the layout of each product can be reused on other pages. For each product, it’s associated categories are shown.
-Separation of the page into a template that can also be used for other pages, and the content that is unique for each page (this content is surrounded by the template).
-Injection of the page name (including the number of products) in the title tag, and in the master template page name.

Measurements

The following variables are used in the response time measurements:
-Number of concurrent users
-Number of products

The memory usage is measured only for the 16 concurrent user with 1000 products test. Usage is measered by roughly looking at the average values using Windows Task Manager. CPU utilization is also measured in this way.

Each framework should return approximately the same HTML page size. Differences can occure because the way I wrote the template pages. For example: there is a difference in size between:

<g:each var="cat" in="${product.categories}">$${cat.name}, </g:each>

and

<g:each var="cat" in="${product.categories}">
	$${cat.name},
</g:each>

I measured the page sizes to make sure that there weren’t big differences. Big differences could impact performance.

The HTTP benchmark was performed by the tool Apache JMeter 2.4, which also measured the response times. Within JMeter, a Response Assertion was used to make sure that the correct page was returned (and not some error pages). The Response Assertion tested whether the result contained the string “Company” (which is part of the layout). No sessions/cookies nor HTTP request managers were set in JMeter, so each HTTP request was performed independently of the other requests.

Test system

-OS: Windows 7 Professional SP1 64bit
-CPU: AMD Phenom II X4 955
-MEM: 4 GB RAM
-Java: SE Update 24, 32bit
-Webserver for JVM based frameworks: apache-tomcat-7.0.12-windows-x86, run with -Xmx1024m

Tomcat was set to Xmx 1024mb, which gives the Java JVM at most 1024mb of available RAM to use. This should be enough to minimize garbage collection.

When settting Tomcat environment options under Windows, don’t use quotes!
set JAVA_OPTS=”-Xmx1024m”
won’t work, even though it is used in books like “Tomcat – The Definitive Guide”. Use instead:
set JAVA_OPTS=-Xmx1024m
You can verify this in the “Tomcat Web Application Manager” under “Server Status”, look for “Max memory”.

Framework: JSP, JSTL, Servlets

Specs:
-JSP 2.1
-JSTL 1.2
-Servlet 2.5

More »

file: WEB-INF/web.xml (URL mappings)
....
<servlet>
	<servlet-name>products</servlet-name>
	<servlet-class>www.ProductsServlet</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>products</servlet-name>
	<url-pattern>/products</url-pattern>
</servlet-mapping>
.....

web.xml is used to map the uri /products to the ProductsServlet class, which acts as a MVC controller.

file: WEB-INF/classes/www/ProductsServlet.java (controller)
public class ProductsServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("products", Service.getProducts());
		
		RequestDispatcher view = request.getRequestDispatcher("/products.jsp");
		view.forward(request, response);
	}	
}

The Servlet container (Tomcat) sends incoming HTTP requests to ProductsServlet (MVC controller), which retrieves the product data as a List object, and puts it in the request object as attributes and dispatches/forwards/pushes the request to products.jsp (MVC view).

file: products.jsp (view)
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="company" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="company2" uri="company" %>

<company:header title="Products Listing" />
					
<table>
	<c:forEach var="product" items="${products}">
		<tr>
			<td><company:product product="${product}" /></td>
			<td>
				<c:forEach var="cat" items="${product.categories}">
					${cat.name}, 
				</c:forEach>
			</td>
		</tr>
	</c:forEach>
</table>

<company:footer />

Products.jsp is the view, which receives data pushed from the ProductsServlet (controller).
The taglib lines define the location of JSP based tags.
The c:forEach tags are used to loop over the products and categories. The “company:product” tag is used as a custom component, which can be implemented as a JSP Tag File (prefix “company”), or as a TLD (Tag Library Descriptor) component (prefix “company2″). The company:header tag and company:footer tag are implemented as Tag Files, which surround the page content with the default layout that can be shared among other pages.

file: WEB-INF/tags/header.tag (heading template)
<%@ attribute name="title" required="true" rtexprvalue="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="default.css" media="screen" rel="stylesheet" type="text/css" />
		
		<!-- Title needs to be injected -->
		<title>${title}</title>
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<!-- Page name needs to be injected -->
					<div><h2>${title}</h2></div>
					<div class="innertube">

This Tag File is the first part of the default layout that can be shared among other pages. The first line defines data that can be passed to this Tag File.

(The footer heading template is similar to this file, but now shown here.)

file: WEB-INF/tags/product.tag (JSP based component)
<%@ tag body-content="empty" %>
<%@ attribute name="product" required="true" rtexprvalue="true" type="domain.Product" %>
<div class="product">
	<img src="${product.name}.jpg" />
	<span class="productname">${product.name}</span>, <span class="price">$${product.price}</span>
</div>

This is the Tag File based custom component used to render products. The attribute tg is used to define the parameters that can be passed to this file.

An alternative to the Tag File based custom component is the use of TLD (Tag Library Descriptor) + Java based code. This alternative isn’t tested in this post, but it’s probably faster than the Tag File based custom component. The code of this alternative is shown below.

(alternative, not tested) file: WEB-INF/default.tld (component declaration)
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	web-jsptaglibrary_2_0.xsd" version="2.0">
	<tlib-version>1.0</tlib-version>
	<uri>company</uri>
	<tag>
		<name>product</name>
		<tag-class>www.ProductTag</tag-class>
		<body-content>empty</body-content>
		
		<attribute>
			<name>product</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>

This is the default TLD (Tag Library Descriptor), which declares the company2:product tag used in products.jsp. It references to the www.ProductTag Java class file.

(alternative, not tested) file: WEB-INF/classes/www/ProductTag.java (Java based component)
public class ProductTag extends SimpleTagSupport {
	private Product product;
	
	public void setProduct(Product product) {
		this.product = product;
	}
	
	@Override
	public void doTag() throws JspException, IOException {
		JspWriter w = getJspContext().getOut();
		w.println("<div class=\"product\">");
		w.println("<img src=\"" + product.getName() + ".jpg\" />");
		w.println("<span class=\"productname\">" + product.getName() + "</span>,");
		w.println("<span class=\"price\">$" + product.getPrice() + "</span></div>");
	}
}

This writes a product as a custom component, it matches the TLD.

Framework: Wicket

Specs:
-Wicket 1.5-RC3

Because of a bug ( https://issues.apache.org/jira/browse/WICKET-3740 ) in Wicket, which might impact performance, Wicket is also tested for the latest snapshot version of Wicket from trunk for 1.5-RC3. (Called “Wicket-trunk” in the test results.)

More »

file: wicketapp/WicketApplication.java
public class WicketApplication extends WebApplication {    	
	...
	@Override
	public void init() {
		...
		mountPage("products", ProductsPage.class);
	}
}

The mountPage method maps the URI /products to the class ProductsPage.

file: wicketapp.TemplatePage.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="default.css" media="screen" rel="stylesheet" type="text/css" />
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<div><h2 wicket:id="pageName">Producs listing</h2></div>
					<div class="innertube">
					
						<wicket:child />
						
					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

This defines a Wicket page that can be used as a template for other Wicket pages; it serves as a base class for those other pages.

This is the template that is shared by other pages (subclasses). Together with TemplatePage.java, TemplatePage.html forms a single page.
The wicket:id is used to bind the HTML tag to a Wicket component. This allows TemplatePage.java to access and modify the HTML element/component, including it’s body. In this case, the wicket:id named “pageName” is used to allow TemplatePage.java to set the name of the page.

The wicket:child element is used to define the place where the content of subclass pages (such as the ProductsPage) will be shown.

file: wicketapp/TemplatePage.java
public class TemplatePage extends WebPage {
	
	private Model pageNameModel = new Model();
	
    public TemplatePage(final PageParameters parameters) {
    	// h2 page name
    	add(new Label("pageName", pageNameModel));
    }
    
    public void setPageName(String name) {
    	pageNameModel.setObject(name);
    }    
}

This is the Java code that is associated with TemplatePage.html. It adds a Label component to the page, which is passed the wicket:id value from TemplatePage.html, and a model object.
Wicket uses models to attach data to components. In case of the Label component is given a model object that is able to retrieve the name of the page.

These models are required because Wicket is designed to let pages be stateful and in Wicket the retrieval of data for a component if seperated from the component itself. This allows pages to be serialized without requiring all the attached model data to be serialized.

file: wicketapp/ProductsPage.html
<wicket:head>
	<title>Product Listing</title>
</wicket:head>

<wicket:extend>
	<table>
		<tr wicket:id="products">
			<td>
				<div wicket:id="product" />
			</td>
			<td>
				<wicket:container wicket:id="categories">
					<span wicket:id="category"></span>, 
				</wicket:container>
			</td>
		</tr>
	</table>
</wicket:extend>

ProductsPage.java extends TemplatePage.java, this will cause ProductsPage.html’s wicket:extend body to be placed at TemplatePage.html’s wicket:child tag’s location.
The wicket:id tags are used to bind the HTML tags to a Wicket component. This allows ProductsPage.java to access and modify those HTML elements/components, including the bodies.
The wicket:container tag is used as a grouping/container, which is bound to a repeating view component that is used to iterate over the categories.
The wicket:head tags allows child pages and components to add tags to the HTML head.

file: wicketapp/ProductsPage.java
public class ProductsPage extends TemplatePage {
	public ProductsPage(final PageParameters parameters) {
		super(parameters);
		ListView<Product> productsLV = new ListView<Product>("products", Service.getProducts()) {
			@Override
			protected void populateItem(ListItem<Product> li) {
				Product product = li.getModelObject();
				ProductPanel productPanel = new ProductPanel("product", product);
				li.add(productPanel);
				
				List<Category> categories = new ArrayList<Category>(product.getCategories());
				
				ListView<Category> categoriesLV = new ListView<Category>("categories", categories) {
					@Override
					protected void populateItem(ListItem<Category> catLi) {
						Category category = catLi.getModelObject();
						catLi.add(new Label("category", category.getName()).setRenderBodyOnly(true));
					}
				};
				li.add(categoriesLV);
			}
		};
		add(productsLV);		
	}
}

ProductsPage.java created the products page together with ProductsPage.html. It is a subclass of TemplatePage (which defines the template that is shared by other pages). It has a ListView componenent which iterates over the products. Each iteration is defined in the populateItem method. Each iteration creates a ProductPanel (a custom component) and a label containing the categories of each product. A nested LiewView is used to iterate over the categories. The strings such as “product”, “categories” and “category” are the component instance names, which match the wicket:id tag values used in ProductsPage.html.
Wicket uses models to attach data, e.g. a list of products, to components. In case of the Label component, the category.getName() string is automatically wrapped in a model.
These models are required because Wicket is designed to let pages be stateful and in Wicket the retrieval of data for a component if seperated from the component itself. This allows pages to be serialized without requiring all the attached model data to be serialized.

file: wicketapp/ProductPanel.html
<wicket:panel>
	<!-- This part/layout of each product needs to be made as a custom component, so that it can be reused at other pages -->
	<div class="product">
		<img wicket:id="image" />
		<span wicket:id="productname" class="productname">A name of product1....</span>, <span wicket:id="price" class="price">$150</span>
	</div>
</wicket:panel>

This is the layout of the custom product component. The wicket:id tags give HTML elements unique names, so that the HTML element can be accessed/modified/replaced as a Wicket component in ProductPanel.java.

file: wicketapp/ProductPanel.java
public class ProductPanel extends Panel {

	public ProductPanel(String id, Product product) {
		super(id);
			
		WebComponent img = new WebComponent("image");
		String imgUrl = product.getName() + ".jpg";
		img.add(new SimpleAttributeModifier("src", imgUrl));
		add(img);
		
		Label nameLabel = new Label("productname", product.getName());
		add(nameLabel);
		
		Label priceLabel = new Label("price", product.getPrice().toString());
		add(priceLabel);
	}
}

This is the Java code of the custom product component. This custom component is composed of three child Wicket components, each consisting of a wicket:id name and associated product data.
The SimpleAttributeModifier is used to add the src HTML attribute of the img HTML element in ProductPanel.html.

production settings

set to production mode using:
System.setProperty(“wicket.configuration”, “deployment”);

Framework: Grails

Specs:
-Grails 1.3.7
-Grails 1.4.0.M1

More »

file: views/layouts/main.gsp
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="${createLinkTo(dir:'', file:'default.css')}" media="screen" rel="stylesheet" type="text/css" />
		<title><g:layoutTitle default="Grails" /></title>
        <g:layoutHead />
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<div><h2>${pageName}</h2></div>
					<div class="innertube">
					
						<g:layoutBody />
						
					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

This defines the default layout that can be shared among other pages. The g:layoutBody tag defines the location where content will be placed.
g:layoutHead can be used to allow pages to inject content in the header.
The createLinkTo method makes sure that the webapp directory is automatically added to the URL, so that incorrect use of slashes won’t cause wrong relative urls to default.css.

file: controllers/grailsapp/ProductsController.groovy
class ProductsController {
    def index = {
		[products: s.Service.getProducts()]
	}
}

The method index will be mapped to the URI /products/index, or in short just /products (because it’s the index). Multiple methods (called actions) can be added in this way in the same controller class.
The index method returns a “model”, which is a map that the view uses when rendering. The keys (“products” in this case) within that map translate to variable names accessible by the view.

file: views/products/index.gsp
<g:set var="pageName" value="Product listing" scope="request" />

<html>
	<head>
		<meta name="layout" content="main"></meta>	
		<title>Product listing</title>
	</head>
	<body>
		<table>
			<g:each var="product" in="${products}">
				<tr>
					<td><g:render template="/shared/product" model="[product:product]" /></td>
					<td>
						<g:each var="cat" in="${product.categories}">$${cat.name}, </g:each>
					</td>
				</tr>
			</g:each>
		</table>
	</body>
</html>

The layout meta tag points to the main layout. The html and body tag will be removed from the final output, because those from the main layout will be used.
The g:each tag is used to iterate over the products and categories.
The s:set tag sets a variable so that it can be used in the shared layout.
The g:render tag is used to render products as custom component/elements using Grails templates.

file: views/shared/_product.gsp
<div class="product">
	<img src="${product.name}.jpg" />
	<span class="productname">${product.name}</span>, <span class="price">${product.price}</span>
</div>

This is the custom component (Grails template) to render products.

production settings

grails prod war

Framework: Ruby On Rails

-Ruby 1.9.2-p180
-Rails 3.0.7
-WEBrick 1.3.1 (webserver)
-mongrel 1.2.0.pre2 (webserver)
-JRuby 1.6.2
-Trinidad 1.2.0 (embedded Tomcat for JRuby)

More »

file: config/routes.rb
Railsapp::Application.routes.draw do
	...
	resources :products	
end

This line makes the products controller including all methods (actions) available under URI pattern /products/actionName. Since we are using the index action, which is the default, the URI will default to /products.

file: app/views/layouts/application.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="/default.css" media="screen" rel="stylesheet" type="text/css" />
		
		<%= stylesheet_link_tag :all %>
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<!-- Page name needs to be injected -->
					<div><h2><%= @pagename %></h2></div>
					<div class="innertube">
						<%= yield %>

					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

This is the shared template that can be used by multiple pages. The yield method is used to specify the location of where the content of the pages will be placed.

file: app/controller/products_controller.rb
class ProductsController < ApplicationController
	skip_before_filter :verify_authenticity_token
	protect_from_forgery :except => :index
	
	def index
		@products = ProductsHelper::Service.getProducts
	end
end

The skip_before_filter and protect_from_forgery method calls are needed to disable some options that might influence benchmark performance, these options aren’t enabled by default on other frameworks.

The index method is the method that is called at each HTTP request to our page. It creates the @products instance variable on each request, which can than be accessed by the view.

file: app/views/products/index.html.erb
<% @pagename = "Product Listing" %>

<table>
	<% @products.each do |product| %>
	<tr>
		<td class="productname"><%= render "shared/product", :product => product %></td>
		<td class="categories">
			<% product.categories.each do |category| %>
				<%= category.name %>, 
			<% end %>
		</td>
	</tr>
	<% end %>
</table>

As shown above, Rails uses plain Ruby code embedded between <% tags to render Rails code.
The @pagename is used to set the pagename so that it can be used in the shared template/layout.
The render method is used to render product as a custom componenent (called partials in Rails).

file: app/views/shared/_product.html.erb
<div class="product">
	<img src="<%= product.name %>.jpg" />
	<span class="productname"><%= product.name %></span>, <span class="price">$<%= product.price %></span>
</div>

This is a custom component (called a partial in Rails) to render a product.

production settings

Rails Webrick:
-rails server -e production

Rails Mongrel:
-cmdline: gem install mongrel
-cmdline: bundle install
-add line to gem Gemfile: gem “mongrel”, ‘>= 1.2.0.pre2′
-cmdline: rails server -e production

JRuby-Rails Webrick:
-jruby script\rails server

JRuby-Rails Trinidad:
-jruby -S trinidad -e production

Framework: Play

Specs:
-Play 1.2.1

More »

file: views/main.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
    <head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		
        <title>#{get 'title' /}</title>

        <link rel="stylesheet" media="screen" href="@{'/public/default.css'}">
        #{get 'moreStyles' /}
        <link rel="shortcut icon" type="image/png" href="@{'/public/images/favicon.png'}">
        #{get 'moreScripts' /}
    </head>
	
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<!-- Page name needs to be injected -->
					<div><h2>#{get 'pagename' /}</h2></div>
					<div class="innertube">	
						#{doLayout /}
					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

The get tags are used to retrieve variables that are set elsewhere, like in the pages. The doLayout tag specifies the location where content of each page will be shown.

file: controller/Products.java
public class Products extends Controller {
   public static void index() {
		List<Product> products = Service.getProducts();
        render(products);	
    }
}

The index method of the controller that is called on each http request to /products/index.

file: views/products/index.html
#{extends 'main.html' /}
#{set title:'Product listing' /}
#{set pagename: 'Product listing' /}

<table>
	#{list items:products, as:'product'}
		<tr>
			<td>#{product product /}</td>
			<td>
				#{list items:product.categories, as:'category'}
					${category.name}, 
				#{/list}
			</td>
		</tr>
	#{/list}
</table>

The extends tag specifies the shared layout that can also be used by other pages. The set title tag sets the title variable so that it can be used in the shared layout.
The list tag is used to iterate over the products. Instead of a list tag, Groovy code (like Grails) can also be used in the views.
The product tag is a custom component to render a product.

file: views/tags/product.html
<div class="product">
	<img src="${_arg.name}.jpg" />
	<span class="productname">${_arg.name}</span>, <span class="price">$${_arg.price}</span>
</div>

This is the custom component (called a tag) to render a product.

production settings

set to production via the file application.conf:
application.mode=prod
%prod.application.mode=prod

play war -o k:\wars\play –zip

Framework: Lift

Specs:
-Lift 2.3
-Scala: 2.8.1

More »

file: webapp/templates-hidden/default.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="default.css" media="screen" rel="stylesheet" type="text/css" />
		
		<!-- Title needs to be injected -->
		<title>Products listing</title>
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<!-- Page name needs to be injected -->
					<div><h2><lift:bind name="pagename">.....</lift:bind></h2></div>
					<div class="innertube" id="content">
						<lift:bind name="content"></lift:bind>
					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

This is the layout that can be shared by multiple pages.
The lift:bind tag is used as a placeholder where data can be placed by other pages or code.

file: bootstrap.liftweb.Boot.scala
class Boot {
	def boot {
		...
		// Build SiteMap
		val entries = List(
			...
			Menu.i("Products listing") / "products",
			...
		)
		...
	}
}

A menu is added to the SiteMap list, this is required for the page to be accessible via an URL. In this case, the name of the menu is “Products listing”, and the URI is /products. It will look for a page at webapp/products.html.

file: webapp/products.html
<lift:surround with="default">
	<lift:bind-at name="pagename">aaaa</lift:bind-at>

	<lift:bind-at name="content">
		<table class="lift:ProductsSnippet.showProducts">
			<tr>
				<td class="productname"></td>
				<td class="categories"></td>
			</tr>
		</table>
	</lift:bind-at>

</lift:surround>

The lift:surround places the body of this tag in the lift:bind tag that has the attribute name=”content” of the template named “default” (webapp/templates-hidden/default.html).
The lift:ProductsSnippet.showProducts value in the class attribute causes Lift to pass the table tag including it’s body to a Scala method in the class “ProductsSnippet” named “showProducts” as an XML object (NodeSeq), or it applies a function that ProductsSnippet.showProducts might return on the table tag. This allows showProducts to perform XML transformations/manipulations at the given table tag.

ProductSnippet.scala
package code
package snippet

import scala.xml.{NodeSeq, Text}
import net.liftweb.util._
import net.liftweb.common._
import java.util.Date
import code.lib._
import Helpers._
import _root_.s._

class ProductsSnippet {

  def showProducts = {
	val products = Service.products
	"tr" #> (in => products.flatMap{ p =>
		(".productname *" #> <div class="product"><img src={p.name + ".jpg"} /><span class="productname">{p.name}</span>, <span class="price">${p.price}</span></div> &
		".categories *" #> p.categories.map(_.name).mkString(", "))(in)
	})  
  }
}

showProducts is a function. The goal of showProducts is to transform the table tag of products.html (including it’s body) to the desired HTML output. In this case, we want the custom product HTML layout (which we call a component) to be placed within the td tag, and we want the categories of each product to be listed in the other td tag.
To do this, we have to iterate over each product, create a custom component/layout for each product, and place it in the td tag. And for each product, we have to iterate over the categories.

showProducts can be difficult to understand if you don’t have experience with functional programming. I’ll try to explain what happens.
Lift takes the table tag of products.html (including it’s body) and calls the showProducts function. showProducts won’t immediately act on the table tag, but it will return a function that will be the result of the function call to the showProducts function. Then Lift passes the table tag as a parameter to the returned function, which will then return the desired HTML output in the form of a NodeSeq object, which will than be placed at the corresponding location in products.html.

(Instead of having showProducts to return a function, it’s also possible to let it receive the HTML (a NodeSeq) immediately, and return the transformed HTML (a NodeSeq). This sounds easier, but the syntax of Lift when returning a function, is shorter and might be easier to write.)

The val keyword declares the “products” variable, which is a List object. “#>” is a method/operator that is added to the String class using Scala’s implicit conversions (via an import statement). The #> method returns a function, but can also be given a function as input parameter.

The first #> method call is used to bind the “tr” tag to HTML (a NodeSeq). The map and flatMap methods are used to translate each product or category to the corresponding HTML output.
The #> method call at “.productname *” binds the new HTML to the body of a HTML element that has “productname” as value of the class attribute.

production settings

set JAVA_OPTS=-Drun.mode=production -Xmx1024m

sbt ~package

Framework: Play-Scala

Specs:
-play-1.2.2RC1
-play-scala-0.9.1

More »

file: app/products.scala (mvc controller)
object Products extends Controller {
    import views.Products._

	def index(n: Int) = html.index(Service.getProducts(n)) 
}

Defines the URI /products/index, and maps it to the index method. The index method takes a parameter ‘n’ that is mapped to the URL querystring parameter ‘n’. Conversions to an integer are applied automatically.
In Play-Scala the view pages/templates are seen as functions (in this case html.index function) that can be passed data (in this case a list of products).

file: app/views/main.scala.html
@(title:String = "", pageName:String = "")(body: => Html)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
		<link href="default.css" media="screen" rel="stylesheet" type="text/css" />
		
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@asset("public/stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@asset("public/images/favicon.png")">
        <script src="@asset("public/javascripts/jquery-1.5.2.min.js")" type="text/javascript"></script>
	</head>
	<body>
		<div id="maincontainer">
			<div id="topsection">
				<div class="innertube"><h1>Company Title .....</h1></div>
			</div>
			<div id="contentwrapper">
				<div id="contentcolumn">
					
					<!-- Page name needs to be injected -->
					<div><h2>@pageName</h2></div>
					<div class="innertube">
					
						<!-- The content that is unique for each page -->
						@body
					</div>
				</div>
			</div>

			<div id="leftcolumn">
				<div class="innertube">
					<h3>Side bar.....</h3>
				</div>
			</div>

			<div id="footer">footer.....</div>
		</div>
	</body>
</html>

In Play-scala pages/templates/tags are seen as functions that can have parameters, so that data can be passed to a page/template/tag.
The first line defines a title, pageName and body parameter. Data can be passed from controllers and other pages/templates/tags.
The “@” sign refers to Scala code.

file: app/views/Products/index.scala.html
@(products: Seq[s.Product])
@import views.tags.html._

@main("Product listing title", "Product Listing page") {
	<table>
		@for(product <- products) {
			<tr>
				<td>@productTag(product)</td>
				<td>
					@for(category <- product.categories.toList) {
						$@category.name,
					}
				</td>
			</tr>
		}
	</table>
}

The first line defines the parameters that can be passed to this page. “main” is a function that refers to the main template. It is passed a title, pageName and the body.

file: app/views/tags/productTag.scala.html
@(product: s.Product)

<div class="product">
	<img src="@(product.name).jpg" />
	<span class="productname">@product.name</span>, <span class="price">$@product.price</span>
</div>

The custom product component (called a tag).

production settings

set to production via the file application.conf:
application.mode=prod
%prod.application.mode=prod

Two production environments were tested:
a) Play-scala running under Tomcat
play war -o k:\wars\play –zip

b) Play-scala running under it’s default builtin webserver called Netty.
JAVA_OPTS=-Xmx1024m
play run

Static file test

The static file test is rendering of plain HTML files served directly by the webserver (Tomcat). So no framework was used in this test.

Test Results

Note: that the more component based frameworks – such as Wicket and Lift – have multiple ways of doing things. Where the simpler MVC push frameworks – such as Rails, JSP, Play, Grails – usually have one way of doing it. Therefore, because there are multiple solutions in Wicket and Lift, there may be faster (and slower) solutions than I have used. However, I did try to use common solutions.

Wicket-1.5rc3 and Wicket-1.5r5trunk use a ListView to iterate over the categories, but Wicketb-1.5rc5trunk uses a RepeatingView.

More »

"u": the number of concurrent users
"p": the number of products to render
"ms": response time in milliseconds
"KB": returned page size in kilobytes.
"%": CPU utilization
"mb": RAM memory usage of the webapp


Grails 1.3.7 - Tomcat
1u, 1000p, 129ms, 205,77 KB, UTF-8
2u, 1000p, 150ms
4u, 1000p, 185ms
8u, 1000p, 428ms
16u, 1000p, 848ms, 155mb, 85%
1u, 0p, 1ms
1u, 1p, 1ms
1u, 10p, 2ms
1u, 100p, 14ms
1u, 500p, 66ms
1u, 1000p, 129ms
1u, 5000p, 629ms

Grails 1.4.0.BUILD-SNAPSHOT (3 June 2011) - Tomcat
1u, 1000p, 107ms, 205,79 KB
2u, 1000p, 115ms
4u, 1000p, 132ms
8u, 1000p, 307ms
16u, 1000p, 622ms, 233mb, 85%
1u, 0p, 1ms
1u, 1p, 1ms
1u, 10p, 2ms
1u, 100p, 12ms
1u, 500p, 55ms
1u, 1000p, 107ms
1u, 5000p, 525ms

Grails 1.4.0.BUILD-SNAPSHOT2 (3 June 2011) - Tomcat
1u, 1000p, 47ms, 205,82 KB
2u, 1000p, 56ms
4u, 1000p, 67ms
8u, 1000p, 149ms
16u, 1000p, 373ms, 197mb, 75%
1u, 0p, 1ms
1u, 1p, 1ms
1u, 10p, 1ms
1u, 100p, 5ms
1u, 500p, 24ms
1u, 1000p, 47ms
1u, 5000p, 229ms

Grails 1.4.0.BUILD-SNAPSHOT (3 June 2011) - Jetty (default builtin)
Same results as Tomcat.


Rails 3.0.7 - Webrick 1.3.1
1u, 1000p, 102ms, 229,08 KB, UTF-8
2u, 1000p, 177ms
4u, 1000p, 254ms
8u, 1000p, 715ms
16u, 1000p, 1438ms, 40mb, 25%
1u, 0p, 15ms
1u, 1p, 15ms
1u, 10p, 15ms
1u, 100p, 16ms
1u, 500p, 52ms
1u, 1000p, 102ms
1u, 5000p, 445ms

JRuby 1.6.2 - Rails 3.0.7 - Webrick 1.3.1
1u, 1000p, 139ms, 229,08 KB
2u, 1000p, 268ms
4u, 1000p, 537ms
8u, 1000p, 1082ms
16u, 1000p, 2252ms, 135mb, 26%
1u, 0p, 2ms
1u, 1p, 2ms
1u, 10p, 4ms
1u, 100p, 16ms
1u, 500p, 71ms
1u, 1000p, 139ms
1u, 5000p, 716ms

Rails 3.0.7 - Ruby 1.9.2-p180 - Mongrel 1.2.0.pre2
1u, 1000p, 110ms, 229,08 KB 
2u, 1000p, 224ms
4u, 1000p, 425ms
8u, 1000p, 583ms
16u, 1000p, 1722ms, 45mb, 25%
1u, 0p, 15ms
1u, 1p, 15ms
1u, 10p, 16ms
1u, 100p, 18ms
1u, 500p, 61ms
1u, 1000p, 110ms
1u, 5000p, 581ms

JRuby 1.6.2 - Rails 3.0.7 - Embedded Tomcat (Trinidad 1.2.0)
1u, 1000p, 142ms, 229,08 KB
2u, 1000p, 144ms
4u, 1000p, 152ms
8u, 1000p, 308ms
16u, 1000p, 621ms, 322mb, 95%
1u, 0p, 2ms
1u, 1p, 2ms
1u, 10p, 3ms
1u, 100p, 16ms
1u, 500p, 73ms
1u, 1000p, 142ms
1u, 5000p, 699ms


JSP 2.1 - JSTL 1.2 - Servlet 2.5 - Tomcat
1u, 1000p, 45ms, 213,58 KB
2u, 1000p, 48ms
4u, 1000p, 54ms
8u, 1000p, 108ms
16u, 1000p, 223ms, 51mb, 85%cpu
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 4ms
1u, 500p, 23ms
1u, 1000p, 45ms
1u, 5000p, 225ms

Static HTML - Tomcat
1u, 1000p, 0s, 213,58 KB
2u, 1000p, 1ms
4u, 1000p, 2ms
8u, 1000p, 5ms
16u, 1000p, 14ms, 72%cpu, 592mb
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 0ms
1u, 500p, 0ms
1u, 1000p, 0ms
1u, 5000p, 4ms

Wicket 1.5-RC3 - Tomcat
1u, 1000p, 251ms, 205,73 KB
2u, 1000p, 506ms
4u, 1000p, 503ms
8u, 1000p, 498ms
16u, 1000p, 499ms, 51mb, 25%cpu
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 2ms
1u, 100p, 19ms
1u, 500p, 119ms
1u, 1000p, 251ms
1u, 5000p, 1885ms

Wicket from trunk (for 1.5-RC5) - Tomcat
1u, 1000p, 251ms, 205,73 KB
2u, 1000p, 263ms
4u, 1000p, 348ms
8u, 1000p, 688ms
16u, 1000p, 1366ms, 158mb, 70%cpu
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 2ms
1u, 100p, 19ms
1u, 500p, 113ms
1u, 1000p, 246ms
1u, 5000p, 1955ms

Wicket from trunk (for 1.5-RC5), RepeatingView version (from Martin G.) - Tomcat
1u, 1000p, 179ms, 220,41 KB
2u, 1000p, 212ms
4u, 1000p, 265ms
8u, 1000p, 544ms
16u, 1000p, 1084ms, 146mb, 70%
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 1ms
1u, 100p, 14ms
1u, 500p, 82ms
1u, 1000p, 179ms
1u, 5000p, 1510m

Wicket from trunk (for 1.5-RC5), Stateful url version (from Martin G.) - Tomcat
NOTE: used with JMeter Cookie manager enabled, otherwise the results will be the same as: Wicket from trunk (for 1.5-RC5), RepeatingView version (from Martin G.) - Tomcat
1u, 1000p, 118ms, 209,67 KB
2u, 1000p, 129ms
4u, 1000p, 141ms
8u, 1000p, 272ms
16u, 1000p, 598ms, 683mb, 90%
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 1ms
1u, 100p, 10ms
1u, 500p, 57ms
1u, 1000p, 118ms
1u, 5000p, 1198ms


Play 1.2.1 - Tomcat
1u, 1000p, 222ms, 197,98 KB, UTF-8
2u, 1000p, 259ms
4u, 1000p, 330ms
8u, 1000p, 676ms
16u, 1000p, 1309ms, 85mb, 85%
1u, 0p, 0ms
1u, 1p, 1ms
1u, 10p, 3ms
1u, 100p, 22ms
1u, 500p, 102ms
1u, 1000p, 222ms
1u, 5000p, 1054ms


Play-Scala 0.9.1 - Play 1.2.2RC1 - Tomcat
1u, 1000p, 26ms, 226,52 KB
2u, 1000p, 30ms
4u, 1000p, 85ms
8u, 1000p, 185ms
16u, 1000p, 406ms, 115mb, 62%
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 3ms
1u, 500p, 14ms
1u, 1000p, 26ms
1u, 5000p, 192ms


Play-Scala 0.9.1 - Play 1.2.2RC1 - Netty
1u, 1000p, 15ms, 226,52 KB
2u, 1000p, 16ms
4u, 1000p, 20ms
8u, 1000p, 42ms
16u, 1000p, 89ms, 572mb, 80%
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 1ms
1u, 500p, 8ms
1u, 1000p, 15ms
1u, 5000p, 79ms

Play-Japid 0.8.3.1 - Play 1.2.1 - Tomcat
1u, 1000p, 4ms, 206,05 KB
2u, 1000p, 6ms
4u, 1000p, 13ms
8u, 1000p, 28ms
16u, 1000p, 63ms, 105mb, CPU too inaccurate to measure
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 0ms
1u, 500p, 2ms
1u, 1000p, 4ms
1u, 5000p, 39ms

Play-Japid 0.8.3.1 - Play 1.2.1 - Netty (builtin)
1u, 1000p, 3ms, 206,03 KB
2u, 1000p, 4ms
4u, 1000p, 5ms
8u, 1000p, 12ms
16u, 1000p, 25ms, 533mb, CPU too inaccurate to measure
1u, 0p, 0ms
1u, 1p, 0ms
1u, 10p, 0ms
1u, 100p, 0ms
1u, 500p, 1ms
1u, 1000p, 3ms
1u, 5000p, 17ms


Lift 2.3 - Scala: 2.8.1 - Tomcat
1u, 1000p, 99ms, 220,74 KB, UTF-8
2u, 1000p, 115ms
4u, 1000p, 138ms
8u, 1000p, 280ms
16u, 1000p, 850ms, starts at 120mb, increases continuously, probably due to a session explosion (each requests creates a new session), 55%
1u, 0p, 10ms
1u, 1p, 10ms
1u, 10p, 10ms
1u, 100p, 17ms
1u, 500p, 52ms
1u, 1000p, 99ms
1u, 5000p, 633ms

Tapestry 5.2.5
1u, 1000p, 20ms, 171,41 KB
2u, 1000p, 24ms
4u, 1000p, 30ms
8u, 1000p, 65ms
16u, 1000p, 192ms, 147mb, 65%
1u, 0p, 1ms
1u, 1p, 1ms
1u, 10p, 1ms
1u, 100p, 3ms
1u, 500p, 10ms
1u, 1000p, 20ms
1u, 5000p, 100ms

Context Framework 0.8.1 / Benchmark 1.0-SNAPSHOT
1u, 1000p, 60ms, 186,88 KB
2u, 1000p, 68ms
4u, 1000p, 133ms
8u, 1000p, 367ms
16u, 1000p, 768ms, 144mb, 41%
1u, 0p, 1ms
1u, 1p, 1ms
1u, 10p, 2ms
1u, 100p, 7ms
1u, 500p, 31ms
1u, 1000p, 60ms
1u, 5000p, 325ms

Grails 1.3.7 - Freemarker 0.3 - Freemarker plugin 0.6.0
1u, 1000p, 22ms, 205,8 KB
2u, 1000p, 32ms
4u, 1000p, 43ms
8u, 1000p, 99ms
16u, 1000p, 299ms, 200mb, 60%
1u, 0p, 2ms
1u, 1p, 2ms
1u, 10p, 2ms
1u, 100p, 4ms
1u, 500p, 12ms
1u, 1000p, 22ms
1u, 5000p, 112ms



Test Remarks

CPU Utilization is inaccurate
More »

JMeter impacts performance results because JMeter needs to collect data and calculate statistics. This is more prominent the faster the response times are, because then more data will be generated. CPU utilization of JMeter sometimes reaches 50%. In these cases, my CPU utilization of the associated framework will be very inaccurate.
Rails
More »

During testing, I noticed some high peeks in response time. This might be due to Garbage collection of Ruby. I measured the response time without including these extreme pauses.
This is more difficult to test when performing a 2 concurrent user test. In this case, Rails was showing 2 groups of response times, where the second group was about half the response time of the first group. The groups seems to interleaf in series.

Commenters have pointed out that Rails should be tested under other webservers than Webrick.

Lift
More »

cpu utilization about 53%, where other webapp have about 85%
Lift required more initial benchmarking time before reaching stable response times, otherwise the average responsetime will drop slowly.
At 16u, the response times fluctuate a lot. I have seen long running averages at 670ms, but also at 950ms, then slowly creeping up, then slowly down etc. This might be due to barbage collection and the effect of starting at 0 sessions or measuring when a higher amount of sessions are present (even though I’m using JMeter without cookies/sessions enables). Because of this, I have set it to 850ms.
A LOT of samples are needed.
Wicket
More »

During testing at 8u and 16u, wicket gave multiple warnings/exceptions:
WARN – PageAccessSynchronizer – “http-apr-8080″-exec-16 failed to acquire lock to page 0, attempted for 1 minute out of allowed 1 minute
Caused by: org.apache.wicket.page.CouldNotLockPageException: Could not lock page 0. Attempt lasted 1 minute

A post commenter (@12) pointed that this is due to a bug that is fixed in the latest trunk version of Wicket. This trunk is tested under “Wicket-trunk” in this post.

Tapestry
More »

Tapestry iterates over the categories using plain Java API (StringBuilder) instead of Tapestry. Because according to the writer of the test code (Kaosko) “the general guideline for minimizing logic in the template”. I expect that the performance of Tapestry will be lower when Tapestry solutions are used to iterate over the categories.
The benchmark test case used to test all frameworks, should be changed to use custom components for categories instead of using plain Strings to render categories.

Also note that even though I try the HTML output to be roughly the same in size, the output size of Tapestry was lower then the rest: 171,41 KB. Tapestry seems to remove excessive whitespaces.

Effects of page size by unneeded whitespaces
More »

As an example, Play-scala-netty is used to show the effects, but the same probably applies to other frameworks.
During testing, I accidentaly forgot to check the page sizes of Play-scala, and tested Play-scala. Later I saw that the page size was: 373,04 KB (for 1000 products). To reduce this size to approximately the same size in which I tested other frameworks, I removed some unneeded whitespaces from products.scala.html, by changing:

@for(category <- product.categories.toList) {
	$@category.name,
}

to

@for(category <- product.categories.toList) { $@category.name, }

The page size then was reduced to: 226,52 KB.

Here the differences in response time for:
users, products, 226.52kb vs 373,04kb
1u, 1000p, 15ms vs 21ms
2u, 1000p, 16ms vs 23ms
4u, 1000p, 20ms vs 30ms
8u, 1000p, 42ms vs 64ms
16u, 1000p, 89ms vs 137ms
1u, 0p, 0ms vs 0ms
1u, 1p, 0ms vs 0ms
1u, 10p, 0ms vs 1ms
1u, 100p, 1ms vs 2ms
1u, 500p, 8ms vs 10ms
1u, 1000p, 15ms vs 21ms
1u, 5000p, 79ms vs 111ms

(With Tomcat gzip compression enabled, the page size is reduced to a page size of about 9kb.)

JMeter

JMeter impacts the test results. This might be due to JMeter using RAM or CPU. I should retest the tests with JMeters Distribution Graph disabled.

Package sizes

grails.war, 22.088kb
jsp.war, 375kb
lift.war, 14.111kb
play.war, 29.124kb
playscala.war, 53.119kb
wicket.war, 2.200kb

Discussion

What suprised me is that even though JSP/JSTL, Rails, Grails and Play use about the same MVC model, the differences in performance are big. Simply switching from template system in Play framework from the default to Japid, has a huge impact (in this test 27 times faster).

Most posts about JRuby on Rails tell that it is faster than Ruby on Rails, however in this test, Ruby on Rails was clearly faster in both the rendering of products and concurrent-user test.
Also, most posts about Rails tell that Webrick is slower than Mongrel, but in this test, Webrick was a bit faster.
JRuby on Rails running on Trinidad does perform faster than other Rails configurations when tested with concurrent users.

Play-Scala using Netty NIO server is faster than Tomcat webserver. I wouldn’t expect the differences to be that big. It’s unclear whether these fast results are caused by Play-Scala being optimized for Netty, or that Netty is simply faster than Tomcat (and thus that other frameworks could also have faster results under Netty).
Note that the memory usage of Play-Scala under Netty is a lot higher than under Tomcat.

The section “Effects of page size by unneeded whitespaces” shows that unneeded whitespaces impact the response time. Frameworks can probably be optimized by stripping unneeded whitespaces from the templates during boot, even when HTTP gzip compression is enabled. (During the test, compression was disabled in Tomcat and Netty.)

Questions

-Does anybody know why the static file test under Tomcat is using so much memory?

Blog post updates

-30 May 2011: Added Play-scala (under Tomcat webserver) and Play-scala-netty (under Play’s builtin Netty webserver). Added the effects of unneeded whitespaces. Added Wicket-trunk, which is the latest Wicket snaphot from trunk (for 1.5-RC5), and info about a performance bug in Wicket.
-31 May 2011: Added Play-Japid and JRails.
-3 June 2011: Added Grails trunk.
-13 June 2011: Added Tapestry, Context-framework and Grails-1.3.7-freemarker

Project files

The files (code, project, html) of this post can be found here: https://github.com/jtdev/blogpost_files

Jan 232011
 

In this article I describe why Wicket framework isn’t suited for websites. But I first start defining the difference between Websites and Webapps.

Websites vs Webapps:

A webapp behaves like a desktop client-server application, but it’s accessible via an URL in a webbrowser instead of as an executable on an OS. Webapps can be rendered in HTML, but also in Flash, Silverlight, Applets etc. Webapps usually don’t have content that should be indexed by search engines, so Search Engine Optimalization (SEO) plays no role in webapps.

A Website on the other hand, is less focussed on the application, but more on serving its content to users, usually rendered in HTML instead of Flash etc. SEO is usually very important.

There are far more website than webapps on the Internet, although a clear distinction between a webapp and a website can sometimes be a bit difficult. Some websites contain parts that can be seen as a webapp. The focus of it determines whether it should be called a webapp or a website. If it’s the primary goal is serving content to users, than it’s a website. If it’s primary goal is allowing users to add/control content where serving content plays a lesser role, than it’s a webapp.

Website owners often try to get as many visitors as possible, this includes search engines. Webapps on the other hand, are often internal for a company, and only want a small number of people to be able to control and view it’s content.

In this article, I’ll describe why Wicket isn’t suited for websites, and that Wicket is targeting Webapps instead.

Sessions:

When developing websites that primarily serve content, the unnecessary usage of sessions should be avoided when the memory costs of sessions are relatively high. However sessions are often needed to preserve state among webpages, especially when users have the ability to login at a website. So in the ideal case, when a guest visits a page, then no sessions are used, but when the guests logs in, than that same page can use sessions. With effort, to some extent, it is possible to achieve this in Wicket, but it’s difficult because Wicket is a framework that heavily depends on session state, and the session size is relatively high. Wicket does have some stateless components that can be used, but only a few exist and they are not matured. To be sessionless, all resources (pages) that are requested by the user within 30 minutes (default) should be completely stateless. If only one Wicket component is stateful, then sessions will be created automatically.

Session memory problems can easily occur when a cookie disabled client (webbrowser or bot) visits a Wicket website. These client will cause new sessions to be created at every page load/refresh. When a single page contains multiple session-state components that are requested under a separate http request as result of a single page request, then the number of sessions can explode. Especially when a bot visits the website. (But you don’t want to block bots, because if you have a website, Search Engine bots are very welcome. This is different when you have a webapp instead of a website.)

So developing (sessionless) websites using Wicket is difficult. There are only a small amount of stateless components, and they aren’t matured.

Ajax:

Basically every web application/website can rendered using just simple HTML, when looking at it in from functional system perspective. However, if you want to take more out of the system, it can be improved  using Javascript/Ajax. Ajax improves user interaction by greatly reducing response times of sending information to the users. So in the end, every matured website should use Ajax. But as told before, there are only a few stateless components in Wicket, and stateless Ajax components don’t exist.

If it was possible in Wicket, then a problem that arises is how to deal with Ajax requests. You don’t want a full Wicket page to be constructed on every Ajax request.

Ending:

Even though Wicket advertises itself with “just HTML”, which makes the suggestion that it is suitable for websites, it is only targeting Webapps. But in contrast to websites, you don’t need “just HTML” for webapps. Webapps can also be build using only Javascript/Ajax solutions because they don’t have SEO requirements.

I like Wickets, there aren’t much similar frameworks that have the same programming model. I hope the Wicket team realises that sessionless/stateless components are very important when it comes to website development in contrast to webapp development.


Updated/added at 27 January 2011:

To come back at my comment of maybe being to harsh at session usage for public facing websites, I don’t think session usage would be a big problem if the session size was small. But the session usage in Wicket is large.
(Size can be checked using RequestCycle.get().getSession().getSizeInBytes() , which has to be called after the page is fully loaded and stored in the session.)

Wicket stores almost everything in sessions for a page is stateful, even when using models. For example, when you want to render a list of String that is retrieved from the database, and render it on a stateful page, then you can use a loadableDetachableModel to retrieve the data without storing/serializing all the strings in the that model. But when you render the strings using a listview, you have to add labels to the listview’s items in the populateItem method (at least if you want to do it the Wicket way). But the labels itself will contain a model that stores the String anyway. Or you can use a compoundpropertymodel using item.setModel(new CompoundPropertyModel(item.getModel())), but that also adds extra objects to the session.

Example, if you have a list of 2253 strings, which in total is 17.5kbyte (7.96kbyte/string on average), that you want to be rendered on a stateful page, then it will cost you about 198kbyte in session usage when using the nested CompoundPropertyModel approach. It will even be larger when using a default label model. 198kbyte imo is way too much, that part of the page should be 0 kbyte.

If you have an internal webapp than you can calculate the maximum memory usage based on a fixed number of internal concurrent users. But if you have a public facing website, than calculating the maximum memory usage is hard. Public facing websites want to attract as many visitors as possible. The number of concurrent users can vary daily. It’s possible that due to linking of external websites, a website get an order of magnitude higher number of visitors the next day. Which can easily cause big problems on website that use large sessions sizes.

 Posted by at 19:46
Jul 042010
 

This post describes my opinion about Wicket framework.

Wicket is a component-based Java web framework from Apache that is gaining some popularity. Like most component-based web frameworks, Wicket is harder to learn than controller-to-view frameworks (Request-based) like Grails, Stripes, Servlets/JSP, Rails etc., but it offers more features and is more focused on the state of HTML elements instead of the state of HTTP requests. (Update 7-July-2010: to be clear, I don’t think controller-to-view frameworks are better, I just think they are easier to learn. But when you need to develop a WebApp, I think component based frameworks make the development easier.)

It’s not that I hate Wicket, but there are some features that I don’t like:

Heavily based on sessions.

Although Wicket does offer a few stateless components and session-less features, it is heavily based on sessions. Without session, state-fullness is difficult. Sessions have two drawbacks: timeouts and memory consumption.
A timeout occurs when a user doesn’t respond within (usually) 30 minutes. When that happens, the state of the page the user visited is lost. There are some Ajax hacks around this, but they are cumbersome. An option is to increase the timeout, but then you will be limited by memory consumption of sessions.
Some argue that memory is cheap, but that depends on your situation. If you’re building some in-house Website/webapp for a  company running its own servers than memory is indeed cheap. If you are a student or a freelance developer that is deploying the website on some leased VPS (Virtual Private Server) or a dedicated server, than the memory usage can increase the costs a lot.
What I like is the solution of Microsofts ASP.NET framework. It uses viewstates instead of sessions, which stores state in hidden html elements that are submitted back to the server when the user triggers an event, by using Javascript. This approach also has some drawbacks, but it doesn’t depend on sessions.

Wicket team had plans of implementing “client-side models for zero-state scalability”, but unfortunately they dropped it.

High learning curve

Component-based frameworks (pull MVC) are more difficult to learn than controller-to-view based frameworks (push MVC). This makes documentation more important, but the recommended book Wicket in Action doesn’t provide much inside in about how Wicket exactly works. This makes it difficult to do a bit more than standard stuff, when after you have read it.

Wicket URLs

I hate it when URLs reveal the usage of a framework. Wicket has Url Coding Strategies to fix this, but when using statefull pages, these urls often reveal the Wicket framework, this because Wicket uses the url to track a version of a web page. For example, you might get URLs like:
http://example.com/product/abc/.1.2 and when you click on some component on that page that will let you stay on the page but which some updated components, then you get http://example.com/product/abc/.1.3
The unwanted part is .1.3. It should stay http://example.com/product/abc all the time.

When clicking a component, there also often is an unwanted extra HTTP redirect before fetching the final HTML.

HTML is not that pure

A philosophy in Wicket is that HTML should strictly be separated from code and component properties, so that a web designer can make the HTML, and the programmer can just code Java. I hate the idea of making it easier for a web designer (highly subjective opinion), since I’m a programmer that makes the HTML/CSS myself, but I like the idea of separating it cleanly. But when using Wicket you will get a lot of tags like this in your HTML when you  need to repeat components:
<wicket:container>……</wicket:container>
So the HTML isn’t that pure.
If you don’t use that container element, than you easily get two nested divs where only one div is needed.

Update 11-July-2010: the commenter “anonymous coward” showed unwanted divs can be prevented by using setRenderBodyOnly. Other not-pure HTML can occur when Wicket Fragments are used, but this scenario doesn’t happen often.

Static component tree

It would be nice if you can create a tree of components dynamically, but in Wicket you have to define the tree structure statically in both the HTML layout and the Java code. It is possible to switch subtrees, but those subtrees have to be defined upfront.

Very verbose

Because of the clean separation of html and Java, and because it’s a component based framework, code will be more verbose than standard push MVC framework. A feature of Wicket that makes it even more verbose is the use of “models”. Model objects can be used by components to retrieve data, so that there is a clear distinction between data and data retrieval. This becomes clear when using repeating elements in HTML. Then you usually need to define LoadableDetachableModel anonymous classes that are nothing more than packed method calls to your DAOs (Data Access Objects) to retrieve data.

What I do like

This blog post is focused on what I don’t like, but to give you a short idea of what I do like:

——————–

Update 7 July 2010: changed “complexity” to “high learning curve”. And wrote more explicitly that I do favor component based frameworks over controller-to-view/request based frameworks, like the commenters below also do.

Update 11 July 2010: changed my opinion about “Not pure HTML” after the post of the commenter “anonymous coward”.

May 222010
 

Background & Problem:

Because I have a lot of Firefox plugins installed, Firefox became pretty slow, so I had some plugins disabled, under which a plugin for running applets. Yesterday, I came on some page that required applets, but the plugin was missing, so I let the browser install it automatically. After that, I was unable to start Java. Trying to reinstall or uninstall Java, gave the error 1723.

System specs:

-Windows 7 64 bit
-JDK 6.18 32 bit

Googled Solutions:

Using Google I found some proposed solutions:

  • http://www.javafixer.org/error-1723.php, doing the Regedit fix damaged the Windows Installer, and Windows Installer 5.0 (needed for Win7) cannot be download from the Microsoft site. So this solution didn’t work for me.
  • JavaRA: http://raproducts.org/. If you try this, don’t forget to run it under administrator. This solution didn’t work for me.
  • RegCleaning by using for example http://www.piriform.com/ccleaner. Also didn’t work.
  • Install Visual C++ 2005 Redistributable Package (x86). Didn’t work.
  • Windows Installer CleanUp Utility from the Microsoft site. Didn’t work.
  • Manually deleting JDK files. Didn’t work.

What did work for me:

On some forum (out of the many that discuss about this irritating error), I found someone that fixed it by removing all “jre” related from the registry. This did it for me :) Open regedit, and search for “jre” and look for keys (directories) that contain “jre” values (fields) that are related to Java. Delete those keys.

After doing this, the JDK installer ran without problems, and without mentioning about existing installations.

 Posted by at 01:09
Jun 202009
 

This post describes how to send a HTTP 301 redirect in the Java Wicket Framework.

HTTP redirect intro

There are two types of HTTP redirects:
-“HTTP 1.1 301 Moved Permanently”
-“HTTP 1.1 302 Found”, previously called “HTTP 1.1 302 Moved Temporarily”

A 301 indicates that the requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs.
Where a 302 indicates that the requested resource resides temporarily under a different URI.

For a normal web browser it doesn’t matter which type of redirect is send to the browser, because the result is the same: the user is redirect to a different URI. But for Search Engines (SE’s) it does (or might) matter, at least if you want the correct URL to be indexed. If you’re using a 301, than you’re telling SE’s that they should use the new URI. If you’re sending a 302 then you’re telling that they should use the old URI.

301 using Wicket

In Wicket, you can send a 301 using:

getRequestCycle().setRequestTarget(new RedirectRequestTarget("/path/to/legacyJspFile.jsp"));

302 using Wicket

The problem is that the redirect method always uses a 302. If you want to perform a 301, you can use this code, which overrides the respond method:

RedirectRequestTarget target = new RedirectRequestTarget(url) {
  @Override
  public void respond(RequestCycle requestCycle) {
    WebResponse response = (WebResponse) requestCycle.getResponse();
    response.reset();
    response.getHttpServletResponse().setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
    response.redirect(url);
  }
};
getRequestCycle().setRequestTarget(target);

This will cause the RedirectRequestTarget.respond(RequestCycle requestCycle) method to be called, which will get a WebResponse object using the requestCycle object, and it will call the WebResponse.redirect(String url) to set the redirect.

More info:

  • http://wicket.apache.org/docs/1.4/
  • http://www.w3.org/Protocols/rfc2616/rfc2616.txt
  • http://cwiki.apache.org/WICKET/how-to-redirect-to-an-external-non-wicket-page.html
Dec 272008
 

Ruby On Rails and Grails are two popular MVC webframeworks. Rails uses the Ruby language, and Grails uses Groovy. In this post I compare Grails vs Rails.

Introduction

Ruby On Rails (in short just “Rails”) is a webframework that uses the Ruby language. It uses a push MVC design pattern, which means that a controller/action receives a client HTTP request, then creates or search (in a DB) for model objects containing data, and forwards those objects to the view where a HTML page is rendered for the HTTP client.

The other webframework, Grails, is also a push MVC webframework that uses some ideas of Rails. In fact, it was previously called Groovy On Rails. Grails uses the Groovy language instead of Ruby.

About the comparison

The way I look at these frameworks is influenced by my prior knowledge and preferences:
-I have a Java background
-I strongly prefer static typed over dynamic typed. (Why would you hide important information in your code about types if you need to document it anyway.)

I’m not an expert in these frameworks. Maybe I don’t even know the existence of some basic features. So if you think I forgot to mention something important, then leave a comment :)

Grails and Rails, in common

  • Development, production and test modes.
  • built-in webserver
  • quick boot/startup
  • hot deploy / class reloading without restarting the server
  • ORM (Object Relational Mapping) / Active record
  • lots of plugins, that can be downloaded from the command line. a plugin manager
  • nice URLs
  • model, view, controller, and test generators
  • popular, an active community
  • easy to learn / use
  • The language supports: string interpolation, multi line strings, raw string (no Java escape hell), closures
  • Full stack frameworks
  • screencasts
  • console for additional testing
  • easy to configure
  • productive
  • Builders. Configuration can be done in Groovy/Ruby files that look like normal configuration files. Easier to read than XML.
  • Books are available
  • quick releases
  • Dare to drop features. Can be good or bad, but I like it when features are dropped in order to keep the framework good.
  • Build tasks
  • Very easy to create tags/reusable HTML components. (Something you cannot say about JSF.)
  • Convention over Configuration

Grails vs. Rails

  • Documentation. The first thing that frustrated me about Rails was documentation. How do you learn Rails? Grails has an excellent up-to-date User guide, but on the Rails doc webpage you have API, Books, some outdated not-working external third-party tutorials, and how-to’s. But no userguide….. It’s very frustrating when you are halfway your first Rails steps in a tutorial (that is directly linked from the official main Rails docpage), and find yourself having to Google for solutions/workarounds because the popular Rails tutorials are so outdated that it doesn’t work anymore. If you want good learning material, you are forced to buy a RECENT (e)book otherwise you’ll find code that doesn’t work.

    API documentation is probably better in Rails than Grails because they have examples and more info in it. Rails also has wiki pages, which can be useful when looking for specific problems. Grails on the other hand has a userguide/tutorial that is very suitable for beginners, it is also useful for a quick reference. Grails website has some pages that have duplicated info about the same subject, sometimes these pages are outdated, and thus conflicting each other. e.g. the Grails pages about validation.

  • Grails uses other solid frameworks underneath it, like Hibernate and Spring. Frameworks that are well known in Java enterprise. These frameworks have a lot of features for the Model and controller, and thus give Grails a lot of features.
  • The View layer in Rails has a lot of features; there are a lot of view helpers/functions, which can be very handy. e.g. link_to_unless_current, which creates a hyperlink to an URL unless it is already the URL of the current page. Another example is Rails’ RJS, which allows you to write Ruby code that is outputted in Javascript.

    But Grails has IMO too less helpers. On this point, Grails is very weak compared to Rails. e.g. a select html input in Grails doesn’t allow selecting more than one item. Also, implementing error textfield highlighting using default Grails tags is very cumbersome.

  • Both frameworks are popular and have an active community. Rails is more popular; it existed before Grails and has inspired other frameworks. Rails has more jobs.
  • Grails automatically adapts the DB when creating/changing model attribute names, but this feature might be a bit unstable sometimes, since updating existing model classes is not very stable in Hibernate. (It is hard to determine whether a new found attribute is a new attribute or a renamed existing attribute when no versioning is used.) (Hibernate can also generate Java classes from an existing DB.)

    Rails uses Migrations to change the DB. A migration is a Ruby file containing almost SQL-like commands; it’s like writing pure SQL, but you have to write it yourself. Every migration has a version, and commands to change versions, so Rails has a DB versioning system. This can be very useful when you need to update the Production servers’ DB in a consistent way.

    Grails has a more object oriented approach; it shields/protects you from low-level sql. Where Rails gives you more SQL control when creating tables, and Rails allows you to control db versions.

  • Grails has GORM (Grails Object Relational Mapping) for making, saving and retrieving the domain models from the database. Rails uses Active Record.

    Grails (GORM) uses Hibernate (one of the best ORM frameworks) underneath its layers. When making a model class in Grails, you make a plain basic class with the attributes defined in it. When making relations between model classes, you’ll have to use special variable names that define the relations. Like belongsTo, hasMany, mappedBy and embedded. Maybe this can be done with Groovy annotations in the future? Grails automatically saves adaptions you make to a model class, to the db. Although, as mentioned previously, it uses Hibernates hbm2ddl, so for safety, you have to check manually that the DB table is what you expected when changing/renaming existing attributes. Validation of attributes is also put in the model class.

    Rails Active Record differs a lot from Grails GORM. A Rails domain class/entity is composed of two files, a migration file and a Rails model class file. All model attributes and datatypes are defined in the migration file and/or database, using an SQL wrapper. So that the migration files can be directly translated to pure SQL; writing a migration file is like writing SQL DDL (CREATE statements). At this point the associated Rails model class file is empty. From an Object Oriented point of view, this is an ugly approach; the attributes are defined in SQL/db instead of the domain model class itself. It also makes IDE autocompletion and refactoring hard. It also makes it cumbersome for yourself to lookup the attributes for a domain model class; you have to look in multiple files for it! Making relations is done both using SQL foreign keys and is similar to Grails, putting special variable names or methods in the model class: belongs_to, has_many etc. Validation is also done in the model class. When you add new attributes to a model, you can use a new Rails Migrations to propagate it to the DB. Which basically is a SQL change table add column command.

    So the Domain model in Rails is database based, instead of OOP based like Grails. I know OOP and Hibernate, so I like starting with OOP for the domain model and generate the DB from it. Btw Hibernate can do both; it can reverse engineer/generate Java classes from an existing DB, and it can generate the DB from domain model classes.

  • Both have books available. Rails has more books.
  • Grails has Implicit Dynamic Scaffolding (optional), you don’t have to write the view. The view (html) is generated, and changes automatically when you add new properties to the model. This can be useful when learning the framework. But when coding a webapp, you probably write the view yourself. Rails had Implicit Dynamic Scaffolding in the past, but they removed it because it’s only useful for beginners. Both frameworks also have explicit scaffolding.

    I prefer the scaffold generated by Rails, but Grails has column sorting.

  • Grails uses Groovy, so you can use new or existing Java classes/libraries, and thus have both dynamic and static typed. You can even code pure Java in Groovy classes, or mix them. Rails uses Ruby, but Rails also has third party JRuby, which allows you to call Ruby classes from Java classes and back. JRuby is less integrated with Java than Groovy. Like Grails, with JRuby you can run a web-app in a Java EE environment. JRuby is probably only interesting for those who want to use existing Java classes.
  • Grails is faster than Rails, but with JRuby, Rails can increase its speed. The ruby Merb framework (similar to Rails) will be merged with Rails in the future. Merb is faster than Rails.
  • In Rails, it’s very easy to pass objects from the controller to the view, because of Ruby. For example in Rails:
    		Rails:
    		*** ProductController ***
    		@product = Product.find(1)
    		@category = Category.find(1)
    		

    In Grails you have an extra step with duplicated names.

    		Grails:
    		*** ProductController ***
    		product = Product.find(1)
    		category = Category.find(1)
    		['product' : product, 'category' : category] // last line in controller action. It defines an identifier twice.
    		
  • Rails has a lot of different names for the same thing, which can be confusing. This is caused by Rails pluralization; controller names and db tables are automatically named in plural from a singular name. For example, when you have a domain class for a shipping address. In Rails you’ll find names:
    • ShippingAddress (model classname)
    • shipping_address (model filename, attribute name)
    • shipping_addresses (controller filename, attribute list name, db table and migration name)
    • ShippinAdresses (controller classname)
    • Pluralization can be turned off, but is enabled by default, it’s the Rails way of naming.

  • Grails uses Jetty as default webserver in development mode. Rails uses Mongrel by default, and Webrick in the past.
  • When generating a Grails project, the project will still use some script files from the Grails_home dir. Rails copies these files, which makes it easier to adapt Rails projects without influencing other projects.
  • Grails uses Java underneath it; it uses more memory than Rails. This probably makes hosting a Rails app cheaper than a Grails (Java) app. (Hosting can be cheap when you use a Virtual Private Server.)
  • Grails has an expression language, like JSP. In a Grails view, you can use:
    • <%= product.getPrice() %>, or
    • ${product.price}

    Rails doesn’t have an expression language, so you can only use <%= product.price %>. I prefer using expression language when possible; it keeps the view cleaner.

  • Grails uses Groovy, which IMO is easier to learn than Ruby, especially is you already know Java. Groovy uses a syntax that is found in other languages, like C++, Javascript and PHP. Ruby however differs from that. Also, in Ruby, there are often multiple ways to do something. Sometimes the language remove one way, while leaving the other. This can be confusing. Ruby, also has no method overloading.
  • Rails feels more matured than Grails because of it’s better View layer. It also is already at version 2.2 where Grails is at 1.0.
  • Rails has a built-in benchmark, profiler. Grails has it using third party plugins.
  • Both Grails and Rails configuration files are easy to read. Grails probably has an easier syntax.
  • Rails inspired other frameworks, like Grails.
  • Rails seems to be released/updated more often. This might be because Graeme Rocher (a Grails developer) was working a Grails book the last couple of months.

Specific for Rails:

  • Easy to change from a single Rails version on a system shared by multiple projects, to a single Rails per project config. So that you can run multiple Rails versions if needed.
  • Very REST by default. nested url resources like /articles/1/comments/5/edit
  • security, authenticity_token against cross site request forgery.
  • You need to restart the webserver when you add a scaffold for a model, because routes.rb gets changed.
  • Rails’ Active Record uses a lot more SQL in code than Grails (Hibernate).
  • Changes in routes.rb requires a restart. Thus adding new resources (like REST controller for a model) requires a server restart.
  • The DB drives the Model. E.g. default model values have to be specified in the DB.
  • Cumbersom to find how you can code in Model classes as Plain Old Ruby Objects. For example you can’t use the initialize method?
  • Rails with Capistrano and Mongrel make it easy to implement load balancing. Not sure if this is also possible with Grails.
  • Rails has special url_path variables/methods, which makes writing urls easier. For example, it automatically has variable/methods names like edit_article_url(article) that translate to the correct URL.

Specific for Grails

  • Grails: Sitemesh breaks the OSIV (Open Session In View) pattern. So you cannot use full GORM in layouts. Something that really needs to be fixed.
  • No Java annotations in Groovy?
  • (Groovy) console/shell tool cannot work with def keyword?
  • Hard to debug errors messages
  • doesn’t work out of the box with all third party servlet based software. For example, UrlRewriteFilter doesn’t work.
  • less secure? Via a html form POST hackers can set properties for new objects even is those properties aren’t defined in the form itself. (This happens when the new MyDomain(params) is used.) FIX: use command objects or bindData method. Not sure if Rails has a better solution.
  • Jsession id’s are sometimes visible in the url. e.g. when using the flash for messages.
  • Grails: Looking up a pretty url given a controller and action and id, isn’t possible? Only the default url scheme is used?

Summary and my preferences:

  • I like both Grails and Rails.
  • I prefer the Groovy language over Ruby, especially because Groovy supports static typed and Java. Although writing in Ruby is also cool.
  • Grails really has to do something about the view layer. Rails is a lot better at this point.
  • I dislike that Rails domain model is database centered. I doesn’t feel object oriented. You cannot use plain Ruby classes, you have to look in the migrations for model attributes. You cannot simply use an initialiser/constructor of the model in Rails, for example when you want to set default values. How do you make a constructor that receives parameters? Ruby also doesn’t support method overloading. The Rails domain model feels limited in a OOP way.
  • Rails feels more matured.
  • Grails is more enterprise and Java EE focussed, using Spring and Hibernate.
  • Grails focusses on the use and incorporation of other well known frameworks using plugins, making it possible to use other webframeworks if needed. For example: Struts, Wicket, Flex, GWT and Echo.
  • Rails project configuration is more flexible.
  • I should have a better look at JRuby.
Jul 242008
 

Making textFields in Grails is a bit verbose, at least if you want error highlighting and returned values on errors. This post shows a quick solution.

Problem

A full textField would be:

<g:textField class="${hasErrors(bean:user, field:'name', 'errors')}" value="${fieldValue(bean:user,field:'name')}" name="name"/>

Which clearly is very verbose; you have to specify “user” twice, and “name” even three times. This verbosity also makes the view less readable.

Googling for this problem resulted in: Smarter Grails Tags (a proposal). Funny that the writer exactly sees the same problem in it, also uses the “user” domain model, and also knows Stripes where you could just use something like

<stripes:text name="name"/>

and specify the bean name in the form. (Stripes has a very good Quick Start Guide, which also shows error highlighting.)

One of the less verbose proposed formats of textField is:

<g:textField bean="user" field="username" />

Implemented Solution

I found that implementing a quick version of this is surprisingly easy in Grails, it only takes for a few statements. Here is the code:

import org.codehaus.groovy.grails.plugins.web.taglib.FormTagLib

// file: project/grails-app/taglib/MyTagLib.groovy
class MyTagLib {
    // tagname "myTextField" within the "g" namespace
    def myTextField = {attrs ->
        // If a controller returned the bean, and the field has an error,
        // then "errors" will be returned as HTML class, otherwise the class will be empty.
        attrs.class = hasErrors(bean:attrs.bean, field:attrs.field, 'errors')
        // Retrieves the field value of the given bean to be rendered in the view.
        // Note: specify the bean and not the bean name. So "${user}" instead of "user"
        attrs.value = fieldValue(bean:attrs.bean, field:attrs.field)
        // Required for textField taglib. attrs.name is a keyname of the params map
        attrs.name = attrs.field
        // renders the HTML tag
        out << new FormTagLib().textField(attrs)
    }
}

Usage

<g:myTextField bean="$user" field="name" />

And ofcourse some CSS to highlight the error in a color. This can be put in the HTML head (or better, a seperate CSS file) :

<style type="text/css">
   .errors {
      background-color: red;
   }
</style>
Jul 202008
 

If you have some existing Java Hibernate entity classes (outside Grails), you only have to add one line in Datasource config, and you can use them immediately. However, if you have some exising POJO (Plain Old Java Object) Hibernate DAO’s (classes that implement a Data Access Object pattern), you’ll have to do some additional steps to make it a bit suitable.

(The solution described in this post can also be handy when you need data access on places where GORM is NOT available. GORM not available? Yes, GORM is not fully available when you access collections via a taglib that is accessed via a Sitemesh layout. (A scenerio that isn’t rare.) (Should be considered as a bug?) In that case you will get a lazily initialize a collection error. If you use HibernateUtil, you can get around this by just opening new session yourself.)

Existing Hibernate entities and GORM

You can use existing Hibernate Java entities directly in Grails. The only thing that you’ll have to configure is:

  1. define mappings in hibernate.cfg.xml
  2. set GrailsAnnotationConfiguration as configClass in DataSource.groovy

For example:
webapp/grails-app/conf/hibernate/hibernate.cfg.xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
		"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
		"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <mapping class="myPackage.Product"/>
        <mapping class="myPackage.Customer"/>
        <mapping class="myPackage.Supplier"/>
    </session-factory>
</hibernate-configuration>

webapp/grails-app/conf/DataSource.groovy :

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration

dataSource {
    configClass = GrailsAnnotationConfiguration.class
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    url = "jdbc:mysql://localhost/mydb"
    username = "myusername"
    password = "mypass"
    dbCreate = "create" // one of 'create', 'create-drop','update'
    dialect= org.hibernate.dialect.MySQLInnoDBDialect
}
hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}

Now you can put your existing Hibernate java entities in webapp/src/entities (or any other package), and they will work immediately and have GORM functionality.
For example, in the Grails controller classes, you can direcly use Product.get(100) (to get a Product instance that has id 100). Hibernate sessions and transactions are created/invoked automatically.

Exising Hibernate DAO’s

If you don’t need any GORM functionality and you don’t want Grails to touch sessions, then you can use your existing unaltered full hibernate.cfg.xml.

However, if you have some POJO DAO’s that use the HibernateUtil helperclass, you will have to do some additional steps to make it a bit suitable. (In this example, I use the configurations above.)

By default Grails injects a SessionFactory
First, your DAO’s will need a HibernateSession to perform work. By default Grails injects a SessionFactory into Grails controllers that have a “sessionFactory” variable defined. So the following controller will automatically have a SessionFactory available:

import org.hibernate.*;

class ProductController {
    // This one will be injected
    SessionFactory sessionFactory

    def index = {
        Session session = sessionFactory.getCurrentSession()
        println session.createQuery("from Product").list()
    }
}

(You can also use Gorm in this controller example and don’t use the SessionFactory yourself, but this just to show that a SessionFactory will be injected.)

HibernateUtil used by the DAO’s
In the example, the DAO’s use HibernateUtil to get a SessionFactory. By default HibernateUtil create a SessionFactory itself, but the SessionFactory provided by Grails is needed instead, so we alter HibernateUtil slightly:

package persistence;

import org.hibernate.*;

public class HibernateUtil {
    private static SessionFactory sessionFactory;

    public static SessionFactory getSessionFactory() { return sessionFactory; }
    public static void setSessionFactory(SessionFactory sf) { sessionFactory = sf; }

    public static void shutdown() { sessionFactory.close(); }	
}

Set SessionFactory for HibernateUtil
We want HibernatUtil to be ready with a SessionFactory after booting, so we configure HibernateUtil during the bootstap. We alter webapp/grails-app/conf/BootStrap.groovy to:

import persistence.HibernateUtil
import org.springframework.web.context.support.WebApplicationContextUtils

class BootStrap {

     def init = { servletContext ->
        def ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)
        def sf  = ctx.getBean('sessionFactory')
        HibernateUtil.setSessionFactory(sf)
     }

     def destroy = {
         HibernateUtil.shutdown()
     }
}

Now the DAO’s can use HibernateUtil.getSessionFactory().getCurrentSession() to get a HibernateSession.