August 2008

« October 2008 | Main | July 2008 »

WSRP Portlets and Sessions

Wednesday, August 27, 2008

One question that comes up from time to time when using WSRP with WebLogic Portal is how are sessions handled with respect to portlets. When using portlets from the same producer, the question is are the portlets sharing the same session and if so is it a good practice for the portlets to share information using the session as a communication mechanism.

Let's deal with the first topic first, do portlets from the same producer share the same session. The answer is that it depends on how your consumer portal is configured. If you look at the file wsrp-producer-registry.xml in WEB-INF, you will see that each producer has a section called requires-initCookie. The values allowed in this XML setting include None, perUser and perGroup. A value of None is straight forward and means that the portlet does not use a session. The perUser value means that every portlet for every user gets its own session and thus no sessions are shared. A value of perGroup means that sessions are shared when portlets are from the same producer and in the same group. The group is determined by the portlet's groupId in the portlet definition (aka the .portlet file). Thus, portlets with the same groupId will share the same session for the same user if they are from the same producer.

As an aside, how cookies, and thus sessions, are handled from consumer to producer is actually part if the WSRP specification. If you check page 24 of the specification here, you will find the following under CookieProtocol Type:

This type is a restriction on the string type that is constrained to the values “none”, “perUser” or “perGroup”. These values carry the following semantics:

  • ”none”: The Producer does not need the Consumer to ever invoke initCookie().
  • ”perUser”: The Consumer MUST invoke initCookie() once per user of the Consumer, and associate any returned cookies with subsequent invocations on behalf of that user.
  • ”perGroup”: The Consumer MUST invoke initCookie() once per unique groupID from the PortletDescriptions for the Portlets it is aggregating on a page for each user of the Consumer, and associate any returned Cookies with subsequent invocations on behalf of that user targeting Portlets with identical groupIDs.

Now for the second question, using the session as a communication mechanism. In general I believe this is a bad practice because it couples the portlets in a way that is fragile and not obvious to the consumer. Since the consumer controls how the sessions are managed, coupling portlets via the session means you are dependent on the consumer to use the right configuration. Another problem is when things are coupled such that Portlet B depends on a session value from Portlet A, what happens if the consumer elects to display B first?

Thus in general when communicating between portlets in WebLogic Portal containers prefer Inter-Portlet Communication as the preferred means for communicating between portlets. IPC decouples the portlets since the communication is event driven and not targeted at specific portlets.

Session sharing can be useful in certain cases, for example if both portlets are accessing the same information that is static for the lifespan of the session then this could be cached in the session. As an example, if we have two portlets that work with a customer object that is expensive to retrieve then there is benefit to sharing access to it in the session. However the portlets are not coupled because either portlet can retrieve the customer object directly if it is not in the session at the moment using a lazy initialization type pattern.

As with anything there is always exceptions. If for some reason your portlets need to pass a 500K piece of data back and forth it would be pretty inefficient to use IPC for this since the data would be sent over the wire up to the consumer and back down to the producer. But in general the exceptions are few and far between so stick with IPC for sharing information and do not use the session for this purpose.

Posted by Gerald Nunn at 12:25 PM | Categories: WebLogic | Permalink |


Rules for Working with Exceptions

Monday, August 04, 2008

Since I work on the consulting side of Oracle I tend to see a lot of code from clients and it surprises me how often I still see developers making basic mistakes when working with exceptions, both when throwing them and when consuming them. At the risk of beating a dead horse, since this topic has been covered to death, here are some basic rules I try to live by when working with exceptions.

Rule #1. If you catch an exception and wrap it in a new thrown exception, make sure to chain the exception by including it in the constructor of the newly thrown exception. For example:

try {
blah..blah..blah
} catch (IOException e) {
   throw new MyApplicationRuntimeException(e);
}

Rule #2. Include meaningful information in the exception, specifically include whatever information is necessary in order to track down the issue if someone needs to look into it further. Nobody likes dealing with exceptions that have something stupid like "Unexpected error" set as the message. As a positive example, if you're writing code for a financial application and an account creation operation fails, include the account number along with other relevant information in the exception that would enable support or operations staff to diagnose the issue. This additional information can be wrapped in fields of a custom exception class or simply included in the exception message.

Rule #3. Log exceptions where they are handled not where they are thrown. I'm sure we have all seen examples of applications where the developers log the same exception over and over again as it traverses up the stack. Applications should only log an exception once and the easiest and most practical way to enforce this is to only log the exception where it is handled. In other words, if your code simply catches the exception and rethrows it as a wrapped exception then do not log it, rely on the code above you to log the exception properly.

Rule #4. In general, prefer unchecked exceptions except in cases where there is a reasonable chance the receiver of the exception can do something meaningful in response, in these cases use checked exceptions. There has been a lot of debate over the usage of checked vesus unchecked exceptions over the years, I tend to fall somewhat in the middle of the debate in that I feel both types are useful. When throwing an exception, the key to knowing which type to throw is to ask youself "Can someone do something useful in response to this exception?". If the answer is yes, then use a checked exception. If the answer is no or you are in doubt then use an unchecked exception. In general the vast majority of thrown exceptions in an application should be unchecked.

Ruke #5. Always document the use of unchecked exceptions in javadoc through the use of the @throws clause.

Posted by Gerald Nunn at 7:29 PM | Categories: Java | Permalink |