WildFly – Performance tuning

If you run the RedHat Application Server WildFly in standalone configuraiton you can customize the Java VM options to do some performance tuning.

The VM Options

In different to GlassFish the VM Options can not be set from the WildFly Web Console. But you can change or add VM Options by changing the standalone.conf file in the /bin directory. (Note that this is not the same as the standalone.xml configuration inside the /stanalone/ folder!)

Typical values to use for a 3G RAM machine  are:

-Xmx1024m 
-Xms1024m 
-Xss128k
-XX:MaxPermSize=256m
-XX:PermSize=64m
-XX:NewRatio=2

or for a machine with 4G RAM.

-Xmx2048m 
-Xms2048m 
-Xss128k
-XX:MaxPermSize=256m
-XX:PermSize=64m
-XX:NewRatio=2

The JAVA_OPTS section in your standalone.conf file then should look like this:

...
# Specify options to pass to the Java VM.
#
if [ "x$JAVA_OPTS" = "x" ]; then
JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:PermSize=64m -Djava.net.preferIPv4Stack=true"
 JAVA_OPTS="$JAVA_OPTS -Djboss.modules.system.pkgs=$JBOSS_MODULES_SYSTEM_PKGS -Djava.awt.headless=true"
else
 echo "JAVA_OPTS already set in environment; overriding default settings with values: $JAVA_OPTS"
fi

You can verify your new settings directly in the beginning of the output when starting your WildFly

=========================================================================

 JBoss Bootstrap Environment
 JBOSS_HOME: /opt/wildfly-8.0.0.Final
 JAVA: java
 JAVA_OPTS: -server -XX:+UseCompressedOops -Xms1024m -Xmx1024m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true

 

Database Pool

Also the Database Pool Configuration in WildFly is different to the settings in GlassFish. GlassFish comes with some useful default values. In WildFly you should add the following Pool Settings:

  • Min Pool Size = 5
  • Max Pools Size = 25
  • Share Prepared Statements = true
  • Statement Cache Size: 32

 

Session EJB Pooling

For some reason the pooling of stateless EJBs is disabled per default in WildFly. If you have  expensive initialization in your stateless session EJBs it is very useful to add pooling for that kind of beans. This can increase the performance of your application dramatically.

Edit the standalone.xml file in the WildFly /standalone/configuration/ directory and change the section “session-bean” like in the following example:

...
  <subsystem xmlns="urn:jboss:domain:ejb3:2.0">
            <session-bean>
                <stateless>
                    <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
                </stateless>
                <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
                <singleton default-access-timeout="5000"/>
            </session-bean>
            <pools>
                <bean-instance-pools>
                    <strict-max-pool name="slsb-strict-max-pool" max-pool-size="32" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
                    <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
                </bean-instance-pools>
            </pools>
....
.....

See also: https://community.jboss.org/message/881747

Migrate from GlassFish to WildFly

In this blog I just want to post some of my thoughts about migrating from GlassFish to WildFly. The main issue here for me is to deploy an existing EAR currently running on GlassFish 3. This EAR contains EJBs, Web, and REST modules and includes TimerServices, Security Issues and custom servlets. So it’s not the easy hello-world example.

I am working on Linux Debian 7 and using Open JDK 1.7.0_55. The examples show the configuration for the Imixs Office Workflow Suite. Continue reading “Migrate from GlassFish to WildFly”

How to use a jquery dialog in jsf 2.0

Combining JSF 2.0 and jQuery / jQuery-UI is in my opinion the best choice to build modern web applications. Your JSF web application becomes much smaller as using one of the JSF component libraries. Also with jQuery you got a lot of flexibility designing your pages.

But things become interesting when you try to integrate a jQuery Dialog box with JSF 2.0. I am talking here about a Dialog Box which contains a JSF form with input elements to be submitted – independent from the current page flow. For example: you have a normal jsf form with input components and a link to open another form (in my case a user-profile dialog) also with data which can be submitted. It takes me some time to figure out the best way to manage this. But with JSF 2.0 and ajax support things are not so difficult.

So here is my Solution:

THE DIALOG FORM

