Creating custom layouts in JBoss Portal

The layout of a portlet is handled by a set of JSP in the portal-core web-app which is part of the jboss-portal.sar. In the web-inf direcotry have a look at portal-layouts.xml to see how various layouts are configured. The following is a snippet (self explainatory):

<layouts>
<layout>
  <name>rbs-1column</name>
  <uri>/layouts/mylayout/index.jsp</uri>
  <uri state="maximized">/layouts/mylayout/maximized.jsp</uri>
  <regions>
    <region name="regionBody"/>
  </regions>
</layout>
</layouts>

You can make changes to these JSPs and the portal-layouts.xml. Alternatively (recommended), create you own theme in a separate web app (war file) and change the following config in jboss-portal.sar/META-INF/jboss-service.xml. You need to change the fillowing lines:

  • Change layout context path: <attribute name="TargetContextPath">/mylayoutapp</attribute>
  • Change path to header jsp: <attribute name="HeaderPath">/WEB-INF/jsp/myheader.jsp</attribute>
  • Change path to tabs (navigation) jsp: <attribute name="TabsPath">/WEB-INF/jsp/mynavigation.jsp</attribute>

The new war file will need to have access to the to portal lib tag-libs. These can be found at jboss-portal.sar/portal-core.war/WEB-INF.  Your layout JSP specified as “url” in the portal-layouts.xml will need to include the following directives:

  • In the html header: <p:theme themeName=”mytheme”/>, <p:headerContent/>.  See http://java.dzone.com/articles/jboss-portal for a guide on creating custom themes.
  • In the body: <p:region regionName=’regionBody’ regionID=’regionBody’ />. This will need to be added for all the regions defined in the portal-layout.xml for this particular layout.

Note: Theme and layouts can be specified in the portal page deployment descriptor (see property theme.id and layout.id)

Creating a Rewrite Rule in JBoss

JBoss comes shipped with a Valve that allows you to do Apache mod_rewrite style URL Rewrites.

  • Under <jboss>/server/conf, create directories called jboss.web/localhost
  • Under the newly created localhost direcotry create a file called rewrite.properties with rewrite rules. For example (RewriteRule   ^/apps/(.+)  http://newappshome/$1) redirects all urls starting with /app to another server. Have a look at Appache documentation of URL Rewriting for more.
  • Edit <jboss>/server/rbs/deploy/jboss-web.deployer/server.xml and add (<Valve className="org.jboss.web.rewrite.RewriteValve" />) under the <Host> (localhost) section.

Controlling JBoss Deployments Using MBeans

JBoss allows you to programmatically control deployments using the MBean interface. Note: the same can be done using the JMX Console and Twiddle.

Approach 1: Copy the app to deploy folder and temporarily turn on hot-deployment scanner. This is not recommended for production since the deploy folder may contain other changes you may not have wanted deployed.

The JNDI name for the Deployment Scanner MBean is jboss.deployment:type=DeploymentScanner,flavor=URL. You can then use the following code to get a reference to the scanner. Note: this code will only work inside the container (you can initialise the JDNI context a performa  lookup if you want the code to run outside the container):

URLDeploymentScannerMBean deploymentScanner = 
   (URLDeploymentScannerMBean) MBeanProxyExt.create(
      URLDeploymentScannerMBean.class, "jboss.deployment:type=DeploymentScanner,flavor=URL",
      MBeanServerLocator.locateJBoss());

You can then deploymentScanner.stop() and deploymentScanner.start(). To determine if the scanner is already started you can check for it’s scannerMBean.getState() to be ServiceMBean.STARTED or ServiceMBean.STARTING

Approach 2: You can use the main deployer to deploy the app specifing the URL to it’s location. To obtain a reference to the deployer in the container:

MainDeployerMBean mainDeployer = (MainDeployerMBean) MBeanProxyExt.create(
   MainDeployerMBean.class, "jboss.system:service=MainDeployer",
   MBeanServerLocator.locateJBoss());

You can then deploy the app:

String webappUrl = "file:///home/username/apps/myapp.war";
if (deployerMBean.isDeployed(webappUrl)) {
   deployerMBean.redeploy(webappUrl);
} else {
   deployerMBean.deploy(webappUrl);
}

JBoss Source Code

A good resource for JBoss related examples and source code is at http://anonsvn.jboss.org

To see exactly what 3rd party libraries a particular version of JBoss was developed with have a look at build-thirdparty.xml in the source code (e.g. http://anonsvn.jboss.org/repos/portal/tags/Enterprise_Portal_Platform_4_3_GA_CP03/build/build-thirdparty.xml)

WSRP the Ideal and the Actual

Web Services for Remote Portlets (WSRP) is a very useful spec. It defines standards to provide “presentation oriented web services” that can be used to aggregate web sites. It is a much richer way of providing site mashups. WSRP not only allows mashing up at the HTML level but also concerns itself with passing application state and security contexts between the aggregators and source websites (Portlet Consumers and Portet Producers respectively). Most Portal Platforms now days provide an implementation of WSRP which is now at version 2.0 .

I’ve recently tried to use this feature in JBoss Portal Server and Websphere Portal with mixed results. My main issue is that the URL handling (e.g. image and css urls) in the portlet HTML is not yet compliant to the spec. All relative URLs that are encountered in the HTML are re-written by the Portlet Consumer to point directly to the Portlet Producer. This implies that the Producers are available on the web making it very difficult to use producers that are shielded behind a firewall. If you don’t have this restriction or know of an implementation that handles resource URLs via the consumer then the technology is well worth the considerations.