Main | Next page »
Samstag Feb 20, 2010

RichFaces on Glassfish

Today I run into a deployment problem during I tried to install my RichFaces Application on Glassfish. The situation was realy crazy. At the first look everything works well. But when I tried to add the rich:tree component into one of my pages the page causes an error on my glassfish server.
Even when I select a Node of my Tree Component I got an  

NoClassDefFoundError: org/apache/xerces/xni/parser/XMLConfigurationException

First I tried to add the newest xerces version into my web app. But this generates more and more problems as the xerces lib conflicts with the xerces parser provided by glassfish.

After playing arround with the richfaces config params in the web.xml I found that the nikohtml library was the problem why glassfish did not run the application properply

I have had used the following additional richfaces configuration in my web.mxl (I did no know why)

   <context-param>
        <param-name>org.ajax4jsf.xmlparser.ORDER</param-name>
        <param-value>NEKO, TIDY</param-value>
    </context-param>


And this leads into a problem with the xerces parser included into glassfish.
The solution easy. I simply replaced the NEKO with TIDY

So now I use the following configuration in my web.xml

    <context-param>
        <param-name>org.ajax4jsf.xmlparser.ORDER</param-name>
        <param-value>TIDY</param-value>
    </context-param>


And now the tree component works perfect !

An usefull link will also be this blog:

http://www.javaplex.com/blog/optimizing-jsf-richfaces-applications/


Donnerstag Feb 11, 2010

JEE6 and packaging an EAR

I spent the last weeks a lot of time to find out what's the best way of packaging an EAR deployable on a JEE6 Application Server like Glassfish V3. I stumble on some problems when I try to deploy my EAR on Glassfish V3 which was running before on JEE5 Glassfish V2.1 server. Now I find out the missing parts and I want to describe my experiences here. 

I am not talking about the typical EAR packaging situation you can see in the most of examples and tutorials where you have an EJB Module containing you business logic and a WEB Module containing your web frontend. As in JEE5 also in JEE6 it is pretty easy to deploy such an application. And there is in most cases no need to think about deployment descriptors as it was necessary before in J2EE (Java 1.3, 1.4).  

What I tried to find out was the right packaging of an EAR including different libraries containing JEE components like EJBs, JPA Entities and Servlets on top of my EJB and WEB Module. I call such libraries "Component-Libraries" to indicate that these libraries containing JEE Components which can be used out of the box.

So first lets take a look on a simple situation where you want to package a simple JAR file together with a EJB and Web module. For example you have a JAR providing some POJOs used by both modules (EJB and web module). In this situation you can drop such a library simply into the /lib folder of you EAR. So your EAR should have the following structure:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF]
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

As the pojo.jar is packaged into the /lib folder (which is the default location for shared libraries) both modules (the web and the ejb) can access the pojo.jar library. This is a typical situation and it is very easy to use.

But what if you have a component-library containing additional EJBs? If you package this library also into the /lib location like this:

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (ejb-components.jar)
 - [META-INF]
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)

the deployment will fail in most cases. The problem now is, that the EJBs  defined in the ejb-components.jar are in the top-level "lib" directory of the ear. That means the classes are visible to all modules in the ear. Each module (the my-ejb.jar and also the my-web.war) is processed for annotations, so the beans defined in the ejb-components.jar are created more than once. This is the reason that it is not recommended to put classes with component-defining annotations in a library .jar!

Ok - so lets put the ejb-components.jar out of the /lib folder location:

[my-ear]
 - [lib]
     |- (pojo.jar)
 - [META-INF]
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
- (ejb-components.jar)

But now the EJBs of the ejb-components.jar will not be deployed because this jar is not a declared as an ejb module. Ok - you can add the jar to the application.xml file and declare this jar to an additional ejb module like this:

<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd" version="5">
  <module>
    <web>
      <web-uri>my-web.war</web-uri>
      <context-root>/my-web</context-root>
    </web>
  </module>
  <module><ejb>my-ejb.jar</ejb></module>
  <module><ejb>ejb-components.jar</ejb></module>
