JSR 286 : The Eventing feature

In order to provide coordination between portlets the Java Portlet Specification, JSR 286 introduces the  following mechanisms

  • Eventing: portlet events that a portlet can receive and send
  • Public Render Parameters: render state that can be shared between portlets

In this blog, i will explain the Eventing feature and in a later blog i will explain the Public Render Parameter feature.

Eventing can be described as a loosely coupled, brokered means of communication between portlets. It is intended to allow portlets to react on actions or state changes not directly related to an interaction of the user with the portlet.
Events are a lifecycle operation that occurs before the rendering phase.


Now let us get into the details of writing portlets that use this feature

The portlet can declare the events in its deployment descriptor using the event-definition element in the portlet application section. In the portlet section each portlet can specify the events it would like to publish via the supported-publishing-event element and the events it would like to process via the supported-processing-event element. The supported-publishing-event and supported-processing-event element must reference the event name defined in the portlet application section in a event-definition element.

The portlet issues events via the setEvent method during the action processing. This will be processed by the portlet container after the action processing has finished.

In order to receive events the portlet must implement the javax.portlet.EventPortlet interface. The portlet container will call the processEvent method for each event targeted to the portlet with an EventRequest and EventResponse object.
The portlet can access the event that triggered the current process event call by using the EventRequest.getEvent method. This method returns an object of type Event encapsulating the current event name and value.

Event names are represented as QNames in order to make them uniquely identifiable. The event name can be either retrieved with the getQName method that returns the complete QName of the event, or with the getName method that only returns the local part of the event name. The value of the event must be based on the type defined in the deployment descriptor.

Following are the steps to write portlets that make use of eventing feature

1.Declare the events in the portlet.xml
    1.1 Set the event definition at the portlet application level. This specifies the event name and the object type.
          Note: The object must be serializable.
    <portlet-app .....>
        <event-definition>
        <qname xmlns:x="http:sun.com/events">
            x:Address.Create
        </qname>
        <value-type>com.test.Address</value-type>
        </event-definition>

    1.2 In the portlet section, specify the event name defined above for those portlets that want to publish this event.
        <portlet>
            .................
            <supported-publishing-event xmlns:x="http:sun.com/events">
                    x:Address.Create
            </supported-publishing-event>

    1.3 In the portlet section, specify the event name defined above for those portlets that want to process this event.
        <portlet>
            .................
           <supported-processing-event xmlns:x="http:sun.com/events">
                  x:Address.Create
           </supported-processing-event>

    
2.Issue an event in the portlet that was specified as supported-publishing-event in the portlet
    @XmlRootElement
    public class Address implements Serializable
    {
        private String street;
        private String city;
        public void setStreet(String s) {street = s;}
        public String getStreet() { return street;}
        public void setCity(String c) { city = c;}
        public String getCity() { return city;}
    }

    void processAction(ActionRequest request, ActionResponse response)
    {
        String myStreet = request.getParameter("street");
        String myCity = request.getParameter("city");
        Address sampleAddress = new Address();
        sampleAddress.setStreet(myStreet);
        sampleAddress.setCity(myCity);
        QName name = new QName("http:sun.com/events", "Address.Create");
        response.setEvent(name, sampleAddress);
    }     

3.Process the event in the portlet that has specified as supported-processing-event in the portlet
    void processEvent(EventRequest request, EventResponse response)
    {
        Event event = request.getEvent();
        if ( event.getName().equals("Address.Create") )
        {
            Address payload = (Address) event.getValue();
            .......
        }
    }

You can checkout the sources from OpenPortal Portlet Container that has the implementation of the eventing feature. Write a portlet that uses the eventing feature and try it.

 

Comments:

Any JSR-286 event payload class -- like Address in this example -- will need to be instrumented with a valid JAXB annotation, which, in this case, involves @XmlRootElement at the class level.

BTW, Apache-Pluto's 1.1-286-COMPATIBILITY branch also implements eventing and most other JSR-286 features. This branch is the basis for the JSR-286 reference implementation.

Posted by Craig Doremus on August 10, 2007 at 10:04 AM IST #

To add flexibility to event processing, a javax.portlet.GenericPortlet subclass can annotate a method with the @ProcessEvent annotation that has a qname parameter. This method most conform to the following signature:
void <methodname> (EventRequest, EventResponse) throws PortletException, IOException

Posted by Craig Doremus on August 10, 2007 at 10:16 AM IST #

Corrected.Thanks

Posted by Deepak on August 10, 2007 at 03:54 PM IST #

Hello Deepak Ji, I am really impressed with this article of yours and i want to know few things about Interportlet Communication like..
1. Can one portlet communicate with the portlets of other WAR files? If can then please have some examples here.