I put my Dialog into a JSF faclet to separate all the dialog stuff in one xhtml element which can be included in the main pages. The interesting thing is here the JSF validation which is also supported. The dialog will not close if a validation error occurs. There for I check the #{facesContext.validationFailed} and save the state in a JavaScript variable. The ajax method ‘processCompleteEvent’ checks if a validation exception was thrown. In that case the dialog stays open, otherwise it will be closed after submit. The command button triggers a JSF 2.0 ajax request to avoid any changes on the main page behind the dialog.

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">

	<script type="text/javascript">
		/*<![CDATA[*/
		$(document).ready(function() {
			// setup dialog
			$("#dialog-myprofile").dialog({
				resizable : false,
				width : 530,
				modal : true,
				autoOpen : false
			});
		});

		// auto close dialog and check validation... 
		var validationError=false;
		function processCompleteEvent(e) {
	          if (e.status == 'success') {
	        	if (!validationError) {
	        	 	$("#dialog-myprofile").dialog("close");
	       	 	}
	          }
	        }
		// open dialog
	 	function openMyProfile() {
			$("#dialog-myprofile").show();
			$("#dialog-myprofile").dialog("open");			
	    	}
		/*]]>*/
	</script>

	<div id="myprofile_view">
		<!-- Dialog Box -->
		<div id="dialog-myprofile" title="#{message['profile.title']}">
			<h:form id="dialog-myprofile-form">
				<ui:include src="/pages/error_message.xhtml" />
				<script>validationError=#{facesContext.validationFailed};</script>
				<h:inputText
					value="#{userController.workitem.item['txtusername']}"
					style="width: 260px;" />

				<!-- Save Action -->
				<h:commandButton actionListener="#{userController.doProcess}"
					 value="#{message.save}">					
					<f:ajax execute="@form" render="@form"
						onevent="processCompleteEvent">
					</f:ajax>
				</h:commandButton>
				<input type="button"
					onclick="$('#dialog-myprofile').dialog('close');"
					value="#{message.close}" />
			</h:form>
		</div>
	</div>
</ui:composition>

 

HOW TO OPEN THE DIALOG FROM THE MAIN PAGE

To open the Dialog from my main template I use a h:commandLink with an onclick event to open the jQuery dialog. See the following code snippet:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:c="http://java.sun.com/jsp/jstl/core"
	xmlns:f="http://java.sun.com/jsf/core"
<h:head>
.....
	<script type="text/javascript" src="../jquery-ui-1.10.0.custom.min.js"></script>
	<script type="text/javascript" src="../jquery-1.9.0.js"></script>
.....
</h:head>
<h:body>
   <f:view id="main_view">
.....
	<h:form id="main_form">
...
		<h:commandLink onclick="openMyProfile();">
			<h:outputText id="profile_userlink"
				value="#{message.open_profile}" />
			<f:ajax render=":dialog-myprofile-form" />
		</h:commandLink> 
	</h:form>
...
	<ui:include src="/pages/profile/myprofile_dialog.xhtml" />
   </f:view>
</h:body>
</html>

The trick here is again the ajax integration of the commandLink.

<f:ajax render=":dialog-myprofile-form" />

The f:ajax tag will rerender the dialog form. This is an important part of this solution, because you need to reset the old data of the dialog when the dialog is reopened. For example when the user opens the dialog, types in some data and close the dialog without submitting the data. In this scenario it is necessary to reload the dialog form data. This is done by the ajax render command.

So that’s it. I hope this will help someone.

Using @multipartconfig in a servlet running on GlassFish 3.2.2