</application>

This will work until you have to overwrite the ejb-jar.xml file. But this situation often occurs if you need to reconfigure the EJBs of the ejb-components.jar. And as you have no sources of this jar you can not easily rebuild it with additional descriptors. So now you have a real problem!

But there is a trick which enables you to take over control of all the EJBs defined in the ejb-componets.jar directly in your my-ejb.jar where you have the sources to build this module.
Simply add a Class-Path definition to the META-INF/MANIFEST.MF file of your ejb module:

Manifest-Version: 1.0
Class-Path: ejb-components.jar

Now the ejb-components.jar become a part of your my-ejb.jar and you can overwrite each setting in you ejb-jar.xml file. If you are using maven as your build tool you can add this additional Manifest entry simply by using the maven-ejb-plugin.

            .......
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-ejb-plugin</artifactId>
                <configuration>
                    <ejbVersion>3.0</ejbVersion>
                    <archive>
                        <manifestEntries>
                            <Class-Path>ejb-components.jar</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>               
            </plugin>
            .......

If you are not using maven simply add the MANFIFEST.MF file into your my-ejb module.

OK why did I talking about all this stuff? In the situation I describe here I assume that your are not in the role of the component-developer of the EJBs implemented in the ejb-components.jar. Your are in the Role of the component-deployer. In this role you do not change the implementation but you may want to overwrite some settings of the ejbs provided by the component-developer. For example you want to define a 'run-as-principal' role to a ejb or a method. Or you would like to rename a ejb or inject a local jndi-mail or jndi-directory resource by name. In this cases you can do this now by the ejb-jar.xml which is located in your ejb modle (my-ejb.jar) and which is under your control.

Remember - JEE is in first place a component architecture. This means you develop an ejb component once and you can reuse and run this component everywhere in your environment. I think this part of JEE is sometimes missed in lots of JEE projects. So this concept follows the goal to simplify your deployment and your project structure but also reuse complex components in an easy way.

Servlets and JPA Entities

Until now I explained how to deploy ejb component jars. Next I want to take a look on another kind of JEE components - Servlets and JPA Entities.

If you have a jee-component.jar containing Servlets you can follow the instructions above. A servlet provided by the ejb-components.jar will be visible to a web module as your my-ejb.jar is part of your EAR. But your servlet will not able to use injected EJB or JNDI Ressources. So an annotation with an EJB injection in your servlet code will not work:

