<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5402106865572708118</id><updated>2011-12-29T06:03:08.924+01:00</updated><category term='logging'/><category term='android'/><category term='jsf'/><category term='java'/><category term='git'/><category term='android layout'/><category term='spring'/><category term='design'/><category term='layout'/><category term='maven'/><category term='eclipse'/><category term='ubuntu'/><category term='java design'/><category term='repository'/><title type='text'>Developing Software</title><subtitle type='html'>Exploring techniques in software development</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-7844816803773347344</id><published>2011-11-11T10:06:00.000+01:00</published><updated>2011-11-11T10:06:18.364+01:00</updated><title type='text'>Using VirtualBox on Ubuntu 11.10</title><content type='html'>&lt;p&gt;
Ubuntu is my regular development environment and to test webapps on Internet Explorer,
I use Windows running in VirtualBox. Installing VirtualBox is easy, since you can get
it from the Ubuntu Software Center.
&lt;p&gt;

&lt;p&gt;
To make it really useful, you should install Guest Additions. This enables copy/paste
between Ubuntu and Windows, and easy transfer of file by mounting a Ubuntu folder into
Windows. You should be able to install Guest Additions by selecting the Devices/Install Guest Additions.
However, I get an error message:
&lt;/p&gt;

&lt;pre&gt;
Failed to download the VirtualBox Guest Additions CD image from http://dlc.sun.com.edgesuite.net/virtualbox/4.1.2_Ubuntu/VBoxGuestAdditions_4.1.2_Ubuntu.iso.
Error downloading http://dlc.sun.com.edgesuite.net/virtualbox/4.1.2_Ubuntu/VBoxGuestAdditions_4.1.2_Ubuntu.iso - server replied: Not Found
&lt;/pre&gt;

&lt;p&gt;
Apparently, the ISO used to be available from SUN, and is probably shutdown after the Oracle merger.
After some googling, I found that you can download the ISO manually here:
&lt;/p&gt;

&lt;pre&gt;
http://download.virtualbox.org/virtualbox
&lt;/pre&gt;

&lt;p&gt;
After downloading, just mount this ISO as a CD in the VirtualBox settings, boot up Windows and
startup the installation yourself. After that, copy/paste and mounting host folders should work.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-7844816803773347344?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/7844816803773347344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=7844816803773347344' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7844816803773347344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7844816803773347344'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/11/using-virtualbox-on-ubuntu-1110.html' title='Using VirtualBox on Ubuntu 11.10'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-3723311514513778906</id><published>2011-11-07T19:49:00.000+01:00</published><updated>2011-11-07T19:49:48.227+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Add Eclipse to Ubuntu Unity lancher</title><content type='html'>&lt;p&gt;Just like many other users of Ubuntu, I upgraded a few weeks ago to Ubuntu 11.10 "Oneiric Ocelot".
Although the new Unity launcher takes a little time to get used to and has a few quirks, I still
like it overall. It takes minimal amount of precious screen real estate and I find the use of the
"Windows key" to start applications and find files very productive.
&lt;/p&gt;

&lt;p&gt;
As a software developer I use Eclipse and I like to install some other tools manually under my
home directory somewhere. 
&lt;/p&gt;

&lt;h2&gt;Add Eclipse to Launcher&lt;/h2&gt;
&lt;p&gt;
To startup Eclipse, I just used the file manager and double clicked on the Eclipse executable.
This gets tiresome really quickly. To integrate my self-installed Eclipse into the Unity launcher,
you can create a configuration file that will tell the launcher how to startup a custom application
like Eclipse.
&lt;/p&gt;

&lt;p&gt;
Create a file with this contents and change the paths to where you installed Eclipse:
&lt;/p&gt;
&lt;pre&gt;[Desktop Entry]
Comment=Eclipse JEE
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
Icon=/home/koert/software/eclipse-indigo-jee/icon.xpm
Name=Eclipse JEE
Path=/home/koert/software/eclipse-indigo-jee
Type=Application
Terminal=false
&lt;/pre&gt;
&lt;p&gt;
Save this file as Eclipse.desktop in the .local/share/applications directory in your home directory.
&lt;/p&gt;

&lt;p&gt;
Now, when you want to startup Eclipse, use the launcher (press the windows button) and enter Eclipse.
The launcher should display the Eclipse icon, which you can use to start Eclipse. You will see
the icon in the dock and you can keep this in the dock.
&lt;/p&gt;

&lt;h2&gt;Start with specific workspace&lt;/h2&gt;
&lt;p&gt;
When you use multiple workspaces, you can choose the workspace when Eclipse starts up by configuring
items on the icon so that you can start a specific workspace.
&lt;/p&gt;

&lt;p&gt;
You can add Shortcut Group items, which you must add to the X-Ayatana-Desktop-Shortcuts property.
&lt;/p&gt;

&lt;p&gt;
This is an example with an option to choose a workspace and two options with specific workspaces:
&lt;/p&gt;

&lt;pre&gt;[Desktop Entry]
Comment=Eclipse JEE
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
Icon=/home/koert/software/eclipse-indigo-jee/icon.xpm
Name=Eclipse JEE
Path=/home/koert/software/eclipse-indigo-jee
Type=Application
Terminal=false
X-Ayatana-Desktop-Shortcuts=ChooseWorkspace;Workspace1;Workspace2

[ChooseWorkspace Shortcut Group]
Name=Choose workspace
Exec=/home/koert/software/eclipse-indigo-jee/eclipse
TargetEnvironment=Unity

[Workspace1 Shortcut Group]
Name=Privilege trunk
Exec=/home/koert/software/eclipse-indigo-jee/eclipse -name "Trunk" -data /home/koert/project/pretium/workspace
TargetEnvironment=Unity

[Workspace2 Shortcut Group]
Name=Privilege branche
Exec=/home/koert/software/eclipse-indigo-jee/eclipse -name "Branch" -data /home/koert/project/pretium/workspaces/branch-prod
TargetEnvironment=Unity
&lt;/pre&gt;