Today I run into a problem with a custom JSF component using the @MultipartConfig. Trying to use my FileUpload Bean (http://www.imixs.org/jsf/fileupload.html) results in the following error message:

[#|2013-04-26T15:37:21.769+0200|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=20;_ThreadName=Thread-2;|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: PWC4016: Request.getParts is called without multipart configuration.  Either add a @MultipartConfig to the servlet, or a multipart-config element to web.xml

It seems that this error did not be thrown on a GlassFish 3.2.1 server.

Finally I was able to fix the problem when adding the following servlet configuration into the web.xml file for my Faces Servlet.

 ...
	<!-- Facelets -->
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>0</load-on-startup>		
		<multipart-config>
	    	  <location>/tmp</location>
	    	  <max-file-size>20848820</max-file-size>
	    	  <max-request-size>418018841</max-request-size>
	    	  <file-size-threshold>1048576</file-size-threshold>
		</multipart-config>
        </servlet>
.....

 

 

How to Submit an Embedded Form in jQuery Dialog using AJAX

Today I searched for a solution to submit a form embedded into a jQuery dialog with ajax.

My situation is the following: I use a jQuery UI Dialog to display a feedback-form in my web application. The feedback form should not change the state of the page the user worked before.

So my first approach was to change my form post action into a ajax post action. This can be done easily during the initialisation of the dialog. See the following code snippet:

/**
 * Method to initialize the feedback dalog.
 * @see contact_dialog.xhtml
 */
function initContactDialog() {
    // set default settings for profile dialog
    $("#dialog-contact").dialog({
        resizable : false,
        height : 530,
        width : 550,
        modal : true,
        autoOpen : false
    });


    // hide contact dialog per default
    $("#dialog-contact").hide();
        
    // the following method modifies the submit request into a ajax request
    // So the dialog will be closed after the submit was successfull without
    // affects to the main page.
    $('#dialog-contact-form').submit(function() {
        
        // show up waiting panel
        $(".ajax-wait-panel").addClass("ajax-waiting"); 
   
        $.ajax({
               type: "POST",
               url: "http://localhost:8080/myrestservice",
               data: $("#dialog-contact-form").serialize(), // serializes the form's elements.
               success: function(data)
               {
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
                   $("#dialog-contact").dialog("close");
               },
               error: function(data)
               {
                   alert('An error occured. Could not send data!'); // show response from post.
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
               }
             });

        return false; // avoid to execute the actual submit of the form.
    });
    
}

With the initContactDialog() method I initialize the dialog and bind a function to the submit event of my form. The function changes the submit into a ajax call and closes the dialog after the ajax request was finished.

This is quite easy and the dialog will automatically close when the Ajax submit was finished.

Here is the html part of my dialog form:

    <!-- Dialog Box -->
        <div id="dialog-contact"  title="#{global.contact_title}">
            <form id="dialog-contact-form" method="post" name="contact_form">

                <h:panelGrid columns="2">

                    <h:panelGroup>
                        <dl>
                            <dt>#{global.contact_firstname}:</dt>
                            <dd>
                                <input type="text" name="txtfirstname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_lastname}:</dt>
                            <dd>
                                <input type="text" name="txtlastname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_email}:</dt>
                            <dd>
                                <input type="text" name="txtemail" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                </h:panelGrid>
                <dl style="margin: 0 0 0 0px;">
                    <dt>#{global.contact_message}:</dt>
                    <dd>
                        <textarea style="width: 450px; height: 80px;" name="_description" />
                    </dd>
                </dl>
                <input type="submit" value="send" />

            </form>
            <div>
                <h2>#{global.please_wait}</h2>
            </div>
        </div>

I open the dialog with the following JavaScript function:

 /**
 * helper method to open the contact dialog. 
 * The method creates a new empty contact workitem.
 */
function openContact() {    
   $("#dialog-contact").show();
   $("#dialog-contact").dialog("open");
}

AJAX ‘WAIT-PANEL’

As you can see in my script and in the html snippet I have added a div section with the class ‘ajax-wait-panel’. This div overlays the form of my dialog when the ajax call is started. So the user will see a ‘Please wait’ message until the ajax request is finished. I simply add the class ‘ajax-waiting’ to the div section in the moment the request starts and remove the class when the submit was finished. So this is the css part of my solution:

/* Ajax-wait-panel can be useded in jquery dialogs
   for long runnign ajax request.
   Start by setting display:none to make this hidden.
   Background we set to 80% white with
   our animation centered, and no-repeating */
 .ajax-wait-panel {
    display:    none;
    position:   absolute;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .6 ) 
                url('ajax-loader.gif') 
                50% 50% 
                no-repeat;
    cursor: wait;
}

.ajax-wait-panel  h2 {
    position: absolute;
    top: 50%;
    margin-top: -80px;
    color: #666;
    text-align: center;
    width: 100%;
}
/* Class to be added when ajax wait panel should 
   be displayed */
.ajax-waiting {
     display: block;
}

jQuery Dialog – how to submit a form with ajax

Today I searched for a solution to submit a form embedded into a jQuery dialog with ajax.

My situation is the following: I use a jQuery UI Dialog to display a feedback-form in my web application. The feedback form should not change the state of the page the user worked before.

So my first approach was to change my form post action into a ajax post action. This can be done easily during the initialisation of the dialog. See the following code snippet:

/**
 * Method to initialize the feedback dalog.
 * @see contact_dialog.xhtml
 */
function initContactDialog() {
    // set default settings for profile dialog
    $("#dialog-contact").dialog({
        resizable : false,
        height : 530,
        width : 550,
        modal : true,
        autoOpen : false
    });

    // hide contact dialog per default
    $("#dialog-contact").hide();

    // the following method modifies the submit request into a ajax request
    // So the dialog will be closed after the submit was successfull without
    // affects to the main page.
    $('#dialog-contact-form').submit(function() {

        // show up waiting panel
        $(".ajax-wait-panel").addClass("ajax-waiting"); 

        $.ajax({
               type: "POST",
               url: "http://localhost:8080/myrestservice",
               data: $("#dialog-contact-form").serialize(), // serializes the form's elements.
               success: function(data)
               {
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
                   $("#dialog-contact").dialog("close");
               },
               error: function(data)
               {
                   alert('An error occured. Could not send data!'); // show response from post.
                   $(".ajax-wait-panel").removeClass("ajax-waiting"); 
               }
             });

        return false; // avoid to execute the actual submit of the form.
    });

}

With the initContactDialog() method I initialize the dialog and bind a function to the submit event of my form. The function changes the submit into a ajax call and closes the dialog after the ajax request was finished.

This is quite easy and the dialog will automatically close when the Ajax submit was finished.

Here is the html part of my dialog form:

    <!-- Dialog Box -->
        <div id="dialog-contact"  title="#{global.contact_title}">
            <form id="dialog-contact-form" method="post" name="contact_form">

                <h:panelGrid columns="2">

                    <h:panelGroup>
                        <dl>
                            <dt>#{global.contact_firstname}:</dt>
                            <dd>
                                <input type="text" name="txtfirstname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_lastname}:</dt>
                            <dd>
                                <input type="text" name="txtlastname" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                    <h:panelGroup>
                        <dl style="">
                            <dt>#{global.contact_email}:</dt>
                            <dd>
                                <input type="text" name="txtemail" value="" />
                            </dd>
                        </dl>
                    </h:panelGroup>
                </h:panelGrid>
                <dl style="margin: 0 0 0 0px;">
                    <dt>#{global.contact_message}:</dt>
                    <dd>
                        <textarea style="width: 450px; height: 80px;" name="_description" />
                    </dd>
                </dl>
                <input type="submit" value="send" />

            </form>
            <div>
                <h2>#{global.please_wait}</h2>
            </div>
        </div>

I open the dialog with the following JavaScript function:

 /**
 * helper method to open the contact dialog. 
 * The method creates a new empty contact workitem.
 */
function openContact() {    
   $("#dialog-contact").show();
   $("#dialog-contact").dialog("open");
}

AJAX ‘WAIT-PANEL’

As you can see in my script and in the html snippet I have added a div section with the class ‘ajax-wait-panel’. This div overlays the form of my dialog when the ajax call is started. So the user will see a ‘Please wait’ message until the ajax request is finished. I simply add the class ‘ajax-waiting’ to the div section in the moment the request starts and remove the class when the submit was finished. So this is the css part of my solution:

/* Ajax-wait-panel can be useded in jquery dialogs
   for long runnign ajax request.
   Start by setting display:none to make this hidden.
   Background we set to 80% white with
   our animation centered, and no-repeating */
 .ajax-wait-panel {
    display:    none;
    position:   absolute;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .6 ) 
                url('ajax-loader.gif') 
                50% 50% 
                no-repeat;
    cursor: wait;
}

