<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/">
  <title>Alexey Kakunin</title>
  <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/rss" />
  <subtitle>Alexey Kakunin</subtitle>
  <entry>
    <title>Workflow and Reports in Liferay 6</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/workflow-and-reports-in-liferay-6" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/workflow-and-reports-in-liferay-6</id>
    <updated>2010-08-04T15:53:06Z</updated>
    <published>2010-08-04T15:05:20Z</published>
    <summary type="html">&lt;p&gt;Liferay 6 has 2 very nice features, probably not well documented yet.
  It is support for Workflows and Reports. Here I want to discuss some
  major details about these features, since there are no too much info
  about them.&lt;/p&gt;
&lt;h3&gt;Support for Workflows&lt;/h3&gt;
&lt;h4&gt;How it works from developer side:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Liferay has set of general interfaces, implemnted working with
    workflows (look at the package com.liferay.portal.kernel.workflow)&lt;/li&gt;
  &lt;li&gt;It is possible to deploy some implementation of these interfaces
    as separate plugin.&lt;/li&gt;
  &lt;li&gt;By default, Liferay 6.0.4 ships with kaleo-web - plugin
    implemented workflow functionality with using own developed workflow
    engine Kaleo;&lt;/li&gt;
  &lt;li&gt;But it is possible to deploy jbpm3 based implementation (available
    in svn: &lt;a href="http://svn.liferay.com/repos/public/plugins/trunk/webs/jbpm-web"&gt;http://svn.liferay.com/repos/public/plugins/trunk/webs/jbpm-web&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;As well as I've started development of jBPM4 based implementation
      (&lt;a
    href="http://www.emforge.net/web/jbpm4-portlet"&gt;http://www.emforge.net/web/jbpm4-portlet&lt;/a&gt;),
    but, since there was no interest from community side, as well as no
    strong requirements in this implementation in my current project
    this implementation currently placed on-hold;&lt;/li&gt;
  &lt;li&gt;Then somebody (any portlet) calls core Workflow methods in Liferay
    - these calls routed into deployed implementation (with using
    internal Liferay's Message Bus).&lt;/li&gt;&lt;/ul&gt;
&lt;h4&gt;How it works from Administrator Side:&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;After deploying some implementation, it is possible to manage
    workflows in the control panel (for example deploy workflow definitions);&lt;/li&gt;
  &lt;li&gt;Set of workflows is individual for each portal instance;&lt;/li&gt;
  &lt;li&gt;As well, for each group it is possible to define own
      &lt;strong&gt;Workflow Configuration&lt;/strong&gt;: mapping of Assets with
    Workflows, responsible for their processing;&lt;/li&gt;&lt;/ul&gt;
&lt;p style="text-align: center;"&gt;
  &lt;img align="middle" alt="" height="423"
    src="http://www.emforge.org/image/image_gallery?uuid=36a9b3b5-1b71-43e9-9db0-0f77be9be753&amp;amp;groupId=10146&amp;amp;t=1280937087693" width="530" /&gt;&lt;/p&gt;
&lt;p&gt;Important thing - in Liferay each process instance (workflow
  instance) are connected to some Asset. It is not possible to just
  &amp;quot;create a task&amp;quot;, but, you can create/edit some asset and it
  will &amp;quot;flow&amp;quot; by some workflow (according to asset type and
  workflow linked with this type in Workflow Configuration).&lt;/p&gt;
&lt;h4&gt;How it works from User Side:&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;Actually, how to work with workflows from user side quite well
  described in &lt;a
    href="http://www.liferay.com/web/juan.fernandez/blog/-/blogs/liferay-workflow-in-action"&gt;Juan's
  blog-post&lt;/a&gt;. I can just add - fi you like to experiment with
  workflows - simple start default Liferay 6.0.4 bundle with 7cogz-hook
  deployed. It deploy's kaleo workflow engine, as well as defined users
  with required roles - you can play with editing web-content by
  &amp;quot;Editor&amp;quot; users, and approve changes by &amp;quot;Publisher&amp;quot;
  user. It is good enough to see how it works (and very fast to start).&lt;/p&gt;
&lt;h3&gt;Support for Reports&lt;/h3&gt;
&lt;p&gt;Supports for reports is very simular to support for Workflow:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Liferay core has some interfaces for working with reports (looks
    at ReportEngine class);&lt;/li&gt;
  &lt;li&gt;It is possible to deploy some implementation;&lt;/li&gt;
  &lt;li&gt;In Incubation SVN you can find JasperReport's based
    implementation: &lt;a href="http://svn.liferay.com/repos/public/plugins/incubation/webs/reporting-jasper-web/"&gt;svn.liferay.com/repos/public/plugins/incubation/webs/reporting-jasper-web/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;By save way - all calls to core ReportEngine are routed to
    implementation with using MessageBus;&lt;/li&gt;
  &lt;li&gt;After deploying some implementation, you can use reports in your
    portlets, but&lt;/li&gt;
  &lt;li&gt;You may deploy &amp;quot;Report Console&amp;quot; portlet from svn
    incubation: &lt;a href="http://svn.liferay.com/repos/public/plugins/incubation/portlets/reports-console-portlet/"&gt;svn.liferay.com/repos/public/plugins/incubation/portlets/reports-console-portlet/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;It will add Reports Tab into your Control Panel - to allow admin
    to deploy reports and manage them, manage data sources and some
    other settings, as well as place &amp;quot;View Report&amp;quot; portlet on
    any page&lt;/li&gt;&lt;/ul&gt;
&lt;p style="text-align: center;"&gt;
  &lt;img alt="" height="423"
    src="http://www.emforge.org/image/image_gallery?uuid=c9d36a2b-3149-48e0-a6f9-f9822404a6a0&amp;amp;groupId=10146&amp;amp;t=1280937130522" width="530" /&gt;&lt;/p&gt;
&lt;p&gt;I think these two features are very good big steps forward to make
  Liferay more powerful and more &amp;quot;Enterprise&amp;quot;. Just again -
  big &amp;quot;thank you&amp;quot; to Liferay team for great job!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-08-04T15:05:20Z</dc:date>
  </entry>
  <entry>
    <title>First project migrated to 6.0.3</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/first-project-migrated-to-6-0-3" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/first-project-migrated-to-6-0-3</id>
    <updated>2010-07-17T20:15:00Z</updated>
    <published>2010-07-17T20:07:31Z</published>
    <summary type="html">&lt;p&gt;I already have several projects based on Liferay 6 branch, some of
  them based on 6.0.1, some on 6.0.2. Few days ago first GA version of
  Liferay 6 &lt;a
    href="http://www.liferay.com/web/brian.chan/blog/-/blogs/liferay-portal-6-ga-released"&gt;was
  released&lt;/a&gt; so, it's time to move project forward.&lt;/p&gt;
&lt;p&gt;Today was first - based on 6.0.1. Here is some notes for developers,
  to know what expect from such migration:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Database upgraded without any problems. Looks like error in
    upgrade-script between 6.0.1 and 6.0.2 is fixed and now everything
    works as expected. Simple place new Liferay instead old one and
    connect to same DB;&lt;/li&gt;
  &lt;li&gt;Dependencies - minor changes required (jstl.jar renamed to jstl-api.jar);&lt;/li&gt;
  &lt;li&gt;Source code - some minor changes required because of changed API (expectable);&lt;/li&gt;
  &lt;li&gt;JSP pages: here was major change I had to do: in my project jsp
    pages was located in /WEB-INF/jsp, and Liferay 6.0.3 is not allowed
    to load resources under WEB-INF (ok, I thin it is configurable - but
    I will prefer to stay with standard configuration as much as
    possible). So, I had to move jsp pages to /jsp (and of course change
    all source-code). Hopefully it is very easy change.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;So, migration from 6.0.1 to 6.0.3 works almost without any problems.
  Good job Liferay Team!&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-07-17T20:07:31Z</dc:date>
  </entry>
  <entry>
    <title>Simple Vaadin Portlet in Liferay Plugins SDK</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/simple-vaadin-portlet-in-liferay-plugins-sdk" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/simple-vaadin-portlet-in-liferay-plugins-sdk</id>
    <updated>2010-07-12T08:49:44Z</updated>
    <published>2010-07-12T08:29:19Z</published>
    <summary type="html">&lt;p&gt;Vaadin is a new word in Liferay world, it looks very promised, but,
  as always, not so much documentation and tutorials. Some of tutorials
  too complex, some not covered some (even simple) questions.&lt;/p&gt;
&lt;p&gt;Here I want to explain for Liferay developers already used Plugins
  SDK (and have experience in Liferay Portlets development) how to write
  simple Vaadin portlet and access Portlet and Liferay infrastructure
  (handle render request, access ThemeDisplay object).&lt;/p&gt;
&lt;p&gt;Actually, you can skip everything and simple get sources from SVN: &lt;a
  href="http://svn.emforge.net/svnroot/akakunin-experiments/sample-vaadin-portlet"&gt;svn.emforge.net/svnroot/akakunin-experiments/sample-vaadin-portlet&lt;/a&gt;
  - it is really very simple.&lt;/p&gt;
&lt;h3&gt;Prerequirements&lt;/h3&gt;
&lt;p&gt;I've used latest public version of Liferay (6.0.2) and it's plugins
  SDK. Also I'm using Eclipse (not using Liferay IDE yet, since had no
  time to switch into it) - but it is not required for this tutorial -
  it is based on Liferay SDK, so, used ant for build and may be used
  with any IDE&lt;/p&gt;
&lt;h3&gt;Create portlet&lt;/h3&gt;
&lt;p&gt;Switch to sdk/portlets and call&lt;/p&gt;
&lt;pre&gt;
#  ./create.sh sample-vaadin
&lt;/pre&gt;
&lt;p&gt;Then remove all renerated jsp-pages, css, images and so on -
  everything was generated for sample portlet&lt;/p&gt;
&lt;h3&gt;Configure web.xml for working with Vaadin&lt;/h3&gt;
&lt;p&gt;Create web.xml (in my case it wasn't created by plugins-sdk) with
  setting to enable using VAADIN in your portlet:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;
&amp;lt;web-app xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot; version=&amp;quot;2.4&amp;quot;&amp;gt;
  &amp;lt;context-param&amp;gt;
      &amp;lt;description&amp;gt;Vaadin production mode&amp;lt;/description&amp;gt;
      &amp;lt;param-name&amp;gt;productionMode&amp;lt;/param-name&amp;gt;
      &amp;lt;param-value&amp;gt;false&amp;lt;/param-value&amp;gt;
  &amp;lt;/context-param&amp;gt;
  &amp;lt;servlet&amp;gt;
      &amp;lt;servlet-name&amp;gt;Vaadin_portlet Application&amp;lt;/servlet-name&amp;gt;
      &amp;lt;servlet-class&amp;gt;
      com.vaadin.terminal.gwt.server.ApplicationServlet&amp;lt;/servlet-class&amp;gt;
      &amp;lt;init-param&amp;gt;
          &amp;lt;description&amp;gt;
          Vaadin application class to start&amp;lt;/description&amp;gt;
          &amp;lt;param-name&amp;gt;application&amp;lt;/param-name&amp;gt;
          &amp;lt;param-value&amp;gt;com.example.vaadin_portlet.Vaadin_portletApplication&amp;lt;/param-value&amp;gt;
      &amp;lt;/init-param&amp;gt;
  &amp;lt;/servlet&amp;gt;
  &amp;lt;servlet-mapping&amp;gt;
      &amp;lt;servlet-name&amp;gt;Vaadin_portlet Application&amp;lt;/servlet-name&amp;gt;
      &amp;lt;url-pattern&amp;gt;/Vaadin_portletApplicationServlet/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;
  &amp;lt;servlet-mapping&amp;gt;
      &amp;lt;servlet-name&amp;gt;Vaadin_portlet Application&amp;lt;/servlet-name&amp;gt;
      &amp;lt;url-pattern&amp;gt;/VAADIN/*&amp;lt;/url-pattern&amp;gt;
  &amp;lt;/servlet-mapping&amp;gt;
&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Add Vaadin into portlet dependencies&lt;/h3&gt;
&lt;p&gt;Liferay itself already has vaadin, you do not need to include it into
  your portlet lib. Simple add it into portal-dependency-jars in liferay-plugin-package.properties:&lt;/p&gt;
&lt;pre&gt;
name=
module-group-id=liferay
module-incremental-version=1
tags=
short-description=
change-log=
page-url=http://www.liferay.com
author=Liferay, Inc.
licenses=LGPL
portal-dependency-jars=\
    vaadin.jar
&lt;/pre&gt;
&lt;h3&gt;Add portlet definition into portlet.xml &amp;amp; liferay-portlet.xml&lt;/h3&gt;
&lt;p&gt;Add into portlet.xml:&lt;/p&gt;
&lt;pre&gt;
    &amp;lt;portlet&amp;gt;
        &amp;lt;portlet-name&amp;gt;sample-vaadin&amp;lt;/portlet-name&amp;gt;
        &amp;lt;display-name&amp;gt;Sample Vaadin&amp;lt;/display-name&amp;gt;
       
        &amp;lt;portlet-class&amp;gt;com.vaadin.terminal.gwt.server.ApplicationPortlet2&amp;lt;/portlet-class&amp;gt;
        &amp;lt;init-param&amp;gt;
            &amp;lt;name&amp;gt;application&amp;lt;/name&amp;gt;
            &amp;lt;value&amp;gt;sample.vaadin.SampleApplication&amp;lt;/value&amp;gt;
        &amp;lt;/init-param&amp;gt;
       
        &amp;lt;!--
          To enable displaying multiple Vaadin portlets on a page,
          they should all use the same widgetset. In that case, the
          widgetset can be configured on the portal level (parameter
          vaadin.widgetset) or here for each portlet.
        --&amp;gt;
        &amp;lt;!--
        &amp;lt;init-param&amp;gt;
            &amp;lt;name&amp;gt;widgetset&amp;lt;/name&amp;gt;
            &amp;lt;value&amp;gt;com.vaadin.portal.gwt.PortalDefaultWidgetSet&amp;lt;/value&amp;gt;
        &amp;lt;/init-param&amp;gt;
        --&amp;gt;
       
        &amp;lt;!-- Supported portlet modes and content types. --&amp;gt;
        &amp;lt;supports&amp;gt;
            &amp;lt;mime-type&amp;gt;text/html&amp;lt;/mime-type&amp;gt;
            &amp;lt;portlet-mode&amp;gt;view&amp;lt;/portlet-mode&amp;gt;
            &amp;lt;!-- &amp;lt;portlet-mode&amp;gt;edit&amp;lt;/portlet-mode&amp;gt; --&amp;gt;
            &amp;lt;!-- &amp;lt;portlet-mode&amp;gt;help&amp;lt;/portlet-mode&amp;gt; --&amp;gt;
        &amp;lt;/supports&amp;gt;
       
        &amp;lt;!-- Not always required but Liferay uses these. --&amp;gt;
        &amp;lt;portlet-info&amp;gt;
            &amp;lt;title&amp;gt;Sample Vaadin&amp;lt;/title&amp;gt;
            &amp;lt;short-title&amp;gt;Sample Vaadin&amp;lt;/short-title&amp;gt;
        &amp;lt;/portlet-info&amp;gt;
    &amp;lt;/portlet&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and liferay-portlet.xml:&lt;/p&gt;
&lt;pre&gt;
    &amp;lt;portlet&amp;gt;
        &amp;lt;portlet-name&amp;gt;sample-vaadin&amp;lt;/portlet-name&amp;gt;
        &amp;lt;ajaxable&amp;gt;false&amp;lt;/ajaxable&amp;gt;
    &amp;lt;/portlet&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Implement Application Class&lt;/h3&gt;
&lt;p&gt;You can get sources of class from svn: &lt;a href="http://svn.emforge.net/svnroot/akakunin-experiments/sample-vaadin-portlet/docroot/WEB-INF/src/sample/vaadin/"&gt;svn.emforge.net/svnroot/akakunin-experiments/sample-vaadin-portlet/docroot/WEB-INF/src/sample/vaadin/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some important points in this class:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Get PortletApplicationContext2 and add PortletListener into it;&lt;/li&gt;
  &lt;li&gt;SamplePortletListener (PortletListener implementation) will allow
    you to access Portlet API (render, action, even, resource);&lt;/li&gt;
  &lt;li&gt;As result, you can use standard way to access (for example)
    ThemeDisplay object - and information about your current context.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;What is all - take fun with Liferay and Vaadin!&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-07-12T08:29:19Z</dc:date>
  </entry>
  <entry>
    <title>Ubutu 10.04, mysql, Java, localhost = WTF?</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/ubutu-10-04-mysql-java-localhost-=-wtf" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/ubutu-10-04-mysql-java-localhost-=-wtf</id>
    <updated>2010-07-11T21:56:15Z</updated>
    <published>2010-07-10T22:06:12Z</published>
    <summary type="html">&lt;p&gt;Today I killed 2 hours of my life for very studip problem.&lt;/p&gt;
&lt;p&gt;I just got new notebook (IBM&amp;nbsp;Thnkpad T400) with 4Gb, so, to be
  able to use whole memory, installed Ubuntu 10.04 64 bit. Then
  installed mysql-server, sun java, eclipse, some other staff and
  started to work. mysql nd sun java was installed via apt with standard settings.&lt;/p&gt;
&lt;p&gt;Created DB, successfully connected via MySQL Admin and Query Browser,
  and, then, trying to connect from my app: failed&lt;/p&gt;
&lt;pre&gt;
Exception in thread &amp;quot;main&amp;quot; com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
Last packet sent to the server was 0 ms ago.
&amp;nbsp;&amp;nbsp;&amp;nbsp; at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Checking JDBC Url - everything is correct, checking username/password
  - same, I can connect to localhost DB with using this
  username/password with using standard mysql tools. But not from java
  via JDBC.&lt;/p&gt;
&lt;p&gt;WTF???&lt;/p&gt;
&lt;p&gt;After spending 2 hours, found &lt;a
    href="http://ubuntuforums.org/showthread.php?t=991141"&gt;this
  forum&lt;/a&gt;. After commenting &lt;strong&gt;bind-address&lt;/strong&gt; in my.cnf
  and changing jdbc url to use my computer IP address (like
  192.168.0.157) instead of localhost it finally started to connect.&lt;/p&gt;
&lt;p&gt;Why? Why it is not working with localhost out-of-box? Why I should
  spent 2 hours for such stupid problems?&lt;/p&gt;
&lt;h2&gt;Problem resolved&lt;/h2&gt;
&lt;p&gt;Ok, today (after sleeping a little bit) I realized the source of
  problem. It is not ubuntu, java, or mysql. It is (of course) - I'm.&lt;/p&gt;
&lt;p&gt;Yesterday I changed by /etc/hosts - so, localhost was defined
  incorrectly (by some reason). But, MySQL clients, in case localhost
  server used - not used TCP at all - then connected to mysql directly.&lt;/p&gt;
&lt;p&gt;JDBC driver does not use it - it always (looks like) tried to use TCP
  and resolve hostname. It is why it connection worked in mysql tools,
  but did not worked in java.&lt;/p&gt;
&lt;p&gt;Ubuntu == cool!&lt;/p&gt;
&lt;p&gt;Java == cool!&lt;/p&gt;
&lt;p&gt;I'm == dummy developer :)&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-07-10T22:06:12Z</dc:date>
  </entry>
  <entry>
    <title>PetClinic GWT application in less then 30 minutes</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/petclinic-gwt-application-in-less-then-30-minutes" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/petclinic-gwt-application-in-less-then-30-minutes</id>
    <updated>2010-05-20T23:30:03Z</updated>
    <published>2010-05-20T12:45:16Z</published>
    <summary type="html">&lt;p&gt;Yesterday I've read announce of new version of &lt;a
    href="http://blog.springsource.com/2010/05/19/spring-roo-1-1-0-m1-released/"&gt;Spring-Roo
  1.1.0M1&lt;/a&gt; and found there at least 2 very interesting features: GWT
  &amp;amp; GAE support.&lt;/p&gt;
&lt;p&gt;So, today I spent some time to play with it - and here is short
  instructions how to make PetClinic application in less then 30 minutes
  (depends from your connection speed).&lt;/p&gt;
&lt;h2&gt;Prepequirements&lt;/h2&gt;
&lt;p&gt;You will need to have JDK 1.6 and &lt;a
    href="http://maven.apache.org/download.html"&gt;Apache Maven&lt;/a&gt;
  installed. I hope it is not a problem and sure 90% readers of this
  blog already have them&lt;/p&gt;
&lt;h2&gt;Download and Install Spring-Roo&lt;/h2&gt;
&lt;p&gt;Simple download it from &lt;a
    href="http://www.springsource.com/download/community?project=Spring%20Roo"&gt;SpringSource
  Site&lt;/a&gt; and unzip into some folder (lets say it &amp;lt;spring-roo-path&amp;gt;)&lt;/p&gt;
&lt;h2&gt;Get clinic.roo file&lt;/h2&gt;
&lt;p&gt;Download &lt;a
  href="http://www.emforge.net/c/document_library/get_file?uuid=092185e8-6a32-4ce4-b961-84ea07563502&amp;amp;groupId=141281"&gt;clinic.roo&lt;/a&gt;
  file. It is script for roo, almost same as default clinic.roo (you can
  find initial version in &amp;lt;spring-roo-path&amp;gt;/samples/clinic.roo)
  but adopted for using GWT:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Commented enums since Roo-GWT is not supported them; In entities
    enums replaced by string;&lt;/li&gt;
  &lt;li&gt;Boolean primitive looks like also not supported - so, changed to java.lang.Boolean;&lt;/li&gt;
  &lt;li&gt;Calendar is not supported changed to Date;&lt;/li&gt;
  &lt;li&gt;Commented out Spring-MVC specific commands&lt;/li&gt;
  &lt;li&gt;Added &lt;strong&gt;gwt setup&lt;/strong&gt; to generate gwt UI.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Run Roo to generate sources&lt;/p&gt;
&lt;p&gt;Lets generate sources with using this roo-file:&lt;/p&gt;
&lt;pre&gt;
# ../bin/roo.sh
# roo&amp;gt; script -file clinic.roo
# roo&amp;gt; exit
&lt;/pre&gt;
&lt;p&gt;It will took some time, but as result you will get maven-based
  project with all required sources.&lt;/p&gt;
&lt;h2&gt;Run it&lt;/h2&gt;
&lt;p&gt;Quite easy:&lt;/p&gt;
&lt;pre&gt;
# mvn gwt:run
&lt;/pre&gt;
&lt;p&gt;It may also take some time, since it will make a build and download
  all required artifacts from maven repositories. But it will long only
  for first time - after all requirements will be downloaded into local
  maven repo, next builds will go much faster.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
  &lt;img alt="" height="267"
    src="http://www.emforge.org/image/image_gallery?uuid=3d899d88-ac8b-4f64-8b42-a8c6b5380470&amp;amp;groupId=10146&amp;amp;t=1274398140279" width="450" /&gt;&lt;/p&gt;
&lt;h2&gt;Try it&lt;/h2&gt;
&lt;p&gt;Copy provided link into clipboard and open it in your browser (it
  will require to install GWT plugin)&lt;/p&gt;
&lt;p style="text-align: center;"&gt;
  &lt;img alt="" height="324"
    src="http://www.emforge.org/image/image_gallery?uuid=3ef6bb6e-2be9-4fca-819c-1d3818226938&amp;amp;groupId=10146&amp;amp;t=1274398162627" width="456" /&gt;&lt;/p&gt;
&lt;p&gt;So, now you can play with it. Not all forms working correctly - ok,
  GWT support in Spring-Roo is not in stable state, but at least it
  provide some ideas how it will be implemented.&lt;/p&gt;
&lt;h2&gt;What we have as result&lt;/h2&gt;
&lt;p&gt;As result, in less then 30 minutes we have great sample of:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Fast application generation with using Spring-Roo. Samples are
    very clear and you can use them as reference material for Roo
    features. Of course - if you interested - it make sense to read more
    Roo documentation&lt;/li&gt;
  &lt;li&gt;Sample of project used Spring Framework, GWT, Hibernate and many more;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;If you just started with one of these technologies, these
  code-samples may be good reference.&lt;/p&gt;
&lt;p&gt;Even you already using them for a long time - I'm pretty sure you
  can find many interesting things you probably did not know about
  Spring, Hibernate or GWT&lt;/p&gt;
&lt;p&gt;Of course created application is not something you can show to
  end-users. But - it may be good &amp;quot;start-point&amp;quot; and safe your
  time for doing some standard things for project initialization again
  and again.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-05-20T12:45:16Z</dc:date>
  </entry>
  <entry>
    <title>Magic options to monitor remote glassfish on ubuntu</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/magic-options-to-monitor-remote-glassfish-on-ubuntu" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/magic-options-to-monitor-remote-glassfish-on-ubuntu</id>
    <updated>2010-05-05T23:15:34Z</updated>
    <published>2010-05-04T22:20:28Z</published>
    <summary type="html">&lt;p&gt;&amp;nbsp;I've tried to setup JMX connection to my remote glassfish
  installed on ubuntu several times, and every time I've got 'cannot
  connect' error from my jconsole or VisualVM&lt;/p&gt;
&lt;p&gt;I've checked many tutorials in internet, in most case it should work
  out of box. Some people reported (like I'm) what they cannot connect
  to remote glassfish - but, without any answer and proper solution.&lt;/p&gt;
&lt;p&gt;Today I finally resolved 2 magic options enabled for me remote
  monitoring of Glassfish under Ubuntu (with using jconsole or
  VisualVM). They are:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;-Djava.rmi.server.hostname=xxx (use domain name you are using to
    access this server);&lt;/li&gt;
  &lt;li&gt;-Djava.net.preferIPv4Stack=true (in my cases by default Glassfish
    used IPv6 stack);&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So, getting Glassfish with default settings (by default JMX conector
  is enabled), add this two JVM options via glassfish admin console and
  (of course if you have no firewall behind you and this server) after
  restarting glassfish it is possible to connect and monitor it with
  using both jconsole and VisualVM (as well as I hope any JMX client).&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-05-04T22:20:28Z</dc:date>
  </entry>
  <entry>
    <title>Securing Remote EJB on Glassfish 2</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/securing-remote-ejb-on-glassfish-2" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/securing-remote-ejb-on-glassfish-2</id>
    <updated>2010-05-04T12:51:27Z</updated>
    <published>2010-05-04T12:39:17Z</published>
    <summary type="html">&lt;p&gt;Today I needed to write simplest remote EJB and command-line client
  for it and protect this EJB - request authentication. Glassfish2 was
  used as application server, but, I&amp;nbsp;suppose same will work (except
  probably required libraries) by same way with Glassfish 3.&lt;/p&gt;
&lt;p&gt;Write EJB&lt;/p&gt;
&lt;pre&gt;
@Stateless
public class TestSecurityBean implements TestSecurityBeanRemote, TestSecurityBeanLocal {
    private static Logger log = Logger.getLogger(TestSecurityBean.class.getName());
    @Resource
    EJBContext ejbContext;
   
    public String sayRemoteHello() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log.info(&amp;quot;EJBContext: &amp;quot; + ejbContext);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Principal principal = ejbContext.getCallerPrincipal();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log.info(&amp;quot;Caller Principal: &amp;quot; + principal);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return &amp;quot;Hello &amp;quot; + principal.getName() + &amp;quot;!&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // Add business logic below. (Right-click in editor and choose
&amp;nbsp;&amp;nbsp;&amp;nbsp; // &amp;quot;Insert Code &amp;gt; Add Business Method&amp;quot;)
&amp;nbsp;
}&lt;/pre&gt;
&lt;p&gt;Say glassfish to request authentication for calling this EJB (in META-INF/sun-ejb-jar.xml):&lt;/p&gt;
&lt;pre&gt;
&amp;lt;sun-ejb-jar&amp;gt;
    &amp;lt;enterprise-beans&amp;gt;
        &amp;lt;ejb&amp;gt;
            &amp;lt;ejb-name&amp;gt;TestSecurityBean&amp;lt;/ejb-name&amp;gt;
            &amp;lt;ior-security-config&amp;gt;
                &amp;lt;transport-config&amp;gt;
                    &amp;lt;integrity&amp;gt;supported&amp;lt;/integrity&amp;gt;
                    &amp;lt;confidentiality&amp;gt;supported&amp;lt;/confidentiality&amp;gt;
                    &amp;lt;establish-trust-in-target&amp;gt;supported&amp;lt;/establish-trust-in-target&amp;gt;
                    &amp;lt;establish-trust-in-client&amp;gt;supported&amp;lt;/establish-trust-in-client&amp;gt;
                &amp;lt;/transport-config&amp;gt;
                &amp;lt;as-context&amp;gt;
                    &amp;lt;auth-method&amp;gt;username_password&amp;lt;/auth-method&amp;gt;
                    &amp;lt;realm&amp;gt;default&amp;lt;/realm&amp;gt;
                    &amp;lt;required&amp;gt;true&amp;lt;/required&amp;gt;
                &amp;lt;/as-context&amp;gt;
                &amp;lt;sas-context&amp;gt;
                    &amp;lt;caller-propagation&amp;gt;supported&amp;lt;/caller-propagation&amp;gt;
                &amp;lt;/sas-context&amp;gt;
            &amp;lt;/ior-security-config&amp;gt;
        &amp;lt;/ejb&amp;gt;
    &amp;lt;/enterprise-beans&amp;gt;
&amp;lt;/sun-ejb-jar&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Write client:&lt;/p&gt;
&lt;pre&gt;public class Client {
    private static Logger log = Logger.getLogger(Client.class.getName());
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws NamingException {
        TestSecurityBeanRemote testSecurityService = getRemoteService();
        String result = testSecurityService.sayRemoteHello();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; log.info(&amp;quot;Result:&amp;quot; + result);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static TestSecurityBeanRemote getRemoteService() throws NamingException {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TestSecurityBeanRemote testSecurityService = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String host = &amp;quot;localhost&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String port = &amp;quot;3700&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Properties props = new Properties();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; props.setProperty(&amp;quot;java.naming.factory.initial&amp;quot;, &amp;quot;com.sun.enterprise.naming.SerialInitContextFactory&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; props.setProperty(&amp;quot;java.naming.factory.url.pkgs&amp;quot;, &amp;quot;com.sun.enterprise.naming&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; props.setProperty(&amp;quot;java.naming.factory.state&amp;quot;, &amp;quot;com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; props.setProperty(&amp;quot;org.omg.CORBA.ORBInitialHost&amp;quot;, host);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; props.setProperty(&amp;quot;org.omg.CORBA.ORBInitialPort&amp;quot;, port);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // standard way to put authentication info into remote ejb call
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // it is not working with Glassfish - own way for authentication should be used
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // props.setProperty(Context.SECURITY_PRINCIPAL, &amp;quot;user1&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // props.setProperty(Context.SECURITY_CREDENTIALS, &amp;quot;password1&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProgrammaticLogin programmaticLogin = new ProgrammaticLogin();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; programmaticLogin.login(&amp;quot;user1&amp;quot;, &amp;quot;password1&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Context amInitial = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; amInitial = new InitialContext(props);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; testSecurityService = (TestSecurityBeanRemote) amInitial.lookup(TestSecurityBeanRemote.class.getName());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return testSecurityService;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
  &lt;code&gt;W&lt;/code&gt;rite auth.conf&lt;/p&gt;
&lt;p&gt;
  &lt;code&gt;default {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
    com.sun.enterprise.security.auth.login.ClientPasswordLoginModule
    required debug=false;&lt;br /&gt;};&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Add required libraries from glassfish into project dependencies:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;$GF_PATH/lib/appserv-rt.jar&lt;/li&gt;
  &lt;li&gt;$GF_PATH/lib/appserv-admin.jar&lt;/li&gt;
  &lt;li&gt;$GF_PATH/lib/javaee.jar&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Run client with option to use this file with option &lt;code&gt;-Djava.security.auth.login.config=./auth.conf&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Add user1 into file realm:&lt;/p&gt;
&lt;p&gt;
  &lt;code&gt;#./asadmin create-file-user user1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now you should be able to call your remote EJB with using specified
  user and password&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-05-04T12:39:17Z</dc:date>
  </entry>
  <entry>
    <title>Liferay 5.2.3 Amazon EC2 Image (AMI) for EU region</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami-for-eu-region" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami-for-eu-region</id>
    <updated>2010-02-03T01:41:19Z</updated>
    <published>2010-02-03T01:31:37Z</published>
    <summary type="html">&lt;p&gt;In one of previous blog post: &lt;a
  href="http://www.emforge.net/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami"&gt;www.emforge.net/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami&lt;/a&gt;
  I've placed information about Liferay AMI.&lt;/p&gt;
&lt;p&gt;Only problem - that AMI was only for US region and I received request
  to make same to be run in EU.&lt;/p&gt;
&lt;p&gt;So - here it is:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;AMI: &lt;strong&gt;ami-0bddf67f&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;To run it you can use command like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ec2-run-instances --region eu-west-1 ami-0bddf67f &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Everything else same as for US region image&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-02-03T01:31:37Z</dc:date>
  </entry>
  <entry>
    <title>Spring 3 + JPA application on Glassfish 2.1</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/spring-3-jpa-application-on-glassfish-2-1" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/spring-3-jpa-application-on-glassfish-2-1</id>
    <updated>2010-01-24T22:58:07Z</updated>
    <published>2010-01-24T22:57:20Z</published>
    <summary type="html">&lt;p&gt;Today I've spent quite a lot of time trying to run one Spring 3.0
  based application used JPA (Hibernate) for working with DB on Glassfish.&lt;/p&gt;
&lt;p&gt;In development we sing tomcat and everything works well, but, on
  test-server I have glassfish installed, and - application did not work
  on it:&lt;/p&gt;
&lt;pre class="alt2" style="border: 1.0px inset;margin: 0.0px;padding: 6.0px;overflow: auto;width: 800.0px;height: 34.0px;text-align: left;"&gt;
Only persistence units with transaction type JTA can be used as a container managed entity manager. 
Please verify your application.&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Solution was found on Spring Forum:&lt;a
    href="http://forum.springsource.org/showthread.php?t=58527"&gt; http://forum.springsource.org/showthread.php?t=58527&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Short fix (since I do not need JTA transactions) - change web.xml
  version to 2.4&lt;/p&gt;
&lt;p&gt;This thead also has set of settings need to be done in the project to
  enable usage of JTA&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-01-24T22:57:20Z</dc:date>
  </entry>
  <entry>
    <title>Install jBPM 4.3 into existed JBoss 5.1</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/install-jbpm-4-3-into-existed-jboss-5-1" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/install-jbpm-4-3-into-existed-jboss-5-1</id>
    <updated>2010-01-19T18:37:12Z</updated>
    <published>2010-01-19T17:53:28Z</published>
    <summary type="html">&lt;p&gt;jBPM package provided ant-based installed with bunch of targets. Main
  target &lt;strong&gt;demo.setup.jboss&lt;/strong&gt;   supposed to do everything
  for you:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Download and install jBoss server (5.0 by default);&lt;/li&gt;
  &lt;li&gt;Download and install eclipse;&lt;/li&gt;
  &lt;li&gt;Install jBPM service and demo applications into jBoss;&lt;/li&gt;
  &lt;li&gt;Install GPD into Eclipse;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;But, in my case I do not need it - I've already have JBoss 5.1
  installed and want to use it. As well, as I've already have Eclipse,
  no needs to install another one.&lt;/p&gt;
&lt;p&gt;So, here is small set of instructions how to run new jBPM 4.3 into
  existed JBoss 5.1 installation.&lt;/p&gt;
&lt;p&gt;In examples bellow I suppose JBoss installed in some
  &lt;em&gt;&amp;lt;path-to-jboss&amp;gt;&lt;/em&gt; and jbpm unzipped into some &lt;em&gt;&amp;lt;path-to-jbpm&amp;gt;&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Change configuration files&lt;/h2&gt;
&lt;p&gt;To perform installation you need to change a little bit &lt;em&gt;&amp;lt;path-to-jbpm&amp;gt;/install/build.xml&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;
  &amp;lt;property name=&amp;quot;jboss.version&amp;quot; value=&amp;quot;&lt;strong&gt;5.1.0.GA&lt;/strong&gt;&amp;quot; /&amp;gt;
  &amp;lt;property name=&amp;quot;jboss.parent.dir&amp;quot; value=&amp;quot;${jbpm.home}&amp;quot; /&amp;gt;
  &amp;lt;property name=&amp;quot;jboss.home&amp;quot; value=&amp;quot;&lt;em&gt;&amp;lt;path-to-jboss&amp;gt;&lt;/em&gt;&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;So, we will tell jBPM istall scripts to use your JBoss server&lt;/p&gt;
&lt;h2&gt;Change DB configuration&lt;/h2&gt;
&lt;p&gt;By default, jBPM configured to use HSQL, what is OK in case we are
  using JBoss server. But, jBPM supposed own HSQL server to be run. Do
  you really need it? In my case I've prefer to use same way as used in
  server for DefaultDS. So, we need to edit &lt;em&gt;&amp;lt;path-to-jbpm&amp;gt;/install/jdbc/hsqldb.properties&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;
jdbc.driver=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:&lt;strong&gt;&lt;em&gt;&amp;lt;path-to-jboss&amp;gt;&lt;/em&gt;&lt;/strong&gt;/server/default/data/hypersonic/jbpmDB
jdbc.username=sa
jdbc.password=
&lt;/pre&gt;
&lt;p&gt;As result jbpmDB will be created in same folder as default localDB&lt;/p&gt;
&lt;p&gt;Of course, if you want to use some other DB - like MySQL or
  PostgreSQL you will need to make your changes accordenly&lt;/p&gt;
&lt;h2&gt;Create DB&amp;nbsp;Schema&lt;/h2&gt;
&lt;p&gt;Simple run in your &lt;em&gt;&amp;lt;path-to-jbpm&amp;gt;/install&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;
# ant create.jbpm.schema
&lt;/pre&gt;
&lt;h2&gt;Install jBPM&lt;/h2&gt;
&lt;p&gt;Now to install jBPM do:&lt;/p&gt;
&lt;pre&gt;
# ant install.jbpm.into.jboss
&lt;/pre&gt;
&lt;h2&gt;&amp;nbsp;Install Example Data&lt;/h2&gt;
&lt;p&gt;If you like - you can add example data (users and processes) into DB
  (JBoss server should be stopped during this actions):&lt;/p&gt;
&lt;pre&gt;
# ant load.example.identities
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;In my cases it is reported 14 SQL statements were executed, but
  it is not created required users (I do not know why), so, I had to do
  it by hand:&lt;/p&gt;
&lt;p&gt;Run HSQL Database Manager:&lt;/p&gt;
&lt;pre&gt;
# ant hsqldb.databasemanager
&lt;/pre&gt;
&lt;p&gt;Connect it to my DB at jdbc:hsqldb:&lt;strong&gt;
    &lt;em&gt;&amp;lt;path-to-jboss&amp;gt;&lt;/em&gt;&lt;/strong&gt;/server/default/data/hypersonic/jbpmDB&lt;/p&gt;
&lt;p&gt;Run SQL statements from &lt;em&gt;&amp;lt;path-to-jbpm&amp;gt;/install/src/demo/example.identities.sql&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Run Server, Validate everything working&lt;/h2&gt;
&lt;p&gt;Now, you can run your server: jbpm-console will be available at
  http://localhost:8080/jbpm-console and you can login as one of the
  users: alex, mike, peter, mary and password 'password'&lt;/p&gt;
&lt;p&gt;As result you have:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;JbpmDS datasource configured, pointed to HSQL DB;&lt;em&gt;
      &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;JbpmService configured;&lt;/li&gt;
  &lt;li&gt;jbpm-console &amp;amp; jbpmeditor web-applications deployed&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;As well as some other staff required for proper jBPM working&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-01-19T17:53:28Z</dc:date>
  </entry>
  <entry>
    <title>SVN Authentication by using username/passwords in Liferay DB (MySQL)</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/svn-authentication-by-using-username-passwords-in-liferay-db-mysql" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/svn-authentication-by-using-username-passwords-in-liferay-db-mysql</id>
    <updated>2010-01-19T12:45:19Z</updated>
    <published>2010-01-12T08:39:48Z</published>
    <summary type="html">&lt;p&gt;Last days I've worked on SVN repositories setup on emforge.net and of
  course I've wanted to use same username/passwords for user
  authentication in SVN as used to login into EmForge Portal.&lt;/p&gt;
&lt;p&gt;After googling a little bit I found what I need: mod-auth-mysql -
  module for Apache allowed to perform authentication with using data in MySQL&amp;nbsp;DB.&lt;/p&gt;
&lt;p&gt;Starting links I've used here:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;a href="http://dev.e-taxonomy.eu/trac/wiki/ApacheMySQLAuthentication"&gt;dev.e-taxonomy.eu/trac/wiki/ApacheMySQLAuthentication&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;a href="http://www.howtoforge.com/mod_auth_mysql_apache2_debian"&gt;www.howtoforge.com/mod_auth_mysql_apache2_debian&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;http://maff.ailoo.net/2009/03/authenticate-apache-against-redmine-with-authmysql/&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So, to setup svn authentication (ok, any authentication in apache
  server) used same usernames/password as in Liferay Portal you need:&lt;/p&gt;
&lt;h3&gt;Setup SVN Repository&lt;/h3&gt;
&lt;p&gt;Of course you need to create svn repository and add it's
  configuration into dav_svn.conf. I'm avoiding here these topics - hope
  it is well-known how to do.&lt;/p&gt;
&lt;p&gt;Also you need to setup and enable mod-auth-mysql module for apache
  server. It depends from your OS used, so, also not covered here.&lt;/p&gt;
&lt;p&gt;Then in your svn-location in dav_svn.conf&amp;nbsp; for specific
  repository you need to setup authentication against mysql DB&lt;/p&gt;
&lt;pre&gt;
  Require valid-user
  # disable password-file based authentication
  #AuthUserFile /vol/svn/passwd
  AuthUserfile /dev/null
  # authenticate against mysql DB
  AuthBasicAuthoritative Off
  AuthMySQL On
  AuthMySQL_Authoritative      on
  AuthMySQL_Host &lt;em&gt;&amp;lt;mysql host&amp;gt;&lt;/em&gt;
  AuthMySQL_User &lt;em&gt;&amp;lt;mysql user name&amp;gt;&lt;/em&gt;
  AuthMySQL_Password &lt;em&gt;&amp;lt;mysql user password&amp;gt;&lt;/em&gt;
  AuthMySQL_DB &lt;em&gt;&amp;lt;portal db in mysql&lt;/em&gt;&lt;em&gt; server&amp;gt;&lt;/em&gt;
  AuthMySQL_Password_Table &lt;strong&gt;user_&lt;/strong&gt;
  AuthMySQL_Username_Field &lt;strong&gt;screenName&lt;/strong&gt;
  AuthMySQL_Password_Field &lt;strong&gt;password_&lt;/strong&gt;
  AuthMySQL_Encryption_Types &lt;strong&gt;SHA1Sum&lt;/strong&gt;
  AuthMySQL_Group_Table &lt;strong&gt;user_&lt;/strong&gt;
  AuthMySQL_Group_Field &lt;strong&gt;active_&lt;/strong&gt;
  Require group         &lt;strong&gt;1&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;This configuration setup connection to Liferay DB (you need use own
  host, db, user and password to connect), specified which table and
  fields to use for authentication.&lt;/p&gt;
&lt;p&gt;Also, it is filtered to allow authentication only for active users.&lt;/p&gt;
&lt;h3&gt;Change configuration in Liferay&lt;/h3&gt;
&lt;p&gt;Unfortunatelly, it is not enough to setup only SVN settings. Even
  both - Liferay and mod-auth-mysql - used &lt;strong&gt;SHA1&lt;/strong&gt; for
  password encoding, Liferay used &lt;strong&gt;base64&lt;/strong&gt; to digester
  encoded passwords, mod-auth-mysql used &lt;strong&gt;hex&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully, liferay also can use it - you need simple add option into
  your portal-ext.properties:&lt;/p&gt;
&lt;pre&gt;
passwords.digest.encoding=hex
&lt;/pre&gt;
&lt;h3&gt;Convert passwords&lt;/h3&gt;
&lt;p&gt;OK, for new Liferay installation it will work, but, in case you
  already have Liferay with many users, you need convert password from
  be digested by base64 to hex.&lt;/p&gt;
&lt;p&gt;Here is a code snippet you can use for such conversion (you can add
  it into StartUpAction for example - but, please, backup you DB before
  it will be run - if by some reason this code will run twice - data in
  DB become invalid):&lt;/p&gt;
&lt;pre&gt;
    private void convertPasswords() throws Exception {
        int count = UserLocalServiceUtil.getUsersCount();
        List&amp;lt;User&amp;gt; users = UserLocalServiceUtil.getUsers(0, count);
        Date now = new Date();
       
        for (User user : users) {
            if (user.getPasswordEncrypted()) {
                String oldPassword = user.getPassword();
               
                byte[] decodedPassword = com.liferay.portal.kernel.util.Base64.decode(oldPassword);
                String newPassword = String.valueOf(org.apache.commons.codec.binary.Hex.encodeHex(decodedPassword));
               
                UserLocalServiceUtil.updatePasswordManually(user.getUserId(),
                                                            newPassword,
                                                            true, false,
                                                            now);
            }
        }
    }&lt;/pre&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2010-01-12T08:39:48Z</dc:date>
  </entry>
  <entry>
    <title>Liferay 5.2.3 Amazon EC2 Image (AMI)</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-5-2-3-amazon-ec2-image-ami</id>
    <updated>2010-02-03T01:40:11Z</updated>
    <published>2009-12-23T23:12:06Z</published>
    <summary type="html">&lt;p&gt;After I've done some performance testing for Liferay on Amazon
  (actually, I've simple tested our EmForge.net) - I received some
  requests to provide AMI&amp;nbsp;with Liferay to play with.&lt;/p&gt;
&lt;p&gt;So - here it is:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;AMI ID&lt;/strong&gt;: &lt;span class="value"&gt;ami-b88c61d1&lt;/span&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;
      &lt;span class="value"&gt;AMI ID (EU Region)&lt;/span&gt;&lt;/strong&gt;
    &lt;span class="value"&gt;:&lt;/span&gt;
    &lt;strong&gt;
      &lt;span class="value" /&gt;&lt;/strong&gt;ami-0bddf67f&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Architecture&lt;/strong&gt;: i386&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;What's inside (in short)&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Ubuntu 9.10 (Latest public for a moment with latest updates) -
    actually this AMI is     based on official Ubuntu AMI;&lt;/li&gt;
  &lt;li&gt;Sun JDK 1.6;&lt;/li&gt;
  &lt;li&gt;Tomcat 6.0.20 as application system;&lt;/li&gt;
  &lt;li&gt;Apache 2.2.12 as front-end server (conneced to tomcat via mod_jk);&lt;/li&gt;
  &lt;li&gt;Liferay 5.2.3 (latest for a moment);&lt;/li&gt;
  &lt;li&gt;MySQL 5.1.37;&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;&amp;nbsp;How to Use&lt;/h2&gt;
&lt;p&gt;Since it is based on standard Ubuntu AMI - I'm highly recommend to
  read &lt;a
    href="https://help.ubuntu.com/community/EC2StartersGuide"&gt;Ubuntu EC2
    Starters Guide&lt;/a&gt; - everything described there correct for our AMI.
  In general - if you have everything setup - you may run instance with command:&lt;/p&gt;
&lt;pre&gt;
ec2-run-instances &lt;span class="value"&gt;ami-b88c61d1&lt;/span&gt; -k ec2-keypair&lt;/pre&gt;
&lt;p&gt;After it - wait some time - check your running instances - after
  instance started Liferay will be available at the default http port 80
  on running server.&lt;/p&gt;
&lt;h2&gt;What is inside (a little bit more detailed)&lt;/h2&gt;
&lt;p&gt;Tomcat was installed from Ubuntu repository - only few settings was
  changed to be able to run Liferay (disabled tomcat security, increased
  memory, changed list of folder used as catalina libs). Liferay itself
  deployed into tomcat and available at /var/lib/tomcat6/webapps/ROOT&lt;/p&gt;
&lt;p&gt;I've removed 7Coz hook and theme - so, actually you will have default
  liferay installation with some additional portlets (Chat, Mail, WOL)&lt;/p&gt;
&lt;p&gt;You can login into Liferay as admin wih default username/password
  (test@liferay.com/test) - &lt;span style="color: rgb(255,0,0);"&gt;Please
    change it!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Liferay is configured to use local MySQL as DB and /var/lib/liferay
  as liferay home (for hot-deploy, lucene indexes and rest Liferay files)&lt;/p&gt;
&lt;p&gt;Connection to DB done via JNDI datasource, so, connection settings
  you can find in /etc/tomcat6/context.xml&lt;/p&gt;
&lt;p&gt;MySQL configured to store data in same instance memory - so, afer
  instance will be stopped - all data will lost. If you want to use this
  AMI in production - you need to change MySQL configuration to store
  data in ESB or to perform backups (for example via replications).&lt;/p&gt;
&lt;p&gt;MySQL root password is changeme - &lt;span
    style="color: rgb(255,0,0);"&gt;please change it&lt;/span&gt;!&lt;/p&gt;
&lt;p&gt;
  &lt;strong&gt;I've did not configured smtp server&lt;/strong&gt; on the instance.
  So, sending emails will not work - please configure your Liferay to
  use some external smtp server or install/configure postfix&lt;/p&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;p&gt;Feel free to use this AMI - I hope it will be helpful for you. I will
  be happy to get any comments/feedack - you can leave comments for this
  post (required register on the site).&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-12-23T23:12:06Z</dc:date>
  </entry>
  <entry>
    <title>Liferay on Amazon EC2 Performance testing results</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-on-amazon-ec2-performance-testing-results" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-on-amazon-ec2-performance-testing-results</id>
    <updated>2009-12-07T14:45:52Z</updated>
    <published>2009-12-07T14:14:04Z</published>
    <summary type="html">&lt;p&gt;Today, during our weekly meeting &lt;a
  href="http://www.emforge.net/web/kwiecienm/home"&gt;Marek&lt;/a&gt; told, what
  some of his friends reported him about performance problems, they met
  with Liferay - in some cases project was failed exactly because it was
  not possible to resolve performance these problems. But - they did not
  remember exact version of Liferay - it was quite long time ago.&lt;/p&gt;
&lt;p&gt;So, we decided to make performance testing of our current emforge.net
  installation - run on the small Amazon EC2 instance (cheapest one) and
  create &lt;a
    href="http://www.emforge.net/web/emforge-portal/tasks/-/tasks/622"&gt;User
  Story&lt;/a&gt; for it&lt;/p&gt;
&lt;p&gt;Initially we planned to write tests on JMeter, but after some
  investigation I found it is much simpler to use &lt;a
  href="http://loadstorm.com/"&gt;LoadStorm&lt;/a&gt; - free account allowed to
  test up to 50 users - what was quite enough for us - I'm not expecting
  bigger traffic in nearest time.&lt;/p&gt;
&lt;p&gt;I will not explain here how to create test-case in LoadStrom - just
  will say - it is quite easy - after spending about 15 minutes for
  registration and test-case creation I've prepared test visited 15
  pages covered most tools used in EmForge: Wiki, Blog, Forum,
  Activities, User Account, Tasks and so on.&lt;/p&gt;
&lt;p&gt;System Configuration is:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Amazon EC2 small instance&lt;/li&gt;
  &lt;li&gt;Ubuntu 9.10&lt;/li&gt;
  &lt;li&gt;Java: Sun JDK 1.6&lt;/li&gt;
  &lt;li&gt;Liferay 5.2.3 with mostly default settings&lt;/li&gt;
  &lt;li&gt;Server: Tomcat 6.0.20&lt;/li&gt;
  &lt;li&gt;DB: MySQL - db stored on EBS&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Quite standard configuration without any special settings done for
  performance by hand comparing default liferay configuration - so, we
  can say it is default liferay configuration.&lt;/p&gt;
&lt;p&gt;Here is results:&lt;/p&gt;
&lt;table border="1" cellpadding="3" cellspacing="0"&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Response&lt;br /&gt;(average)&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Errors&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Requests&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;RPS&lt;br /&gt;(average)&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;RPS&lt;br /&gt;&amp;nbsp; (peak)&lt;/span&gt; &amp;nbsp;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Throughput&lt;br /&gt;(average)&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Throughput&lt;br /&gt;(peak)&lt;/span&gt;&lt;/th&gt;
      &lt;th&gt;
        &lt;span style="font-size: small;"&gt;Total&lt;br /&gt;Transfer&lt;/span&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;span style="font-size: small;"&gt;
          &lt;strong&gt;HTML&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;td
        align="right"&gt;0.167&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;td
        align="right"&gt;1,674&lt;/td&gt;&lt;td align="right"&gt;0.8&lt;/td&gt;&lt;td
        align="right"&gt;1.5&lt;/td&gt;&lt;td align="right"&gt;15&lt;/td&gt;&lt;td
        align="right"&gt;29&lt;/td&gt;&lt;td align="right"&gt;31 MB&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;span style="font-size: small;"&gt;
          &lt;strong&gt;Other&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;td
        align="right"&gt;0.077&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;td
        align="right"&gt;2,092&lt;/td&gt;&lt;td align="right"&gt;1.0&lt;/td&gt;&lt;td
        align="right"&gt;1.8&lt;/td&gt;&lt;td align="right"&gt;144&lt;/td&gt;&lt;td
        align="right"&gt;269&lt;/td&gt;&lt;td align="right"&gt;303 MB&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;span style="font-size: small;"&gt;
          &lt;strong&gt;Total&lt;/strong&gt;&lt;/span&gt;&lt;/td&gt;&lt;td
        align="right"&gt;0.117&lt;/td&gt;&lt;td align="right"&gt;0&lt;/td&gt;&lt;td
        align="right"&gt;3,766&lt;/td&gt;&lt;td align="right"&gt;1.7&lt;/td&gt;&lt;td
        align="right"&gt;3.3&lt;/td&gt;&lt;td align="right"&gt;158&lt;/td&gt;&lt;td
        align="right"&gt;298&lt;/td&gt;&lt;td align="right"&gt;334 MB&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So, average page generation time is 0.167 seconds, static resources
  average time is 0.077 seconds - what is good enough I hope.&lt;/p&gt;
&lt;p&gt;Here is some charts:&lt;/p&gt;
&lt;p&gt;
  &lt;img alt="" height="405"
    src="http://www.emforge.org/image/image_gallery?uuid=fb4b3ced-f838-4a2e-9ae4-3f956f0911cb&amp;amp;groupId=10146&amp;amp;t=1260196430931" width="765" /&gt;&lt;/p&gt;
&lt;p&gt;This chart shows how number of users and requests per second is
  growing. Maximum is about 50 users and 3 request per second&lt;/p&gt;
&lt;p&gt;Second chart display response time&lt;/p&gt;
&lt;p&gt;
  &lt;img align="middle" alt="" height="393"
    src="http://www.emforge.org/image/image_gallery?uuid=719b9ceb-7a61-475d-b28e-bcee1a946682&amp;amp;groupId=10146&amp;amp;t=1260196706735" width="762" /&gt;&lt;/p&gt;
&lt;p&gt;Average time is flat - that means system is not loading 100% and
  number of users is not affected on response time.&lt;/p&gt;
&lt;p&gt;There are one peak of maximum time (5 secs) - but it is because at
  this time Garbage Collector was run.&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;OK, it is hard to say 50 users is a serious testing, but from another
  side Liferay run on smallest Amazon instance without any additional
  settings - and, hand this amount of users without any problem.&lt;/p&gt;
&lt;p&gt;I hope this information may be helpful for anybody, interested in
  liferay performance. Any comments as always welcomed!&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-12-07T14:14:04Z</dc:date>
  </entry>
  <entry>
    <title>jBPM vs Intalio in 2 words</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/jbpm-vs-intalio-in-2-words" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/jbpm-vs-intalio-in-2-words</id>
    <updated>2009-12-04T20:16:04Z</updated>
    <published>2009-12-04T20:06:16Z</published>
    <summary type="html">&lt;p&gt;OK, not sure will able to compare them in 2 words, but will try to do
  it in short:&lt;/p&gt;
&lt;p&gt;From my point of view, &lt;a
  href="http://www.jboss.org/jbossjbpm/"&gt;jBPM&lt;/a&gt; is great tool for
  &lt;strong&gt;developers&lt;/strong&gt;. If you need embedded workflow solution,
  with easy to access to java-code, spring beans, sql, task forms from
  your process definition (I'm not taling about testing processes with
  JUnit tests!) - jBPM is defenetly right solution for you.&lt;/p&gt;
&lt;p&gt;
  &lt;a href="http://www.intalio.com/products/bpm/"&gt;Intalio&lt;/a&gt; - is not so
  easy to use as embeddable solution, processes operated only (in
  general) with web-service, so, even for any simple operations in java
  (or sql) you will need to define Web-Services. But it is much more
  powerful (I think in all context - starting from more poewrful
  designer and finishing with server).&lt;/p&gt;
&lt;p&gt;So, both are goos, but what is better - depends form your needs.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-12-04T20:06:16Z</dc:date>
  </entry>
  <entry>
    <title>Very Promised Liferay 5.3 RoadMap</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/very-promised-liferay-5-3-roadmap" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/very-promised-liferay-5-3-roadmap</id>
    <updated>2009-12-04T11:56:03Z</updated>
    <published>2009-12-04T11:20:26Z</published>
    <summary type="html">&lt;p&gt;Just reviewed &lt;a
    href="http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/RoadMap"&gt;Liferay
    5.3 RoadMap&lt;/a&gt; and wanted to write about most expected features -
  but, looks like most of them are VERY expected. It should be really
  huge step forward.&lt;/p&gt;
&lt;p&gt;But still- from this list I found some quite important (at least for me):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;strong&gt;Possibility to use JPA&lt;/strong&gt; - I think it is first - but
    I hope not last step for close integration with J2EE application
    server. In one of my &lt;a
      href="http://www.emforge.net/web/akakunin/blogs/-/blogs/why-to-use-webspace"&gt;previous
    post&lt;/a&gt; I pointed to weak reusing of functionality provided by J2EE
    server (in case then Liferay run not in Tomcat or Jetty). Looks like
    it should be changed in future&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Maven2&lt;/strong&gt; - if it will be possible to use maven-based
    projects for Liferay development (including ServiceBuilder
    functionality) - it will be great!&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Allow Plugins to publish JSON and SOAP web services&lt;/strong&gt;
    - also good improvement - I do not like to use Ext Environment, but
    - exoporting services via JSON or SOAP was possible only in Ext
    Environment (even I do not want to change basic Liferay
    functionality). Hope it will work well in 5.3 even in Plugins&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;Integration with Gmail &amp;amp; Google Docs&lt;/strong&gt; - I think
    it may be very helpful in some projects;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;jBPM support and ability to switch to Intalio&lt;/strong&gt; - I
    never used jBPM - but going to use soon. Liferay already had had
    some kind of integration - but not directly (via Mule) and as I
    understand from forums - very painful for configuration. I think it
    is important to have some workflow functionality in Portal
    out-of-box without additional configurations;&lt;/li&gt;
  &lt;li&gt;
    &lt;strong&gt;JasperReports &amp;amp; BIRT support&lt;/strong&gt; - another task I
    planned to touch in some nearest feature - if it will be ready to
    use out-of-box - it should save me a lot of time!&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So, let's wait for 2010 (planned release day) - I hope to get good
  New&amp;nbsp;Year present from Liferay team :)&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-12-04T11:20:26Z</dc:date>
  </entry>
  <entry>
    <title>Autologin from custom portlet</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/autologin-from-custom-portlet" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/autologin-from-custom-portlet</id>
    <updated>2009-12-03T22:59:07Z</updated>
    <published>2009-12-03T22:56:03Z</published>
    <summary type="html">&lt;p&gt;Liferay wiki has &lt;a
    href="http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Customizing+the+portal+login+page"&gt;page
    explained how to customize login page&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;But let's say you need to autologin during some user-actions in some
  of your portlets? And, it happens, you are working in plugin
  environment - so, cannot access some very helpful, but internal
  Liferay classes (like LoginUtil)?&lt;/p&gt;
&lt;p&gt;here is small sample how to login - it simple redirects to the login
  action in standard login portlet. It looks like more a hack - but it works!&lt;/p&gt;
&lt;pre&gt;
public class LoginPortlet extends JSPPortlet {
    /** process login action
     *
     * @param actionRequest
     * @param actionResponse
     * @throws IOException
     * @throws PortletException
     */
    public void login(ActionRequest actionRequest,
                      ActionResponse actionResponse) throws IOException, PortletException {
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String login = ParamUtil.getString(actionRequest, &amp;quot;login&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String password = ParamUtil.getString(actionRequest, &amp;quot;password&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; // go o the login url
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ThemeDisplay td = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; String loginUrl = td.getURLPortal() + &amp;quot;/web/guest/home?p_p_id=58&amp;amp;&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;p_p_lifecycle=1&amp;amp;&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;p_p_state=normal&amp;amp;&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;p_p_mode=view&amp;amp;&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;saveLastPath=0&amp;amp;&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;_58_struts_action=%2Flogin%2Flogin&amp;quot; +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;quot;&amp;amp;login=&amp;quot; + login +
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;&amp;amp;password=&amp;quot; + password;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; actionResponse.sendRedirect(loginUrl);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-12-03T22:56:03Z</dc:date>
  </entry>
  <entry>
    <title>Liferay with JBoss Cache</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-with-jboss-cache" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/liferay-with-jboss-cache</id>
    <updated>2009-11-27T20:55:32Z</updated>
    <published>2009-11-27T20:42:43Z</published>
    <summary type="html">&lt;p&gt;Last days I'm working on Liferay based project with JBossAS 5.1 used
  as server.&lt;/p&gt;
&lt;p&gt;Since during redeploy I've met strange problems from ehcache used as
  second-level cache (in general it works well, but looks like during
  redeploy it cannot find some classes/methods from Hibernate) I've
  decided to try to use JBoss Cache as second-level cache for hibernate.&lt;/p&gt;
&lt;p&gt;OK, first try is failed - I did not managed to make it working - but
  I hope I will able soon - any comments or suggestions will be very helpful!&lt;/p&gt;
&lt;p&gt;Until now - to make Liferay to use JBoss Cache - I changed
  portal.properties (in my case, since I'm working in ext-environment
  I've edited portal-ext.properties) to contains:&lt;/p&gt;
&lt;pre&gt;
hibernate.cache.provider_class=
hibernate.cache.region.factory_class=org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory
hibernate.cache.region.jbc2.cachefactory=java:CacheManager
hibernate.cache.region.jbc2.cfg.entity=mvcc-entity
hibernate.cache.region.jbc2.cfg.query=local-query
hibernate.cache.region_prefix=tempdb
&lt;/pre&gt;
&lt;p&gt;Don't have clear ideas about all these configurations - just got it
  from Hibernate + JBoss Cache tutorial.&lt;/p&gt;
&lt;p&gt;His settings said to use cache from JBoss service
  &lt;strong&gt;CacheManager&lt;/strong&gt; (got from JNDI) - what is nice -&amp;nbsp;
  it is possible to configure cache to work (for example) clustering on
  server-level, and use this cache in different applications.&lt;/p&gt;
&lt;p&gt;Also - note:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;JBoss Cache and CacheManager service is included (by default) only
    into &lt;strong&gt;all&lt;/strong&gt; configuration, so, you need run JBoss in
    this configuration and deploy Liferay into it&lt;/li&gt;
  &lt;li&gt;If you are using ant-script to clean/deploy ext-environment -
    please be sure it is not removed libraries from
    &amp;lt;jboss&amp;gt;/server/all/lib folder - if removed - please return
    them back&lt;/li&gt;&lt;/ol&gt;
&lt;h3&gt;Why it is failed?&lt;/h3&gt;
&lt;p&gt;So, as I told - in my case it is not working. During starting Liferay
  I've got exception:&lt;/p&gt;
&lt;pre&gt;
Caused by: org.hibernate.cache.CacheException: unsupported access type [read-write]
    at org.hibernate.cache.jbc2.entity.EntityRegionImpl.buildAccessStrategy(EntityRegionImpl.java:66)
    at org.hibernate.impl.SessionFactoryImpl.&amp;lt;init&amp;gt;(SessionFactoryImpl.java:256)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1327)
&lt;/pre&gt;
&lt;p&gt;I've checked sources - yes, this class supports only
  AccessType.READ_ONLY &amp;amp; AccessType.TRANSACTIONAL. There is TODO to
  add support for READ_WRITE - but - looks like it is not implemented yet.&lt;/p&gt;
&lt;p&gt;As I checked - for all classes in liferay mappings - read-write
  strategy is used for class-cache, so, it is failed to use JBoss Cache...&lt;/p&gt;
&lt;h3&gt;How to fix?&lt;/h3&gt;
&lt;p&gt;I do not have clear idea for now. I see few steps:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Understand why read-write is not supported - and is it difficult
    to add such support?&lt;/li&gt;
  &lt;li&gt;use wrapper - to convert requested read-write access-type into
    read-only - but - it need to be investigated - probably such change
    of strategy will produce ome problems during Liferay working - or
    big performance degradation.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;OK, at least for now it is not top priority for me - so, leave it for
  some future time.&lt;/p&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-11-27T20:42:43Z</dc:date>
  </entry>
  <entry>
    <title>Ajax based File-Upload for PHP 5.2 under Win32 system</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/ajax-based-file-upload-for-php-5-2-under-win32-system" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/ajax-based-file-upload-for-php-5-2-under-win32-system</id>
    <updated>2009-11-21T17:15:01Z</updated>
    <published>2009-11-21T17:08:28Z</published>
    <summary type="html">&lt;p&gt;If you will look into Google for words 'file-upload, ajax, php' you
  will find a lot of links to the different articles described how to do
  it. But there were several problems:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;For versions less then 5.2 you needed to patch PHP&lt;/li&gt;
  &lt;li&gt;For version 5.2 you need to use &lt;a class="external"
      href="http://pecl.php.net/package/uploadprogress"&gt;Upload Progress
      PHP Extension&lt;/a&gt;. It was possible to use this extension without
    any patching for PHP, but... It doesn't worked for Win32 due to &lt;a
      class="external"
      href="http://pecl.php.net/bugs/bug.php?id=9584"&gt;this problem&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Also, on the &lt;a class="external"
      href="http://blog.liip.ch/archive/2006/09/28/upload-progress-meter-extension-for-php-5-2.html"&gt;uploadprogress
      extension developer blog&lt;/a&gt; a lot of reports about problems with
    this extension under windows.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We had a task to implement uploading of several files with PHP and
  displaying progress-bar on windows... As result -&lt;a
    href="https://sourceforge.net/projects/emforge/files/php_ajax_upload/emdev_upload_demo.zip/download"&gt;
    this file&lt;/a&gt; contains solution for this task. I will just describe
  major ideas:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Ajax-based upload itself implemented with using iframe (standard
    solution for this task);&lt;/li&gt;
  &lt;li&gt;demo.html contains all client code - it is also used &lt;a
      class="external" href="http://www.prototypejs.org/"&gt;prototype
      java-script framework&lt;/a&gt; - big friend for web-developers;&lt;/li&gt;
  &lt;li&gt;receiving the file is implemented in uploader.php;&lt;/li&gt;
  &lt;li&gt;For getting upload-progress information we are using
    &lt;b&gt;Ajax.PeriodicalUpdater&lt;/b&gt; Prototype function on client-side and
    monitor.php - on server-side. Monitor.php simple get information
    from uploadprogress extension;&lt;/li&gt;
  &lt;li&gt;To make uploadprogress extension working under windows we had to
    fix it a little bit. Source code and result dll included in separate
    attachments &lt;a
    href="https://sourceforge.net/projects/emforge/files/php_ajax_upload/uploadprogress-0.3.0-emdev.zip/download"&gt;here&lt;/a&gt;.
    I hope this fixes will be included by extension developer and
    correct version will be included into php destribution by default: &lt;ol&gt;
      &lt;li&gt;Removed &lt;b&gt;PHP_EXPORTS&lt;/b&gt; define in project settings;&lt;/li&gt;
      &lt;li&gt;Use fopen instead of (todo). We are not very familiar with PHP
        extensions development, but in our case this function caused
        exceptino then we tried to use opened file with fprintf and fget;&lt;/li&gt;
      &lt;li&gt;Delete target file before renaming;&lt;/li&gt;
      &lt;li&gt;Cast time_t to the integers;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;
  &lt;li&gt;It is important to set &lt;b&gt;No-Cache&lt;/b&gt; options in monitor.php - we
    got this code working under FireFox but it defently did not work
    under IE (both 6.0 and 7.0) until we did not included this option.&lt;/li&gt;&lt;/ol&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-11-21T17:08:28Z</dc:date>
  </entry>
  <entry>
    <title>Ajax Based File-Upload for Java</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/ajax-based-file-upload-for-java" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/ajax-based-file-upload-for-java</id>
    <updated>2009-11-21T16:58:36Z</updated>
    <published>2009-11-21T16:45:06Z</published>
    <summary type="html">&lt;table width="100%" style="table-layout: fixed;"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;
&lt;p&gt;Today everything in the web is about AJAX. If you want to have a fashionable site with user-friendly interface, you have to use it. HTML hasn't been designed to be a user interface, so we have to provide some tricks and hacks to make it look like real GUI. A visual response is one of the things that HTML lacks, especially for the file uploading. Googling around i was lead to the article &lt;a href="http://www.ioncannon.net/java/38/ajax-file-upload-progress-for-java-using-commons-fileupload-and-prototype/" class="external"&gt;&amp;quot;AJAX file upload progress for Java using commons fileupload and prototype&amp;quot; by carson&lt;/a&gt; The last comment about the new version of file upload listener looked very promising and i decided to check it out.&lt;/p&gt;
&lt;h3 id="section-AjaxBasedFileUploadForJava-ServerSideCode"&gt;Server side code&lt;/h3&gt;
&lt;p&gt;Main idea: Use commons-fileupload-1.2 &lt;a title="Create &amp;quot;ProgressListener&amp;quot;" href="http://www.emforge.org/edit/ProgressListener" class="createpage"&gt;ProgressListener&lt;/a&gt; class to monitor the upload of files dynamically.&lt;/p&gt;
&lt;p&gt;The first thing you need is &lt;a href="http://jakarta.apache.org/commons/fileupload/" class="external"&gt;Apache Commons FileUpload&lt;/a&gt;,  go there and grab the new binaries for version 1.2.  Add it to your project. You will also need to update commons-io library to version 1.3&lt;/p&gt;
&lt;p&gt;If you're using &lt;a href="http://maven.apache.org/" class="external"&gt;Maven&lt;/a&gt;, just add or change dependencies if they already exist in your pom.xml:&lt;/p&gt;
&lt;pre&gt;
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;commons-io&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;commons-io&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.3&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;   
    &amp;lt;dependency&amp;gt;
      &amp;lt;groupId&amp;gt;commons-fileupload&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;commons-fileupload&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;1.2&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Create a servlet that will handle file uploads:&lt;/p&gt;
&lt;pre&gt;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
public class TestUpload extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    public TestUpload() {
        super();
    }      
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }      
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }                  
}
&lt;/pre&gt;
&lt;p&gt;Add it to servlet mapping (web.xml), don't forget to change package name:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;servlet&amp;gt;
    &amp;lt;description&amp;gt;Servlet for test file uploads&amp;lt;/description&amp;gt;
    &amp;lt;display-name&amp;gt;TestUpload&amp;lt;/display-name&amp;gt;
    &amp;lt;servlet-name&amp;gt;TestUpload&amp;lt;/servlet-name&amp;gt;      
    &amp;lt;!-- TODO: add here fully qualified TestUpload class name! --&amp;gt;
    &amp;lt;servlet-class&amp;gt;ru.emdev.EmForge.web.TestUpload&amp;lt;/servlet-class&amp;gt;
&amp;lt;/servlet&amp;gt;
&amp;lt;servlet-mapping&amp;gt;
    &amp;lt;servlet-name&amp;gt;TestUpload&amp;lt;/servlet-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/testupload&amp;lt;/url-pattern&amp;gt;
&amp;lt;/servlet-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Create a class that implements org.apache.commons.fileupload.ProgressListener&lt;/p&gt;
&lt;pre&gt;
public class UploadListener implements org.apache.commons.fileupload.ProgressListener {
    private volatile long bytesRead;
    private volatile long contentLength;
    private volatile long item;  
    public UploadListener() {
        bytesRead = 0;
        contentLength = 0;
        item = 0;
    }
    public void update(long i_bytesRead, long i_contentLength, int i_item) {
        bytesRead = i_bytesRead;
        contentLength = i_contentLength;
        item = i_item;
    }
    public long getBytesRead() {
        return bytesRead;
    }
    public long getContentLength() {
        return contentLength;
    }
    public long getItem() {
        return item;
    }
}
&lt;/pre&gt;
&lt;p&gt;Add this piece of code into doPost method of the TestUpload servlet:&lt;/p&gt;
&lt;pre&gt;
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response.setContentType(&amp;quot;text/html&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // create file upload factory and upload servlet
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileItemFactory factory = new DiskFileItemFactory();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServletFileUpload upload = new ServletFileUpload(factory);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // set file upload progress listener
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UploadListener listener = new UploadListener();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpSession session = request.getSession();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; session.setAttribute(&amp;quot;LISTENER&amp;quot;, listener);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // upload servlet allows to set upload listener
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; upload.setProgressListener(listener);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List items = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FileItem fileItem = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String filename = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // iterate over all uploaded files
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items = upload.parseRequest(request);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (Iterator i = items.iterator(); i.hasNext();) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fileItem = (FileItem) i.next();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!fileItem.isFormField()) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(fileItem.getSize()&amp;gt;0) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // code that handle uploaded fileItem
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // don't forget to delete uploaded files after you done with them! Use fileItem.delete();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // indicate that the upload was successfull
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response.getWriter().write(&amp;quot;upload successful&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (FileUploadException e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response.getWriter().write(e.getMessage());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; response.getWriter().write(e.getMessage());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } finally {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; session.removeAttribute(&amp;quot;LISTENER&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/pre&gt;
&lt;p&gt;This part will handle the file upload process. When request for file comes to doUpload function,  we create and attach UploadListener to ServletFileUpload object. It allows us to monitor the upload progress.&lt;/p&gt;
&lt;p&gt;And now the doGet method:&lt;/p&gt;
&lt;pre&gt;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    PrintWriter out = response.getWriter();
               
    HttpSession session = null;
    UploadListener listener = null;
    long contentLength = 0;
               
    if ( ((session = request.getSession()) == null) ||
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((listener = (UploadListener)session.getAttribute(&amp;quot;LISTENER&amp;quot;)) == null) ||&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((contentLength = listener.getContentLength())&amp;lt;1)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.write(&amp;quot;&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.close();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; response.setContentType(&amp;quot;text/html&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp; long percentComplite = ((100*listener.getBytesRead()) / contentLength);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; out.print(percentComplite);
&amp;nbsp;&amp;nbsp;&amp;nbsp; out.close();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
}
&lt;/pre&gt;
&lt;p&gt;In this method we can poll our upload listener for the progress of upload. In our case we want to find out  how much of file has been uploaded, in percents. We just get listener that has been binded to our session,  poll it for the number of uploaded bytes and calculate the result.&lt;/p&gt;
&lt;h3 id="section-AjaxBasedFileUploadForJava-ClientPartOfCode"&gt;Client part of code&lt;/h3&gt;
&lt;p&gt;Main idea: use IFRAME as a target for uploading files; as the result, the page won't be reloaded.  Use AJAX to periodically poll progress of upload and draw progress bar.&lt;/p&gt;
&lt;p&gt;Create simple HTML page.&lt;/p&gt;
&lt;pre&gt;
&amp;lt;HTML&amp;gt;
&amp;lt;HEAD&amp;gt;
&amp;lt;/HEAD&amp;gt;
&amp;lt;BODY&amp;gt;
&amp;lt;/BODY&amp;gt;
&amp;lt;/HTML&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Add inside &amp;lt;BODY&amp;gt;&amp;lt;/BODY&amp;gt; tags iframe and form below it, exactly in that order.&lt;/p&gt;
&lt;pre&gt;
&amp;lt;iframe id=&amp;quot;trgID&amp;quot; name=&amp;quot;uploadTrg&amp;quot; height=&amp;quot;0&amp;quot; width=&amp;quot;0&amp;quot; frameborder=&amp;quot;0&amp;quot; scrolling=&amp;quot;yes&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;form id=&amp;quot;myFrm&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; method=&amp;quot;post&amp;quot; target=&amp;quot;uploadTrg&amp;quot; action=&amp;quot;testupload&amp;quot; onsubmit=&amp;quot;submitPostUsingAjax();&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;input type=&amp;quot;file&amp;quot; name=&amp;quot;txtFile0&amp;quot; id=&amp;quot;txtFile0&amp;quot;&amp;gt;&amp;lt;/input&amp;gt;&amp;lt;br&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;input type=&amp;quot;submit&amp;quot; id=&amp;quot;submitID1&amp;quot; name=&amp;quot;submit&amp;quot; value=&amp;quot;Upload&amp;quot;&amp;gt;&amp;lt;/input&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Here we specify the form &amp;quot;action&amp;quot; that will send file data to our servlet, and the form &amp;quot;target&amp;quot; for the iframe name. Using of form attributes method=&amp;quot;post&amp;quot; and enctype=&amp;quot;multipart/form-data&amp;quot; is required too.  As the result, when we click on the &amp;quot;Upload&amp;quot; button, the request will be sent to &amp;quot;TestUpload&amp;quot; servlet,  the response will be written to iframe, and the code in javascript function submitPostUsingAjax() will be executed.&lt;/p&gt;
&lt;p&gt;Add hidden div for updating and the progress bar (just a table) below the form:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;div id=&amp;quot;uploadStatusDiv&amp;quot; style=&amp;quot;width:0px; height:0px; visibility:hidden;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;table id=&amp;quot;progressBar&amp;quot; width=&amp;quot;0px&amp;quot; style=&amp;quot;border:1px; width:0px; background-color: red; color:black; visibility:hidden; &amp;quot;&amp;gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now about monitoring part. I have used the prototype because it's a simple, clean, one-file solution for AJAX, DHTML manipulation and even more. Code also looks much more clean with it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.prototypejs.org/download" class="external"&gt;Download&lt;/a&gt; latest prototype from it's  &lt;a href="http://www.prototypejs.org/" class="external"&gt;offical site&lt;/a&gt;. When writing this article i used version 1.5.0&lt;/p&gt;
&lt;p&gt;Place prototype.js to the same place where your HMTL page is located and include  it to the top inside &amp;lt;HEAD&amp;gt;&amp;lt;/HEAD&amp;gt; tags:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;prototype.js&amp;quot;&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then add the following code:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // global object that contains Ajax.PeriodicalUpdater
&amp;nbsp;&amp;nbsp;&amp;nbsp; var updater;&amp;nbsp;
&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // main function for upload monitoring
&amp;nbsp;&amp;nbsp;&amp;nbsp; function submitPostUsingAjax() {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // get upload status
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updater = new Ajax.PeriodicalUpdater('uploadStatusDiv','testupload', {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; asynchronous:true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; frequency:1,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; method:'get',
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; onSuccess:function(request) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (request.responseText.length &amp;gt; 1) {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $('progressBar').style.visibility = 'visible';
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $('progressBar').style.width = request.responseText + '%';
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch(e) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert('submitPostUsingAjax() failed, reason: ' + e);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } finally {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // executes function after page loaded
&amp;nbsp;&amp;nbsp;&amp;nbsp; function addLoadEvent(func) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var oldonload = window.onload;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (typeof window.onload != 'function') {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.onload = func;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; window.onload = function() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; oldonload();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; func();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // this function will be executed after &amp;quot;target&amp;quot; IFRAME content changed
&amp;nbsp;&amp;nbsp;&amp;nbsp; function handleUploadFinished() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // stop updater manually
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (typeof updater != 'undefined') {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updater.stop();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updater = null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // observe IFrame object for &amp;quot;load&amp;quot; event to stop AJAX updater
&amp;nbsp;&amp;nbsp;&amp;nbsp; function observeFormSubmit() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // add event to observe upload target
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Event.observe('trgID', 'load', handleUploadFinished);
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // add event handler only after page loaded
&amp;nbsp;&amp;nbsp;&amp;nbsp; addLoadEvent(observeFormSubmit);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;lt;/script&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/pre&gt;
&lt;p&gt;The function submitPostUsingAjax() creates Ajax.PeriodicalUpdater that  will poll our servlet every second and retrives the progress of file upload in percent.  The parameter &amp;quot;uploadStatusDiv&amp;quot; Ajax.PeriodicalUpdater is needed only to receive the update events.&lt;/p&gt;
&lt;p&gt;The function addLoadEvent() is needed for attaching the listener to IFRAME object after it is created.  This function was taken from &lt;a href="http://www.dustindiaz.com/top-ten-javascript" class="external"&gt;Top 10 custom JavaScript functions of all time&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the handleUploadFinished() function AJAX updater will be stopped when the upload is finished or interrupted.&lt;/p&gt;
&lt;p&gt;After the page is loaded, IFRAME object will monitor the 'onload' event. When a user clicks on the &amp;quot;Upload&amp;quot; button, Ajax.PeriodicalUpdater will periodically poll our servlet for upload status and accordingly set the width of the progress bar.  After the upload has been finished, successfully or not, IFRAME content is changed, and we will stop AJAX updater manually.&lt;/p&gt;
&lt;p&gt;That's it, enjoy.&lt;/p&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-11-21T16:45:06Z</dc:date>
  </entry>
  <entry>
    <title>Implementing Captcha with JSF</title>
    <link rel="alternate" href="http://www.emforge.org/web/akakunin/blogs/-/blogs/implementing-captcha-with-jsf" />
    <author>
      <name>Alexey Kakunin</name>
    </author>
    <id>http://www.emforge.org/web/akakunin/blogs/-/blogs/implementing-captcha-with-jsf</id>
    <updated>2009-11-24T21:13:12Z</updated>
    <published>2009-11-21T16:14:57Z</published>
    <summary type="html">&lt;table width="100%" style="table-layout: fixed;"&gt;     &lt;tbody&gt;         &lt;tr&gt;             &lt;td&gt;&lt;p&gt;In registration form, used in &lt;a href="http://www.emforge.org/project/EmForge" class="wikipage"&gt;EmForge&lt;/a&gt; we           needed   Captcha-implementation to save it from robots. I           looked into internet   -but did not found any ready solution           for JSF-based project - so, here   is one.&lt;/p&gt;             &lt;h3 id="section-ImplementingCaptchaWithJSF-CaptchaGeneration"&gt;Captcha Generation&lt;/h3&gt;             &lt;p&gt;For generating Captcha we used&lt;a href="http://jcaptcha.sourceforge.net/" class="external"&gt; JCaptcha&lt;/a&gt;           library. It is   quite powerfull library with many features -           and one of them -   generation and validation of captcha images.&lt;/p&gt;             &lt;h3&gt;Adding JCaptcha into Project.&lt;/h3&gt;             &lt;p&gt;Since both: EmForge and   &lt;a href="http://jcaptcha.sourceforge.net/" class="external"&gt;JCaptcha&lt;/a&gt;           are Maven based projects and I found   jcaptcha in the public           maven repositories it was quite easy to add   jcaptcha into           project - just add it into projects dependency in             pom.xml&lt;span style="text-decoration: underline;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;             &lt;pre&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.octo.captcha&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jcaptcha-all&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0-RC6&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;             &lt;p&gt;If your project is not maven-based - just download jcaptcha           jar and   add into your WEB-INF/libs folder.&lt;/p&gt;             &lt;h3 id="section-ImplementingCaptchaWithJSF-IncludingCaptchaIntoJSFPage"&gt;Including           Captcha into JSF Page&lt;/h3&gt;             &lt;p&gt;For rendering Captcha in JSF page we used &lt;a href="http://livedemo.exadel.com/richfaces-demo/richfaces/paint2D.jsf" class="external"&gt;paint2D&lt;/a&gt;           control from rich-faces:&lt;/p&gt;             &lt;pre&gt;
&amp;lt;h:form id=&amp;quot;registerForm&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:panelGrid columns=&amp;quot;2&amp;quot; styleClass=&amp;quot;properties-table&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- CaptchaImage --&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;rich:paint2D id=&amp;quot;captcha&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; width=&amp;quot;#{registerController.captchaWidth}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; height=&amp;quot;#{registerController.captchaHeight}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; format=&amp;quot;jpeg&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; paint=&amp;quot;#{registerController.paintCaptcha}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; data=&amp;quot;#{registerController.randomString}&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:outputText value=&amp;quot;Text on Image:&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:panelGroup&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:inputText id=&amp;quot;secureText&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; value=&amp;quot;#{registerController.secureText}&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; size=&amp;quot;40&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; required=&amp;quot;true&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;emforge:captchaValidator/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/h:inputText&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:message for=&amp;quot;secureText&amp;quot; errorClass=&amp;quot;errorMessage&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/h:panelGroup&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:commandLink action=&amp;quot;#{registerController.submit}&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;h:outputText value=&amp;quot;Submit&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/h:commandLink&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/h:panelGrid&amp;gt;
&amp;lt;/h:form&amp;gt;
&lt;/pre&gt;             &lt;p&gt;&amp;nbsp;&lt;/p&gt;             &lt;p&gt;In &lt;a href="http://www.emforge.org/edit/RegisterController" class="createpage"&gt;RegisterController&lt;/a&gt;           we need to:&lt;/p&gt;             &lt;ol&gt;                 &lt;li&gt;define id, used for storing generated text;&lt;/li&gt;                 &lt;li&gt;Add &lt;a href="http://www.emforge.org/edit/ImageCaptchaService" class="createpage"&gt;ImageCaptchaService&lt;/a&gt;;&lt;/li&gt;                 &lt;li&gt;Add Method, generated image&lt;/li&gt;                 &lt;li&gt;And accessor to secure text, entered by user&lt;/li&gt;                 &lt;li&gt;And method to generate random string:&lt;/li&gt;             &lt;/ol&gt;             &lt;p&gt;(only part of class is here - whole code you can see here: &lt;a href="http://www.emforge.org/browser/EmForge/trunk/emforge-web/src/main/java/ru/emdev/EmForge/security/RegisterController.java" class="external"&gt;RegisterController.java&lt;/a&gt;)&lt;/p&gt;             &lt;pre&gt;
public class RegisterController extends BaseControllerImpl implements InitializingBean {
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static final String CAPTCHA_ID = &amp;quot;EmForge&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private ImageCaptchaService&amp;nbsp;&amp;nbsp;&amp;nbsp; m_imageCaptchaService;
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private String &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; m_secureText;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setImageCaptchaService(ImageCaptchaService i_imageCaptchaService) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_imageCaptchaService = i_imageCaptchaService;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public String getSecureText() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return m_secureText;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setSecureText(String i_secureText) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_secureText = i_secureText;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; protected BufferedImage generateCaptcha() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return m_imageCaptchaService.getImageChallengeForID(CAPTCHA_ID);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception ex) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.error(&amp;quot;Cannot generate captcha image&amp;quot;, ex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int getCaptchaWidth() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 200;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public int getCaptchaHeight() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 100;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Paints Captcha Image
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param g2d
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param obj
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void paintCaptcha(Graphics2D g2d, Object obj) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BufferedImage secureImage = generateCaptcha();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g2d.setClip(0,0,secureImage.getWidth(), secureImage.getHeight());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g2d.drawImage(secureImage, 0,0, null);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception ex) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.error(&amp;quot;Cannot generate captcha image&amp;quot;, ex);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; /** Generates Random Text for displaying on the image */
&amp;nbsp;&amp;nbsp;&amp;nbsp; public String getRandomString() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String str=new&amp;nbsp; String(&amp;quot;QAa0bcLdUK2eHfJgTP8XhiFj61DOklNm9nBoI5pGqYVrs3CtSuMZvwWx4yE7zR&amp;quot;);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuffer sb=new StringBuffer();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Random r = new Random();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; int te=0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for(int i=1;i&amp;lt;=6;i++){
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; te=r.nextInt(62);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; sb.append(str.charAt(te));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return sb.toString();
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;/pre&gt;             &lt;p&gt;Since JCaptcha supports integration with spring-framework, &lt;a href="http://www.emforge.org/edit/ImageCaptchaService" class="createpage"&gt;ImageCaptchaService&lt;/a&gt;           may be defined as spring bean and passed int           registerController as   param (part of beans configuration):&lt;/p&gt;             &lt;pre&gt;
&amp;lt;beans&amp;gt;
    ...
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bean id=&amp;quot;imageCaptchaService&amp;quot; class=&amp;quot;com.octo.captcha.service.image.DefaultManageableImageCaptchaService&amp;quot; scope=&amp;quot;session&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;bean id=&amp;quot;registerController&amp;quot; class=&amp;quot;ru.emdev.EmForge.security.RegisterController&amp;quot; scope=&amp;quot;request&amp;quot;&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&amp;quot;imageCaptchaService&amp;quot; ref=&amp;quot;imageCaptchaService&amp;quot;/&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/bean&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ...
&amp;lt;/beans&amp;gt;
&lt;/pre&gt;             &lt;p&gt;Now, you will able to generate and render the captcha image,           as well   as enter the text.&lt;/p&gt;             &lt;h3 id="section-ImplementingCaptchaWithJSF-ValidatingCaptcha"&gt;Validating Captcha&lt;/h3&gt;             &lt;p&gt;For validating Captcha we implemented special validator - &lt;b&gt;             &lt;a href="http://www.emforge.org/edit/CaptchaValidator" class="createpage"&gt;CaptchaValidator&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;             &lt;p&gt;(assigned to secureText input):&lt;/p&gt;             &lt;pre&gt;
package ru.emdev.EmForge.security.web.validator;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import ru.emdev.EmForge.security.RegisterController;
import com.octo.captcha.service.image.ImageCaptchaService;
/**
 * Validates inputed name for a project
 *
 * @author mchirkov
 */
public class CaptchaValidator implements Validator {
    public static final char[]     INVALID_CHARS                     = new char[] {'*', '@', '/', '\\'};
    public static final int        MAX_NAME_LENGTH                 = 50;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static final String &amp;nbsp;&amp;nbsp;&amp;nbsp; VALUEREQUIRED_ERROR_MESSAGE &amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;quot;Value is required.&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static final String &amp;nbsp;&amp;nbsp;&amp;nbsp; TEXTNOTNATCH_ERROR_MESSAGE &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; = &amp;quot;Text not match text on image&amp;quot;;
&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public void validate(FacesContext context, UIComponent component,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object value) throws ValidatorException {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String val = StringUtils.strip((String)value);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (StringUtils.isEmpty(val)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ValidatorException(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new FacesMessage(VALUEREQUIRED_ERROR_MESSAGE, VALUEREQUIRED_ERROR_MESSAGE)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; );
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpServletRequest request = (HttpServletRequest)context.getExternalContext().getRequest();
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebApplicationContext appContext =
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assert appContext != null;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ImageCaptchaService imageCaptchaService = (ImageCaptchaService)appContext.getBean(&amp;quot;imageCaptchaService&amp;quot;);&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!imageCaptchaService.validateResponseForID(RegisterController.CAPTCHA_ID, val)) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ValidatorException(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new FacesMessage(TEXTNOTNATCH_ERROR_MESSAGE, TEXTNOTNATCH_ERROR_MESSAGE));
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
}
&lt;/pre&gt;             &lt;p&gt;&lt;a href="http://www.emforge.org/edit/ImageCaptchaService" class="createpage"&gt;ImageCaptchaService&lt;/a&gt;,           stored inside itself the text, generated in image, so, here,           we simple   get this bean from Spring Context, and validate it&lt;/p&gt;             &lt;p&gt;So, now we only need to declare validator in &lt;b&gt;faces-config.xml&lt;/b&gt;:&lt;/p&gt;             &lt;pre&gt;
    &amp;lt;validator&amp;gt;
        &amp;lt;validator-id&amp;gt;captchaValidator&amp;lt;/validator-id&amp;gt;
        &amp;lt;validator-class&amp;gt;ru.emdev.EmForge.security.web.validator.CaptchaValidator&amp;lt;/validator-class&amp;gt;
    &amp;lt;/validator&amp;gt;
&lt;/pre&gt;             &lt;p&gt;and define validator tag in our facelets taglib (&lt;b&gt;emforge.taglib.xml&lt;/b&gt;)&lt;/p&gt;             &lt;pre&gt;
    &amp;lt;tag&amp;gt;
        &amp;lt;tag-name&amp;gt;captchaValidator&amp;lt;/tag-name&amp;gt;
        &amp;lt;validator&amp;gt;
            &amp;lt;validator-id&amp;gt;captchaValidator&amp;lt;/validator-id&amp;gt;
        &amp;lt;/validator&amp;gt;   
    &amp;lt;/tag&amp;gt;
&lt;/pre&gt;             &lt;p&gt;&amp;nbsp;&lt;/p&gt;             &lt;p&gt;What is all. Enjoy!&lt;/p&gt;             &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/td&gt;         &lt;/tr&gt;     &lt;/tbody&gt; &lt;/table&gt;</summary>
    <dc:creator>Alexey Kakunin</dc:creator>
    <dc:date>2009-11-21T16:14:57Z</dc:date>
  </entry>
</feed>