&lt;p&gt;
This saves me a little bit of time to startup Eclipse in the workspace that I want.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-3723311514513778906?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/3723311514513778906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=3723311514513778906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/3723311514513778906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/3723311514513778906'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/11/add-eclipse-to-ubuntu-unity-lancher.html' title='Add Eclipse to Ubuntu Unity lancher'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-8978638069593678263</id><published>2011-09-07T09:23:00.002+02:00</published><updated>2011-09-07T09:26:57.026+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Quickly update your project version with Maven</title><content type='html'>When you want to update the version of your project, you can edit the pom.xml file and change the version by hand. When you have a project with multiple sub projects, this is time consuming and error prone.
&lt;br /&gt;
Maven has a very useful utility to quickly update the version of your project, you can just run this Maven command:
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
mvn versions:set -DnewVersion=1.2.0-SNAPSHOT&lt;/div&gt;
&lt;br /&gt;
This will update the version of your current project and its sub projects to "1.2.0-SNAPSHOT". This will save the previous version in backup files so you can revert back with this command:
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mvn versions:revert&lt;/div&gt;
&lt;br /&gt;
If you are happy with the results and want to get rid of the backup files, just do a commit with:&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;
mvn versions:commit&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-8978638069593678263?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/8978638069593678263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=8978638069593678263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/8978638069593678263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/8978638069593678263'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/09/quickly-update-your-project-version.html' title='Quickly update your project version with Maven'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-7375792696503064558</id><published>2011-05-12T15:33:00.000+02:00</published><updated>2011-05-13T22:24:35.435+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Using GIT as SubVersion (SVN) client</title><content type='html'>&lt;h2&gt;Install git-svn in Ubuntu&lt;/h2&gt;
All git-* commands are implemented in Ubuntu with the git command: 'git-svn' is in Ubuntu 'git svn', notice the space. 

&lt;h2&gt;Checkout&lt;/h2&gt;
Do a checkout from SVN with  &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
git svn clone -s -r [revision] [SVN URL] [new directory]
&lt;/pre&gt;&lt;/blockquote&gt;

The [SVN URL] is the root of your SVN repository, the remote directory that contains your trunk, tags and branches subdirectories. 

The [revision] is the SVN revision number from which you want to retrieve history from. You may want to limit the history, because it takes time to retrieve all of the history from SVN. 

Example: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
git svn clone -s -r 198 https://nextaction.googlecode.com/svn nextaction
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h2&gt;Update from SVN&lt;/h2&gt;
To update your local files from SVN, execute: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
git svn rebase
&lt;/pre&gt;&lt;/blockquote&gt;

If the update refuses to pull the changes from SVN and displays a message with "needs update", you probably made changes that you have not commited yet. Apparently, you must commit your changes locally first 

&lt;h2&gt;Commit to GIT&lt;/h2&gt;
When you make changes to your local files, you can commit them with: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
git commit -a -m "Commit message"
&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h2&gt;Commit to SVN&lt;/h2&gt;
This will only commit changes to your local GIT repository, to commit (or "push" in the GIT jargon) to SVN, use: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
git svn dcommit
&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-7375792696503064558?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/7375792696503064558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=7375792696503064558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7375792696503064558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7375792696503064558'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/05/using-git-as-subversion-svn-client.html' title='Using GIT as SubVersion (SVN) client'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-6285908422941651482</id><published>2011-03-29T18:39:00.002+02:00</published><updated>2011-03-29T18:41:14.569+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Creating a reusable layout component in Android</title><content type='html'>Let us say that we want to use a common layout in several places in your user interface. 

Something like a box with a label and value text view vertically layed out. The application uses the same label/value TextView in 3 different places.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-epNXYP7q_qw/TZILL1gkOeI/AAAAAAAABBI/ZKh0kz8TTnU/s1600/dashboard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-epNXYP7q_qw/TZILL1gkOeI/AAAAAAAABBI/ZKh0kz8TTnU/s320/dashboard.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This is the common label/value layout component (file: layout/dashboard_item.xml): &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;LinearLayout 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"&amp;gt;
  
     &amp;lt;TextView android:id="@+id/label"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_weight="0"
         android:gravity="center_horizontal"
         style="@style/label"
     /&amp;gt;
     &amp;lt;TextView android:id="@+id/value"
         android:layout_width="fill_parent"
         android:layout_height="fill_parent"
         android:layout_weight="1"
         android:gravity="center"
         style="@style/output"
     /&amp;gt;
&amp;lt;/LinearLayout&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
We want to use it in a screen definition (file: layout/home.xml): &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:labelValue="http://schemas.android.com/apk/res/net.kazed.sailor"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"
      style="@style/screen"
      &amp;gt;

    &amp;lt;net.kazed.sailor.view.LabelValueItem android:id="@+id/vmg"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:layout_weight="1"
       labelValue:label="@string/vmg"
    /&amp;gt;
    
   &amp;lt;/LinearLayout&amp;gt;
&amp;lt;/RelativeLayout&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
Here we reuse the label/value custom component implemented by the LabelValueItem class. This component has one custom attribute: "labelValue:label". Notice that this attribute has a namespace that corresponds with the package name of the Android application (defined in AndroidManifest.xml). 

The component class retrieves the value of the custom attribute and uses it to set the text of the label TextView (file: src/net/kazed/sailor/view/LabelValueItem.java): &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: java"&gt;public class LabelValueItem extends LinearLayout {
   
   public LabelValueItem(final Context context, final AttributeSet attrs) {
      super(context, attrs);
      LayoutInflater.from(context).inflate(R.layout.dashboard_item, this, true);

      TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.labelValue, 0, 0);

      TextView label = (TextView) findViewById(R.id.label);
      String labelText = array.getString(R.styleable.labelValue_label);
      if (labelText != null) {
         label.setText(labelText);
      }

      array.recycle();
   }

}
&lt;/pre&gt;
&lt;/blockquote&gt;
To make it all work, the application must define the custom attribute (file: values/attr.xml): &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;resources&amp;gt;
   &amp;lt;declare-styleable name="labelValue"&amp;gt;
      &amp;lt;attr name="label" format="string" /&amp;gt;
   &amp;lt;/declare-styleable&amp;gt;