.ajax-wait-panel  h2 {
    position: absolute;
    top: 50%;
    margin-top: -80px;
    color: #666;
    text-align: center;
    width: 100%;
}
/* Class to be added when ajax wait panel should 
   be displayed */
.ajax-waiting {
     display: block;
}

JSF f:ajax – How to locate componets outside the current context

Using JSF 2.0 and Ajax simplifies the web design and provides a lot of cool tricks to extend the user experience. With the render and execute tags form the f:ajax tag it is use to update components dynamically.

But in the past I run often into problems when trying to update a component outside the current ui context. For example when you try to update a part of your form for a single row in h:datatable component you will typically see log messages like this one:

f:ajax contains an unknown id 'j_idt90:painelTabela' - cannot locate it in the context of the component j_idt75

To solve such kind of problems you need to specify the full component id to be rendered or executed. This is not always as easy at it sounds. When your component is nested in a complex component tree the component id can be prafixed with a long list of parent component ids. This happens typically in h:datatables, ui:repeats or c:forEach sections.

One solution is to navigate back in the tree to the correct ui node and get the componentID using an EL syntax like this:

<f:ajax render=":#{component.parent.parent.parent.parent.clientId}:new-minute-panel:" />

This looks not really nice and it creates new problems when you redesign or move your ui components into a new structure on your jsf page.