public class WorkflowRestService extends javax.servlet.http.HttpServlet
implements javax.servlet.Servlet {
....
    @EJB
    org.imixs.workflow.jee.ejb.EntityService entityService;
.....

The reason why the entityService EJB in this case will not be injected is that the servlet class located in the ejb-componets.jar is visible to the web module but the servlet will not be scanned for injections because it is now part of our EJB module. So it is not recommended to deploy a component-library containing a servlet in the way described before.

Component-libraries containing Servlets and also JPA Entities can be still placed into the /lib location of your EAR.

[my-ear]
 - [lib]
     |- (pojo.jar)
     |- (servlet-components.jar)
     |- (jpa-components.jar)
 - [META-INF]
     |- application.xml
     |- sun-application.xml
 - (my-ejb.jar)
 - (my-web.war)
- (ejb-components.jar)

In this case your servlet from the servlet-components.jar is visible now to the web module (my-web.war) and Injection will work as expected. So do not! mix up EJB, JPA and WEB components into one component-library. This is also important as you increase the deployment flexibility of your project for future.

I the case of the jpa-components.jar there is another detail to be pointed out.

I assume that the jpa-comonents.jar includes Entitie EJBs like this:

package org.imixs.workflow.jee.jpa;
.....
@javax.persistence.Entity
public class Entity implements java.io.Serializable {
......

The Entities are typical injected by EJB components using an JPA EntityManager

    @PersistenceContext(unitName = "org.imixs.workflow.jee.jpa")
    private EntityManager manager;

As the jpa-components.jar is now located in the /lib folder of the ear you need to declare the location of the jpa unit in the persistence.xml file. And now I am back to the my-ejb.jar module where you are the component-developer. As you control this module you can place the persistence.xml file into the META-INF folder and define the location of your jpa-component.jar there:

persistence.xml:

<persistence>
    <persistence-unit name="org.imixs.workflow.jee.jpa">
        <jta-data-source>jdbc/workflow-db</jta-data-source>
        <properties>
            <property name="toplink.ddl-generation"
                value="create-tables" />
        </properties>
        <jar-file>lib/jpa-components.jar</jar-file>
    </persistence-unit>
</persistence>

So again you have full control about the deployment of all your components provided by third party component-libraries.

Conclusion

After some problems starting deploying my EAR on Glassfish V3 (migrating from Glassfish V2.1) I think JEE6 is still a flexible and powerful application platform. Also the platform supports strong capabilities in the configuration of complex applications and the usage of third party components. And JEE6 is a component architecture which supports a modular concept of build applications from components to be reused in different situations.

But I still have some problems in deploying WebService components from a component-library. I will continue to figure out how to deploy such components. If you have any suggestions or comments please let me know and post them here.

Montag Feb 08, 2010

Imixs JEE Workflow 2.0.2 release

I am currently working on the next release of the Imixs JEE Worklfow Engine (2.0.2). My main goal is to support JEE6 / Glassfish V3. Currently there are some changes necessary to extend the REST Service API and simplify the Deployment on glassfish servers. Also I hope to support JBoss Application Server V5 soon. See the Issue Tracker on imixs.org for more details.


 

Sonntag Jan 31, 2010

Eclipse Galileo - JSF Content Assist for xhtml files

In the past I wrote some articles about how to configure Eclipse to get a content assistance for xhtml files in a jee project (things like code completion and mouse over hints). (see: Ganymede and faclets and Eclipse JSF/Facelet Support)

As Thiago dos Santos Prado posted in one of the comments all the stuff of configuration seems to be dispensable in Eclipse Galileo. But still Eclipse Galileo is not disposed to support content assistance for xhtml file out of the box. I can't find out why Eclipse ignores xhtml files in most jee projects as this is a standard file format for JSF applications. Maybe that the problem only exists for Maven based projects as maven is a little bit untended in Eclipse IDE. 

But it seems to be now very easy to add this missing feature simply by adding an additional content type for xhtml files:

  1.  Open "window" > "Preferences..." and select "General" > "Content Types"

     

  2. Next click the button "Add..." button and add the new content type ".xhtml"

     

  3. Finally check if the File Association for .xhtml Files is set to "JSP Editor". In my case this is already configured right.




Thats it!

Now you have content assistence for Java Server Faces and also all included JSF third libraries like RichFaces or MyFaces.

 

Sonntag Jan 17, 2010

Glassfish & OpenID - JSR-196 with OpenID4Java

Today I implemented a new ServerAuthModule based on JSR-196 using the OpenID4Java library. OpenID4Java is a open source library supporting the Client side authentication process to login a user with an OpenID.

OpenID is an open standard that allows a User to sign into web sites through a single URL (a single digital identity). This URL can be a personal home page, a blog or a web service (e.g from a OpenID Provider like myopenid, Google or yahoo.com) that the user is already using. In any case the user must register only once with his OpenID service provider and therefore he need only one password. Another advantage of using OpenID in your web application is the exemption of hosting and managing user accounts and password informations. You can read more about the details on openid.net.

Using JSR-196 and OpenID

There are different solutions available to enable a Web Application to login users with there OpenID account. One of the most auspicious mechanisms to integrate OpenID in JEE Applications is the jsr-196. This authentication service allows web containers to use different login modules - like an external openid provider. JSR-196 is part of Glassfish Server so a Login Mechanism based on the jsr-196 is very easy to use in a JEE or Web application. Ron Monzillo who is the specification lead gives a good overview about the jsr-192 on his blog  "concepts behind JRS-196".

How to Install the OpenID4JavaAuthModule

The OpenID4JavaAuthModule I have written is easy to install. To enable your JEE Web application for OpenID you need a Server plattform supporting JSR-196. The following section will describe the installation steps for a Glassfish Application Server. Glassfish supports JSR-196. But there may be also other web containers supporting JSR-196.

To install the OpenID4Java AuthModule you first need to download the following parts:

Copy the imixs-openid-0.0.2-SNAPSHOT.jar into the Glassfish Lib folder

[GLASSFISHHOME]/lib/

Extract the the openid4java zip archive and copy the following jars into your Glassfish Domain lib/ext/ folder.

  • openid4java-0.9.5.jar
  • commons-codec-1.3.jar
  • commons-httpclient-3.0.1.jar
  • commons-logging-1.03.jar 

The glassfish domain specific /lib folder is located on the following path:

[GLASSFISHHOME]/domains/domain1/lib/ext/

where domain1 is your prefered domain (domain1 is the default domain typical used).

Notice: The tree commons-* libraries are appache utilities which are used by openid4java.

Configuration of the OpenID4JavaAuthModule

Now you can configure the OpenID4JavaAuthModule using the GlassFish Admin Console following the next steps:

  1. Make sure the GlassFish Application Server is running. If it is not already running, you can start it using the following command:
       <GF_HOME>bin/asadmin start-domain domain1

    where <GF_HOME> is the directory where you installed GlassFish

  2. Open the GlassFish Admin Console by pointing your browser to the URL: http://localhost:4848/.
  3. Login to the Admin Console by entering your ID and password.
  4. Expand the Configuration node at the bottom of the left-hand pane.
  5. Navigate to the Security node, expand it, and click MessageSecurity.




  6. Under Message Security Configurations, either open the HttpServlet layer if it already exists, or create it if it doesn't exist by clicking the New button. Clicking the button opens the New Message Security Configuration window.
  7. If you can not see the HttpServlet node you need to create the layer:

     

     Click the "New" button and you can than start to configure the new provider in one step. To do that:

    • Set the following in the New Message Security Configuration window:

      Provider Type: server
      Provider ID: OpenIDProvider
      Class Name: org.imixs.openid.openid4java.OpenID4JavaAuthModule

      Do not check the Default Provider: Enabled check box.

       

    • Click the OK button. This saves the settings and opens the Message Security Configurations window.
    • Click on HttpServlet in the Authentication Layer column.
    • Select the Providers tab. This opens the Provider Configuration window.
    • Select OpenIDProvider in the Provider ID column you just created. This opens the Edit Provider Configuration window.
    • Click the Save button to complete the configuration of the provider.

    If the HttpServlet layer already exists, you open first the provider list and add a new Provider:

    • Open the HttpServlet layer by selecting it in the Message Security Configurations window.
    • Select the Providers tab to open the Provider Configuration window.




    • Click the New button to open the New Provider Configuration window.
    • In the Provider Configuration area of the window, set the following:

      Provider Type: server
      Provider ID: OpenIDProvider
      Class Name: org.imixs.openid.openid4java.OpenID4JavaAuthModule

      Do not check the Default Provider: Enabled check box.

For the first configuration this is a little bit confusing as you need to create the HttpServlet Layer. But in general the hole configuration is very simple. 

Also note that the provider configuration utility also provides a dialog box that you can use to configure additional properties. We will use this properties to configure out OpenIDProvider for our applications.

Configure additional Properties

After adding the new OpenIDProvider like described before you can start using the provider in your web application. But there a also a few additional properties which can be configured for each provider instance. You can add these properties by using the box "additional properties at the end of you configuration page:

 

The different properties and there usage are described below:

assign.groups

This property is the most important one. It defines which group will be assigned to a user how has logged on with his OpenID. Typical this is a default group used in your web application. 

debug.stages

This property allows you define different debug stages. So you can follow the different phases during the logon process on the server log. Remove this property to turn the debug modus off to switch off debugging.

loginpage

Per default the login module will prompt the user with a simple login page where he can enter his OpenID. You can replace this default page with a individual page supported by your web application (similar to a form based authentication). I will discus this later.

(The other params - verfiymode and debug - shown in the screenshot are deprecated and can be left)

 

Configuration of your Web Application

Now I will explain how you can configure your web application to use openid as a login mechanism. If you have installed the OpenID Login module like described before this step is quiet easy. 

web.xml & sun-web.xml

The first thing what you should do is remove existing tag login-config like basic or form-based authentification configuration from the web.xml if available. Using JSR-196 you now only need the security-constraint configuration.

This is an example of the security-constraint seciton in my web.xml

....
<security-constraint>
<display-name>Access Manager Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>AUTHENTICATED_RESOURCE
</web-resource-name>
<url-pattern>/pages/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>org.imixs.ACCESSLEVEL.AUTHORACCESS
</role-name>
</auth-constraint>
</security-constraint>

<security-role>
<role-name>org.imixs.ACCESSLEVEL.AUTHORACCESS
</role-name>
</security-role>
.....

Next you need to link your openid provider configured on glassfish admin client with you web application in the sun-web.xml. 

Therefor you need to add the attriubte "httpservlet-security-provider" with the name of your openid provider. The the following example of my sun-web.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
<sun-web-app error-url="" httpservlet-security-provider="OpenIDProvider">

<context-root>/openidtestclient</context-root>

<security-role-mapping>
<role-name>org.imixs.ACCESSLEVEL.AUTHORACCESS</role-name>
<group-name>Author</group-name>
</security-role-mapping>

<class-loader delegate="true" />
<jsp-config>
<property name="keepgenerated" value="true">
<description>Keep a copy of the generated servlet class java
code.</description>
</property>
</jsp-config>
</sun-web-app>

That's it!

Now You will see a default login page if you try to login to your web application: 

 


Role Mapping

Notice that we mapped also our default group "Author" to a application specific role name. The group "Author" was configured in the OpenIDProvider property "assign.groups". So each user how have successful authenticated against his OpenID Provider will default to this group and the role  "org.imixs.ACCESSLEVEL.AUTHORACCESS". You can change this settings to the requirements of your application.

Login Form

If you did not specific a login form with the additional property "loginpage" the OpenID Login Module will answer an unautenticated request with an simple login form as shown above.

You can implement you own login form if you like and use this form as the default form for your openidProvider module. 

There for add the property "loginpage"  to your provider configuration and support a valid Page inside your application or a simple HTTP page located on a web server.

This is a simple example for a individual login form based on JSF :

	<form method="get"
action="#{facesContext.externalContext.requestContextPath}/openid_login">
<f:facet name="header">
<h:outputLabel value="#{global.login_title} " />
</f:facet>
<h:panelGrid columns="2">
<h:outputLabel value="#{global.username}:" />
<h:inputText id="openid_identifier" />

<h:inputHidden id="return_to"
value="#{loginMB.serverURI}#{facesContext.externalContext.requestContextPath}/pages/notes.jsf" />

</h:panelGrid>
<input type="submit" value="#{global.login}" />


<!-- BEGIN ID SELECTOR -->
<script type="text/javascript" id="__openidselector"
src="https://www.idselector.com/selector/e0ed3a269b77fa785de90aeaa20fa0f985746767"
charset="utf-8"></script>
<!-- END ID SELECTOR -->
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-3469303-6");
pageTracker._trackPageview();
</script>
</form>
 

Your form need to care about three things:

  1. The form action method need to point to the method path "/openid_login". This path indicates the OpenIDLogin Module to start an OpenID Login process.
  2. The users Input field to enter his OpenID URL should be named "openid_identifier". Make sure that the "name" and "ID" attribute are set to "openid_identifier"
  3. The form must support a hidden field "return_to" with points to a page where the user is redirected after login process succeed.

 

The ID Selector Script is just a funny script provided by http://www.idselector.com to support the user with a nice widget to simplify using openid.

Conclusion

You can see that using JSR-196 and OpenID4Java is a very comfortable way to support a new and easy to use login mechanism for web applications. For Internet applications openid opens you web site to millions of users. It is easy to use and you don't have to handle all the stuff with managing userids and passwords.

If you have any suggestions or comments let me know.

You can download the source file of my Implementation also from here.

I also want to thank the OpenID4Java Team for there work.

Mittwoch Jan 13, 2010

Maven & SVN Plugins for Eclipse Galileo

Today I installed the Maven M2 and Subversive Plugins in my Eclipse Galileo Installation.

This is a little bit tricky because the M2 Plugin needs some additional Plugins if the Plugin should work together with the Subversion Plugin Subversive.

These are the steps I go through the Eclipse Update Manager to get all things work:

First I added the Suversive SVN Team Provider provided from the Galileo Download Site. This Site is available in the Eclipse "Install new Software" Dialog. Select the Option:

"Collaboration->Suversive SVN Team Provider"

 

After restarting Eclipse the SVN Plugin will ask for a Subversive Connector. This is a new cool feature so you did not add an Updite URL for these plugins manually. I selected only the option SVN Kit 1.3.0:

 

...the wizard will select two additional plugins to be installed next...

 

In the next step I added an additional Plugin which is needed to get a better Maven/SVN Integration.

Therefore I added in the Eclipse Install Dialog the following new Update site:

 http://download.eclipse.org/technology/subversive/0.7/update-site/

From This site I selected only(!) the Plugin 

"Subversive SVN Team Provider (Incubation)"

 

 After Restarting Eclipse I add now the "SVN Maven Support" provided by the following Update Site:

http://www.polarion.org/projects/subversive/download/integrations/update-site/

This is an additional Plugin needed to get better SVN Support. I select the "Subversive Integration for the M2Eclipse Project" Plugin:


Now finally its time to add the Maven Integration Plugin itself form the Update Site:

 http://m2eclipse.sonatype.org/update/

You should not(!) select the Maven SCM Integration if you followed my recommanded installation steps.

So I select the MavenEmbeder, Pom Editor and Maven Central Repository:


 

 After restarting Eclipse Galileo once more you can now Checkout a Maven Project from any SVN Repository with the option "Check out as maven Project..."  and use the M2 Integration Plugin Features like the POM Editor.

 

 

If anybody knows an easier way to get Maven and SVN Integration for Eclipse Galileo installed please let me know...

Dienstag Jan 12, 2010

Migration Derby DB to MySQL

Today I migrated successfully this Blog from a Derby DB into a MySQL Database. 

From the Apache Blog Software Roller this is no big deal. And as I run the blog on a Glassfish Server there was only a new JDBC Database Pool necessary which is connected to the JDBC Ressource used by the roller web app (jdbc/rollerdb).

But what to do with all the data? Therefore I used the open source software tool OpenDBCopy. With this tool you can migrate the data from one database system into another database system independent form the platform.

 

As there was no provided Derby Driver Setting provided I used "PostgreSQL" as a dummy and edited the driver class and url setting as you can see in the first picture.

To migrate the data from one database into another it is necessary that in both databases the database scheme still exists. Also as the destination database is still empty. To get the database schema created on my mySQL database I started roller first with the new mysql database connection to force roller to create a new database schema. So next I was able to copy my data from the source database (Derby) to the destination (MySQL) successfully with openDBCopy:

 

That's it. Next I restarted my web server and now my blog runs on MySQL with all the data.

Thanks to the developers from OpenDBCopy!

 


 


Freitag Dez 11, 2009

JEE5 EAR EJB Deplyoment

Today I found this wunderfull article about EJB Deploymen tin JEE5:

http://www.developer.com/java/ejb/article.php/10931_3670496_1/Packaging-EJB-3-Applications.htm

I think this article is helpfully for anyone how struggles with deployment strategies in JEE5 EARs.

I do this fight currently as I try to find out the best way to deploy the Imixs JEE Worklfow components in an enterprise application.... ;-)


 

 

Dienstag Dez 08, 2009

Glassfis: Using saxon XSL Processor instat of xerces

Glassfish Application server provides an Xerces XSL Processor. This processor did only support XSL 1.0 but no XSL 2.0 which comes with a lot of additional functions.

So in a Web Application which is doing some XML/XSL transformation the xerces processor will be used per default. To change this behavior you can simply copy the saxon processor into the /lib folder of your web module.

Or if you are using maven add the following dependency into your pom.xml

<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>saxon</artifactId>
<version>8.7</version>
</dependency>

Thats it. Now your web module will run with saxon xml/xsl and you can work with all the cool XSL 2.0 functions.

Samstag Nov 28, 2009

Imixs Workflow API 2.0.1 release

Today I have finally released new version 2.0.1 of the Imixs Workflow API.

Read more on www.imixs.org

Dienstag Okt 06, 2009

AWStats and Glassfish

AWStats is a free powerful tool that generates graphically web server statistics. This log analyzer works also in combination with the Glassfish Application Server.

To get the web statistic out form the glassfish server there are a few things to be payed attention for after you have installed AWStats successfully on your server. 

First off all you need to activate the Access Log in Glassfish. The Access Log is switched off per default.

 

Also it maks sense to use a new feature from glassfish which allows to generate a kind of standard log file format called Apache combined log format. This Log format gets out much more informations from a web server statistic. See Jan Luehe's Blog for details.

You can activate the Access Log in Glassfish using the Glassfish Console.

 

To activate the combined log format enter 'combined' in the Format Field.

Next it is also necessary to tell AWStats how to access the daily logfiles generated by glassfish server and which log file format (Apache combined log format) should be used by AWStats. Therefor it is necessary to edit the awstats.config file of your webdomain (on linux the config files are located in /etc/awstats/).

Edit the config File and change two important properties to optimize AWSats to work with glassfish:

LogFile

This property defines the location of the AccessLog files. These files are typical stored in the logs/access folder form the glassfish domain. Set these property like this:

LogFile="/usr/glassfish/domains/domain1/logs/access/server_access_log.%YYYY-0-%MM-0-%DD-0.txt"

where /usr/glassfish/ should point to your glassfish install directory. 

LogFormat

The second property is the LogFormat. This property has a default setting of "4" which indicates to use the Apache common log format. Change this Property to "1" to indicate to use the Apache combined log format.

After this changes the Web statistic of your glassfish server should look cool and gives you all the informations you are looking for.

Freitag Aug 14, 2009

RichFaces - SuggestionBox and hidden Field

Today I was faced with a problem implementing a suggestionbox in my JSF web application using RichFaces. There are a lots of examples and well documented api in the RichFaces Developer Guide. But my problem was that the seach phrase the user types into the input field was only for searching in the backend. After the user select one entry form the suggegstion box I need to set an internal key into a  property of my BackingBean. But this key should not be shown to the user. So the typical examples did not work for me:

<h:inputText value="#{bean.property}" id="suggest"/>
<rich:suggestionbox for="suggest" suggestionAction="#{bean.autocomplete}"  var="suggest">
        <h:column>
                <h:outputText value="#{suggest.text}"/>
        </h:column>
</rich:suggestionbox>

The solution for me was to left the value binding of the input component. Instead of that I use the f:setPropertyActionListener to update my backing bean property. So I was able to display user-friendly values from my backend. After user select one entry I store the key of that entry into my backing bean.

<h:inputText id="suggest_input" />
   <rich:suggestionbox for="suggest_input" minChars="1"
       fetchValue="" nothingLabel="no entry found"
        suggestionAction="#{myMB.suggestData}" var="suggest">
        <h:column>
            <h:outputText value="#{suggest.firstname}" />
        </h:column>
         <h:column>
            <h:outputText value="#{suggest.lastname}" />
         </h:column>
            <a4j:support ajaxSingle="true" event="onselect"
                action="#{myMB.refreshData}" reRender="data_id">
            <f:setPropertyActionListener value="#{suggest.userID}"
                    target="#{myMB.userID}" />
         </a4j:support>
  </rich:suggestionbox> 

myMB is my BackingBean which processes the SQL Data lookup with the method "suggestData". The user enters first or last name and my suggestData method did a SQL search using some LIKE statements.

    public ArrayList<UserData> suggestData(Object event)
            throws SQLException {
        ArrayList<UserData> list = new ArrayList<UserData>();
        String sPref = event.toString();
        int iPref = -1;

        sQuery = "SELECT patID,firstname,lastname FROM userlist "
                + " WHERE firstname LIKE '"
                + sPref
                + "%' OR lastname LIKE '"
                + sPref
                + "%' "
                + " ORDER BY lastname ASC";
.....
........

The BackingBean holds also the userID which is an internal primary key. But the suggestData method returns an Array of userData containing the First, Last and userID. But the userid is not displayed in the suggestionbox. When the user selects an entry the a4j:support Ajax Action is triggerd whid did some rerendering (but this is not the trick). The trick is to use the f:setPropertyActionListner to update the userID property form my backing bean myMB. The inputText component is not bound to any value of my backing beans. So this is a simple search input field.

Maybe this example could be useful for someone.

Donnerstag Aug 13, 2009

Eclipse Galileo and the Glassfish Server Plugin

For some reasons it is not possible to install and add the Glassfish Server Adapter in Eclipse Galileo with the Buildin Wizard form the "New Server" Wizzard (Function - "Download additional server")

 But you can add the Glassfish Server Adapter easily with the "Help->Install new Software" Dialog, using this additional Download URL:

https://ajax.dev.java.net/eclipse

 

Donnerstag Jul 16, 2009

New! Imixs Workflow Project

I am proud to announce that we started the new Open Source Workflow Project Imixs-Workflow on dev.java.net. This project arise from the ix-workflow project we developed about for more than 3 years. But the new project is much more easy to use. We developed a bunch of simplifications in the Workflow API so the hole project is now much easier to integreate. I would be happy if you can give me some feedback to that project on the project home page.

I will provide a short video next time to show how easy it is building workflow applications based on the API.

Donnerstag Jul 09, 2009

Glassfish TimerService - Expunging timer after failed deliveries

On my glassfish installation I am running different TimerServices. In one I saw the problem that the TimerService stopped unexpected after running more than 20 hours. 

In this situations a exeption is logged by the server like this one:

[#|2009-07-09T03:10:56.375+0200|INFO|sun-appserver2.1|javax.enterprise.system.container.ejb|_ThreadID=15;_ThreadName=p: thread-pool-1; w: 4;'1@@1247059844937@@server@@domain1' 'TimedObject = ScheduledWorkflowServiceImplementation' 'Application = myapp.ear-1.3.4' 'BEING_DELIVERED' 'PERIODIC' 'Container ID = 81721584505847814' 'Wed Jul 08 15:30:44 CEST 2009' '600000' ;2;|EJB5119:Expunging timer ['1@@1247059844937@@server@@domain1' 'TimedObject = ScheduledWorkflowServiceImplementation' 'Application = myapp.ear-1.3.4' 'BEING_DELIVERED' 'PERIODIC' 'Container ID = 81721584505847814' 'Wed Jul 08 15:30:44 CEST 2009' '600000' ] after [2] failed deliveries|#]

There is a Bugreport concerning this issue:

https://glassfish.dev.java.net/issues/show_bug.cgi?id=4634

and also this discussion thread:

http://forums.java.net/jive/thread.jspa?messageID=219367

arround this toppic.

Now I will test if changing the TimerService settings in the EJB Containterconfiguration will solve the problem.

First I will change the following Params

  • "Maximum Redeliveries" from "1" -> "16"
  • "Redelivery Interval" from 5000 -> 30000

 not sure if this will help....