&amp;lt;/resources&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-6285908422941651482?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/6285908422941651482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=6285908422941651482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6285908422941651482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6285908422941651482'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/03/creating-reusable-layout-component-in.html' title='Creating a reusable layout component in Android'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-epNXYP7q_qw/TZILL1gkOeI/AAAAAAAABBI/ZKh0kz8TTnU/s72-c/dashboard.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-2944330768244321546</id><published>2011-02-21T13:19:00.001+01:00</published><updated>2011-02-21T13:19:59.868+01:00</updated><title type='text'>Error messages for required fields in JSF 1.2</title><content type='html'>&lt;h3&gt;JSF 1.1&lt;/h3&gt;
When you have required fields in your JSF page, you simple add the required="true" attribute to the inputField and the user will get error message when user the field the field blank. &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
&amp;lt;h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" /&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

This is all great, since we don't have to do much as a developer. However, the user gets an ugly error message: "accountForm:accountnumber: Validation Error: Value is required." This message is customizable by overriding this message in your message bundle and is pretty limited in how customized you want it to be. 

&lt;h3&gt;JSF 1.2&lt;/h3&gt;
JSF 1.2 and later makes it easier to create custom error messages for required fields, just add the requiredMessage attribute: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
&amp;lt;h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" requiredMessage="Account number is required" /&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

When the user has forgotten to enter something in this field, the JSF framework will display the error message supplied with the requiredMessage attribute. 

To supply translations for different languages, you can put the message in a resource bundle. Note that you must configure this resource bundle in faces-config.xml like this: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
&amp;lt;application&gt;
  &amp;lt;!-- ... --&gt;
  &amp;lt;resource-bundle&gt;
    &amp;lt;base-name&gt;com.example.messages&amp;lt;/base-name&gt;
  &amp;lt;var&gt;bundle&amp;lt;/var&gt;
  &amp;lt;/resource-bundle&gt;
&amp;lt;/application&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

This makes it possible to use the configured variable "bundle" anywhere in your pages, including the requiredMessage: &lt;blockquote&gt;&lt;pre class="brush: xml"&gt;
&amp;lt;h:inputText id="accountnumber" value="#{accountSetting.accountNumber}"
  required="true" requiredMessage="#{bundle.error_required_accountNumber}" /&gt;
&lt;/pre&gt;&lt;/blockquote&gt;

I have found that the old way of using the loadBundle JSF component does not work with requiredMessage. The configured resource-bundle in faces-config.xml is much neater anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-2944330768244321546?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/2944330768244321546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=2944330768244321546' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/2944330768244321546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/2944330768244321546'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/02/error-messages-for-required-fields-in.html' title='Error messages for required fields in JSF 1.2'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-5695403367617034963</id><published>2011-01-03T12:06:00.002+01:00</published><updated>2011-01-03T14:57:57.128+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='repository'/><title type='text'>Getting started with GIT</title><content type='html'>I recently started working on a new project and decided to try out the source repository GIT. As a long time user of CVS and Subversion (SVN), these distributed repositories take a little time getting used to.
&lt;br /&gt;
As long as you use it yourself in a one man project, a distributed repository is almost the same as CVS and SVN. You check code out, make modifications and commit. The major difference is that you then "push" your commits to another repository, usually a remote server.
&lt;br /&gt;
&lt;h2&gt;



Create a local repository&lt;/h2&gt;
To get started, after installing GIT, you can create a repository with the "init" command.
&lt;br /&gt;
&lt;pre&gt;cd /path/to/repository
git init
&lt;/pre&gt;
&lt;h3&gt;


Make modifications&lt;/h3&gt;
Just like CVS and SVN, you can add/modify/delete files and commit them.
&lt;br /&gt;
&lt;pre&gt;git add readme.txt
git commit -a -m "added readme text"
&lt;/pre&gt;
Note that this commit is stored locally, it is not committed to a central server.

&lt;br /&gt;
&lt;h3&gt;



Copy a repository&lt;/h3&gt;
You can create a copy of a local repository with the "clone" command. This way you can locally make a branch.
&lt;br /&gt;
&lt;pre&gt;cd /path/to/workspace
git clone /path/to/repository
&lt;/pre&gt;
&lt;h2&gt;


Shareable repository&lt;/h2&gt;
To create a sort of "central" repository like CVS or SVN, you can create a shareable repository with the "init" command. Do this on your server.&lt;br /&gt;
&lt;pre&gt;cd /path/to/repository
git init --bare --shared
&lt;/pre&gt;
&lt;h3&gt;


Checkout with SSH&lt;/h3&gt;
I use SSH to "checkout" from the remote repository, do this on your client.
&lt;br /&gt;
&lt;pre&gt;cd /path/to/workspace
git clone ssh://myserver/path/to/repository
&lt;/pre&gt;
This makes a copy of the remote repository to my local workspace. Here I can make modifications and commit them. GIT will store your commit locally until you "push" this to the central repository.
&lt;br /&gt;
&lt;pre&gt;git add readme.txt
git commit -a -m "added readme text"
git push origin master
&lt;/pre&gt;
This last command will update the remote repository with your commits.


&lt;br /&gt;
&lt;h2&gt;



See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I found this excellent article on GIT on stackoverflow:
&lt;a href="http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide"&gt;http://stackoverflow.com/questions/315911/git-for-beginners-the-definitive-practical-guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;