A simple trick to solve the problem is to bind the component which need to be rendered into a ui param. So you can reference its full clientId in the ajax context. See the following example:

<h:panelGroup layout="block" id="mylist" binding="#{myListComponent}">                
   <ui:repeat var="attachment" value="#{myController.myList}">
       ....
       <!-- some ajax functionality... -->
       <f:ajax render=":#{myListComponent.clientId}">
           <h:commandLink actionListener="#{myController.soSomething}">click me</h:commandLink>
       </f:ajax>
 ...
   </ui:repeat>
....

In this example I use the binding tag to bind the panelGroup to a param named ‘myListComponent’. Inside the ui:repeat I can now access the outer component and render the component fom my f:ajax element accessing the clientId

<f:ajax render=":#{myListComponent.clientId}"

As a result the ajax component no longer depends on the position in my page and I can reuse it in any part of my jsf page.

TRANSFER CLIENTIDS TO SUBFORMS

Another solution using the binding is to transfer a component into a subform. See the following example:

 <h:panelGroup id="my_panel" binding="#{myListComponent}">
     <h:dataTable id="mydatatable" value="#{myController.myList}" var="child">
       .....
        <ui:include src="/forms/sub_myeditor.xhtml" >
            <ui:param name="myPanel" value="#{myListComponent}" />            
        </ui:include>
       .....
     </h:dataTable>

In this example I transfer the ui:component containing my h:datatable to a subpage ‘sub_myeditor.xhtml’  which is included inside the table. Now I can access the panelGroup inside my subpage and render it after an ajax event:

<h:commandButton ....  >
       <f:ajax render=":#{myListComponent.clientId}" 
                execute=":#{myListComponent.clientId}"/>
</h:commandButton>

Also in this example the component in the ajax tag is addressed with its absolute path.

Glassfish and Active Directory

Running JEE Applications on Glassfish can be easily connected to an existing Microsoft Active Directory Structure.

To authenticate a JEE application against Active Directory (AD) you can setup a LDAPRealm in Glassfish. Use the folowing example settings:

  •  JAAS Context: ‘ldapRealm’
  • Direcotry : ldap://your-ad-server:389
  • Base DN: ‘DC=mycompany,DC=local’

Additional to these standard connection settings (you should use your own environment configuration) you need to add the following additioanl Properties:

  • search-filter = (&(objectClass=user)(sAMAccountName=%s))
  • group-search-filter = (&(objectClass=group)(member=%d))
  • search-bind-dn = some-technical-account (do not use distinguished name)
  • search-bind-password = your-technical-account-password
  • java.naming.referral = follow

The property ‘java.naming.referral = follow’ is necessary in most cases to avoid internal exceptions during a search request.

Thats it.

HOW TO CONFIGURE AN  EXTERNAL JNDI RESOURCE

You can also use the AD to lookup additional ldap attributes from you application code. There for you need to add a external JNDI Resource which can be configured from the GlassFish console. Use the following example settings:

  • JNDI Name : you-custom-resource-name
  • Resource Type: javax.naming.ldap.LdapContext
  • Factory CLass: com.sun.jndi.ldap.LdapCtxFactory
  • JNDI Lookup: ‘DC=mycompany,DC=local’

Also here you should add some additional properties:

  • java.naming.provider.url = ldap://your-ad-server:389
  • java.naming.security.authentication = simple
  • java.naming.security.principal = some-technical-account (do not use distinguished name)
  • java.naming.security.credentials = your-technical-account-password
  • java.naming.referral = follow

