Main | Next page »
Mittwoch Aug 18, 2010

Liferay, Glassfish, Hot Deploy

Today I played around with the hotdeplyoment of a portlet into my Liferay server 5.3  which runs on top of Glassfish 2.1.

There are different documentations about this topic. But I run into the problem that my portlet (developed with Eclipse and Maven) was deployed but also immediately undeployed. The deployment process allways ends with a message like:

[#|2010-08-17T13:35:54.446+0200|INFO|sun-appserver9.1|javax.enterprise.system.tools.deployment|_ThreadID=17;_ThreadName=Timer-16;|
[AutoDeploy] Successfully autoundeployed : /opt/glassfish_v2ur2/domains/lportal/autodeploy/imixs-workflow-portlet-sample-0.0.4-SNAPSHOT.war.|#]

I did not know why, but the solution for me was to change the Deploy Directory configured in the liferay server from the Glassfish Autodeploy folder to a directory outside my glassfish/liferay server.

You can change the settings in the Plugin-Installer Portlet from liferay. I did not use the property file 'portal-ext.properties'!

 

After I changed the  "Deploy Directory" and leave the "Destination Directory" blank, hot deployment works for me.

Ok I forget to explain how my portlet goes into my local autodeploy folder ;-)

I am developing my portlets with maven. So in my pom.xml I added the following maven-antrun-plugin which copies the portlet war into my autodeploy folder:

......  
           <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>pre-integration-test</phase>
                        <configuration>
                            <tasks>
                              
                                <echo message="About to copy plugin to autodeploydirectory..." />
                                <echo> Plugin:
                                    ${project.build.directory}/${project.build.finalName}.war
                                    autodeploy directory: /home/rsoika/liferay_autodeploy </echo>
                                <copy
                                    file="${project.build.directory}/${project.build.finalName}.war"
                                    todir="/home/rsoika/liferay_autodeploy" />
                                <echo message="Copied to portletdeploy directory." />
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
......

Montag Aug 09, 2010

OpenID and Yahoo

Today we recognized a problem concerning the openID login with yahoo.com on the Imixs BPM Portal

using the officical yahoo URL "http://yahoo.com" did no longer work. This wasn't a problem form the OpenID4Java module we use.  Also other OpenID Login modules like the one provided by Liferay Portal did not work with "http://yahoo.com".

The problem seems to be something with the yahoo servers outside the united states. Logins e.g from german web servers failing with a HTTP 404 Error. 

This problem can be fixed using the yahoo OpenID url "http://me.yahoo.com"

We have changed this on the Imixs BPM Portal.

Sonntag Aug 01, 2010

Liferay, JSF and Glasssfish

Developing a JSF portlet in Liferay 6.0.4 running on Glassfish 3 is not as easy as it sounds like. I investigated several days (and nights) to found a working solution. I think the reason why it takes so much time for me was the fact that there are to many examples spread over the last two years. And as more you mix them up as more problems occur.   

Running Liferay on top of Glassfish 3 is a good choice as the Glassfish application server supports a powerful platform for EJB and Web development. For the portlet development there are different APIs and specifications which need to be separated with care.

After my personal journey through the portlet/jsf world I come to the conclusion that the best combination of all portlet technologies is the Portlet API 2.0 (JSR 286) and JSF 2.0 (JSR 314). To fit them together you need a JSF-Portlet Bridge.

The best working solution for now seems to be the portletfaces-bridge from portletfaces.org. This bridge is not yet final but it works well with Liferay and Glassfish. ?The portletfaces bridge supports development of JSF 2.0 apps that run inside a Portlet 2.0 compliant portlet container, such as the one provided by Liferay Portal. In addition, the bridge facilitates the deployment of ICEfaces 2.0 applications.

The two artifacts "portletfaces-bridge-api" and portletfaces-bridge-impl"are not available through an official maven repository.So you need to add the Maven repository 'http://repo.portletfaces.org/mvn/maven2/' to your maven settings.xml file. Then you can use them in your projects using maven2.

The current alpha releases are:

  • portletfaces-bridge-api-2.0.0-ALPHA4.jar
  • portletfaces-bridge-impl-2.0.0-ALPHA4.jar

You can checkout an example portlet form the Imixs Workflow Portlet Project at the following location:

https://imixs-workflow.dev.java.net/svn/imixs-workflow/imixs-workflow-portlet-sample/tags/0.0.3

Note: To get access you simply need an account on dev.java.net.

I will post the interesting parts of the example here:

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<description>Imixs RichFacesPortlet</description>
<context-param>
<param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
<!--
Although the FacesServlet will not be invoked by any portlet requests,
it is required to initialize JSF.
-->
<servlet>
<servlet-name>FacesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>