Git for SVN users:
&lt;a href="http://git.or.cz/course/svn.html"&gt;http://git.or.cz/course/svn.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-5695403367617034963?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/5695403367617034963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=5695403367617034963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/5695403367617034963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/5695403367617034963'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2011/01/getting-started-with-git.html' title='Getting started with GIT'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-6255446742902443267</id><published>2010-11-26T11:25:00.002+01:00</published><updated>2010-11-26T11:28:25.332+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android layout'/><title type='text'>Flexible layout with RelativeLayout in Android</title><content type='html'>I often create a layout for my Android applications with a list and horizontal row of buttons on the bottom. Considering that Android devices come in very different sizes, you want to make this layout flexible so that the list takes up the entire area above the row of buttons on the bottom.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/_BlzxUAFTt6w/TO-KdXW5m4I/AAAAAAAABAk/s1IhlazaMBU/s1600/relativelayout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_BlzxUAFTt6w/TO-KdXW5m4I/AAAAAAAABAk/s1IhlazaMBU/s320/relativelayout.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;


You could do this with a LinearLayout and use layout_weight. This often does not behave the way I want to because the LinearLayout is quite limited.

I found an easier way to use a RelativeLayout, see the example:&amp;nbsp; &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"&amp;gt;
    
     &amp;lt;LinearLayout android:id="@+id/button_bar"
          android:orientation="horizontal"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          &amp;gt;

        &amp;lt;Button android:id="@+id/add_task_context_button"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:text="@string/task_context_add_button_title"
             /&amp;gt;
        &amp;lt;Button android:id="@+id/cancel_button"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:text="@string/cancel_button_title"
             /&amp;gt;
        &amp;lt;Button android:id="@+id/ok_button"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:text="@string/ok_button_title"
             /&amp;gt;
     &amp;lt;/LinearLayout&amp;gt;

    &amp;lt;ListView android:id="@+id/android:list"
              android:layout_width="fill_parent" 
              android:layout_height="fill_parent"
              android:layout_alignParentTop="true"
              android:layout_above="@id/button_bar"
              android:drawSelectorOnTop="false"
              style="@style/list"  
              /&amp;gt;

    &amp;lt;TextView android:id="@+id/android:empty"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_alignParentTop="true"
              android:text="@string/no_task_contexts"
              style="@style/label"                
              android:padding="10px"
              /&amp;gt;
              

&amp;lt;/RelativeLayout&amp;gt;

&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;
When you use a RelativeLayout, pay attention to the order of components. Because you specify where components are positioned relative to the parent's borders and other components.
&lt;/p&gt;

&lt;p&gt;
To make my layout work, I first specify the horizontal row of buttons first (button_bar), contained in a LinearLayout with android:layout_alignParentBottom="true". When you position the list on the top with android:layout_alignParentTop="true", you also attach the bottom of the list with the top of the button row with android:layout_above="@id/button_bar". This way, the RelativeLayout will stretch the list between the top of the parent and the top of the button_bar.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-6255446742902443267?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/6255446742902443267/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=6255446742902443267' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6255446742902443267'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6255446742902443267'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2010/11/flexible-layout-with-relativelayout-in.html' title='Flexible layout with RelativeLayout in Android'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_BlzxUAFTt6w/TO-KdXW5m4I/AAAAAAAABAk/s1IhlazaMBU/s72-c/relativelayout.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-1259890760683756541</id><published>2010-03-02T09:48:00.000+01:00</published><updated>2010-03-02T09:48:15.966+01:00</updated><title type='text'>Handling portrait/landscape switch in Android</title><content type='html'>When you develop an Android application, you will notice that when the user changes the orientation of the device, the UI framework will recreate the current screen layout with the corresponding UI objects. The framework calls these methods of the current activity: onPause, onStop, onDestroy, and then onCreate, onStart, onResume to display the activity again. 

The onCreate method of the activity retrieves the data it displays from a database and populates the input fields with the private populateFields method. &lt;blockquote&gt;&lt;pre class="brush: java"&gt;
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  /* UI setup here */
          
  Uri itemUri = getIntent().getData();
  if (newRecord) {
    customer = new Customer();
  } else {
    customer = retrieveCustomer(itemUri);
  }

  populateFields(customer);
}
&lt;/pre&gt;&lt;/blockquote&gt;

When the user switches orientation, the Android framework will destroy this activity and call onCreate again, which will retrieve the data and populate the input fields. The result is that the user will lose entered data, because this input fields will contain what the activity retrieved from the database. 

A solution is to store the entered data in the database in the onPause method: &lt;blockquote&gt;&lt;pre class="brush: java"&gt;
protected void onResume() {
  copyFromInput(customer);
  if (newRecord) {
    saveCustomer(customer);
  } else {
    updateCustomer(customer);
  }

  super.onResume();
}
&lt;/pre&gt;&lt;/blockquote&gt;

This solution mostly works and also takes care of automatic saving the entered data when the user uses the "home" button. This may also surprise the user, since the data is saved without the user explicitly asking to save it. 

A better solution is to use the savedInstanceState parameter that the Android framework passes into the onCreate method. This parameter is null when the user navigates to the activity. When the user changes orientation of the Android device, the framework destroys the activity after saving the contents of the input fields in a Bundle object. When the framework recreates the activity after an orientation change, the savedInstanceState parameter is not null and contains all the data that your application would want save during this change. 

The Android framework already automatically saves and restores the contents of the input fields, so your application does not need to do this. The thing that your application needs to be aware of is that it should only set the contents of the input fields when the savedInstanceState parameter is null.   &lt;blockquote&gt;&lt;pre class="brush: java"&gt;
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  /* UI setup here */
          
  Uri itemUri = getIntent().getData();
  if (newRecord) {
    customer = new Customer();
  } else {
    customer = retrieveCustomer(itemUri);
  }
  
  if (savedInstanceState == null) {
    populateFields(fragment);
  }
}
&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-1259890760683756541?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/1259890760683756541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=1259890760683756541' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/1259890760683756541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/1259890760683756541'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2010/03/handling-portraitlandscape-switch-in.html' title='Handling portrait/landscape switch in Android'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-2544080272083752631</id><published>2010-01-29T10:10:00.004+01:00</published><updated>2010-01-29T13:44:38.068+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>ID design</title><content type='html'>We often take the IDs that we use in databases and applications for granted. As long as we can identify a data record with a unique number, everything is great. Recently, I ran into an interesting problem in an existing application. The ID that was used has this format: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;ABBBCCC