The property ‘java.naming.referral = follow’ again is important here.

To lookup the external resource from your application you can use the either a annotation:

@Resource(name = "you-custom-resource-name")
private DirContext ldapConn;

You can also do a programatic lookup like this:

Context initCtx = new InitialContext();
ldapCtx = (LdapContext) initCtx.lookup("you-custom-resource-name");

 

JSF 2.0 – ajax suggestion box

Since JSF 2.0 has introduced the ajax support it is quite simple to implement functional widgets like a suggestion input box. The following short tutorial shows how to build your own suggestion widget using JSF 2.0 and it’s ajax capabilities.

1. THE HTML FORM

First you need a simple input field where the user can type in a search phrase. This can be done wit the h:inputText element. After the user typed in some character a suggestion widget should start a backend search and provide the user with a list of suggestions (you can see this behaviour when searching for something on google.com). To connect your inputText element with a backend component you can use the new build-in ajax feature provided by JSF 2.0. So your input element looks something like this:

<h:panelGroup layout="block" style="margin-bottom:5px;">
     <h:inputText value="#{suggestController.input}">
        <f:ajax event="keyup"  render="suggest_box" /> 
     </h:inputText>
</h:panelGroup>

 

2. DEFINE THE SUGGEST BOX

With the ‘render’ attribute of the f:ajax tag you specify which part of your page should be rerendered after the ajax event was fired. In this case an element with the ID ‘suggest_box’ will be updated. This is the part where you can display the results of your backend search:

<h:panelGroup id="suggest_box">
	<ul>
		<ui:repeat var="entry" value="#{suggestController.result}">
			<li>#{entry}</li>
		</ui:repeat>
	</ul>
</h:panelGroup>

 

To bind you backend component (suggestController) to the event just use the listener tag:

 <f:ajax event="keyup" render="suggest_box"
	listener="#{suggestController.search}" >
</f:ajax>

Your suggest controller implementation can look like this:

....
public void search(AjaxBehaviorEvent event) {
	....
	result=new ArrayList<String>();
	....
}

public List<String> getResult() {
	return result;
}

If you are working with EL 2.2 support (GlassFish 3.1) you can also pass params as method arguments:

<f:ajax event="keyup" render="suggest_box"
	listener="#{suggestController.search('abc')}" >
</f:ajax>
public void search(String param) {
       ..
}

 

3) LAYOUT

Now you can do some layout stuff. Typically the suggestion box should only be displayed with a user typed in a search phrase. And the suggestion box should hidden if the focus is lost. This can be done with some css definition:

.suggestbox {
	position: relative;
}

.suggestbox .resultlist {
	display: block;
	position: absolute;
	z-index: 1;
	left: 2px;
	top: 22px;
	border: 1px solid #CCC;
	background-color: #EEE;
}

To hide the resultlist you can use the f:ajax event ‘blur’

 <f:ajax event="blur" render="suggest_box"
                    listener="#{suggestController.reset}" />

The listener is bound to a backend method which resets the result list. So you can display the complete box in order of the current result. This is the complete code:

JSF Code:

<h:panelGroup layout="block">
	<!-- Process references -->
	<h:panelGroup layout="block" style="margin-bottom:5px;">
		<h:inputText value="#{suggestController.input}">
			<f:ajax event="keyup" render="suggest_box"
				listener="#{suggestController.search('')}" />
			<f:ajax event="blur" render="suggest_box"
				listener="#{suggestController.reset}" />
		</h:inputText>
	</h:panelGroup>
	<h:panelGroup id="suggest_box">
		<h:panelGroup id="suggest_resultlist"
			rendered="#{! empty suggestController.result}">
			<ul>
				<ui:repeat var="entry" value="#{suggestController.result}">
					<li>#{entry}</li>
				</ui:repeat>
			</ul>
		</h:panelGroup>
	</h:panelGroup>
</h:panelGroup>

 SuggestController:

@Named("suggestController")
@RequestScoped
public class SuggestController implements Serializable {

	private static final long serialVersionUID = 1L;
	private List<String> result=null;
	private String query = null;
	private String input =null;
	
