NEW!! FREE MOCK EXAM SIMULATORS FOR IBM PORTAL TEST 399 & IBM PORTLET CERTIFICATION EXAM TEST 829!!!
Everything You Ever Wanted To Know About JSR-168 Portlet Development . . . PORTAL + TUTORIAL = www.portorials.com
Google
WebSphere and JSR-168 Portlet and Portal Development Best Practices and Design Suggestions

Knowing how to code a JSR-168 compliant portlet is one thing; However, there's a big difference between how, and how best, to develop a portlet application. As with any application, there are no right ways to develop, there are only wrong ways, and the best we can do is not come up with a wrong way. This article will simply discuss a few best practices for coding, developing, and getting the most out of a JSR168 portal framework, and hopefully, help you avoid a wrong way.


Don't Use PortletPreferences

Okay, telling you never to use PortletPreferences is a pretty over the top statement. There are actually good uses for PortletPreferences. My problem with PortletPreferences is the fact that the object is so overly used and abused in a typical development environment.

The PortletPreferences object provides the ability to store information persistently about how a client wants to use a particular portlet, sitting on a particular page. For example, with the weather portlet, a user can provide postal code information to the portlet, and the portlet will store that information persistently using the PortletPreferences object. The next time the user visits the view mode of the portlet, the weather for that user's postal code will be displayed. Persistently storing this information, and tying the corresponding data to the user and the portlet, is all done behind the scenes for you by the portal framework. This all sounds good, right?

Well, let me ask you: how does the portal server save PortletPreferences information? Does it write it to the hard drive? Does it write it to a small, lightweight database like Derby? Does it store it in 16 kilobyte blocks in a DB2 database? Well, the answer is, I don't know. How data is stored is completely up to the portal vendor. The portlet developer, and for that matter, the database or portal administrator, has very little control over it. Go ask your database administrators what they think about having very little control over data. I have a feeling they won't like it; and neither should you.

Imagine you stored a true/false flag in PortletPreferences. I can guarantee you that PortletPreferences isn't storing that as a boolean value in a database. The information is probably being turned into character data, or a CLOB, or something very inefficient. If you wrote a little program to store that true/false flag in your own database, you could use a boolean datatype, and consume only one tiny bit of drive space, as opposed to the overhead of using some large and unwieldy character type.

Furthermore, how do you mine information stored to PortletPreferences? Imagine you had a little tax portlet, that estimated a user's tax burden, based on their income. Imagine you stored the user's income as a PortletPreference. How would you go back and mine that income data? If your boss comes to you and says "You know how we keep track of a user's income in that tax portlet you created? Well, I'd like a list of all the users with income greater than $100,000 a year. Get it to me this afternoon." How are you going to do that?

If you don't know how the portal stores your PortletPreferences data, and you don't know how the portal ties a particular preference to a particular user, you're going to have a pretty hard time mining your own data. And in a world where information is power, you are giving up a lot of power when you hand your data over to the PortletPreferences object.

Now I'm not saying you should never, ever use PortletPreferences. PortletPreferences are great when used for what they are intended - a simple, configurable, portlet preference. If a user wants their portlet to have a pink background colour, then store that information in PortletPreferences. If a user wants a 14 point font, store that information in the PortletPreferences object. If the user wants to tell you where they live, or how much money they make, well, that's something I would really hesitate to store as a PortletPreference.

When you store information in the PortletPreferences object, you are giving up control over where the data is stored, how the data is stored, and how easy it is to potentially mine that data in the future. That's a whole lot of control to be giving up.


Get Service Oriented

Don't try to do too much in your portlets. Behavior coded into one portlet is very difficult to reuse in another portlet. Instead, factor our useful and potentially common behavior into a service layer.

Portlets themselves should be fairly thin, and really focused on client side presentation. Making a portlet too complex can slow down the portal, and create a frustrating experience for the user.

When common and useful behavior is factored out into a service tier, the service layer can be accessed by many different portlets, workload managed, and updated in a highly controlled fashion.


Servlet and JSP Rules Apply

The Portlet API draws heavily from the Servlet and JSP API, so many of the rules pertaining to JSP and Servlet development apply equally well to Portlet Development.

Three rules of Servlet and JSP development that rarely get violated are 1. don't spawn new threads in a Servlet, 2. don't declare instance variables in a Servlet and 3, don't synchronize Servlet methods. These rules apply equally well to portlets.

The portal server is already threading client invocations. Spawning new threads will only wreak havoc on the portal server.

As far as instance variables go, there are times when they are appropriate, but those times usually involve extending the Servlet or Portal framework, as opposed to creating a portlet or servlet that corresponds to a business case. When you are tempted to place an instance variable in a portlet, think instead about how the various scopes, such as the PortletSession or the PortletContext, might be a more appropriate place to maintain the data.

