Thursday, March 5, 2009

Deployment on WebSphere Portal 5.1 and extensible to 6

Summary

This post discusses a comprehensive description of portlet deployment on WebSphere Portal (WP) server. The focus is on automated WP 5.1 deployment of an EAR containing the portlet(s) to be deployed, using Ant scripts. Some background information is given as well.
Introduction and background
Portlets are normally packaged into single WAR files. Although these single WAR files can be deployed as such, it usually is favourable to package one or more WAR files, possibly together with library JAR files into on single EAR file, since as of WebSphere Portal (WP) 5.1 it is possible to deploy portlets in a single EAR. Note that in this case it is not possible to update a single portlet.

The structure of the EAR is roughly as follows (depending on your particular application):

* my-portlet-1.0.war, the WAR containing the portlet
* META-INF/Manifest.mf, manifest file generated by the IDE
* META-INF/ibm-application-bnd.xmi, currently unsure whether this file is necessary
* META-INF/application.xml, the deployment descriptor, which looks something similar like


"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN"
"http://java.sun.com/dtd/application_1_3.dtd">

my-application
My application


my-portlet-1.0.war
/wps/my-app



Portal Web Services Role
PortalWebServicesRole



To administer WebSphere Application Server (WAS) and portal server a couple of tools are available. Depending on what you are trying to achieve, you may have a choice of at least one and possibly more from the following list of administration tools:

* Using the web interface of WAS (by default running on port 9090) and the portal administration portlets offered by WP.
* Using the XML configuration interface (XMLAccess, program xmlaccess.sh).
* Using the wsadmin (program wsadmin.sh) tool that may use both Jacl and Jython scripts.
* A combination of the former two tools invoked via (an) Ant script(s). To this extent, IBM offers dedicated Ant tasks, see IBM infocenter.

In this post the focus will be on WP 5.1 deployment of an EAR containing the portlet(s) using Ant scripts.
Recipe
The following steps need to be executed when deploying an EAR on WP:

1. Deploy the EAR on WAS. The portlets are now pre-deployed. This EAR should now be administered from WP. For example, the executiion status (running, stopped, etc.) cannot be controlled from the WAS web interface (as a matter of fact, not via the WP administration portlets either, but via the wsadmin tool).
2. Register the pre-deployed EAR file in WP.
3. Modify the classloader policy from PARENT_FIRST to PARENT_LAST, if necessary. Please read the post "Changing Classloader Mode of modules inside an EAR in WebSphere Portal". This post explains how to change the classloader mode for your portlet(s) web modules, so they are the same as when deploying them as a WAR.
4. Start your application (using wsadmin tool).
5. Create pages to deploy your portlet(s) to.
6. Deploy portlet(s) to page(s).

Step 1
Installation of the EAR:



ear="${ear.file}"
conntype="NONE"
user="${PortalAdminId}"
password="${PortalAdminPwd}"
options="-installdir ${wps.home}/installedApps -server ${WpsServer} -usedefaultbindings" />


Of course, the Ant property values should properly be initialized. The variables was.home and wps.home point to the installation directories of WAS and WP, WpsServer typically equals WebSphere_Portal.
Step 2
Register the pre-deployed EAR in WP using XMLAccess:



user="${PortalAdminId}"
password="${PortalAdminPwd}"
url="http://${WpsHostName}:${WpsHostPort}/${WpsContextRoot}/config${VirtualPortalName}"
srcfile="portlet-install.xml" />



Again the necessary Ant variables should have been properly initialized. This command invokes the following XMLAccess script:


xsi:noNamespaceSchemaLocation="PortalConfig_1.3.xsd"
type="update"
create-oids="true">


uid="com.company.nl.ap.id.webmod"
active="true"
predeployed="true">
file:///opt/WebSphere/PortalServer/installedApps/myapp.ear/myapp.war
/wps/my-context-myapp
my-application
active="true"
uid="com.company.nl.ap.id">






The "uid" attribute in the element should correspond to the ID in the portlet.xml file.

Moreover:

* For the deploy_target_directory in the url tag specify the directory to which you deployed the EAR file on the WebSphere Application Server.
* The default target directory is AppServer, but when deploying portlet for your portal it is a good option to specify PortalServer as the target directory.
* This XML script works only for portlets that are written to comply with the Standard Portlet API (JSR 168).
* In this case consider the following hints:
o With the web-app tag Standard API portlets do not have a uid attribute. Use the id attribute of the portlet-app tag in the file portlet.xml instead. Append webmod to the end of the id attribute to make up the uid.
o With the portlet-app tag Standard API portlets do not have a uid attribute. Use the id attribute of the portlet-app tag in the file portlet.xml instead.
o With the portlet-app tag Standard API portlets do not have a name attribute. Remove the tag for Standard API portlets.

Step 3
Set the classloader policy. Consult the link mentioned in the Recipe section if needed.
Step 4
Start the application. This can be accomplished using a Jacl script and the wsadmin tool (described in this post), or using a dedicated Ant task::


server="${WpsServer}"
node="${WpsNodeName}"
host="${TargetServer}"
conntype="SOAP"
port="${SOAPConnectionPort}"
user="${PortalAdminId}"
password="${PortalAdminPwd}"
application="my-application" />


The SOAP connection port usually equals 8882.
Step 5 and 6
The scripts for these steps will be postponed to a forthcoming post. However, creating pages and deploying portlets to these pages can be done using the portal administration portlets and has to be carried out only once. Thereafter, even after uninstalling your EAR, you merely have to go through the above steps, and the portlets contained in the EAR will again be available.
References
Please consult the following links for additional information:

* Deploy J2EE resources with portlet application WAR files
* Sample XML configuration files
* Automated Deployment of Enterprise Application Updates



Comments:

Very useful tip/caveat: your JAVA_HOME environment variable must point to $WAS_HOME/java. Strange errors may show up if not set correctly!!!


Caveat: we experienced weird problems when trying to deploy on Unix/Linux. It turned out that some properties that are optional, break the deployment procedure that worked fine under Windows!

Summarizing, it turned out to be necessary to strip some attributes of the wsadmin and wsStartApp tasks of step 3 and 4 to become:


wasHome="${config.was.home}"
conntype="${config.ConnectionType}"
port="${config.SOAPConnectionPort}"
lang="jacl"
script="${scripts.dir}/set_classloader_mode.jacl" >





and


wasHome="${config.was.home}"
server="${config.WpsServer}"
conntype="${config.ConnectionType}"
port="${config.SOAPConnectionPort}"
application="my-application" />