A = last digit of year
BBB = day number of the year
CCC = sequence number
&lt;/pre&gt;
&lt;/blockquote&gt;
For example, you could get on 2 february 2009 this ID: 9033012. This would be the twelveth data record of the day. 

&lt;br /&gt;
&lt;h3&gt;




More digits&lt;/h3&gt;
Sometimes, the application would generate more than 1000 data records on a day and run out of numbers. In that case the application just add digits to get something like this: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre&gt;ABBBCCCDDD

A = last digit of year
BBB = day number of the year
CCCDDD = sequence number with additional digits
&lt;/pre&gt;
&lt;/blockquote&gt;
Example: 9003123456&lt;br /&gt;
&lt;br /&gt;
Perhaps you can sense some trouble here... &lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h3&gt;




Decade trouble&lt;/h3&gt;
Obviously, you will run into problems after 10 years of using this application. It makes you wonder if the designers of this application have learned anything from the Y2K problems, is storage space really this precious that you cannot spare another 3 bytes? 

&lt;br /&gt;
&lt;h3&gt;




Length confusion&lt;/h3&gt;
The fact that the system adds another 3 digits is pretty confusing. Technically, the ID is still unique and valid. Normally we add digits in the front of the number, not in the back of the number. This makes it impossible to sort these IDs in a meaningful way. 

For example, an ID created on january 1 (9001123456) could have a higher value than an ID created on january 2 (9002001). 

&lt;br /&gt;
&lt;h3&gt;




Number interpretation&lt;/h3&gt;
After the year 2010 started, the IDs suddenly started with a "0", like 0003123456 and in some subsystems, this ID is interpreted as a number, which would make it 3123456. Suddenly this ID can collide with an already existing ID from the year 2003. 

&lt;br /&gt;
&lt;h3&gt;




ID should have no content&lt;/h3&gt;
When the engineers were trying to solve this problem, they wanted to change the ID generator to just use an Oracle sequence and do away with the year/day nonsense. Because the system has grown rather large and complex over the year, changing the ID generation may cause more problems, because no one is sure that the contents of the ID is not interpreted in same way. It could be that a part of the system is making use of the fact that the ID contains the year and day number. 

&lt;br /&gt;
&lt;h3&gt;




Conclusion&lt;/h3&gt;
As you can see, designing an ID can be tricky. Lessons learned:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;if you use a year, please use the full year, do not try to save a little bit of storage, it might cost a lot of money later on&lt;/li&gt;
&lt;li&gt;avoid meaningful content in the ID to prevent "clever" people from exploiting this, otherwise you can never change the way an ID is generated&lt;/li&gt;
&lt;li&gt;allocate enough digits in the ID, the application may live much longer than you think&lt;/li&gt;
&lt;li&gt;keep it simple, use a sequence generator 

&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-2544080272083752631?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/2544080272083752631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=2544080272083752631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/2544080272083752631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/2544080272083752631'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2010/01/id-design.html' title='ID design'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-1954008820966130754</id><published>2009-12-15T13:59:00.017+01:00</published><updated>2010-02-01T09:27:04.590+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><title type='text'>Using a Syslog appender in log4j</title><content type='html'>The log4j framework has several appenders and one of them is the SyslogAppender. This appender lets you append log messages to syslog, a popular logging service on Unix and Linux. To use this appender, just add this to your log4j.xml configuration file: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;&amp;lt;appender name="syslog" class="org.apache.log4j.net.SyslogAppender"&amp;gt;
  &amp;lt;param name="Facility" value="USER"/&amp;gt;
  &amp;lt;param name="SyslogHost" value="localhost"/&amp;gt;
  &amp;lt;param name="Threshold" value="WARN"/&amp;gt;
  &amp;lt;layout class="org.apache.log4j.PatternLayout"&amp;gt;
    &amp;lt;param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} MYAPP: %-5p %m%n"/&amp;gt;
  &amp;lt;/layout&amp;gt;
&amp;lt;/appender&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
You can use the usual log4j API to log messages: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: java"&gt;public class AppWithStandardLogger {
  private static final Logger logger = Logger.getLogger(AppWithStandardLogger.class);

  public void someMethod() {
    try {
       // ...
    } catch (ConnectionException e) {
       logger.fatal("#Failed to connect to database", e);
    }
  }
}
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
Severity level mapping&lt;/h3&gt;
If you use logger.fatal(), the standard log4j syslog appender will log this message with the highest syslog severity, which is level 0, "emerg". This level is usually reserved for the most urgent operating system related messages and on most Unix systems will print the message on the terminal session of every logged in user. 

For most applications, this is probably not what you want. If an application encounters a fatal error, it should log the message as a lower level like "critical", level 2. You can do this by implementing an appender which overrides the "append" method: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: java"&gt;import org.apache.log4j.Level;
import org.apache.log4j.spi.LoggingEvent;

/**
 * Appender that fixes level mapping to syslog.
 */
public class SyslogAppender extends org.apache.log4j.net.SyslogAppender {
 @Override
 public void append(LoggingEvent event) {
  Level log4jLevel = event.getLevel();
  Level newLevel = null;
  if (log4jLevel.equals(Level.FATAL)) {
   newLevel = SyslogLevel.FATAL;
  } else {
   newLevel = event.getLevel();
  }
  LoggingEvent newLoggingEvent = new LoggingEvent(
    event.getFQNOfLoggerClass(), event.getLogger(), event.getTimeStamp(), newLevel,
    event.getMessage(), event.getThreadName(), event.getThrowableInformation(),
    event.getNDC(), event.getLocationInformation(), event.getProperties());
  super.append(newLoggingEvent);
 }

 /**
  * Fix for level mapping - log4j "fatal" is mapped to syslog "critical".
  */
 public static class SyslogLevel extends Level {
  private static final long serialVersionUID = 1L;
  public static final Level FATAL = new SyslogLevel(FATAL_INT, "FATAL", 2);
  