<security-constraint>
<web-resource-collection>
<web-resource-name>Page Sources</web-resource-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspx</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>nobody</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>nobody</role-name>
</security-role>
</web-app>

portlet.xml

 <?xml version="1.0"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
    <portlet>
        <portlet-name>1</portlet-name>
        <display-name>Imixs Portlet Sample RichFaces</display-name>
        <portlet-class>org.portletfaces.bridge.GenericFacesPortlet</portlet-class>
        <init-param>
            <name>javax.portlet.faces.defaultViewId.view</name>
            <value>/pages/echo.xhtml</value>
        </init-param>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>VIEW</portlet-mode>
        </supports>           
        <portlet-info>
            <title>ImixsRichFacesEchoPortlet</title>
            <short-title>ImixsRichFacesEchoPortlet_Short</short-title>
            <keywords>Sample</keywords>
        </portlet-info>
          <security-role-ref>
            <role-name>administrator</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>guest</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>power-user</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>user</role-name>
        </security-role-ref>       
</portlet>
</portlet-app>


 liferay-plugin-package.properties

 

name=ImixsPortletSample
module-group-id=liferay
module-incremental-version=1
tags=sample
short-description=This plugin leverages the Sun OpenPortal JSF Portlet Bridge and shows how to use the JSF 1.2 Sun RI and the Facelets view-handler within Liferay.
change-log=
page-url=http://www.liferay.com
author=Liferay, Inc.
licenses=MIT

portal-dependency-jars=

 

faces-config.xml

 <?xml version="1.0" encoding="UTF-8"?>
<faces-config 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/web-facesconfig_2_0.xsd"
    version="2.0">
 
   <application>
 
   </application>
   
   <managed-bean>
      <description>Echo Bean</description>
      <managed-bean-name>echo</managed-bean-name>
      <managed-bean-class>com.imixs.portlet.test.EchoBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        <managed-property>
            <property-name>text</property-name>
            <value>Hello Liferay</value>
        </managed-property>
   </managed-bean>

    
</faces-config>


Dienstag Mai 04, 2010

Ubuntu 10.4, Glassfish V3 and Java.....

After I did an update of my Ubuntu from 9.10 to 10.4 my Glassfish V3 server did not work any more properly. The reason was that I used an older version of JDK and for some reasons after my update the things did not work together as they should. 

I found these usefull links:

http://forums.java.net/jive/thread.jspa?messageID=399990&#399990

and in a german ubuntu wiki:

http://wiki.ubuntuusers.de/Java/Installation 

Finally I solved my situation with the following steps:

  1. I updated my apt package sources adding the additional source for ubuntu 10.4 to get sun-java:
    deb http://archive.canonical.com/ lucid partner
  2. next I installed the sun-java6-jdk packages using apt
  3. now I switched my jdk in general using the following command (I have also still an OpenJDK intalled on my ubuntu):
    sudo update-java-alternatives -s java-6-sun

  4. And finally I changed a config File of my Glassfish V3 installation to start GF 3 with the Sun JDK
    • edit file:  [glassfishinstall]/glassfish/config/asenv.conf
    • change var AS_JAVA to point directly into the sun jdk
      AS_JAVA=/usr/lib/jvm/java-6-sun

Now everything works fine again. My Sun JDK is now

java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)

Sonntag Apr 18, 2010

EJB 3.0 and WebServices

If you are interesting in programming EJB 3.0 (JEE5 / JEE6) you may be also try to implement a web service. Developing WebServices in JEE5 is not so hard. There are a lot of good books about all this stuff. I spent a lot of time the last two years in developing JEE5 WebServices.

But now after I started to migrate the Imixs Workfow Project  to Glassfish 3 I run into a lot of problems. And today I found out that there is a really big trap where I stumbled into.

In most of the JEE5 EJB/WebService examples you learn to annotate simply your stateless session ejb with the @webservice annotation to generate a new web service. So these examples combine EJB and Webservice in one implementation. The code result cann look something like this:

 .....
@DeclareRoles( { "myrole1",
        "myrole2" })