2. How to successfully execute JSF portlet in JBoss Portal 2.0 .

Please help me out..

Posted by Bimal Thapa on July 02, 2008 at 04:28 AM IST #

Thanks Bimal Ji.
1. Yes one portlet can communicate with the portlets of other WAR files. I will upload the sample shortly and will let you know. You can also check this article( http://java.sun.com/developer/technicalArticles/J2EE/sdk_portletcontaineru5/ ) that explains various features of JSR 286 with examples.

2. I don't how to do it on JBoss Portal. You check this article( http://developers.sun.com/portalserver/reference/techart/open-src-portletbridge.html ) on executing JSF Portlet on OpenPortal Portlet Container.

Posted by Deepak Gothe on July 02, 2008 at 05:21 AM IST #

Thanks Deepak Ji, I am very much pleased with your response and will be waiting for the sample you will upload.

Posted by Bimal Thapa on July 02, 2008 at 08:01 AM IST #

I have question, how IPC should be used with the Portlet Bridge.

How do I get handle to actionResponse() from normal faces application if I am using Portlet Bridge.

Posted by Ganesh Puri on November 09, 2008 at 10:45 AM IST #

As of now the Portlet Bridge does not support eventing. You need to subclass FacesPortlet and provide your implementation. Thanks.

Posted by Deepak Gothe on November 11, 2008 at 04:14 AM IST #

This jaxb think does not work for me at all.

I have tried various ways of doing, such as the way you tell it should work, or something like:

@XmlRootElement(name="event",namespace="http://mycomp.de/events")
public class MyEvent implements Serializable{

and even followed the ibm instructions with the annotating the package-info.java look more here: http://www-10.lotus.com/ldd/portalwiki.nsf/dx/03122008043639WEBDAG.htm

And still, the only thing I can push through is a primitive such as java.lang.String.

The exception I always get is the following:

SEVERE: java.lang.IllegalArgumentException: The provided event value type org.mycom.MyEvent does not have a valid jaxb annotation

SO I don't get it, but it does not has to be such a pain in the butt, this JAXB stuff.

Do you have any suggestions?

Posted by nik on March 20, 2009 at 09:25 AM IST #

Hi,
Just annotating like shown below should work. Also you should you have no-args constructor. Did you try the eventing samples @ https://portlet-container.dev.java.net/public/Samples.html. Are you trying this with OpenPortal Portlet Container on GlassFish or you trying on Web Space server.

@XmlRootElement
public class MyEvent implements Serializable{

}

Posted by Deepak Gothe on March 20, 2009 at 11:49 AM IST #

Hallo Depak,

thanx for the reply.

The simple annotation

@XmlRootElement
public class MyEvent implements Serializable{

}

ain't working that's for sure. I have tried it on JBoss Portal 2.7.1 and Liferay.

My current guess is that this could be connected to JSF and RichFaces I am using.

The only thing I can push through as an event object is a String. not even HashMap is working.

The link you posted for me ain't working, I get error page. I have seen some other examples (Sun's included) of JSR 286 but those examples are with pure HTML! Who is using pure HTML today?

It seems to me that JSR286 is released for it's own sake, and we developers are forwarded to the ice age of programming web.

As already said. I can push a String through portlets, and as long that works I can get around for my needs, but that is not what it was meant to be, isn't it?

Did Sun made the JSR 286 spec working only for OpenPortal Portlet Container on GlassFish. I will give it a try and see what happens. But my target environmen is pre given, so I can't just jump and tell the customers to start using GlassFish.

Sad but true.

Thanx any way.

Posted by nik on March 20, 2009 at 01:13 PM IST #

Hi,
The JAXB annotation is basic and it should work. I am surprised that its not working. Sun's implementation of JSR 286 spec, i.e OpenPortal Portlet Container is part of Liferay and GlassFish Web Space server. The download from https://portlet-container.dev.java.net has a portlet driver which is used to test portlets and is meant for development purposes. It works both on GlassFish and Tomcat. If you want to try with Liferay you can use 5.2.2 and in portlet-ext.properties, set "portlet.container.impl=sun". If you are using Tomcat bundle, you need to set JVM as JDK1.6, as Tomcat does not support JAXB OOTB, while GlassFish does. The link that i sent was just samples, you can also check TourIPCPortlets from http://wiki.java.net/bin/view/OpenPortal/PortletsInTheRepository. And as far as JBoss is concerned, if you use JVM as JDK1.6, JAXB stuff should work.

Posted by Deepak Gothe on March 21, 2009 at 03:27 PM IST #

Hi Deepak,

thanx for your reply. As I understand it now is that only Java 1.6 is my solution for the JAXB problem.

I must use Java 1.5. As being so, I have had included the jaxb-api.2.1.9.jar in my class path. As the practice showed for me, it ain't working that way. Maybe I need additional JAR, I don't really know.

What ever it is, I am stuck with basic String, and for now it will do it.

What bother's me, is that I have seen examples, which use HashMap but even this ain't working for me.

Anyways thank you very much for your effort replying me.

Nik

Posted by nik on March 23, 2009 at 09:44 AM IST #

Hi Nik,
You need to include both JAXB API and Impl in your classpath. This has to be in server classpath. HashMap(or any other Collection) is not a valid JAXB object. You need to use a custom class and add the Collection object as a field.

Posted by Deepak Gothe on March 23, 2009 at 09:54 AM IST #

Hi Deepak,

thanx for your effort answering me. I admit,I did not include the IMP version of JAXB jar, but even when I did that now, it won't work.

I tried it out wit Java 6 and it did work fine. That's where I stop experimenting.

Since I am stuck with Java 1.5 I will have to make my way with simple String for the time being. For later I will see if we upgrade to Java 6.

Kind greetings,
Nik

Posted by nik on March 25, 2009 at 12:50 PM IST #

I am in same boat as Nik. Any one has any solution other than upgrading to 1.6 ? Appreciate your help in advance.

thx
Srinivas

Posted by Srinivas Chamarthi on June 25, 2009 at 03:14 PM IST #

For JAXB runtime you need: activation.jar, jaxb-api.jar, jaxb-impl.jar, jsr173_1.0_api.jar. You can get these from https://jaxb.dev.java.net/2.1.11/.

Posted by Deepak on June 26, 2009 at 08:47 AM IST #

Hmm.. didn't help. I debugged through jboss portal code and found something strange happening, where as similar code in test class is working fine. Not sure whats wrong.

This is always returning false with 1.5

boolean b = valueType.isAnnotationPresent(XmlRootElement.class);

where as the same code is returning true with jdk1.6

but same code with 1.5.0_15 in standalone class is return true.

public static void main(String args[]) {
NavigationEvent value = new NavigationEvent();
Class<? extends Serializable> valueType = value.getClass();
boolean b = valueType.isAnnotationPresent(XmlRootElement.class);
System.out.println(b);
}

Posted by Srinivas Chamarthi on June 27, 2009 at 04:22 PM IST #

Did you copy the jars to the JBoss appserver classpath. Looks like JBoss Appserver may not be loading the JAXB jars that you have copied. As i am not well versed with JBoss, i am giving GlassFish example..in GF there is glassfish/lib and glassfish/domains/domain1/lib(i.e server classpath). The jars in glassfish/lib take precedence over jars in glassfish/domains/domain1/lib. Check what JBoss server says about JAXB support.

Posted by Deepak on June 29, 2009 at 03:36 AM IST #

Hmm thank you so much ! this did the trick, earlier i was bundling the jars with my application war. After moving to server lib, it worked like a charm. Thank you so much for help.

However I have small doubt regarding the eventing,

am trying to do something like this

actionResponse.setRenderParameter("navaction","Test");
actionResponse.setEvent(QName,LoginEvent);

somehow jboss behaves weird in this case. I dont see the render parameters in my controller method when I receive the event.

Just want to know if response.setRenderParameter will apply parameters on the event ?

Posted by Srinivas Chamarthi on July 02, 2009 at 04:09 PM IST #

The render parameters that you set on actionResponse is available in the processEvent of that portlet, not in the processEvent of other portlet. Render parameters are private to a portlet.

Posted by Deepak on July 03, 2009 at 05:02 AM IST #

Thanks for these posts. I had the exact problem:

java.lang.IllegalArgumentException: The provided event value type my.example.MyEvent does not have a valid jaxb annotation

Just to be clear for others reading--the solution worked for me when I \*removed\* the jaxb jars (activation.jar, jaxb-api.jar, jaxb-impl.jar, jsr173_1.0_api.jar) from my war and \*only\* placed them in the jboss portal classpath ($JBOSS_HOME/server/default/lib/). Note also that it worked for me with Java 1.5.

Posted by Spurgeon on October 08, 2009 at 06:23 PM IST #

Hi Deepak,
We have a new IBM websphere portal environment and trying to deploy our old WARs on this portal with all required jars on shared lib on the server.
When we try to access these portlets then it gives us an error copied below.
It looks an issue related to conflictng jars.In my shared library there are no duplicate jars.
Kindly suggest the way to remove this error.

Thanks,
Gaurav

java.lang.ClassCastException: org.apache.xerces.jaxp.SAXParserFactoryImpl incompatible with javax.xml.parsers.SAXParserFactory at javax.xml.parsers.SAXParserFactory.newInstance(Unknown Source) at org.apache.taglibs.standard.tlv.JstlBaseTLV.validate(JstlBaseTLV.java:152) at org.apache.taglibs.standard.tlv.JstlCoreTLV.validate(JstlCoreTLV.java:96) at com.ibm.ws.jsp.translator.visitor.validator.ValidateVisitor.validateTagLib(ValidateVisitor.java:1103) at com.ibm.ws.jsp.translator.visitor.validator.ValidateVisitor.visitJspRootStart(ValidateVisitor.java:486) at com.ibm.ws.jsp.translator.visitor.JspVisitor.processJspElement(JspVisitor.java:233) at com.ibm.ws.jsp.translator.visitor.JspVisitor.visit(JspVisitor.java:216) at com.ibm.ws.jsp.translator.JspTranslator.processVisitors(JspTranslator.java:127) at com.ibm.ws.jsp.translator.utils.JspTranslatorUtil.translateJsp(JspTranslatorUtil.java:253) at com.ibm.ws.jsp.translator.utils.JspTranslatorUtil.translateJspAndCompile(JspTranslatorUtil.java:120) at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.translateJsp(AbstractJSPExtensionServletWrapper.java:512) at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper._checkForTranslation(AbstractJSPExtensionServletWrapper.java:439) at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.checkForTranslation(AbstractJSPExtensionServletWrapper.java:297) at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:147) at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.include(WebAppRequestDispatcher.java:673) at com.ibm.ws.portletcontainer.core.impl.PortletRequestDispatcherImpl.include(PortletRequestDispatcherImpl.java:98) at com.ibm.ws.portletcontainer.core.impl.PortletRequestDispatcherImpl.include(PortletRequestDispatcherImpl.java:230) at com.tcs.dgmi.apps.portlet.hrms.leave.FinalJoiningReportPortlet.doView(FinalJoiningReportPortlet.java:126) at javax.portlet.GenericPortlet.doDispatch(GenericPortlet.java:328) at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)