  protected SyslogLevel(int level, String levelStr, int syslogEquivalent) {
   super(level, levelStr, syslogEquivalent);
  }
 }
}
&lt;/pre&gt;
&lt;/blockquote&gt;
This custom appender will map the log4j "fatal" messages to syslog "critical" (level 2) severity. 

&lt;br /&gt;
&lt;h3&gt;
Stack traces&lt;/h3&gt;
With log4j you can also log the stack trace when you pass the exception as extra parameter. In my work the syslog system will pass the messages through to Tivoli and this monitoring system should not receive stack traces. 

With a custom log4j PatternLayout, we can filter out stack traces by overriding the ignoresThrowable() method:  &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: java"&gt;import org.apache.log4j.PatternLayout;

/**
 * Layout that prevents stack traces to be logged.
 */
public class NoStackTracePatternLayout extends PatternLayout {
 @Override
 public boolean ignoresThrowable() {
  return false;
 }
}
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
Putting it together&lt;/h3&gt;
To use both the custom Appender and Layout, use this configuration: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;    &amp;lt;appender name="syslog" class="net.kazed.log4j.SyslogAppender"&amp;gt;
     &amp;lt;param name="Facility" value="USER"/&amp;gt;
     &amp;lt;param name="SyslogHost" value="localhost"/&amp;gt;
     &amp;lt;param name="Threshold" value="WARN"/&amp;gt;
     &amp;lt;layout class="net.kazed.log4j.NoStackTracePatternLayout"&amp;gt;
       &amp;lt;param name="ConversionPattern" value="%d{MMM dd HH:mm:ss} MYAPP: %-5p %m%n"/&amp;gt;
     &amp;lt;/layout&amp;gt;
    &amp;lt;/appender&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
The code is unchanged, we only changed the configuration. 

&lt;br /&gt;
&lt;h3&gt;
Using a named syslog logger&lt;/h3&gt;
If you want to have control over what and how the application logs to the log file and syslog, you could configure a separate logger with a name:    &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: xml"&gt;    &amp;lt;logger name="monitoring"&amp;gt;
      &amp;lt;level value="WARN" /&amp;gt;
      &amp;lt;appender-ref ref="syslog" /&amp;gt;
    &amp;lt;/logger&amp;gt;
&lt;/pre&gt;
&lt;/blockquote&gt;
In the code, you refer to the "monitoring" logger and you can log a different message to the monitoring system: &lt;br /&gt;
&lt;blockquote&gt;
&lt;pre class="brush: java"&gt;public class AppWithNamedLogger {
 private static final Logger logger = Logger.getLogger(AppWithNamedLogger.class);
 private static final Logger monitorLogger = Logger.getLogger("monitoring");
 
    public void someMethod() {
     try {
   throw new ConnectionException();
   // ...
  } catch (ConnectionException e) {
   logger.fatal("Failed to connect to database", e);
   monitorLogger.error("Failure to connect to database");
  }
 }
}
&lt;/pre&gt;
&lt;/blockquote&gt;
As you can see, we must change the code and add a second logger and use this to log explicitly to the monitoring system. 

&lt;br /&gt;
&lt;h3&gt;
Conclusion&lt;/h3&gt;
When logging to a monitoring system you can avoid changes to the source code by changing the configuration and add the monitoring logger. The standard syslog appender  implementation maps the log4j fatal to syslog emerg, which level is too high for most Unix/Linux installations. A custom appender can fix this mapping. To avoid logging stack traces, you can implement custom Layout. 