	public SuggestController() {
		super();
		result = new ArrayList<String>();
	}

	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}

	public String getInput() {
		return input;
	}

	public void setInput(String input) {
		this.input = input;
	}
	
	public void reset(AjaxBehaviorEvent event) {
		 result=new ArrayList<String>();
	}
	
	public void search(String query) {
    	result=new ArrayList<String>();
		result.add("Hallo "  + System.currentTimeMillis());
		result.add("World "+ + System.currentTimeMillis());

	}
	
	public List<String> getResult() {
		return result;
	}

}

4) DELAY AJAX EVENTS

Maybe you run into a problem with the onblur ajax call to hide your overlay section. If the section contains h:command links or buttons the action and actionListeners will not be called because the ajax blur event hides the overlay to early.

With a trick from BalusC you can delay the blur event a little bit. So just add the following jQuery code into your page:

$(document).ready(function() {
	$(".suggestinput").each(function(index, input) {
	    var onblur = input.onblur;
	    input.onblur = null;
	
	    $(input).on("blur", function(event) {
	        delay(function() { onblur.call(input, event); }, 300);
	    });
	    // turn autocomplete of
	    $(this).attr('autocomplete','off');
	});

});

var delay = (function() {
    var timer = 0;

    return function(callback, timeout) {
        clearTimeout(timer);
        timer = setTimeout(callback, timeout);
    };
})();

 

JEE6 – How to package an EAR – Part II.

As I explained in my previous blog entry about JEE6 ear packaging, there is a flexible and powerful way to deploy EARs containing JEE component libraries.

Using maven makes it much easy to build such ear deployment units. The interessting part of the pom.xml of the ear module looks something like this:

 

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <version>6</version>
                    <modules>
                        <webModule>
                            <groupId>myweb</groupId>
                            <artifactId>imixs-web</artifactId>
                            <contextRoot>/test</contextRoot>
                        </webModule>
                        <ejbModule>
                            <groupId>myejb</groupId>
                            <artifactId>imixs-ejb</artifactId>
                        </ejbModule>
                        <JarModule>
                            <groupId>org.imixs.workflow</groupId>
                            <artifactId>imixs-workflow-engine</artifactId>
                            <bundleDir>/</bundleDir>
                        </JarModule>                        
                    </modules>
                </configuration>
            </plugin>
        </plugins>
 ....

In this example the artefact ‘imixs-workflow-engine’ is a component library containingg EJBs. You can refere to those libraries from your ejb module (in this example ‘myejb’) by using the ‘manifestEntries’ tag in your maven ejb module configuration. This is what I explained here.

But what if you need some more additional external libraries containing non-jee-components (simple pojo’s like for example apache commons-xx.jars) ?

You can add those dependencies to your ear pom.xml – so these jars will also become part of the ear root directory. But now you need to add them again to the manifest file of your ejb module if you need access to these libraries. And this will result in a strange situation because indirect dependencies will make it impossible for you to manage your manifest file manually.

I run in this situation when a need the apache fop-1.0 library in one of my ejb components.

But the solution is again quite simple when using maven and the ear-plugin. The plugin provides a configuration tag named ‘defaultLibBundleDir’. And you simply need to the the value to ‘lib’ to get all your libraries moved in the default lib directory of an ear:

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-ear-plugin</artifactId>
       <version>2.6</version>
       <configuration>
            <version>6</version>
            <defaultLibBundleDir>lib</defaultLibBundleDir>
            <modules> 
         .....
  ....
</plugin>

But you need to be careful because also your jee-component libraries will be moved into that location if you did not overwrite the default behaviour now.  You can do this by declaring each of your jee component libraries as a ‘JarModule’ where you specifiy the ‘bundleDir’ with ‘/’:

....
<module>
 ....
  <JarModule>
       <groupId>org.imixs.workflow</groupId>
       <artifactId>imixs-workflow-core</artifactId>
       <bundleDir>/</bundleDir>
  </JarModule>
</module>
...

This will result in a ear structure where your own jee-components will become part of the root of your ear, and all other library dependencies will be moved to the /lib directory of your ear. So any libary can be seen from your ejb, web and component modules. And you jee-component.jars will still be parsed for JEE annotations during deployment.

I hope this helps you to build you own custom enterprise applications using all the strength of JEE.