Posted by guest on October 12, 2011 at 12:39 PM IST #

Did you try IBM's forum? From the exception it looks like you may have xerces jar in your webapp or in the shared lib. Try removing that and retry.

Posted by Deepak on October 12, 2011 at 04:38 PM IST #

I dont have this jar in Application library.Still i have the same issue
Kindly help

Thanks,
Gaurav

Posted by guest on October 13, 2011 at 05:38 AM IST #

I dont have this jar in Application library.Still i have the same issue
Kindly help

Thanks,
Gaurav

Posted by Gaurav on October 13, 2011 at 11:11 AM IST #

Did you try IBM's forum? It looks like same jar at different places like webapp level or application level or server level.

Posted by Deepak on November 17, 2011 at 03:27 AM IST #

Hi
i tried the jsr 286 eventing feature myself as well as downloaded few samples from internet but none of them are abe to call processAction().

is there anything that need to be enabled to use this feature?

Posted by guest on November 23, 2011 at 12:47 PM IST #

During eventing processAction() is not called processEvent() is called. When you do any action on the portlet, processAction() is called and from processAction() you need to call setEvent in order for processEvent() to get called as explained in this blog.

Posted by Deepak on November 24, 2011 at 03:35 AM IST #

Hi. I realize this is a very old thread. However, I'm having a similar issue with portlet events. Getting this exception:
javax.xml.bind.JAXBException: "com.opentext.itapps.csssite.events" doesnt contain ObjectFactory.class or jaxb.index

I think it is the same issue some others have had with jaxb jar files in the portlet webapp. However, removing them is not an option because my portlet is using jaxb itself to unmarshall some rest/xml service calls. Does anyone know how to get around this?

Posted by Clay Embry on January 24, 2012 at 07:16 AM IST #

Why wont jaxb jars in the server classpath work?why do you need it in the webapp?

Posted by Deepak on January 24, 2012 at 09:52 PM IST #

Deepak, I will try that. Our portal is also deployed as a webapp in the same appserver and it also uses those jars. Do those need to be removed from the portal webapp as well? It's unfortunate that there is not another workaround as this makes an extra thing to remember for configuring and deploying the app server and portlet webapp when portlet uses events and jaxb. Thanks for your help.

Posted by Clay on January 25, 2012 at 01:29 AM IST #

Hi Deepak,
As you mentioned that you will write an article for cross WAR eventing.
Kindly share the path for the same if uploaded.

I am using IBM Web Sphere Portal 6.1

Thanks,
Gaurav

Posted by Gaurav on February 07, 2012 at 12:05 PM IST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Deepak Gothe

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today