With a named logger you can log special messages explicitly to the monitoring system. This requires changing the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-1954008820966130754?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/1954008820966130754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=1954008820966130754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/1954008820966130754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/1954008820966130754'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2009/12/using-syslog-appender-in-log4j.html' title='Using a Syslog appender in log4j'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-7133290347944641077</id><published>2007-12-18T15:37:00.000+01:00</published><updated>2007-12-18T16:28:39.544+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java design'/><title type='text'>Use Enumeration instead of Constant</title><content type='html'>&lt;h3&gt;Using Enumeration instead of Constant&lt;/h3&gt;
I think we all regularly use integer or String status codes or other &lt;i&gt;magic&lt;/i&gt; numbers in our Java code. And we probably also define (static final) constants to make these constants known to the users of our code. While this works fine for small projects, I noticed, when working on larger scale project, that I spent a considerable amount of time trying to find which constants I needed.&lt;br&gt;&lt;br&gt;In many applications I encounter, this kind of API for a service is quite common:&lt;br&gt;
&lt;blockquote&gt;&lt;pre&gt;public static final String DOCUMENT_TYPE_TEXT = "text";
public static final String DOCUMENT_TYPE_SPREADSHEET = "spreadsheet";
List findDocuments(String documentType);
&lt;/pre&gt;&lt;/blockquote&gt;
In the above API, it is pretty obvious that I should use the listed constants as the &lt;i&gt;documentType &lt;/i&gt;parameter. However, I have seen many cases where the constants are defined in some other place and sometimes an archeology expedition was needed to find the correct values to use. I also have the freedom to pass any String that I didn't get from a constant and just hardcoded. Because of this freedom, the service must check if the passed in &lt;i&gt;documentType &lt;/i&gt;parameter is valid (who knows what 
the user passes to the service).&lt;br&gt;&lt;br&gt;To make the API more watertight, we could require the user to supply a constant of a class that we define ourselves:&lt;br&gt;
&lt;blockquote&gt;&lt;pre&gt;List findDocuments(DocumentType documentType);&lt;/pre&gt;&lt;/blockquote&gt;
This is the DocumentType class:&lt;br&gt;
&lt;blockquote&gt;&lt;pre&gt;public class DocumentType {&lt;br&gt;  public static final DocumentType TEXT = new DocumentType("text");&lt;br&gt;  public static final DocumentType SPREADSHEET = new DocumentType("spreadsheet");&lt;br&gt;&lt;br&gt;  private String name;&lt;br&gt;&lt;br&gt;  private DocumentType(String &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;) {&lt;br&gt;    this.&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;= &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;;&lt;br&gt;  }&lt;br&gt;&lt;br&gt;  public String getName() {&lt;br&gt;    return &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;;&lt;br&gt;  }&lt;br&gt;}&lt;br style="font-family: Courier New;"&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;h2&gt;Apache common lang Enum&lt;/h2&gt;&lt;p&gt;In the example above we still need to implement the equals() and hashCode() methods to make it possible to check which documentType the user passed to the service. The easy way is to subclass from &lt;a title="the Apache common lang Enum class" href="http://commons.apache.org/lang/api-release/org/apache/commons/lang/enums/Enum.html" id="d2fv"&gt;the Apache common lang Enum class&lt;/a&gt;, this superclass implements the boring stuff (equals, hashCode, compareTo, getName):&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;import &lt;/span&gt;&lt;font style="font-family: Courier New;" size="-1"&gt;org.apache.commons.lang.enums.Enum;&lt;/font&gt;&lt;span style="font-family: Courier New;"&gt;&lt;br&gt;public class DocumentType&lt;/span&gt; &lt;span style="font-family: Courier New;"&gt;extends Enum&lt;/span&gt; &lt;span style="font-family: Courier New;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;   public static final DocumentType TEXT = new DocumentType("text");&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;   public static final DocumentType SPREADSHEET = new DocumentType("spreadsheet");&lt;/span&gt;&lt;br&gt; &lt;br&gt;&lt;span style="font-family: Courier New;"&gt;  private DocumentType(String &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;) {&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;     super(&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;name&lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;);&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;   }&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;This solution works well if you're stuck with Java 1.4. However, if you work on a project that runs on Java 5 or later, you should consider the build-in &lt;i&gt;enum&lt;/i&gt; types.&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;Migrate to Java 5 enum&lt;/h3&gt;The Java language designers have added the &lt;i&gt;enum&lt;/i&gt; type in Java 5 to make it easier to define a type-safe constant. The DocumentType enumeration becomes very simple:&lt;br&gt;&lt;br&gt;&lt;blockquote style="font-family: Courier New;"&gt;&lt;pre&gt;public enum DocumentType {&lt;br&gt;    TEXT,&lt;br&gt;    SPREADSHEET;&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;/blockquote&gt;The code of our service runs unchanged, since the &lt;i&gt;equals&lt;/i&gt; method of an enum behaves the same way. In the case you need to interface with legacy code that gets a string from a database or property file to create the corresponding constant, you can add a String as private member of the enum:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;pre&gt;public enum DocumentType {
    TEXT("text"),&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    SPREADSHEET("spreadsheet");&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;    &lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    private final String name;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;    &lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    DocumentType(String name) {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;        this.name = name;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    public String getName() {&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;        return name;&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;    }&lt;/span&gt;&lt;br style="font-family: Courier New;"&gt;&lt;span style="font-family: Courier New;"&gt;}&lt;/pre&gt;&lt;/blockquote&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;Using strong types instead of Strings or integers has these advantages:&lt;br&gt;&lt;ul&gt;&lt;li&gt;the interface of your objects is much clearer and less ambiguous,&lt;/li&gt;&lt;li&gt;you get code completion in your IDE (no need to "hunt for constants"),&lt;/li&gt;&lt;li&gt;easier refactoring by your IDE,&lt;/li&gt;&lt;li&gt;type safety - your client cannot supply invalid String or integer constants.&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-7133290347944641077?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/7133290347944641077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=7133290347944641077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7133290347944641077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7133290347944641077'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2007/12/use-enumeration-instead-of-constant.html' title='Use Enumeration instead of Constant'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-7640808831266639701</id><published>2007-11-19T20:05:00.000+01:00</published><updated>2007-11-20T09:34:13.899+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Spring bean configuration validation</title><content type='html'>If you enthousiastically use Spring like me and dutifully inject every dependency in your beans with Spring's XML configuration, you have probably encountered the situation that you forgot to inject a property and received a NullPointerException from an unexpected place in your code. Wouldn't it be nice to check the configuration of your bean after it is instantiated?

Your bean could implement the &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/beans/factory/InitializingBean.html"&gt;InitializingBean&lt;/a&gt; interface, which would cause the Spring application context to call the afterPropertiesSet method after your bean is instantiated and injected with dependencies. This would make your bean directly dependent on Spring and you probably would not want that.

&lt;h3&gt;Attribute "init-method"&lt;/h3&gt;
A better solution is to call a method of your bean that validates its own configuration with the "init-method" attribute of the bean element in the application context XML:
&lt;pre&gt;
&amp;lt;bean id="bean1" class="net.kazed.spring.config.validator.ExampleBean1" init-method="validateConfiguration"&amp;gt;
 &amp;lt;property name="bean2" ref="bean2"/&amp;gt;
 &amp;lt;property name="bean3" ref="bean3"/&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;

&lt;pre&gt;
public void validateConfiguration() {
 DependencyAssert.notNull(bean2, "bean2");
 DependencyAssert.notNull(bean3, "bean3");
}
&lt;/pre&gt;

The Spring container will call the "validateConfiguration" method after your bean, in which you can check if all required dependencies are injected. The only thing is that you should not forget to add the "init-method" attribute.

&lt;h3&gt;BeanPostProcessor&lt;/h3&gt;
Since our goal was to catch configuration mistakes, this solution just is not good enough. Fortunately, you can create a post-processor for the Spring container that will examine every created bean after instantiation and dependency injection. By implementing a BeanPostProcessor, you can invoke the validateConfiguration method. To make it nice and intuitive, we can create an interface ValidatableConfiguration with the validateConfiguration method.

Interface:
&lt;pre&gt;public interface ValidatableConfiguration {
/**
 * Validate the configuration of the object.
 */
void validateConfiguration();
}
&lt;/pre&gt;ValidatingBeanProcessor:
&lt;pre&gt;
public class ValidatingBeanProcessor implements BeanPostProcessor {
  public Object postProcessBeforeInitialization(Object bean, String beanName)
   throws BeansException {
   return bean;
  }