Synchronizing methods is also a bad idea in a portlet. This can create a bottleneck in your applications. Move complex logic as far away from the portlet tier as possible, and if you really need to synchronize a method, synchronize it in that far away place, not in the portlet itself.


Use Good Variable Names

It annoys the life out of me when I go into a development shop, and see tonnes of KLOCs hacked out, without a single variable name being more than four letters long. It also annoys the life out of me when people have abbreviated common words by removing the vowels, as if typing out an 'e' or an 'o' is going to be the difference between making a deadline, or being out of a job. Application development is not an episode of Wheel of Fortune. You do not have to spin for a letter, and you do not have to pay $500 for a vowel.

And reading code shouldn't be a fun game of trying to figure out the meaning of an obscure, personalized license plate. The variable name h8s10s shouldn't indicate that the user hates tennis.


Minimize Session Bloat

For managing state information about a user, the PortletSession is great. But remember, managing the PortletSession requires a great deal of effort from the Portal Server. When the vendor that provided you your portal server implemented the PortletSession, they did it in such a way that the data stored in the PortletSession could be clustered, and managed across many servers, in a horizontally and vertically scaled, workload managed, environment. Implementing this type of solution takes a lot of thought, and a lot of effort, not to mention a lot of overhead at runtime.

Furthermore, most application servers serialize the information stuffed into the PortletSession, and save all of that information as a character string, or potentially, a CLOB, in a centralized database. That will probably imply a somewhat inefficient storage of your data, not to mention the overhead of reading and writing data to a database when session data is accessed or updated. With large object graphs, it's sometimes more efficient to create your own, temporary database table, to store the information, as opposed to using the PortletSession.

Poor session management, and poor database connection management, are the two most common performance bottlenecks I encounter when troubleshooting performance issues. Minimize the potential of a session bottleneck by not throwing too much into the PortletSession, keeping the data you put into the PortletSession fairly small, and remove items from the PortletSession when you're done with them.


Comment Your Friggin' Code

I do believe that good code comments itself. Good variable names, and a proper use of the API, should make it fairly easy for a new developer to figure out what your code is doing. But I also, strongly believe, that good code is commented.

Commenting your code makes it extremely clear to other developers what your code was trying to accomplish. It also makes it easier for you to clear your thoughts and think about what you are trying to achieve as you write your code. Commented code is also a great reminder about what you were trying to accomplish when you first wrote the code. You'd be surprised how many times you come back to a piece of code and think "what the heck was I trying to do there???"

I will admit that many of the examples in this book do not contain comments. But that's because this entire book is a comment. Yes, I have left out a few, one line comments in my code, only because the code is then followed by three pages of text trying to explain it. J I also think that when learning how to use an API, it makes it a bit easier to learn when you're just looking at the code, and not a mass of comments. But code in a tutorial is different from code written in the development phase of an application. Comment your code. It's important.


Handle IO Exceptions

When the portal invokes your portlet, but decides that it's not going to wait for your portlet to finish processing, your portlet will encounter an IOException. You should handle the IOException in your code, to ensure that when there is a problem, your clients get a message that's a little more informative than simply "Portlet Unavailable."

If a portlet consumes a massive amount of processing time, and the portal server doesn't want to wait for your portlet to finish processing, your portlet will encounter an IOException. In fact, if you're doing a lot of heavy lifting in a portlet, you should occasionally check the flush method of the PrintWriter and handle a potential IOException. If you call the flush method of a PrintWriter or OutputStream in a portlet, and you get an exception, the portal server has put the kibosh on your portlet, and your portlet will not be rendered. At that point, you can end all of your complex computations, because nobody is ever going to witness the results.

Look out for the IOException in your portlet code. It will make your portlet applications all the more robust.


Encode Your NameSpaces

Many portlets, from potentially many different portlet providers, can appear on a portal page. Each of those vendors can potentially throw a textfield named password on the page, or a JavaScript method called validate. These types of name collisions can result in portlets reacting to the wrong input data, or even worse, scripting errors when the web page is delivered to the user.

To avoid name collisions on the portal server, all scripts, URLs, HTML form attributes, and the like, should be namespace encoded. Without encoding a namespace, your portlets will likely work properly in a sequestered, local test environment, but may encounter some very obscure and difficult to reproduce errors when your portlets go into production.


Use the expiration-cache Tag

Each portlet can have an expiration-cache entry in its deployment descriptor. This entry allows a portlet to cache content for a specified period of time. Caching of content can significantly improve the response-time of a portlet, and subsequently relieve the portal server from doing unneeded processing.

