Posted by timboudreau
on August 16, 2008 at 10:32 AM PDT
I'm helping a friend work on a project involving Portlets. There is a nice integration of OpenPortal with NetBeans, for one-click deployment. But OpenPortal is missing the Apache Portlet Bridges stuff necessary to use the wicket portlet. So I wrote an implementation last night. It's not beautiful but it will get you going.
Addendum, two days later: The solution here almost works, but doesn't. You really need the actual servlet, not something being proxied by WicketFilter - action processing happens before the ThreadLocal for the HTTP request and response have been assigned. Basically, you can get a wicket portlet up in OpenPortal this way, but the first request after that will fail.
I have patched OpenPortal to implement the apache portal bridge properly (add a class that assigns the ThreadLocal inside
and unassign it on exit; then implement the bridge calling that (I'm sure this is not
how the OpenPortal folks would prefer such a thing to be implemented - the Portlet API appears to have been written to take great pains not to assume servlets are part of the equation, and that's probably a Good Thing™, but here it's needed.
The result is almost
working - still have to figure out why OpenPortal sometimes sends an ActionResponse where it looks like it should be a RenderResponse; that and completely grokking how
is really supposed to rewrite URLs (looking at how Apache Jetspeed does it didn't help as much as I'd hoped) should do it.
So, sorry for the false alarm, but given that my instructions involved patching a bunch of stuff (now it involves patching OpenPortal, Wicket and
Apache Portal Bridges - it's been a long day of reading source code for multiple portal servers - I expect nobody went off and immediately tried to duplicate this.
For anybody concerned about it, the 80/20 rule still stands :-)
I'm helping my friend Jon
on a project involving Portlets. There is a nice integration of OpenPortal
(the Sun Java System We Made This Name So Long You Can't Say It Portal Server
by any other name) with NetBeans
, for one-click deployment. But OpenPortal is missing the Apache Portlet Bridges stuff necessary to use the wicket portlet. So I wrote an implementation last night. It's not beautiful, and is currently tied to Wicket, but it will get you going.
It's a fun project also because Jon and I grew up a mile from each other and learned programming together. Interesting that we're doing today (sitting in front of a computer coding together) exactly what we were doing 28 years ago (except that we were about 12 and it was Z-80 assembly language).
Anyway, he's trying to get some stuff going with Wicket and Portlets. I've got to say I'm not in love with the Portlet spec to say the least - for some light reading check out the WSRP spec
(although if a portal server implements it, what it does could be cool). I do like the idea of writing Portlets as simple Wicket Applications - that
Anyway, here's what you need to do to make it work. It goes through Wicket to get the filter, which is probably not really what you want, but it does make it usable (if someone knows a way to get this stuff from inside the bowels of OpenPortal and implement it right, let me know).
First you need to get the sources to the Apache Portals Bridges
project. Don't get scared - we're just patching one file to fix a bug
subproject, and it's simple. Open
. If you have NetBeans Maven Support
, you can just open the project, look up the type and rebuild it.
does something odd: It calls
and casts the result as a String. Then it puts a Double under that key. Needless to say, if this method is called twice in the same session, it will throw a
, which is what we're fixing. Change two lines and add one so it looks like this:
Object portletWindowId = session.getAttribute(PORTLET_WINDOW_ID);
if ( portletWindowId == null )
Double value = new Double(Math.random());
portletWindowId = value;
Enumeration names = session.getAttributeNames(PortletSession.APPLICATION_SCOPE);
String name = (String)names.nextElement();
if (PortletSessionUtil.decodeAttributeName(name).equals(PORTLET_WINDOW_ID) &&
portletWindowId = name.substring("javax.portlet.p.".length(),name.indexOf('?'));
The thing we need now is implementations of
for OpenPortal. Not being a portlet expert, this is a bit of a hack, because I'm getting the servlet context from the Wicket Application. Hopefully someone will read this and know where in OpenPortal-source to do this.
Anyway, it's all in the attached project - get that and build it and put it on the classpath of your web application. It contains an interface your Wicket application needs to implement (provides public access to WicketFilter->ServletContext) and a subclass of
[or you can implement
from the attached project on your existing Application if you're already subclassing it - this is the ugly stuff]). Similarly, your WicketApplication subclass needs to implement
Finally, modify your
to point to my subclass of
(I said this was ugly, didn't I?) or your portlet if it now implements my
Now you need to add two parameters to your
to tell it where the implementations of the two Apache Portals Bridges implementation are:
If you've already got your Portlet working on, say, JetSpeed
, you won't need to modify the
file for your web application. If you're just getting going, here's mine for completeness:
<web-app version="2.5" 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 " title="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
Anyway, it would be nice if this stuff would just work
with OpenPortal, but this should work in the until then. I've filed a bug with the fix for commons-bridges, so hopefully that will be fixed soon. Also, perhaps I can add a portal template to NetBeans Wicket Support
so you can just do New Project > Web > Wicket Portal Project (although it would be nice to get rid of the hacks first).
The implementation of the bridges interfaces can be downloaded here
- it's just an Ant-based NetBeans project. Add it to your web app's classpath and implement the two interfaces described above. A zip of the sources
is also available (you need portals-bridges-common, Wicket 1.3.x and the servlet API on the classpath to build it).