  public Object postProcessAfterInitialization(Object bean, String beanName)
   throws BeansException {
   if (bean instanceof ValidatableConfiguration) {
     try {
       ((ValidatableConfiguration) bean).validateConfiguration();
     } catch (DependencyNullException e) {
       throw new ConfigurationValidationException("Configuration of bean '" + beanName
         + "' failed - " + e.getMessage(), e);
     }
   }
   return bean;
  }
}
&lt;/pre&gt;
We just declare the ValidatingBeanProcessor once in the application context, and the container will use it for every created bean:
&lt;pre&gt;&amp;lt;bean id="beanValidator" class="net.kazed.spring.config.validator.ValidatingBeanProcessor"&amp;gt;
&lt;/pre&gt;
The nice thing is that we only have to make the bean implement the ValidatableConfiguration interface and it will automatically be used to validate the bean whenever you declare it in the application context.

Advantages:
&lt;ul&gt;&lt;li&gt;Intuitive design - implement interface and it will be validated&lt;/li&gt;&lt;li&gt;No special configuration (except from the one ValidatingBeanProcessor)&lt;/li&gt;&lt;li&gt;Validation is done only once and during instantiation of the application context - it will fail early&lt;/li&gt;&lt;li&gt;Error message is descriptive - no more puzzling NullPointerException&lt;/li&gt;&lt;/ul&gt;

&lt;h3&gt;Constructor injection&lt;/h3&gt;
Traditionally, the Spring team favored setter injection because of more readable configuration. Spring has always also supported constructor injection and recently this has received more attention in the Spring community (see &lt;a href="http://blog.interface21.com/main/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/"&gt;Alef's blog&lt;/a&gt;). Constructor injection makes validation incredibly simple: just validate in the constructor.
&lt;pre&gt;
public ExampleBean1(ExampleBean2 bean2, ExampleBean3 bean3) {
 super();
 DependencyAssert.notNull(bean2, "bean2");
 DependencyAssert.notNull(bean3, "bean3");
 this.bean2 = bean2;
 this.bean3 = bean3;
}
&lt;/pre&gt;
&lt;pre&gt;&amp;lt;bean id="bean1c" class="net.kazed.spring.config.validator.ExampleBean1"&amp;gt;
 &amp;lt;constructor-arg ref="bean2"/&amp;gt;
 &amp;lt;constructor-arg ref="bean3"/&amp;gt;
&amp;lt;/bean&amp;gt;
&lt;/pre&gt;As you can see, constructor injection is a bit harder to read because the arguments are nameless and depend on the order.
&lt;h3&gt;Conclusion&lt;/h3&gt;
I would prefer to use constructor injection and use (or combine with) setter injection if some dependencies are optional. The BeanPostProcessor is very useful because it is non-obtrusive and automatically validates the configuration of a bean when it implements an interface that you define yourself and can be a logical part of your domain model.
Retrieve &lt;a href="http://www.kazed.net/dist/blog-1.0-SNAPSHOT-src.zip"&gt;here the source code of these examples&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-7640808831266639701?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/7640808831266639701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=7640808831266639701' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7640808831266639701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/7640808831266639701'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2007/11/spring-bean-configuration-validation.html' title='Spring bean configuration validation'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5402106865572708118.post-6624357109415412925</id><published>2007-10-26T11:07:00.000+02:00</published><updated>2007-10-26T11:27:03.355+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jsf'/><title type='text'>Create your own JSF variable resolver</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;/span&gt;The system I am working on, uses a singleton service factory (that uses Spring to configure the services) to lookup service instances. The JSF backing beans use these services to perform business operations and need to lookup the services with the central service locator. This is quite straightforward and unfortunately less straightforward when you want to unit test it: it would be a lot easier to inject the services into the backing beans like we are used to in Spring.

Spring has a variable resolver that makes it possible to inject Spring managed beans defined in WEB-INF/applicationContext.xml into JSF managed beans. For various reasons the system I am working on cannot put the services in application context of the web application (service instances must be shared between multiple web applications on the server). To make the same sort of injection possible, I created a JSF variable resolver that will lookup the desired service in the global service locator.&lt;span style="font-family:arial;"&gt;&lt;/span&gt;
&lt;pre style="overflow: auto;"&gt;
public class ServiceLocatorVariableResolver extends VariableResolver {

private VariableResolver originalVariableResolver;
private ServiceLocator serviceLocator;

/**
* Constructor.
* @param originalVariableResolver Original JSF variable resolver.
*/
public ServiceLocatorVariableResolver(VariableResolver originalVariableResolver) {
   this.originalVariableResolver = originalVariableResolver;
}

/**
* {@inheritDoc}
*/
public Object resolveVariable(FacesContext context, String name) throws EvaluationException {
   Object result = null;
   result = originalVariableResolver.resolveVariable(context, name);
   if (result == null) {
     if (serviceLocator == null) {
         serviceLocator = ServiceLocatorFactory.getInstance().getLocator();
     }
     try {
         result = serviceLocator.getBean(name);
     } catch (NoSuchBeanDefinitionException e) {
         // ignore exception - bean not found
     }
   }
   return result;
}
}
&lt;/pre&gt;
As you can see, creating a variable resolver is quite straightforward and make dependency injection possible, even if you use an old fashioned service locator. Unit testing becomes a lot easier this way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5402106865572708118-6624357109415412925?l=kazed.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kazed.blogspot.com/feeds/6624357109415412925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5402106865572708118&amp;postID=6624357109415412925' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6624357109415412925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5402106865572708118/posts/default/6624357109415412925'/><link rel='alternate' type='text/html' href='http://kazed.blogspot.com/2007/10/create-your-own-jsf-variable-resolver.html' title='Create your own JSF variable resolver'/><author><name>koert</name><uri>http://www.blogger.com/profile/10367249400655051559</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