Furthermore, the RenderRepsonse object can be used to override the time specified in the deployment descriptor by using the EXPIRATION_CACHE property:

renderResponse.setProperty(EXPIRATION_CACHE, time);

Note, that the time is entered in seconds, and setting the time to -1 means the cache will never expire, and setting the cache to zero, 0, means the caching mechanism for the portlet is completely disabled.

Think about the life expectancy of your portlet content, and set an expiration-cache tag appropriately.


Not Every Portlet is a Framework Portlet

I always hate jumping onto a project with a bunch of developers who just took a design-patterns class, because everything they see is either a friggin' factory, or a friggin' singleton. Similarly, when portlet developers are introduced to the JSF portlet framework, or the struts portlet framework, everything they see is either a JSF or a struts portlet.

JSF and struts portlets certainly serve a purpose, but not every portlet needs to be a framework portlet. Sometimes, having a subclass of GenericPortlet acting as a controller, and then calling on a JSP or two, is all you really need. Don't go seeing framework portlets where you don't need them.

And framework portlets aren't an all or nothing thing. You don't have to decide on whether to use JSF in your portal or not. Some portlets can be JSF portlets, some can be PERL or struts portlets, and some portlets can be just regular, vanilla ice, portlets. All of the various portlet types can co-exist in the portal server.

Don't see framework portlets where they are not needed.



NEW: Free Mock Portal Certification Exam Simulators for IBM Portal Test 399 and Test 829!!!

Man, have I ever been busy. People seem to love free, online, mock exam simulators. I put together a bunch of free online exams to promote my Sun Certified Java Associate (SCJA) books, and people have been just bugging the life out of me to create some similar online tests for the IBM Portlet Development certification exams 399 and 829. Well, I've managed to do it, and they're online now.

There are five different exams, with fifteen questions each. That's 75, free, online exam questions!!! Seriously, when you get all rich and successful, please don't forget about me.

I've actually sorta cheated on the exam link names. I've listed them on the links tab as being on five different subjects. That's a bit of bait and switch, because each of the mock exams is a mish-mash of different test 399 topics, including testing, debugging, JSR168 API concepts, C2A (Click-2-Action), WebSphere Portlet Services, Struts and JSF Portlet development, and the like. The fact is, if you can pass these tests, and know why certain answers are wrong, and why certain answers are correct, you'll do well on the actual exam. If you can't score high on these exams, you're probably not ready for the exam yet.

Here's the links to the exams:

I put these together pretty late at night. If there are any errors or typos, or even questions you have an issue with, please leave a message on the message board. I love a little portal debate.

Become a Sun Certified Java Associate Now!!! The New, Entry Level, Sun Java Certification

Is SCJA Java certification on your horizon? Then you've come to the right place. We have resources galore, from discounts on the best selling SCJA Certification Guide, to free mock tests and multimedia tutorials.

Test yourself with our free, on-line, mock SCJA exam simulators. We have provided over fifty questions, hitting on five of the eight key objectives of the SCJA exam. Take our on-line tests, and gauge how prepared you are for certification.

And if you need more practice, pick up a copy of both the SCJA Certification Guide, and SCJA Exam Questions guide. Together, they have over 350 exam inspired questions, along with thorough, expert answers to help solidify your knowledge of the SCJA material before you tackle the real exam.

Get yourself prepared, with Cameron McKenzie's SCJA Certification Guides!

Is Someone You Know New to WebSphere???

Or maybe you and a friend just need a deeper understanding of the technology that drives your middle tier?

There's only one way to become the most knowledgeable and informed member of your IT team; pick up a copy of the ultimate book on IBM's middle-tier: "What is WebSphere?"

"What is WebSphere?" tackles all of those tough, technical, WebSphere related questions in a funny, informative and easy to understand manner.

From EJBs to the intricacies of the Portal Server, from performance to WebSphere classloaders, "What is WebSphere?" is the only reference you need to start mastering, managing, and capitalizing on an IBM based, WebSphere infrastructure.

Buy What is WebSphere? now on Amazon!

Other Must Have Resources

How many times have I told you that "What is WebSphere?" by Cameron McKenzie is the only reference you need to start capitalizing on a WebSphere infrastructure? Oh well, some people just don't listen. Here are some other great books you might want to pick up if you're interested in becoming a WebSphere Jedi:

Google



eXTReMe Tracker

ActionRequest ActionResponse GenericPortlet PortletRequestDispatcher . Portlet ..... PortletURL
PortletContext PortletException PortletMode a PortletModeException PortletPreferences
PortalContext PortletResponse PortletSession PortletSecurityException PreferencesValidator
PortletConfig RenderRequest RenderResponse UnavailableException PortletSessionUtil
PortletRequest ValidatorException WindowState WindowStateException UnmodifiableException