<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18577364</id><updated>2011-11-28T02:30:50.941+01:00</updated><category term='apache'/><category term='portlet 2'/><category term='debug'/><category term='jsr-286'/><category term='msysgit'/><category term='plink'/><category term='java 5'/><category term='retrotranslator'/><category term='backport'/><category term='JSR168'/><category term='tutorial'/><category term='junit'/><category term='portlet20'/><category term='maven'/><category term='tomcat'/><category term='jsr286'/><category term='retrotranslator-maven-plugin'/><category term='maven 2'/><category term='jboss portal'/><category term='GIT_SSH'/><category term='mod_proxy_html'/><category term='archetype'/><category term='rewrite'/><category term='portlet'/><category term='apache http server'/><category term='tortoisesvn'/><category term='git'/><category term='java 1.4'/><category term='jetty'/><category term='portlet 2.0'/><category term='integration testing'/><category term='mod_proxy'/><category term='ssh client'/><category term='weblogic'/><category term='eclipse'/><category term='pluto'/><category term='jwebunit'/><category term='portlet archetype'/><category term='run'/><category term='struts 2'/><title type='text'>PortletWork</title><subtitle type='html'>JSR 168 and JSR 286 related News, Tips, Tricks, Hints, Tutorials and other Portlet/Portal Resources.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18577364.post-4551653974488663183</id><published>2009-04-14T12:32:00.000+02:00</published><updated>2009-04-14T12:59:51.619+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mod_proxy'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='mod_proxy_html'/><category scheme='http://www.blogger.com/atom/ns#' term='rewrite'/><category scheme='http://www.blogger.com/atom/ns#' term='apache http server'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='weblogic'/><title type='text'>Setting up Apache and mod_proxy_html for my web application</title><content type='html'>Recently I had to set up &lt;a href="http://httpd.apache.org/"&gt;Apache HTTP Server&lt;/a&gt; as a &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html"&gt;proxy&lt;/a&gt; to our web application running on WebLogic. Should be a simple task, except the application has a different context path when served by Apache. This is how it's set up:&lt;br /&gt;&lt;br /&gt;Web App context path in WebLogic: &lt;span style="font-style: italic;"&gt;http://localhost:8013/mywebapp&lt;/span&gt;&lt;br /&gt;Web App context path in Apache: &lt;span style="font-style: italic;"&gt;http://localhost:8080/some/extra/path/elements/mywebapp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With this configuration, the web application generate urls like &lt;span style="font-style: italic;"&gt;http://localhost:8080/mywebapp/some/link&lt;/span&gt;, which causes problems since that path doesn't point to the web application. The correct url should be &lt;span style="font-style: italic;"&gt;http://localhost:8080/some/extra/path/elements/mywebapp/some/link&lt;/span&gt;. After doing some research, I found the &lt;a href="http://apache.webthing.com/mod_proxy_html/"&gt;mod_proxy_html&lt;/a&gt; Apache module. This module parses the HTML from the web application and based on a specified rule set, it replaces urls in the HTML with rewritten, correct urls.&lt;br /&gt;&lt;br /&gt;After following the &lt;a href="http://www.apachetutor.org/admin/reverseproxies"&gt;initial configuration tutorial&lt;/a&gt;, I only got a message in the log saying "&lt;span style="font-style: italic;"&gt;No links configured: nothing for proxy-html filter to do&lt;/span&gt;". Aparently, the documentation I read was a bit outdated, and after doing a google search, I found &lt;a href="http://ckdake.com/node/235"&gt;an article&lt;/a&gt; explaining some extra steps needed to get things up and working. Together with &lt;a href="http://dltj.org/article/apache-httpd-and-tomcat/"&gt;another useful guide&lt;/a&gt;, I was able to set things up producing the result I wanted.&lt;br /&gt;&lt;br /&gt;This set up is not specific to WebLogic. It should work with other containers as well, such as &lt;a href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt;, &lt;a href="http://www.mortbay.org/jetty/"&gt;Jetty&lt;/a&gt; etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-4551653974488663183?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/4551653974488663183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=4551653974488663183' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4551653974488663183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4551653974488663183'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2009/04/rewriting-urls-in-web-application-using.html' title='Setting up Apache and mod_proxy_html for my web application'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-7169275581241800319</id><published>2009-01-20T06:17:00.000+01:00</published><updated>2009-01-20T13:22:09.703+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='tortoisesvn'/><category scheme='http://www.blogger.com/atom/ns#' term='GIT_SSH'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh client'/><category scheme='http://www.blogger.com/atom/ns#' term='plink'/><category scheme='http://www.blogger.com/atom/ns#' term='msysgit'/><title type='text'>Problem with Git on Windows</title><content type='html'>Just a little tip from a &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt; newbie using Windows and &lt;a href="http://code.google.com/p/msysgit/"&gt;msysGit&lt;/a&gt;. Yesterday I couldn't push changes to my &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt; repository. I have no idea why... Maybe it had something to do with the size and number of files in the change set? Anyway, I kept getting error messages saying &lt;span style="font-style:italic;"&gt;"unable to read from standard input"&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;"remote end hung up unexpectedly"&lt;/span&gt;. After struggling with the problem for a while, I tried switching from &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;PuTTY&lt;/a&gt; &lt;span style="font-style:italic;"&gt;plink.exe&lt;/span&gt; to &lt;a href="http://tortoisesvn.tigris.org/"&gt;TortoiseSVN&lt;/a&gt; &lt;span style="font-style:italic;"&gt;TortoisePlink.exe&lt;/span&gt; as the SSH client (&lt;span style="font-style:italic;"&gt;export GIT_SSH="C:\Program Files\TortoiseSVN\bin\TortoisePlink.exe"&lt;/span&gt;), and for some reason, everything started to work again.&lt;br /&gt;&lt;br /&gt;If anyone know why this problem occured, and why it was solved by switching SSH client, please let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-7169275581241800319?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/7169275581241800319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=7169275581241800319' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/7169275581241800319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/7169275581241800319'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2009/01/problem-with-git-on-windows.html' title='Problem with Git on Windows'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-4669577038755993446</id><published>2008-06-19T16:54:00.000+02:00</published><updated>2008-06-19T16:59:24.262+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr286'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr-286'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet20'/><title type='text'>JSR-286 specification is ready</title><content type='html'>The &lt;a href="http://jcp.org/en/jsr/detail?id=286"&gt;Portlet 2.0 specification&lt;/a&gt; &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=49711"&gt;has been released&lt;/a&gt;. Maybe a bit overdue, but I guess late is better than never. As I have pointed out in an earlier post, &lt;a href="http://portletwork.blogspot.com/2008/03/experimenting-with-jsr286-portlet-20.html"&gt;I'm working on a Portlet 2.0 plugin for Struts 2&lt;/a&gt;. The basics are in place, but there's still a lot of work to be done. But do try it out if you want!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-4669577038755993446?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/4669577038755993446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=4669577038755993446' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4669577038755993446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4669577038755993446'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2008/06/jsr-286-released.html' title='JSR-286 specification is ready'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-3643086172467904658</id><published>2008-03-31T17:30:00.001+02:00</published><updated>2008-03-31T17:53:40.596+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr286'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet 2'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Experimenting with JSR286 (Portlet 2.0) support in Struts 2</title><content type='html'>I've started playing with &lt;a href="http://jcp.org/en/jsr/detail?id=286"&gt;portlet 2.0&lt;/a&gt; support in Struts 2, and the &lt;a href="http://boss.bekk.no/display/BOSS/Struts+2+Portlet+2.0+Plugin"&gt;experimental JSR286 plugin&lt;/a&gt; currently supports both basic event and resource serving, which are two of the most anticipated features of the new portlet specification. In parallel, I've adapted the &lt;a href="http://boss.bekk.no/display/BOSS/Maven+Jetty+Pluto+Embedded"&gt;maven-jetty-pluto-embedded&lt;/a&gt; artifact to support &lt;a href="http://portals.apache.org/pluto/"&gt;Pluto 2.0&lt;/a&gt;, so I can easily develop and test directly with Maven or my IDE.&lt;br /&gt;&lt;br /&gt;This is still &lt;span style="font-style: italic;"&gt;very&lt;/span&gt; experimental, but feel free to give it a try. I've also created a very basic sample portlet that uses the plugin which you can &lt;a href="https://boss.bekk.no/repos/projects/jsr286-portlet/"&gt;check out and build&lt;/a&gt;. Note that you might have to build Pluto 2.0 from source unless you find it in a Maven repository somewhere.&lt;br /&gt;&lt;br /&gt;Please drop me a line if you find anything that doesn't work, or if you want to discuss implementation and features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-3643086172467904658?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/3643086172467904658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=3643086172467904658' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/3643086172467904658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/3643086172467904658'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2008/03/experimenting-with-jsr286-portlet-20.html' title='Experimenting with JSR286 (Portlet 2.0) support in Struts 2'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-6873806092184128631</id><published>2008-02-19T10:43:00.000+01:00</published><updated>2008-08-06T09:28:48.298+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss portal'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><title type='text'>Struts 2 Portlet in JBoss Portal</title><content type='html'>I have been asked if &lt;a href="http://struts.apache.org/2.x/docs/portlet-plugin.html"&gt;Struts 2 portlets&lt;/a&gt; can be deployed in &lt;a href="http://labs.jboss.com/jbossportal/"&gt;JBoss Portal&lt;/a&gt;, and if yes, how to deploy Struts 2 portlets to JBoss Portal. &lt;br /&gt;&lt;br /&gt;The answer to the first question is of course yes. Since Struts 2 Portlet is a JSR168 framework, it can be deployed to any portlet container supporting the JSR168 standard, including JBoss Portal. &lt;br /&gt;&lt;br /&gt;To answer the second question, I had to browse through the JBoss Portal &lt;a href="http://docs.jboss.com/jbportal/v2.6.4/referenceGuide/html/"&gt;reference guide&lt;/a&gt;, and found that you have to write &lt;a href="http://docs.jboss.com/jbportal/v2.6.4/referenceGuide/html/tutorials.html#d0e2127"&gt;two custom deployment descriptors&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For the Struts 2 sample portlet application, I added the following:&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;portlet-instances.xml&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" standalone="yes"?&gt;&lt;br /&gt;&amp;lt;!DOCTYPE deployments PUBLIC&lt;br /&gt;   "-//JBoss Portal//DTD Portlet Instances 2.6//EN"&lt;br /&gt;   "http://www.jboss.org/portal/dtd/portlet-instances_2_6.dtd"&gt;&lt;br /&gt;&amp;lt;deployments&gt;&lt;br /&gt;   &amp;lt;deployment&gt;&lt;br /&gt;      &amp;lt;instance&gt;&lt;br /&gt;         &amp;lt;instance-id&gt;StrutsPortletInstance&amp;lt;/instance-id&gt;&lt;br /&gt;         &amp;lt;portlet-ref&gt;StrutsPortlet&amp;lt;/portlet-ref&gt;&lt;br /&gt;      &amp;lt;/instance&gt;&lt;br /&gt;   &amp;lt;/deployment&gt;&lt;br /&gt;&amp;lt;/deployments&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;struts2-portlet-object.xml&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br /&gt;&amp;lt;!DOCTYPE deployments PUBLIC&lt;br /&gt;   "-//JBoss Portal//DTD Portal Object 2.6//EN"&lt;br /&gt;   "http://www.jboss.org/portal/dtd/portal-object_2_6.dtd"&gt;&lt;br /&gt;&amp;lt;deployments&gt;&lt;br /&gt;   &amp;lt;deployment&gt;&lt;br /&gt;      &amp;lt;parent-ref&gt;default.default&amp;lt;/parent-ref&gt;&lt;br /&gt;      &amp;lt;if-exists&gt;overwrite&amp;lt;/if-exists&gt;&lt;br /&gt;      &amp;lt;window&gt;&lt;br /&gt;         &amp;lt;window-name&gt;StrutsPortletWindow&amp;lt;/window-name&gt;&lt;br /&gt;         &amp;lt;instance-ref&gt;StrutsPortletInstance&amp;lt;/instance-ref&gt;&lt;br /&gt;         &amp;lt;region&gt;center&amp;lt;/region&gt;&lt;br /&gt;         &amp;lt;height&gt;1&amp;lt;/height&gt;&lt;br /&gt;      &amp;lt;/window&gt;&lt;br /&gt;   &amp;lt;/deployment&gt;&lt;br /&gt;&amp;lt;/deployments&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I added both files to the &lt;span style="font-style:italic;"&gt;WEB-INF&lt;/span&gt; folder of the application.&lt;br /&gt;&lt;br /&gt;With both files added, put the &lt;span style="font-style:italic;"&gt;war&lt;/span&gt; file in the &lt;span style="font-style:italic;"&gt;deploy&lt;/span&gt; folder of your server, and your portlet should appear on the default page of the portal.&lt;br /&gt;&lt;br /&gt;Consult the documentation for a description of these files, and the relations between the names and ids in them.&lt;br /&gt;&lt;br /&gt;I would rather not have to specify the instances, page and placement of the portlet in a descriptor in the portlet application itself, but that is how it was described in the documentation.&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Update:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;It appears that these descriptors are indeed optional. You can deploy a plain Struts 2 Portlet (or any JSR168 portlet for that matter) and do all the required steps in the portal administration.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-6873806092184128631?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/6873806092184128631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=6873806092184128631' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/6873806092184128631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/6873806092184128631'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2008/02/struts-2-portlet-in-jboss-portal.html' title='Struts 2 Portlet in JBoss Portal'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-9112633642857607153</id><published>2008-02-11T23:17:00.001+01:00</published><updated>2008-02-12T00:20:16.536+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='java 5'/><category scheme='http://www.blogger.com/atom/ns#' term='java 1.4'/><category scheme='http://www.blogger.com/atom/ns#' term='backport'/><category scheme='http://www.blogger.com/atom/ns#' term='retrotranslator'/><category scheme='http://www.blogger.com/atom/ns#' term='retrotranslator-maven-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><title type='text'>Struts 2 Portlet in WebSphere 5.1</title><content type='html'>At work I recently wanted to build a &lt;a href="http://struts.apache.org/2.x/docs/portlet-plugin.html"&gt;Struts 2 Portlet&lt;/a&gt; to see if I could deploy it in WebSphere Portal 5.1. As you know, Struts 2 requires Java 5 to run, and as you might also know, WebSphere Portal 5.1 only runs Java 1.4. &lt;a href="http://retrotranslator.sourceforge.net/"&gt;Retrotranslator&lt;/a&gt; to the rescue! I added the &lt;a href="http://mojo.codehaus.org/retrotranslator-maven-plugin/"&gt;retrotranslator-maven-plugin&lt;/a&gt; from the &lt;a href="http://mojo.codehaus.org/"&gt;Codehaus Mojo project&lt;/a&gt;, and set it up to run the &lt;a href="http://mojo.codehaus.org/retrotranslator-maven-plugin/translate-war-mojo.html"&gt;translate-war&lt;/a&gt; goal:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;build&gt;&lt;br /&gt;  &amp;lt;plugin&gt;&lt;br /&gt;    &amp;lt;groupId&gt;org.codehaus.mojo&amp;lt;/groupId&gt;&lt;br /&gt;    &amp;lt;artifactId&gt;retrotranslator-maven-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;    &amp;lt;version&gt;1.0-alpha-2&amp;lt;/version&gt;&lt;br /&gt;    &amp;lt;executions&gt;&lt;br /&gt;      &amp;lt;execution&gt;&lt;br /&gt;        &amp;lt;goals&gt;&lt;br /&gt;          &amp;lt;goal&gt;translate-war&amp;lt;/goal&gt;&lt;br /&gt;        &amp;lt;/goals&gt;&lt;br /&gt;        &amp;lt;configuration&gt;&lt;br /&gt;        &amp;lt;classifier&gt;jdk1.4&amp;lt;/classifier&gt;&lt;br /&gt;        &amp;lt;attach&gt;true&amp;lt;/attach&gt;&lt;br /&gt;          &amp;lt;advanced&gt;true&amp;lt;/advanced&gt;&lt;br /&gt;        &amp;lt;/configuration&gt;&lt;br /&gt;      &amp;lt;/execution&gt;&lt;br /&gt;    &amp;lt;/executions&gt;&lt;br /&gt;  &amp;lt;/plugin&gt;&lt;br /&gt;&amp;lt;/build&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I also had to include a couple of new dependencies introduced by Retrotranslator:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;dependencies&gt;&lt;br /&gt;  &amp;lt;dependency&gt;&lt;br /&gt;    &amp;lt;groupId&gt;backport-util-concurrent&amp;lt;/groupId&gt;&lt;br /&gt;    &amp;lt;artifactId&gt;backport-util-concurrent&amp;lt;/artifactId&gt;&lt;br /&gt;    &amp;lt;version&gt;3.0&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;/dependency&gt;&lt;br /&gt;  &amp;lt;dependency&gt;&lt;br /&gt;    &amp;lt;groupId&gt;net.sf.retrotranslator&amp;lt;/groupId&gt;&lt;br /&gt;    &amp;lt;artifactId&gt;retrotranslator-runtime&amp;lt;/artifactId&gt;&lt;br /&gt;    &amp;lt;version&gt;1.2.1&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;/dependency&gt;&lt;br /&gt;&amp;lt;/dependencies&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I had to use the &lt;span style="font-style:italic;"&gt;1.0-alpha-2&lt;/span&gt; version of the plugin, otherwise I got an obscure &lt;span style="font-style:italic;"&gt;java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean&lt;/span&gt; failure...&lt;br /&gt;&lt;br /&gt;Unfortunately, that was not quite enough. When running the portlet, I would get an exception about a missing &lt;span style="font-style:italic;"&gt;javax.xml.namespace.NamespaceContext&lt;/span&gt; class which &lt;a href="http://www.opensymphony.com/xwork/"&gt;XWork&lt;/a&gt; aparently needs. It appears that this class is included in the Java 5 libraries, but not with Java 1.4. I found it in the &lt;span style="font-style:italic;"&gt;jaxp-api.jar&lt;/span&gt; in the &lt;a href="http://java.sun.com/webservices/downloads/previous/webservicespack.jsp"&gt;Sun Java Web Services Developer Pack 2.0&lt;/a&gt;. I placed this jar in the &lt;span style="font-style:italic;"&gt;%WAS_HOME%/java/jre/lib/ext&lt;/span&gt; folder (I tried putting it in the web application, but that didn't work... Classloading in JEE application servers has always been fun...). I also had to exclude any web application dependencies that included &lt;span style="font-style:italic;"&gt;Xerces&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;Xalan&lt;/span&gt; or &lt;span style="font-style:italic;"&gt;xml-apis&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;No guarantees that this works for you though. But I guess as long as you don't break any of the &lt;a href="http://retrotranslator.sourceforge.net/#limitations"&gt;limitations&lt;/a&gt; retrotranslator has, you'll be fine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-9112633642857607153?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/9112633642857607153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=9112633642857607153' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/9112633642857607153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/9112633642857607153'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2008/02/struts-2-portlet-in-websphere-51.html' title='Struts 2 Portlet in WebSphere 5.1'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-3943861408005821156</id><published>2008-01-07T14:11:00.000+01:00</published><updated>2008-01-09T15:03:45.323+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><title type='text'>Struts 2 Portlet Tutorial</title><content type='html'>I have made available a new &lt;a href="http://cwiki.apache.org/confluence/display/WW/Struts+2+Portlet+Tutorial"&gt;Struts 2 portlet tutorial&lt;/a&gt; in the &lt;a href="http://cwiki.apache.org/confluence/display/S2PLUGINS/Home"&gt;Struts 2 Plugin Repository wiki&lt;/a&gt;. The tutorial is work in progress and is currently based on the 2.1.1-SNAPSHOT of &lt;a href="http://sruts.apache.org/2.x"&gt;Struts 2&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The tutorial is using the Struts 2 portlet archetype which includes much of the stuff I have written about in this blog to (hopefully) &lt;a href="http://portletwork.blogspot.com/2007/10/easy-portlet-development-and-reduced.html"&gt;improve portlet developmet productivity&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Please try it out and let me know of any issues you encounter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-3943861408005821156?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/3943861408005821156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=3943861408005821156' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/3943861408005821156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/3943861408005821156'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2008/01/struts-2-portlet-tutorial.html' title='Struts 2 Portlet Tutorial'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-4111877536433388407</id><published>2007-10-06T03:20:00.000+02:00</published><updated>2007-11-22T08:35:20.901+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='struts 2'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><category scheme='http://www.blogger.com/atom/ns#' term='archetype'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet archetype'/><title type='text'>Easy portlet development and reduced roundtrip with the updated Struts 2 portlet archetype</title><content type='html'>&lt;span style="font-weight:bold;"&gt;The entry has been updated to reflect the new 2.1.1-SNAPSHOT release&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have just deployed an updated version of the Struts 2 portlet archetype, which is based on Struts 2.1.1. The archetype also includes the &lt;a href="http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html"&gt;jetty-pluto integration&lt;/a&gt; which should reduce the roundtrip from development to testing and running quite a lot.&lt;br /&gt;&lt;br /&gt;To create a basic Struts 2 portlet with the archetype, run the command&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mvn archetype:create&lt;br /&gt;  -DgroupId=&amp;lt;groupId&gt;&lt;br /&gt;  -DartifactId=&amp;lt;artifactId&gt;&lt;br /&gt;  -DarchetypeGroupId=org.apache.struts&lt;br /&gt;  -DarchetypeArtifactId=struts2-archetype-portlet&lt;br /&gt;  -DarchetypeVersion=2.1.1-SNAPSHOT&lt;br /&gt;  -DremoteRepositories=&lt;br /&gt;        http://people.apache.org/repo/m2-snapshot-repository&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;(all on one line)&lt;br /&gt;&lt;br /&gt;Just replace &lt;span style="font-style: italic;"&gt;&amp;lt;groupId&gt;&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;&amp;lt;artifactId&gt;&lt;/span&gt; with your real groupId and artifactId. Now you can just type &lt;span style="font-style: italic;"&gt;mvn jetty:run -P pluto-embedded&lt;/span&gt; to run the portlet in pluto. The &lt;span style="font-style: italic;"&gt;pluto-embedded&lt;/span&gt; profile does the magic of setting up the integration between the &lt;span style="font-style: italic;"&gt;maven-jetty-plugin&lt;/span&gt; and pluto. To test it, just open a browser and point it to &lt;span style="font-style: italic;"&gt;http://localhost:8080/&amp;lt;artifactId&gt;/pluto/index.jsp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have also included a class called &lt;span style="font-style: italic;"&gt;JettyPlutoLauncher&lt;/span&gt; (you might recognize it from a &lt;a href="http://portletwork.blogspot.com/2007/08/launching-and-debugging-portlets-from.html"&gt;previous entry&lt;/a&gt;) in the test sources of the generated project. It is simply a class with a main method that can be used to launch the portlet from your IDE. To use it with eclipse simply type &lt;span style="font-style: italic;"&gt;mvn eclipse:eclipse -P pluto-embedded&lt;/span&gt;, import the project in Eclipse, and select to run the &lt;span style="font-style: italic;"&gt;JettyPlutoLauncher&lt;/span&gt; class. Then open a browser to the same URL as described above.&lt;br /&gt;&lt;br /&gt;This will hopefully get you up and running with Struts 2 portlet development pretty quick!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-4111877536433388407?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/4111877536433388407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=4111877536433388407' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4111877536433388407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4111877536433388407'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2007/10/easy-portlet-development-and-reduced.html' title='Easy portlet development and reduced roundtrip with the updated Struts 2 portlet archetype'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-8964856182139876573</id><published>2007-08-27T07:47:00.000+02:00</published><updated>2007-10-22T07:06:46.229+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='run'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='debug'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><title type='text'>Launching and debugging Portlets from Eclipse with Jetty and Pluto</title><content type='html'>&lt;a href="http://portletwork.blogspot.com/2007/08/testing-portlets-with-jetty-pluto-and.html"&gt;Last time&lt;/a&gt; I showed how you can combine &lt;a href="http://www.mortbay.org"&gt;Jetty&lt;/a&gt;, &lt;a href="http://portals.apache.org/pluto"&gt;Pluto&lt;/a&gt; and &lt;a href="http://jwebunit.sourceforge.net/"&gt;JWebUnit&lt;/a&gt; (or any other web testing framework for that matter) to easily write integration tests for your portlets. As a short follow up, I'll show you how to use the same setup to create a simple "Launcher" to get your portlets up and running quickly from Eclipse (but it can easily be modified to work in your favorite IDE).&lt;br /&gt;&lt;br /&gt;The first thing to do is to add the usual dependencies to your &lt;span style="font-style:italic;"&gt;pom.xml&lt;/span&gt; file (assuming you're using Maven 2 to build your portlet project. If not, add the dependencies to your classpath manually):&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Update: The maven-jetty-pluto-embedded artifact is available in the Maven 2 repositories.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;dependency&gt;  &lt;br /&gt;  &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;  &lt;br /&gt;  &amp;lt;artifactId&gt;jetty&amp;lt;/artifactId&gt;  &lt;br /&gt;  &amp;lt;version&gt;6.1.5&amp;lt;/version&gt;  &lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;  &lt;br /&gt;&amp;lt;/dependency&gt;  &lt;br /&gt;&amp;lt;dependency&gt;  &lt;br /&gt;  &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;  &lt;br /&gt;  &amp;lt;artifactId&gt;jsp-2.1&amp;lt;/artifactId&gt;  &lt;br /&gt;  &amp;lt;version&gt;6.1.5&amp;lt;/version&gt;  &lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;  &lt;br /&gt;&amp;lt;/dependency&gt;  &lt;br /&gt;&amp;lt;dependency&gt;  &lt;br /&gt;  &amp;lt;groupId&gt;com.bekk.boss&amp;lt;/groupId&gt;  &lt;br /&gt;  &amp;lt;artifactId&gt;maven-jetty-pluto-embedded&amp;lt;/artifactId&gt;  &lt;br /&gt;  &amp;lt;version&gt;1.0&amp;lt;/version&gt;  &lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;  &lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(if you want to know what the &lt;span style="font-style:italic;"&gt;maven-jetty-pluto-embedded&lt;/span&gt; artifact is, read &lt;a href="http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html"&gt;this&lt;/a&gt;). Note that if you have any other dependencies that either directly or indirectly has a dependency to a different version of the servlet api that Jetty 6.1.5 is using (like &lt;a href="http://www.brodwall.com/johannes/blog/2007/01/20/commons-logging-youre-on-notice/"&gt;commons-logging&lt;/a&gt;), you need to explicitly exclude this dependency, adding the following snippet inside the dependency:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;exclusions&gt;  &lt;br /&gt;  &amp;lt;exclusion&gt;  &lt;br /&gt;    &amp;lt;groupId&gt;javax.servlet&amp;lt;/groupId&gt;  &lt;br /&gt;    &amp;lt;artifactId&gt;servlet-api&amp;lt;/artifactId&gt;  &lt;br /&gt;  &amp;lt;/exclusion&gt;  &lt;br /&gt;&amp;lt/exclusions&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you have not already done so, run &lt;span style="font-style:italic;"&gt;mvn eclipse:eclipse&lt;/span&gt; to add the dependencies to your Eclipse project. Next, create a new class called &lt;span style="font-style:italic;"&gt;JettyPlutoLauncher&lt;/span&gt; (I put it in my &lt;span style="font-style:italic;"&gt;src/test/java&lt;/span&gt; folder). We'll add a &lt;span style="font-style:italic;"&gt;main&lt;/span&gt; method to this class, doing the exact same as the &lt;span style="font-style:italic;"&gt;setUp()&lt;/span&gt; method of our base integration test described in the &lt;a href="http://portletwork.blogspot.com/2007/08/testing-portlets-with-jetty-pluto-and.html"&gt;previous entry&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import org.apache.pluto.core.PortletServlet;&lt;br /&gt;import org.mortbay.jetty.Server;&lt;br /&gt;import org.mortbay.jetty.servlet.ServletHolder;&lt;br /&gt;import org.mortbay.jetty.webapp.WebAppContext;&lt;br /&gt;&lt;br /&gt;public class JettyPlutoLauncher {&lt;br /&gt; public static void main(String[] args) throws Exception {&lt;br /&gt;     System.setProperty("org.apache.pluto.embedded.portletId", "portletId");&lt;br /&gt;     Server server = new Server(8080);&lt;br /&gt;     WebAppContext webapp = new WebAppContext("src/main/webapp", "/contextRoot");&lt;br /&gt;     webapp.setDefaultsDescriptor("/WEB-INF/jetty-pluto-web-default.xml");&lt;br /&gt;     ServletHolder portletServlet = new ServletHolder(new PortletServlet());&lt;br /&gt;     portletServlet.setInitParameter("portlet-name", "portletId");&lt;br /&gt;     portletServlet.setInitOrder(1);&lt;br /&gt;     webapp.addServlet(portletServlet, "/PlutoInvoker/portletId");&lt;br /&gt;     server.addHandler(webapp);&lt;br /&gt;     server.start();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Replace all occurrences of &lt;span style="font-style:italic;"&gt;portletId&lt;/span&gt; with the actual id of the portlet to run, and &lt;span style="font-style:italic;"&gt;contextRoot&lt;/span&gt; with the context root you want for your application.&lt;br /&gt;&lt;br /&gt;That's it. Now you can simply select your class and do "Run As - Java Application" to run, or "Debug As - Java Application" to do step by step debugging your portlet!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-8964856182139876573?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/8964856182139876573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=8964856182139876573' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/8964856182139876573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/8964856182139876573'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2007/08/launching-and-debugging-portlets-from.html' title='Launching and debugging Portlets from Eclipse with Jetty and Pluto'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-8191583110082978464</id><published>2007-08-18T23:07:00.000+02:00</published><updated>2007-10-22T07:13:48.083+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='integration testing'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='jwebunit'/><title type='text'>Testing Portlets with Jetty, Pluto and JWebUnit</title><content type='html'>After my last &lt;a href="http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html"&gt;two&lt;/a&gt; &lt;a href="http://portletwork.blogspot.com/2007/07/mvnjetty-and-portlets.html"&gt;entries&lt;/a&gt;, I've gotten some questions about using pluto embedded in jetty to create automated integration tests for &lt;a href="http://www.jcp.org/en/jsr/detail?id=168"&gt;JSR 168&lt;/a&gt; portlets. Using the &lt;a href="http://www.mortbay.org/maven-plugin/index.html"&gt;maven-jetty-plugin&lt;/a&gt; for running the portlets is great for fast, iterative development. But it can't be used to run automated integration tests. Remembering an excellent &lt;a href="http://www.brodwall.com/johannes/blog/2006/12/10/in-process-web-integration-tests-with-jetty-and-jwebunit/"&gt;article &lt;/a&gt; from &lt;a href="http://www.brodwall.com/johannes/blog/"&gt;Johannes Brodwall's blog&lt;/a&gt; about integration testing with &lt;a href="http://www.mortbay.org/"&gt;Jetty&lt;/a&gt; and &lt;a href="http://jwebunit.sourceforge.net/"&gt;JWebUnit&lt;/a&gt;&lt;/span&gt;, I wanted to extend his approach to use the embedded jetty-pluto setup I have created. This turned out to be to be quite easy.&lt;br /&gt;&lt;br /&gt;To illustrate the solution, let's start from scratch, creating a simple portlet displaying a personalized "Hello World" message (how original...). &lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Note that this is only a very simple example, outlining how it is possible to set up the infrastructure for simple web integration testing of portlets.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first step is to create a blank portlet project, using Maven 2 and the portlet archetype:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mvn archetype:create &lt;br /&gt;    -DgroupId=com.mycompany.app&lt;br /&gt;    -DartifactId=my-portlet &lt;br /&gt;    -DarchetypeArtifactId=maven-archetype-portlet&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(Type this on one line)&lt;br /&gt;&lt;br /&gt;I'll use Eclipse for this example, so I'll set up an Eclipse project for the portlet by typing &lt;span style="font-style:italic;"&gt;mvn eclipse:eclipse&lt;/span&gt;. Now you can go ahead importing the project into Eclipse as an existing project.&lt;br /&gt;&lt;br /&gt;Unfortunately, it appears that the portlet arhcetype contains a &lt;a href="http://jira.codehaus.org/browse/ARCHETYPE-86"&gt;bug&lt;/a&gt;, so make sure you update the &lt;span style="font-style:italic;"&gt;portlet-class&lt;/span&gt; element in the &lt;span style="font-style:italic;"&gt;portlet.xml&lt;/span&gt; file with the correct portlet class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;portlet-class&gt;com.mycompany.app.MyPortlet&amp;lt;/portlet-class&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we need some dependencies to &lt;span style="font-style:italic;"&gt;Jetty&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;JWebUnit&lt;/span&gt; and the &lt;span style="font-style:italic;"&gt;maven-jetty-pluto-embedded&lt;/span&gt; artifact, so add these to the dependencies section of the &lt;span style="font-style:italic;"&gt;pom.xml&lt;/span&gt; file of the portlet project:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Update: The maven-jetty-pluto-embedded artifact is available in the Maven 2 repositories.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;  &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;&lt;br /&gt;  &amp;lt;artifactId&gt;jetty&amp;lt;/artifactId&gt;&lt;br /&gt;  &amp;lt;version&gt;6.1.5&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;  &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;&lt;br /&gt;  &amp;lt;artifactId&gt;jsp-2.1&amp;lt;/artifactId&gt;&lt;br /&gt;  &amp;lt;version&gt;6.1.5&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;  &amp;lt;groupId&gt;net.sourceforge.jwebunit&amp;lt;/groupId&gt;&lt;br /&gt;  &amp;lt;artifactId&gt;jwebunit-htmlunit-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;  &amp;lt;version&gt;1.4.1&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;  &amp;lt;exclusions&gt;&lt;br /&gt;    &amp;lt;exclusion&gt;&lt;br /&gt;      &amp;lt;groupId&gt;javax.servlet&amp;lt;/groupId&gt;&lt;br /&gt;      &amp;lt;artifactId&gt;servlet-api&amp;lt;/artifactId&gt;&lt;br /&gt;    &amp;lt;/exclusion&gt;&lt;br /&gt;  &amp;lt;/exclusions&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&amp;lt;dependency&gt;&lt;br /&gt;  &amp;lt;groupId&gt;com.bekk.boss&amp;lt;/groupId&gt;&lt;br /&gt;  &amp;lt;artifactId&gt;maven-jetty-pluto-embedded&amp;lt;/artifactId&gt;&lt;br /&gt;  &amp;lt;version&gt;1.0&amp;lt;/version&gt;&lt;br /&gt;  &amp;lt;scope&gt;test&amp;lt;/scope&gt;&lt;br /&gt;&amp;lt;/dependency&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(The JWebUnit dependency has an indirect dependency on commons-logging, which for some weird reason &lt;a href="http://www.brodwall.com/johannes/blog/2007/01/20/commons-logging-youre-on-notice/"&gt;has a dependency on the servlet-api&lt;/a&gt;!? This version of the servlet-api causes problems for the version of jetty we're running, so we have to exclude it)&lt;br /&gt;&lt;br /&gt;Run &lt;span style="font-style:italic;"&gt;mvn eclipse:eclipse&lt;/span&gt; again to download the new dependencies. If you want to know what the &lt;span style="font-style:italic;"&gt;maven-jetty-pluto-embedded&lt;/span&gt; artifact is, you should read my &lt;a href="http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html"&gt;previous&lt;/a&gt;   &lt;a href="http://portletwork.blogspot.com/2007/07/mvnjetty-and-portlets.html"&gt;entries&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;Open the &lt;span style="font-style:italic;"&gt;MyPortlet&lt;/span&gt; portlet that was generated for us, and remove everything but the method signature for the &lt;span style="font-style:italic;"&gt;doView()&lt;/span&gt; method, like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class MyPortlet extends GenericPortlet {&lt;br /&gt;&lt;br /&gt;    public void doView( RenderRequest request, RenderResponse response ) {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we'll start preparing the test, and this is where the fun begins. We'll have to configure Jetty in our test to use the embedded jetty pluto setup from the previous articles. Create a new source folder, &lt;span style="font-style:italic;"&gt;src/test/java&lt;/span&gt;, and create a new blank &lt;a href="http://jwebunit.sourceforge.net/quickstart.html#Creating%20a%20TestCase"&gt;WebTestCase&lt;/a&gt;:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;package com.mycompany.app;&lt;br /&gt;&lt;br /&gt;import net.sourceforge.jwebunit.junit.WebTestCase;&lt;br /&gt;&lt;br /&gt;public class MyPortletIntegrationTest extends WebTestCase {&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We'll have to create a &lt;span style="font-style:italic;"&gt;setUp()&lt;/span&gt; metohd that initializes the Jetty server, and configures it with the pluto driver:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;protected Server server;&lt;br /&gt;&lt;br /&gt;public void setUp() throws Exception {&lt;br /&gt;    System.setProperty("org.apache.pluto.embedded.portletId", "my-portlet");&lt;br /&gt;    server = new Server(8080);&lt;br /&gt;    WebAppContext webapp = new WebAppContext("src/main/webapp", "/test");&lt;br /&gt;    webapp.setDefaultsDescriptor("/WEB-INF/jetty-pluto-web-default.xml");&lt;br /&gt;    ServletHolder portletServlet = new ServletHolder(new PortletServlet());&lt;br /&gt;    portletServlet.setInitParameter("portlet-name", "my-portlet");&lt;br /&gt;    portletServlet.setInitOrder(1);&lt;br /&gt;    webapp.addServlet(portletServlet, "/PlutoInvoker/my-portlet");&lt;br /&gt;    server.addHandler(webapp);&lt;br /&gt;    server.start();&lt;br /&gt;    getTestContext().setBaseUrl("http://localhost:8080/test");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void tearDown() throws Exception {&lt;br /&gt;    server.stop();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So what does all this mean? Basically, we have just copied the setup from the configuration of the maven-jetty-plugin that we used earlier, and configured the Jetty server programatically in our integration test. In addition, we've added and configured an instance of the pluto &lt;span style="font-style:italic;"&gt;PortletServlet&lt;/span&gt; so we don't have to modify our &lt;span style="font-style:italic;"&gt;web.xml&lt;/span&gt; file (which normally would be something our build takes care of). We also added a &lt;span style="font-style:italic;"&gt;tearDown()&lt;/span&gt; method to gracefully shut down the server.&lt;br /&gt;&lt;br /&gt;Now it's time to write an actual test. We'll start very, very simple, by just testing if the portlet displays a simple message when it is displayed normally in the view mode:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void testIndexPageDisplaysMessage() throws Exception {&lt;br /&gt;    // Start at the pluto driver entry point&lt;br /&gt;    beginAt("/pluto/index.jsp");&lt;br /&gt;    assertTextPresent("Hello World from MyPortlet!");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running the test, it will of course fail since we have not implemented anything in the portlet yet. So let's create an &lt;span style="font-style:italic;"&gt;index.jsp&lt;/span&gt; file in the &lt;span style="font-style:italic;"&gt;/WEB-INF&lt;/span&gt; folder of the portlet:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%&gt;&lt;br /&gt;&lt;br /&gt;Hello World from MyPortlet!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the &lt;span style="font-style:italic;"&gt;doView()&lt;/span&gt; method of the portlet, we'll just dispatch to this jsp:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void doView( RenderRequest request, RenderResponse response ) throws IOException, PortletException {&lt;br /&gt;    getPortletContext().getRequestDispatcher("/WEB-INF/index.jsp").include(request, response);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, run the test again. This time, it should show a green bar! That was quick and simple! Let's try to complicate the case a little bit by adding and working with a form. The form should be a form with two text fields, one named &lt;span style="font-style:italic;"&gt;firstName&lt;/span&gt; and a second named &lt;span style="font-style:italic;"&gt;lastName&lt;/span&gt;. When submitting the form, the user should be displayed a personalized "Hello World" message:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void testPersonalizedHelloWorldMessage() throws Exception {&lt;br /&gt;    // Start at the pluto driver entry point&lt;br /&gt;    beginAt("/pluto/index.jsp");&lt;br /&gt;    // Expect a form with name "helloWorldForm" present on the page&lt;br /&gt;    assertFormPresent("helloWorldForm");&lt;br /&gt;    // This form should have two text fields. We'll populate these with data&lt;br /&gt;    setWorkingForm("helloWorldForm");&lt;br /&gt;    setTextField("firstName", "Donald");&lt;br /&gt;    setTextField("lastName", "Duck");&lt;br /&gt;    submit();&lt;br /&gt;    assertTextPresent("Quack quack, Donald Duck!");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We populate the form with some data, submit it, and verify the result. Running the test now, you'll see it fails, as expected. So let's implement the expected functionality. Normally, I would use a MVC framework with portlet support, such as &lt;a href="http://struts.apache.org/2.x"&gt;Struts 2&lt;/a&gt; or &lt;a href="http://www.springframework.org"&gt;Spring MVC&lt;/a&gt;, but since I'm only using the core APIs in this example, we'll have to use the portlet as a very basic controller. The portlet will handle the form submits and the logic for including the correct jsp. Let's start by adding the form to the &lt;span style="font-style:italic;"&gt;index.jsp&lt;/span&gt; page:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%&gt;&lt;br /&gt;&lt;br /&gt;Hello World from MyPortlet!&lt;br /&gt;&lt;br /&gt;&amp;lt;form name="helloWorldForm" action="&amp;lt;portlet:actionURL/&gt;" method="POST"&gt;&lt;br /&gt;  &amp;lt;b&gt;First name&amp;lt;/b&gt;: &amp;lt;input type="text" name="firstName"/&gt;&amp;lt;br/&gt;&lt;br /&gt;  &amp;lt;b&gt;Last name&amp;lt;/b&gt;: &amp;lt;input type="text" name="lastName"/&gt;&amp;lt;br/&gt;&lt;br /&gt;  &amp;lt;input type="submit"/&gt;&lt;br /&gt;&amp;lt;/form&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we'll implement the &lt;span style="font-style:italic;"&gt;processAction()&lt;/span&gt; method and process the incoming form submit:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException, IOException {&lt;br /&gt;    String firstName = actionRequest.getParameter("firstName");&lt;br /&gt;    String lastName = actionRequest.getParameter("lastName");&lt;br /&gt;    actionResponse.setRenderParameter("firstName", firstName);&lt;br /&gt;    actionResponse.setRenderParameter("lastName", lastName);&lt;br /&gt;    actionResponse.setRenderParameter("action", "viewResult");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we'll add some "routing logic" to the &lt;span style="font-style:italic;"&gt;doView()&lt;/span&gt; method so it will dispatch us to the correct view:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void doView( RenderRequest request, RenderResponse response ) throws IOException, PortletException {&lt;br /&gt;    String action = request.getParameter("action");&lt;br /&gt;    if("viewResult".equals(action)) {&lt;br /&gt;        getPortletContext().getRequestDispatcher("/WEB-INF/hello.jsp").include(request, response);&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;        getPortletContext().getRequestDispatcher("/WEB-INF/index.jsp").include(request, response);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And finally, the &lt;span style="font-style:italic;"&gt;/WEB-INF/hello.jsp&lt;/span&gt; file that generates the output:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%&gt;&lt;br /&gt;&amp;lt;portlet:defineObjects/&gt;&lt;br /&gt;&lt;br /&gt;Quack quack, &amp;lt;%=renderRequest.getParameter("firstName") %&gt; &amp;lt;%=renderRequest.getParameter("lastName") %&gt;!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Run the test again, and it should become green! &lt;br /&gt;&lt;br /&gt;Next, let's assume that the portlet should do something useful in the edit portlet mode. But how can we simulate a click on the edit button? After some looking though the source of the generated pluto html, I found the XPath expressions that identifies each of the portlet mode and window state buttons. With this information, let's write a test that switches the portlet to edit mode, and assert that we get to the correct page:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void testSwitchToEditMode() throws Exception {&lt;br /&gt;    beginAt("/pluto/index.jsp");&lt;br /&gt;    switchEdit();&lt;br /&gt;    assertTextPresent("This is MyPortlet in edit mode!");&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;private void switchEdit() {&lt;br /&gt;    clickElementByXPath("//span[@class='edit']/..");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;switchEdit()&lt;/span&gt; method simulates a click on the edit mode control of the portlet, using the correct XPath expression.&lt;br /&gt;&lt;br /&gt;Try to run the test, and it will turn red with a message stating that "Unable to locate element with XPath...". This is because pluto does not display the edit link for the portlet. Looking in the &lt;span style="font-style:italic;"&gt;portlet.xml&lt;/span&gt; for the portlet, you can see that currently the only supported portlet mode is &lt;span style="font-style:italic;"&gt;VIEW&lt;/span&gt;. So let's add &lt;span style="font-style:italic;"&gt;EDIT&lt;/span&gt; to the supported modes as well:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;supports&gt;&lt;br /&gt;  &amp;lt;mime-type&gt;text/html&amp;lt;/mime-type&gt;&lt;br /&gt;  &amp;lt;portlet-mode&gt;VIEW&amp;lt;/portlet-mode&gt;&lt;br /&gt;  &amp;lt;portlet-mode&gt;EDIT&amp;lt;/portlet-mode&gt;&lt;br /&gt;&amp;lt;/supports&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Running the test again, it will fail, but now with a different error message, stating  that the "Expected text was not found". So it's time to implement the &lt;span style="font-style:italic;"&gt;doEdit()&lt;/span&gt; method and the corresponding JSP. Create an &lt;span style="font-style:italic;"&gt;edit.jsp&lt;/span&gt; file in the &lt;span style="font-style:italic;"&gt;/WEB-INF&lt;/span&gt; folder, which just contains&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;This is MyPortlet in edit mode!&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the portlet, the &lt;span style="font-style:italic;"&gt;doEdit()&lt;/span&gt; method should look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public void doEdit(RenderRequest request, RenderResponse response) throws IOException, PortletException {&lt;br /&gt;    getPortletContext().getRequestDispatcher("/WEB-INF/edit.jsp").include(request, response);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This time when you run the test, it should turn green.&lt;br /&gt;&lt;br /&gt;As you can see, writing integration tests for a portlet is pretty simple, using the right tools. But why this approach, instead of just running JWebUnit (or Selenium or &amp;lt;insert your favourite web testing framework here&gt;) against a running portal server with the portlet installed? First of all, using this "in process" approach is quicker! It doesn't require you to start a big, heavy portal server, and no login is required. Asserting and verifying content is easier since the only portlet generating content is the one you're testing. And since it's in process, it's really simple to debug. Just run the JUnit test in debug mode, and you can debug the portlet as it responds to the request of the web testing framework.&lt;br /&gt;&lt;br /&gt;As a final note, I have uploaded an abstract WebTestCase that you can &lt;a href="http://static.nilshelgeogmaria.com/struts2/BasePortletTest.java"&gt;download&lt;/a&gt; and use as a base for your integration tests. It has everything set up for starting Jetty with the pluto portal driver, and with helper methods for switching portlet modes and window states.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-8191583110082978464?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/8191583110082978464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=8191583110082978464' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/8191583110082978464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/8191583110082978464'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2007/08/testing-portlets-with-jetty-pluto-and.html' title='Testing Portlets with Jetty, Pluto and JWebUnit'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-4747638242032005420</id><published>2007-08-05T10:49:00.000+02:00</published><updated>2007-10-22T07:17:01.108+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><title type='text'>maven-jetty-plugin and JSR168 portlets - Part 2</title><content type='html'>My &lt;a href="http://portletwork.blogspot.com/2007/07/mvnjetty-and-portlets.html"&gt;last post&lt;/a&gt; outlined how I made the &lt;a href="http://www.mortbay.org/maven-plugin/index.html"&gt;maven-jetty-plugin&lt;/a&gt; work with a maven 2 portlet project. As I mentioned, there were some issues with the approach if you're using Spring in your application. Also, there were some files you needed to include in your project. That's not too big of a problem solving using &lt;a href="http://maven.apache.org/pom.html#Resources"&gt;excludes&lt;/a&gt; in your pom so the files are not included in your build, but it's still a bit annoying having them around. And finally, there were no portlet controls, so changing modes and window states were impossible unless you manually created links in your portlet. So the solution had to improve...&lt;br /&gt;&lt;br /&gt;The first obstacle to overtake was how to enable the controls for switching modes and window states. I thought this was going to be easy, but trial and (mostly) error should prove me wrong. It became clear to me that the approach of adding the pluto dependencies to the plugin instead of the application caused problems with loading a resource bundle that the pluto taglib required. I solved this temporarily by adding the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal/src/main/resources/ToolTips.properties"&gt;ToolTips.properties&lt;/a&gt; file to the pluto-portal-driver-1.1.4.jar file. Good enough for now. This brought me one step further: The &lt;span style="font-style:italic;"&gt;pluto:modeAnchor &lt;/span&gt; and &lt;span style="font-style:italic;"&gt;pluto:windowStateAnchor&lt;/span&gt; tags now rendered correctly, but they required some stylesheets and javascript files that comes with the pluto web application to actually show the controls. This forced me to add a bunch of new files to my application, and it was really starting to pollute my project. &lt;br /&gt;&lt;br /&gt;The next task was Spring support. Having Spring on the application- and plugin classpath will cause classloader problems (you'll get ClassCastExceptions since the Spring classes are loaded from two different classloaders). Another problem is that both your application and pluto requires the &lt;a href="http://www.springframework.org/docs/reference/webintegration.html#webintegration-common"&gt;ContextLoaderListener&lt;/a&gt; and the &lt;span style="font-style:italic;"&gt;contextConfigLocation&lt;/span&gt; context parameter to be set. Basically, to make this work with just maven-jetty-plugin configuration options would require me to split the configuration options into three separate files; a &lt;a href="http://docs.codehaus.org/display/JETTY/webdefault.xml"&gt;webdefaults descriptor&lt;/a&gt;, web.xml and an &lt;a href="http://docs.codehaus.org/display/JETTY/override+web.xml"&gt;override descriptor&lt;/a&gt;. This is really starting to look bad...&lt;br /&gt;&lt;br /&gt;Coming this far, I realized that the current solution wasn't going to be a very good. It would work, but it wasn't good enough. First of all, the classloading issues with the resource bundle and Spring classes convinced me that it was better adding the dependendices to the application instead of the plugin. I also needed to find a solution to the problem with the &lt;span style="font-style:italic;"&gt;ContextLoaderListener&lt;/span&gt;. And last, I needed to get rid of all the stylesheets, images, javascripts, jsp files and configuration files from the application, into one single artifact that could be included as a dependency to the application. This means that I would have to serve all the required resources from one jar file. &lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;ContextLoaderListener&lt;/span&gt; problem was solved using a custom, jetty specific, context listener that use the internal jetty &lt;a href="http://www.mortbay.org/xref/org/mortbay/jetty/handler/ContextHandler.html"&gt;context classes&lt;/a&gt; to modify the context parameters and ensuring that only one context loader listener instance exists. I then added this listener to the &lt;span style="font-style:italic;"&gt;webdefaults&lt;/span&gt; file, ensuring it is the very first listener that is executed. Quite brutal, but it works...&lt;br /&gt;&lt;br /&gt;Identifying and collecting all the required stylesheets, JSP files, images etc into one jar file was easy. The hard part was how to make them available to the pluto driver, when they always were meant to be a part of the running web application... So all lookups/URLs to files like &lt;span style="font-style:italic;"&gt;/pluto.css&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;/images/controls/edit.png&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;/WEB-INF/pluto-portal-driver-config.xml&lt;/span&gt;, and not to forget, the jsp that acts as the entry point to the portlet container (I've named it &lt;span style="font-style:italic;"&gt;/pluto/index.jsp&lt;/span&gt;), would have to be served from this jar. Taking inspiration from the &lt;a href="https://svn.apache.org/repos/asf/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java"&gt;Struts 2 FilterDispatcher&lt;/a&gt;, serving static resources referenced from URLs to the web application was easy using a servlet filter. But how was I going to "intercept" the lookups to the resources in &lt;span style="font-style:italic;"&gt;/WEB-INF&lt;/span&gt;? And how can one serve a JSP file from within a JAR file? Looking through the source of the &lt;a href="https://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/RenderConfigServiceImpl.java"&gt;RenderConfigServiceImpl&lt;/a&gt; (which loads the &lt;span style="font-style:italic;"&gt;/WEB-INF/pluto-portal-driver-config.xml&lt;/span&gt; file) and the Jasper &lt;a href="http://svn.apache.org/repos/asf/tomcat/jasper/tc6.0.x/src/share/org/apache/jasper/servlet/JspServlet.java"&gt;JspServlet&lt;/a&gt;, it appears that they both look up resources using &lt;a href="http://www.mortbay.org/apidocs/javax/servlet/ServletContext.html#getResource(java.lang.String)"&gt;ServletContext.getResource&lt;/a&gt; and &lt;a href="http://www.mortbay.org/apidocs/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String)"&gt;ServletContext.getResourceAsStream&lt;/a&gt;. If I could intercept these calls and look up the resources from the classpath instead, the problem should be solved. So I wrote a wrapper servlet for the &lt;span style="font-style:italic;"&gt;JspServlet&lt;/span&gt;, and a wrapper context listener for the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalStartupListener.java"&gt;PortalStartupListener&lt;/a&gt; (which in turn initializes the RenderConfigServiceImpl) that just delegates to the wrapped objects, passing them a wrapped instance of &lt;span style="font-style:italic;"&gt;ServletContext&lt;/span&gt; that looks up the resources it does not find in /WEB-INF with the &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)"&gt;ClassLoader.getResource&lt;/a&gt; and &lt;a href="http://www.mortbay.org/apidocs/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String)"&gt;ClassLoader.getResourceAsStream&lt;/a&gt; methods instead. Problem solved! &lt;br /&gt;&lt;br /&gt;This left me with two resources; the &lt;a href="https://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal/src/main/webapp/WEB-INF/tld/pluto.tld"&gt;pluto.tld&lt;/a&gt; file and the customized &lt;span style="font-style:italic;"&gt;webdefaults descriptor&lt;/span&gt;. For the &lt;span style="font-style:italic;"&gt;pluto.tld&lt;/span&gt; file, I just placed it in the &lt;span style="font-style:italic;"&gt;META-INF&lt;/span&gt; folder of the jar file, and renamed it to &lt;span style="font-style:italic;"&gt;taglib.tld&lt;/span&gt;. This is discovered by the servlet container automatically when it is referenced through the correct uri in the jsp files using it. One file left; the &lt;span style="font-style:italic;"&gt;webdefaults descriptor&lt;/span&gt;. After a lot of trial and error (again...) (I even tried extending the maven-jetty-plugin to add a new configuration option, but this proved fruitless as I discovered that &lt;a href="http://jira.codehaus.org/browse/MNG-3042"&gt;it is not possible to extend a maven 2 plugin&lt;/a&gt;...), I could not find a solution. So it remains unsolved until the maven-jetty-plugin is modified to look up a webdefaults descriptor by some other means than just a file path (I'll probably create a JIRA issue for this. &lt;span style="font-style:italic;"&gt;Update: &lt;a href="http://jira.codehaus.org/browse/JETTY-414"&gt;JIRA issue created&lt;/a&gt;&lt;/span&gt;). But still, I'm now left with only one jar file added to the dependency of the application, and one webdefaults file that I add to the application itself (and is easily excluded in the pom). I've also added the dependency to a profile, so it's only active when I specify this profile on the command line. It looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Update: The maven-jetty-pluto-embedded artifact is available in the Maven 2 repositories.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;profiles&gt;&lt;br /&gt;  &amp;lt;profile&gt;&lt;br /&gt;    &amp;lt;id&gt;pluto-embedded&amp;lt;/id&gt;&lt;br /&gt;    &amp;lt;build&gt;&lt;br /&gt;      &amp;lt;plugins&gt;&lt;br /&gt;        &amp;lt;plugin&gt;&lt;br /&gt;          &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;&lt;br /&gt;          &amp;lt;artifactId&gt;maven-jetty-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;          &amp;lt;configuration&gt;&lt;br /&gt;     &amp;lt;webXml&gt;${project.build.directory}/pluto-resources/web.xml&amp;lt;/webXml&gt;&lt;br /&gt;            &amp;lt;webDefaultXml&gt;src/main/webapp/WEB-INF/jetty-pluto-web-default.xml&amp;lt;/webDefaultXml&gt;&lt;br /&gt;     &amp;lt;systemProperties&gt;&lt;br /&gt;       &amp;lt;systemProperty&gt;&lt;br /&gt;         &amp;lt;name&gt;org.apache.pluto.embedded.portletId&amp;lt;/name&gt;&lt;br /&gt;         &amp;lt;value&gt;MyPortletAsDefinedInPortletXml&amp;lt;/value&gt;&lt;br /&gt;       &amp;lt;/systemProperty&gt;&lt;br /&gt;            &amp;lt;/systemProperties&gt;&lt;br /&gt;          &amp;lt;/configuration&gt;&lt;br /&gt;        &amp;lt;/plugin&gt;&lt;br /&gt;      &amp;lt;/plugins&gt;&lt;br /&gt;    &amp;lt;/build&gt;&lt;br /&gt;    &amp;lt;dependencies&gt;&lt;br /&gt;      &amp;lt;dependency&gt;&lt;br /&gt;        &amp;lt;groupId&gt;com.bekk.boss&amp;lt;/groupId&gt;&lt;br /&gt;        &amp;lt;artifactId&gt;maven-jetty-pluto-embedded&amp;lt;/artifactId&gt;&lt;br /&gt;        &amp;lt;version&gt;1.0&amp;lt;/version&gt;&lt;br /&gt;      &amp;lt;/dependency&gt; &lt;br /&gt;    &amp;lt;/dependencies&gt;&lt;br /&gt;  &amp;lt;/profile&gt;&lt;br /&gt;&amp;lt;/profiles&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of course, you need the &lt;span style="font-style:italic;"&gt;maven-pluto-plugin&lt;/span&gt; as well, as described in the previous post. Also, note the system property configuration specifying the id of the portlet to run.&lt;br /&gt;&lt;br /&gt;I run this setup using the command &lt;span style="font-style:italic;"&gt;mvn jetty:run -P pluto-embedded&lt;/span&gt;. Now I'm a lot more happy with the solution. Below is a screenshot how this looks running with the Struts 2 sample portlet application (click the image to enlarge):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://static.nilshelgeogmaria.com/struts2/pluto.jpg"&gt;&lt;img src="http://static.nilshelgeogmaria.com/struts2/pluto.jpg" alt="maven jetty plugin running embedded with Pluto" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can download the &lt;a href="http://static.nilshelgeogmaria.com/struts2/jetty-pluto-web-default.xml"&gt;jetty-pluto-web-default.xml&lt;/a&gt; file and try it yourself. Just put the xml file in your &lt;span style="font-style:italic;"&gt;/WEB-INF&lt;/span&gt; folder. All feedback is appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-4747638242032005420?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/4747638242032005420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=4747638242032005420' title='34 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4747638242032005420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4747638242032005420'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html' title='maven-jetty-plugin and JSR168 portlets - Part 2'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-4864506186007652182</id><published>2007-07-31T12:17:00.000+02:00</published><updated>2007-08-24T12:14:09.420+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSR168'/><category scheme='http://www.blogger.com/atom/ns#' term='maven 2'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='portlet'/><category scheme='http://www.blogger.com/atom/ns#' term='pluto'/><title type='text'>maven-jetty-plugin and JSR168 portlets</title><content type='html'>Inspired by Don Brown's &lt;a href="http://struts.apache.org/2.x/docs/developing-a-portlet-using-eclipse.html"&gt;Developing a Portlet using Eclipse&lt;/a&gt; tutorial for Struts 2 and some information I found on the &lt;a href="http://portals.apache.org/pluto/faq.html"&gt;Pluto FAQ&lt;/a&gt;, I started playing around with embedding pluto in a Maven 2 project. The goal was to be able to use the maven-jetty-plugin to run and test my portlets with Jetty just by typing &lt;span style="font-style: italic;"&gt;mvn jetty:run&lt;/span&gt;. That would definitively be a step up to increase developer productivity!&lt;br /&gt;&lt;br /&gt;After googling a lot and collecting information from &lt;a href="http://wiki.oss-watch.ac.uk/PlutoNotes"&gt;various&lt;/a&gt; &lt;a href="http://svn.apache.org/viewvc/portals/pluto/tags/pluto-1.1.4/"&gt;sources&lt;/a&gt;, I managed to get things up and running! Here's the steps needed to get the maven-jetty-plugin to work with your Maven 2 portlet project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;The formula&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First of all, this only works with Pluto 1.1.4, which is not currently released, but probably will be &lt;a href="http://www.nabble.com/Pluto-1.1.4-t4112330.html"&gt;soon&lt;/a&gt;. The reason is that Pluto 1.1.3 &lt;a href="http://issues.apache.org/jira/browse/PLUTO-375"&gt;does not work with JSP 2.1&lt;/a&gt;. So the first thing to do is to get the Pluto sources from SVN from the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/"&gt;pluto-1.1.4 tag&lt;/a&gt; and build it according to the &lt;a href="http://portals.apache.org/pluto/v11/getting-started.html"&gt;istructions&lt;/a&gt;. This will install the pluto 1.1.4 artifacts in your local maven repository. Alternatively, I guess you could just add the apache maven &lt;a href="http://people.apache.org/builds/portals-pluto/m2-staging-repository/"&gt;staging repository&lt;/a&gt; to your &lt;span style="font-style:italic;"&gt;pom.xml&lt;/span&gt; (which does sound a bit easier when I think of it...)&lt;br /&gt;&lt;br /&gt;The next step is to add the &lt;span style="font-style: italic;"&gt;maven-pluto-plugin&lt;/span&gt; to your &lt;span style="font-style: italic;"&gt;pom.xml&lt;/span&gt;. This is needed to add the &lt;span style="font-style: italic;"&gt;web.xml&lt;/span&gt; entries for the wrapper servlets for the portlet.&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;plugin&gt;&lt;br /&gt; &amp;lt;groupId&gt;org.apache.pluto&amp;lt;/groupId&gt;&lt;br /&gt; &amp;lt;artifactId&gt;maven-pluto-plugin&amp;lt;/artifactId&gt;&lt;br /&gt; &amp;lt;version&gt;1.1.3&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;executions&gt;&lt;br /&gt;   &amp;lt;execution&gt;&lt;br /&gt;     &amp;lt;phase&gt;generate-resources&amp;lt;/phase&gt;&lt;br /&gt;     &amp;lt;goals&gt;&lt;br /&gt;       &amp;lt;goal&gt;assemble&amp;lt;/goal&gt;&lt;br /&gt;     &amp;lt;/goals&gt;&lt;br /&gt;   &amp;lt;/execution&gt;&lt;br /&gt; &amp;lt;/executions&gt;&lt;br /&gt;&amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And of course, we need the jetty plugin as well:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;plugin&gt;&lt;br /&gt; &amp;lt;groupId&gt;org.mortbay.jetty&amp;lt;/groupId&gt;&lt;br /&gt; &amp;lt;artifactId&gt;maven-jetty-plugin&amp;lt;/artifactId&gt;&lt;br /&gt;&amp;lt;/plugin&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, we need to add the dependencies needed by the pluto portlet container. I chose to add these to the plugin classpath, but you could also add them to the project dependencies instead. So within the scope of the plugin tag for the jetty plugin, add a section of dependencies:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;dependencies&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.apache.pluto&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;pluto-portal-driver&amp;lt;/artifactId&gt;&lt;br /&gt;   &amp;lt;version&gt;1.1.4&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;/dependency&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.apache.pluto&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;pluto-portal-driver-impl&amp;lt;/artifactId&gt;&lt;br /&gt;   &amp;lt;version&gt;1.1.4&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.apache.pluto&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;pluto-container&amp;lt;/artifactId&gt;&lt;br /&gt;   &amp;lt;version&gt;1.1.4&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;/dependency&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.apache.pluto&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;pluto-taglib&amp;lt;/artifactId&gt;&lt;br /&gt;   &amp;lt;version&gt;1.1.4&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;/dependency&gt;&lt;br /&gt; &amp;lt;dependency&gt;&lt;br /&gt;   &amp;lt;groupId&gt;org.springframework&amp;lt;/groupId&gt;&lt;br /&gt;   &amp;lt;artifactId&gt;spring-web&amp;lt;/artifactId&gt;&lt;br /&gt;   &lt;&amp;lt;version&gt;2.0.2&amp;lt;/version&gt;&lt;br /&gt; &amp;lt;/dependency&gt;&lt;br /&gt;&amp;lt;/dependencies&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;(That's right, there's a Spring dependency in there, which can cause some troubles if you're using Spring already, but let's skip that for now...)&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;maven-pluto-plugin&lt;/span&gt; generates a &lt;span style="font-style: italic;"&gt;web.xml&lt;/span&gt; file and puts it in the &lt;span style="font-style: italic;"&gt;${project.build.directory}/pluto-resources/&lt;/span&gt; folder.  So we need to customize the configuration of the plugin a bit. So add this to the &lt;span style="font-style: italic;"&gt;maven-jetty-plugin&lt;/span&gt; definition in the &lt;span style="font-style: italic;"&gt;pom.xml&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;configuration&gt;&lt;br /&gt; &amp;lt;webXml&gt;${project.build.directory}/pluto-resources/web.xml&amp;lt;/webXml&gt;&lt;br /&gt;&amp;lt;/configuration&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Still, that's unfortunately not entirely enough for the jetty plugin. We also need to add a context-parameter, filter, filter-mapping(s) and some servlet context listeners to the &lt;span style="font-style: italic;"&gt;web.xml&lt;/span&gt;. Now, I don't want to pollute my original &lt;span style="font-style: italic;"&gt;web.xml&lt;/span&gt; with this stuff, so I considered a couple of options. Either, I could add an &lt;a href="http://docs.codehaus.org/display/JETTY/override+web.xml"&gt;overrideweb.xml file&lt;/a&gt;, which is added to the web application configuration after the &lt;span style="font-style: italic;"&gt;jetty:run&lt;/span&gt; goal is invoked, or I could create a new &lt;a href="http://docs.codehaus.org/pages/viewpage.action?pageId=45902"&gt;webdefault xml file&lt;/a&gt;, which is applied before. After trying both options, I decided to go for the second solution (I'm not going into that now, but it's the only way I could get it to work with Spring in a way I was happy with). Therefore, I extracted the &lt;span style="font-style: italic;"&gt;webdefault.xml&lt;/span&gt; file from the jetty jar file, and added the required cofigurations:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;!-- Spring configuration file for the portlet container services --&gt;&lt;br /&gt;&amp;lt;context-param&gt;&lt;br /&gt; &amp;lt;param-name&gt;contextConfigLocation&amp;lt;/param-name&gt;&lt;br /&gt; &amp;lt;param-value&gt;/WEB-INF/pluto-portal-driver-services-config.xml&amp;lt;/param-value&gt;&lt;br /&gt;&amp;lt;/context-param&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- The Spring context loader listener and the startup listener for the dummy portal --&gt;&lt;br /&gt;&amp;lt;listener&gt;&lt;br /&gt; &amp;lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&gt;&lt;br /&gt;&amp;lt;/listener&gt;&lt;br /&gt;&amp;lt;listener&gt;&lt;br /&gt; &amp;lt;listener-class&gt;org.apache.pluto.driver.PortalStartupListener&amp;lt;/listener-class&gt;&lt;br /&gt;&amp;lt;/listener&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- The pluto driver that will intercept our JSP "portal" --&gt;&lt;br /&gt;&amp;lt;filter&gt;&lt;br /&gt; &amp;lt;filter-name&gt;plutoPortalDriver&amp;lt;/filter-name&gt;&lt;br /&gt; &amp;lt;filter-class&gt;org.apache.pluto.driver.PortalDriverFilter&amp;lt;/filter-class&gt;&lt;br /&gt;&amp;lt;/filter&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- The filter will intercept our /test-portal/index.jsp file and everything beneath it --&gt;&lt;br /&gt;&amp;lt;filter-mapping&gt;&lt;br /&gt; &amp;lt;filter-name&gt;plutoPortalDriver&amp;lt;/filter-name&gt;&lt;br /&gt; &amp;lt;url-pattern&gt;/test-portal/index.jsp&amp;lt;/url-pattern&gt;&lt;br /&gt;&amp;lt;/filter-mapping&gt;&lt;br /&gt;&amp;lt;filter-mapping&gt;&lt;br /&gt; &amp;lt;filter-name&gt;plutoPortalDriver&amp;lt;/filter-name&gt;&lt;br /&gt; &amp;lt;url-pattern&gt;/test-portal/index.jsp/*&amp;lt;/url-pattern&gt;&lt;br /&gt;&amp;lt;/filter-mapping&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!-- The container taglibs that invoke our portlet in the portlet container --&gt;&lt;br /&gt;&amp;lt;jsp-config&gt;&lt;br /&gt;  &amp;lt;taglib&gt;&lt;br /&gt;    &amp;lt;taglib-uri&gt;http://portals.apache.org/pluto&amp;lt;/taglib-uri&gt;&lt;br /&gt;    &amp;lt;taglib-location&gt;/WEB-INF/tld/pluto.tld&amp;lt;/taglib-location&gt;&lt;br /&gt;  &amp;lt;/taglib&gt;&lt;br /&gt;&amp;lt;/jsp-config&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For now, I just put this new webdefault xml file (I named it &lt;span style="font-style: italic;"&gt;jetty-pluto-web-default.xml&lt;/span&gt;) in the &lt;span style="font-style: italic;"&gt;/WEB-INF&lt;/span&gt; folder of the application, and added a new configuration option for the jetty plugin:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;&amp;lt;configuration&gt;&lt;br /&gt; &amp;lt;webDefaultXml&gt;src/main/webapp/WEB-INF/jetty-pluto-web-default.xml&amp;lt;/webDefaultXml&gt;&lt;br /&gt; &amp;lt;webXml&gt;target/pluto-resources/web.xml&amp;lt;/webXml&gt;&lt;br /&gt;&amp;lt;/configuration&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Almost done now! We need three files from pluto. These are configuration- and taglib files that initialize the portlet container, and instead of listing them here, just download the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal/src/main/resources/pluto-portal-driver-config.xml"&gt;pluto-portal-driver-config.xml&lt;/a&gt;  and the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal/src/main/webapp/WEB-INF/pluto-portal-driver-services-config.xml"&gt;pluto-portal-driver-services-config.xml&lt;/a&gt; and put them in the &lt;span style="font-style: italic;"&gt;WEB-INF&lt;/span&gt; folder of your application. Then create a &lt;span style="font-style: italic;"&gt;tld&lt;/span&gt; folder in the same folder, and download the &lt;a href="http://svn.apache.org/repos/asf/portals/pluto/tags/pluto-1.1.4/pluto-portal/src/main/webapp/WEB-INF/tld/pluto.tld"&gt;pluto.tld&lt;/a&gt; file to this folder.&lt;br /&gt;&lt;br /&gt;The last steps is to create a "dummy portal" entry point. I created a folder named &lt;span style="font-style: italic;"&gt;test-portal&lt;/span&gt; in the &lt;span style="font-style: italic;"&gt;src/main/webapp&lt;/span&gt; folder, and created an &lt;span style="font-style: italic;"&gt;index.jsp&lt;/span&gt; file that acts as the entry point to the portlet container. The &lt;span style="font-style: italic;"&gt;index.jsp&lt;/span&gt; file looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %&gt;&lt;br /&gt;&amp;lt;pluto:portlet portletId="/struts2-portlet.StrutsPortlet"&gt;&lt;br /&gt; &amp;lt;div class="portlet" id="struts2-portlet.StrutsPortlet"&gt;&lt;br /&gt;   &amp;lt;div class="header"&gt;&lt;br /&gt;     &amp;lt;h2 class="title"&gt;&amp;lt;pluto:title&gt;&amp;lt;/pluto:title&gt;&amp;lt;/h2&gt;&lt;br /&gt;  &amp;lt;/div&gt;&lt;br /&gt;   &amp;lt;div class="body"&gt;&lt;br /&gt;     &amp;lt;pluto:render&gt;&amp;lt;/pluto:render&gt;&lt;br /&gt;  &amp;lt;/div&gt;&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&amp;lt;/pluto:portlet&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;portletId&lt;/span&gt; in the &lt;span style="font-style: italic;"&gt;&amp;lt;pluto:portlet&gt;&lt;/span&gt; tag is composed of the &lt;span style="font-style:italic;"&gt;context root&lt;/span&gt; of the web application, and the &lt;span style="font-style:italic;"&gt;name of the portlet&lt;/span&gt; as defined in the &lt;span style="font-style: italic;"&gt;portlet.xml&lt;/span&gt; file.&lt;br /&gt;&lt;br /&gt;Now, everything should be set up, and you should be able to view your portlet by pointing your browser to &lt;span style="font-style:italic;"&gt;http://localhost:8080/&amp;lt;context-root&gt;/test-portal/index.jsp&lt;/span&gt; (note that you need to point to the &lt;span style="font-style: italic;"&gt;index.jsp&lt;/span&gt; file, it will not work just pointing it to &lt;span style="font-style: italic;"&gt;/test-portal/&lt;/span&gt; due to the filter mappings).&lt;br /&gt;&lt;br /&gt;If you don't want to do all these steps manually, I have created an archived &lt;a href="http://static.nilshelgeogmaria.com/struts2/myportlet.zip"&gt;maven project&lt;/a&gt; based on the &lt;span style="font-style:italic;"&gt;struts2-archetype-portlet&lt;/span&gt;, as described in &lt;a href="http://struts.apache.org/2.x/docs/developing-a-portlet-using-eclipse.html"&gt;Don's tutorial&lt;/a&gt;, and added all the required files and settings.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This might seem like an awful lot of work to get the jetty plugin to work with portlets, but I believe it's worth the effort. I have never been more productive developing portlets than after I got this up and running. And when you have been through this once, just add it to your set of templates/archetypes so you won't have to do it again.&lt;br /&gt;&lt;br /&gt;And please, if you find any errors in this article, please drop me a comment so I can correct them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Update: See &lt;a href="http://portletwork.blogspot.com/2007/08/maven-jetty-plugin-and-jsr168-portlets.html"&gt;part 2&lt;/a&gt; to see how the solution has improved.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;span style="font-style:italic;"&gt;Update 2: Pluto 1.1.4 has been released and should be available from the regular maven repositories.&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-4864506186007652182?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/4864506186007652182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=4864506186007652182' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4864506186007652182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/4864506186007652182'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2007/07/mvnjetty-and-portlets.html' title='maven-jetty-plugin and JSR168 portlets'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-113264804061118792</id><published>2005-11-22T09:17:00.000+01:00</published><updated>2005-11-22T18:20:19.316+01:00</updated><title type='text'>PortletWork example application</title><content type='html'>I have made available a very basic example application for the PortletWork framework. It does not do much besides supporting different portlet modes, some form submitting, and example of Spring support, but it can nevertheless aid as a template for PortletWork application development. &lt;br /&gt;&lt;br /&gt;Yesterday, I tried to deploy the sample application to different portlet containers. Earlier, I have successfully deployed it to WebSphere Portal Server 5.x, JetSpeed2, Pluto and JBoss Portal. This time, Liferay and Gridsphere were the targets. &lt;br /&gt;&lt;br /&gt;Deployment to Liferay quite straight forward once I got the server up and running, and did not require any additional descriptors. Just invoke an ant task, and off you go. &lt;br /&gt;&lt;br /&gt;Gridsphere, however, was a bit more tedious. After a while, I found &lt;a href="http://www.drrockit.com/space/JSR+168+Portlet+Deployment+in+GridSphere"&gt;this&lt;/a&gt; resource describing the additional steps needed to get a JSR168 portlet up and running in Gridsphere. After adding the extra descriptors and library, everything was up and running.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-113264804061118792?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/113264804061118792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=113264804061118792' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/113264804061118792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/113264804061118792'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2005/11/portletwork-example-application.html' title='PortletWork example application'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18577364.post-113096065315091897</id><published>2005-11-03T05:46:00.000+01:00</published><updated>2005-11-03T15:31:56.560+01:00</updated><title type='text'>PortletWork 1.0-beta-1: JSR168/XWork/WebWork framework</title><content type='html'>I finally decided to publish PortletWork, which is a JSR168 portlet development framework I've been developing for about a year.&lt;br /&gt;&lt;br /&gt;PortletWork is a framework built on XWork/WebWork and JSR168. It is basically a dispatcher for XWork in a Portlet Container, in addition to some re-use of the WebWork JSP tag libraries and interceptors. Only minor changes in the xwork.xml configuration file, and one custom JSP taglib (due to the special handling of URLs in a portlet container) is required to start using PortletWork. It currently runs with XWork 1.0.5 and WebWork 2.1.7.&lt;br /&gt;&lt;br /&gt;The motivation for making PortletWork was not only to ease the migration of existing web applications to a portlet environment, but also to provide a solid framework for building "native" portlet applications, utilizing the core concepts of JSR168 such as modes, phases, preferences etc. It is possible, for instance, to map XWork package namespaces to portlet modes, and to have multiple portlets in a portlet application using different package namespaces. This makes it trivial to group actions into a logical structure of packages.&lt;br /&gt;&lt;br /&gt;Some of the remaining tasks before 1.0 final is documentation (surprise, surprise), and releasing a proper example application that can be used as a template for development.&lt;br /&gt;&lt;br /&gt;There is a maven generate site with some documentation at &lt;a href="http://boss.bekk.no/boss/portletwork"&gt;http://boss.bekk.no/boss/portletwork&lt;/a&gt;. The project itself is published on SourceForge at &lt;a href="http://www.sf.net/projects/portletwork"&gt;http://www.sf.net/projects/portletwork&lt;/a&gt;. &lt;a href="http://boss.bekk.no/boss/portletwork"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;All feedback is appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18577364-113096065315091897?l=portletwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://portletwork.blogspot.com/feeds/113096065315091897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18577364&amp;postID=113096065315091897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/113096065315091897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18577364/posts/default/113096065315091897'/><link rel='alternate' type='text/html' href='http://portletwork.blogspot.com/2005/11/portletwork-10-beta-1.html' title='PortletWork 1.0-beta-1: JSR168/XWork/WebWork framework'/><author><name>Nils-Helge Garli Hegvik</name><uri>http://www.blogger.com/profile/15756010546034756427</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