@RolesAllowed( { "myrole1" })
@Stateless
@Remote(org.imixs.workflow.jee.ws.WorkflowWebService.class)
@WebService(name = "WorkflowManagerService", targetNamespace = "http://imixs.org/workflow/services", serviceName = "WorkflowManagerService", portName = "WorkflowManagerServicePort", wsdlLocation = "ix_workflowservice.wsdl")
public class WorkflowWebServiceBean implements
        WorkflowWebService {

    @EJB
    SomeServiceEJB myService;
....

    @WebMethod
    public Entity myMethod(@WebParam(name = "workitemid", mode = Mode.IN)String uniqueid)
            throws Exception {
        ....
    }
....

This is a code snippet out of the Imixs workflow project which works very well in Glassfish 2.1.
At the end the combination of @Stateless and @WebService annotations looks interesting but I dissuade you to do so! You may run into a lot of problems make it hard to get a platform independent ejb code. The reason is that you are forced to provide a lot of application server specific deployment configuration in your descriptors. For example in Glassfish you have to define the authentifcation method in the sun-ejb-jar.xml. Also providing wsdl files is not so easy as they are now mixed with your ejb code. This seems to be mostly a problem for JEE6 / Glassfish 3. I run into these problems when I tried to deploy my bullet proved code from Glassfish 2.1 on Glassfish 3 or JBoss 5. JEE6 makes things easier and the goal should be to move away as many declarations in source code as possible.

So at the end my recommendation is to saperate allways(!) the web service implementation from the EJB module. Do not bundle stateless session ejbs together with webservices in a JEE EJB 3.0 module. The best way seems to be to implement the webservice classes (those classes which use the @WebSerivce annotation) in a web module. You can simply add this web module to you ear package to make use of EJB code like I do in my code example above. This will work in JEE5 (Glassfish 2.1) as well as in JEE6 (Glassfish 3).

And finally if you separate your code in different modules you can kick the webservice module if you do not need it in your application. In most cases web services are long-winded code. Better work with REST services ... ;-)

Dienstag Apr 06, 2010

RichFaces and Prototype - how to avoid problems

Today I have had a strange problem with my RichFaces web application. In some cases widgets did not work as expected. For example the calendar components did not work - sometimes. The reason was the HTML design template I used. The template was provided by my customer and includes a lot of CSS and also javaScript pages. One of the JavaScirpt pages was a prototyp.js library (v 1.6.0.3).

And as RichFaces (3.3.3) is also using this protype version the libraries conflicts to each other.  But when I removed the prototype.js library form my template I run into the next problem. Now the JavaScript Navigationbar-provided by the customers HTML template - did no longer work. The reason was that RichFaces did not load all scripts per default but on demand. So in complex pages with a lot of RichFaces Widges everything works fine - the NavigationToobar loads. But in a simple welcome page my Navigationbar was missing the prototype scripts and throws an javascript error (method not found).

To solve this problem and also avoid the conflict of the RichFaces Prototype Library with an external Prototype library you can use the RichFaces config Param: org.richfaces.LoadScriptStrategy

If you set this param to "ALL" all scripts will be loaded in every page - so my external navigation bar was now happy with the prototype scripts provided by richtfaces.

So now I use the following setting in my web.xml file:

    <context-param>
        <param-name>org.richfaces.LoadScriptStrategy</param-name>
        <param-value>NONE</param-value>
    </context-param>

Montag Mrz 22, 2010

Imixs Workflow on JEE6

I have just started the new release 2.0.2 of the Imixs JEE Workflow. The new version runs on JEE6 application servers like Glassfish V3 and JBoss 6 and it is tested on Glassfish V3.
I would like to invite everyone to comment this project and I invite you to help me in further development of improvements and feature requests.
To get started with the current release of the Imixs JEE Workflow Management System you can just check out the JSF Sample Application (0.0.2-SNAPSHOT) from the source code repository (https://imixs-workflow.dev.java.net/source/browse/imixs-workflow/).

The sample application and also all sub projects of the Imixs Workflow Project are based on maven2 so it is not so hard to get things up and running. I have also written a tutorial which shows the hole picture and helps you for the first steps.
It would be nice if some of you can help me in the current JEE6 develpment.


 

Mittwoch Mrz 10, 2010

AXIOM jar Conflict in Glassfish 2.1.1

 

Today I found the reason why my ear/web application did not work in Glassfish V 2.1.1. (it works in V 2.1.0) The app deploys but when I try to open the Web context URL I see the following exception in glassfish server.log:

Exception
sending context initialized event to listener instance of class
com.sun.faces.config.ConfigureListener
com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! This
parser does not support specification "null" version "null" at
com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:215)

After some searching I think that the problem was forced by some additional libraries which I provided in my web module.

So after I removed my axiom-api dependency (maven 1.2.7) and I removed xercesImpl-2.6.2 the app works fine again.

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.

Please note that I have started a little project site on googlecode to publish the sources and provide a platform to discuss and exchange experience. You are welcome to join this project.

 http://code.google.com/p/openid4java-jsr196/

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!