Create a simple portlet

 

+
Search Tips   |   Advanced Search

 


Contents

  1. Write the portlet code
  2. Compiling Java source
  3. Create the JAR file
  4. Write the portlet descriptors
  5. Set up the WAR file directory structure
  6. Package and deploying portlets
  7. IBM portlet API examples for Hello World

 

Write the portlet code

The Hello World portlet provides an introduction to writing your first portlet. The portlet is provided along with the source in the IBM Portlet Samples package, which is available from the portlet catalog by searching for navcode 1WP10004N. Hello World provides the fewest methods required for a portlet. It uses the portlet response object to write simple output directly to the portal page.

Example: Java source for Hello World portlet (JSR 168)

package com.ibm.wps.samples.jsr;

import javax.portlet.*;
import java.io.*;

public class HelloWorld extends GenericPortlet {
 
   public void init  PortletConfig(portletConfig) throws UnavailableException, PortletException
   {
      super.init(portletConfig);
   }

   public void doView(RenderRequest request, RenderResponse response)
                      throws PortletException, IOException
   {

      // set return content type 
      response.setContentType("text/html");
      PrintWriter writer = response.getWriter();
      writer.println("<p class='wpsPortletText'>Hello Portal World!</p>");
    }

}

If you are familiar with writing to the IBM portlet API, here are some of the key differences between this JSR 168 example and the corresponding IBM example Hello World portlet.

API element IBM portlet API Java Portlet Specification
import statements org.apache.jetspeed.portlet javax.portlet
Portlet class PortletAdapter GenericPortlet which also can throw a PortletException.
Request object PortletRequest RenderRequest
Response object PortletResponse RenderResponse

Also notice that the content type must be set in the response.

 

Compiling Java source

Use the JDK provided by WebSphere Application Server to compile your Java source files. Before you compile your Java source, set the CLASSPATH for the compiler to find the JAR files for any portlet packages that your portlet uses. The following JAR files should be set in the CLASSPATH to compile portlets:

JSR 168 portlets
JAR file Purpose
wp.pe.api.standard Java Portlet Specification
wp.portletservices.api.standard Portlet services
IBM portlets
JAR file Purpose
wp.pe.api.legacy IBM portlet API
wp.portletservices.api.legacy Portlet services
wp.pe.rt.api Portlet menus

Then, compile the portlet using the fully-qualified path to the Java portlet source.

  javac -classpath %CLASSPATH% com.ibm.wps.samples.jsr.HelloWorld.java

  javac -classpath %CLASSPATH% com.ibm.wps.samples.v4.HelloWorld.java

 

Loading classes for portlets

WebSphere Portal classloading follows the WebSphere Application Server hierarchy for classpaths and search orders. A particular classloader can reference other classes as long as the other classes can be loaded by the same classloader or any of its ancestors, but not its children. The graphic illustrates where WebSphere Portal and portlet applications fit into the classloading hierarchy.

portal classpaths

As illustrated, WebSphere Portal is an application extension (AEX) under WebSphere Application Server. Consequently, the WebSphere Portal core classes are in the classpath wp_root/shared/app. If an installed portlet application includes a classloader, the portlet application classloader is an application classloader (ACx) under WebSphere Portal.

If you suspect a classloading problem, ensure that the required classes are in the appropriate classpath according to the classloading hierarchy.

 

Create the JAR file

Next, the portlet must be packaged in the JAR file format. To create a JAR file with the name HelloWorld.jar, enter the following command:

   jar -cf HelloWorld.jar HelloWorld.class

Refer to the JDK documentation for more information about the JAR command.

 

Write the portlet descriptors

The following samples can be packaged with the Hello World portlet.

 

JSR 168 Web application deployment descriptor:

According to the JSR 168 specification, only Web resources that are not portlets should be declared in the web.xml. However, the following properties should be set to correspond to the portlet descriptor:

  • <description/>

    describes the portlet application.

  • <display-name/>

    indicates the portlet application name.

  • <security-role/>

    indicates the portlet application security role mapping. Omit this tag if the portlet does not use this feature.

Example: Web application deployment descriptor for Hello World (JSR 168)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
                         "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp">
 <display-name>Hello World (JSR)</display-name>
 <description>Basic JSR 168 portlet</description>
</web-app>

If you are familiar with the web.xml for IBM portlets, the key difference between this example and the corresponding IBM example Web application deployment descriptor is the required <servlet/> element in the web.xml for IBM portlets.

 

JSR 168 portlet deployment descriptor:

The following shows the minimum elements required for the JSR 168 portlet deployment descriptor.

Example: Portlet deployment descriptor for Hello World (JSR 168)

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd 
                                 http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
   <portlet>
      <portlet-name>HelloWorld portlet name</portlet-name>
      <display-name>Hello World portlet (JSR)</display-name>
      <display-name xml:lang="en">Hello World portlet (JSR)</display-name>
      <portlet-class>com.ibm.wps.samples.jsr.jsrHelloWorld</portlet-class>
      <supports>
         <mime-type>text/html</mime-type>
         <portlet-mode>view</portlet-mode>
      </supports>
      <supported-locale>en</supported-locale>
      <portlet-info>
         <title>Hello World (JSR)</title>
      </portlet-info>
   </portlet>
</portlet-app>

There are number of differences between the elements in this example and the corresponding IBM example Portlet deployment descriptor. In addition, the JSR 168 portlet.xml is defined by an XML schema and does not require a DTD.

 

Set up the WAR file directory structure

Before you package your portlet, the class files and resources must be arranged in the WAR file directory structure described here. A portlet application exists as a structured hierarchy of directories.

Do not package the portlet_1.1.dtd or the portlet.tld with the portlet application WAR file.

/

The root directory of the portlet file structure.

/images

Location for any images the required by the portlet.

/WEB-INF

Location for all protected resources. The /WEB-INF directory stores the portlet descriptor document and all of the runtime executable JAR files and classes that the packaged portlet requires.

The portlet information directory is not part of the public document tree of the application. Files that reside in /WEB-INF are not served directly to a client.

/WEB-INF/lib

Location for storing portlet JAR files.

/jsp

Location for JSP files. This is a suggested path name. Your JSPs can be packaged in any location outside of the /WEB-INF directory.

/WEB-INF/classes

Location for portlet class files. Individual class files should be stored in a directory structure within /WEB-INF/classes that reflects the class package. For example, the class HelloWorld.class, in package com.ibm.wps.samples, would be stored in /WEB-INF/classes/com/ibm/wps/samples/HelloWorld.class .

/META-INF

Location for the manifest file, manifest.mf and the Java 2 security file, was.policy (if present). The manifest is in the standard JAR file format as defined by the Java 1.3 specification. The Java 2 security policy files is used to allow a portlet to perform operations that might be restricted if Java 2 security is enabled The contents of the /META-INF directory is not served to clients.

The appserver searches for security policy files in the location of the enterprise application archive rather than the Web application archive. Therefore, the portal server copies was.policy from the appname.war/META-INF directory to the generated appname.ear/META-INF directory during deployment of a portlet WAR file.

 

Package and deploy portlets

To deploy a portlet and run it on the server, it must be packaged in the form of a Web application ARchive or WAR file. The WAR file format contains the Java classes and resources that make up one or more portlets in a portlet application. The resources can be images, JSP files, portlet descriptors, and property files containing translated message text. Packaging portlet classes, resources, and descriptive information in a single file makes distribution and deployment of portlets easier.

WebSphere Portal includes an administrative portlet for installing, uninstalling, and updating portlets. Portlets contained in WAR files have the advantage of being dynamically downloaded and installed. The portal administrator can download a WAR file from the Internet and then use the portal administration interface to install the portlet to WebSphere Portal. After installation, the portlet is ready for use and does not require the server to be restarted. To package your portlet in a WAR file, you can use the JAR utility to package the files .

Because Windows limits the maximum path length to 260 characters, the name of the WAR file must be less than 25 characters. On a portal server running on Windows, installing a WAR file with a name that is more than 25 characters will result in an error.

 

Package a portlet and resources into a WAR file

Any JAR utility may be used to build a WAR file. Below are examples of how to use the JAR utility provided by WebSphere Application Server.

  • To create a WAR file with the name HelloWorld.war and include all of the files in the /WEB-INF and /images directories:

       jar -cf HelloWorld.war images WEB-INF
    
    

  • To update an existing WAR file, HelloWorld.war with a revised portlet descriptor:

       jar -uf HelloWorld.war WEB-INF/portlet.xml
    
    

  • To extract the portlet descriptor from the WAR file, HelloWorld.war :

       jar -xf HelloWorld.war WEB-INF/portlet.xml
    
    

  • To extract all files from an existing WAR file, HelloWorld.war:

       jar -xf HelloWorld.war
    
    

After the WAR file is created, it can be installed to WebSphere Portal as described in portal administration .

 

Prepare the portlet application for installation

You can provide a portlet configuration file that can be invoked by XMLAccess, allowing the portlet developer to specify places, pages, themes, skins, supported markups and clients, and other settings. This is especially useful for portlets that use messaging because these portlets have to be placed on the same page.

When constructing XMLAccess scripts for use in installing JSR 168 compliant portlets, use the following values.

  • uid attribute for the <web-app> element:

    Use the uid attribute of the <portlet-app/> subelement with a .webmod suffix. As described subsequently in this topic, the uid attribute of the <portlet-app/> subelement is dependent on the presence of the id attribute of the <portlet-app/> element from the portlet.xml.

  • uid attribute for the <portlet-app> element:

    Use the id attribute of the <portlet-app/> element from the portlet.xml. If this value has not been specified, specify the WAR file name of the portlet application in its place. For portlet updates, the WAR file name must be the original name of the WAR file used to install the portlet application. That is, the WAR file name can be changed, but the uid must indicate the original uid used during portlet installation.

  • name attribute for the <portlet> element:

    Use the content of the <portlet-name/> element from the portlet.xml.

  • referenceid attribute of the <servlet> element:

    Use the content of the <portlet-name/> element from the portlet.xml appended with the .servlet suffix.

For example, a portlet application might use a portlet descriptor as follows:


  <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
                  version="1.0"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
                                      http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">
        <portlet>
        <portlet-name>External Bookmarks</portlet-name>
        ...

In this example, there is no id attribute provided on the <portlet-app/> element. Therefore, the <portlet-app/> element of the XMLAccess script would use the WAR file name, as follows:


 <web-app action="update" active="true" removeable="true" uid="bookmarks.war.webmod">
    <url>file:///$server_root$/installableApps/bookmarks.war</url>
       <servlet action="update" active="true" 
                   objectid="_V_0830MVP9KE0A1B94_6A" 
                   referenceid="External Bookmarks.servlet"/>
    <portlet-app action="update" active="true" uid="bookmarks.war">
       <portlet action="update" active="true" name="External Bookmarks"</portlet>
    </portlet-app>
 </web-app>

 

IBM portlet API examples for Hello World

Example: Java source for Hello World portlet (IBM)


package com.ibm.wps.samples.v4;

import org.apache.jetspeed.portlet.*;
import java.io.*;

public class HelloWorld extends PortletAdapter {

   public void init  PortletConfig(portletConfig) throws UnavailableException
   {
      super.init(portletConfig);
   }

   public void doView PortletRequest(request, PortletResponse response)
                      throws PortletException, IOException
   {
      PrintWriter writer = response.getWriter();
      writer.println("<p class='wpsPortletText'>Hello Portal World!</p>");
   }

}

Example: Web application deployment descriptor (IBM)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
                         "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp">
        <display-name>HelloWorld</display-name>
        <servlet id="com.ibm.wps.samples.HelloWorld.a0ae41f2d3c1001710b7b313e1a97">
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>com.ibm.wps.samples.HelloWorld</servlet-class>
        </servlet>
    <servlet-mapping 
       id="ServletMapping_com.ibm.wps.samples.HelloWorld.a0ae41f2d3c1001710b7b313e1a97">
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/HelloWorld/*</url-pattern>
    </servlet-mapping>
</web-app>

The href attribute of the <portlet/> element references the servlet ID from Web deployment descriptor. The portlet deployment descriptor references the portlet_1.1.dtd, which portal server finds in...

was_root/installedApps/hostname/wps.ear/wps.war/dtd

Do not package the DTD with the portlet application WAR file.

Example: Portlet deployment descriptor (IBM)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 1.1//EN" 
                                 "portlet_1.1.dtd">
<portlet-app-def>
  <portlet-app uid="com.ibm.wps.samples.HelloWorld.a0ae41f2d3c1001710b7b313e1a97" 
               major-version="1" minor-version="0">
    <portlet-app-name>HelloWorld application</portlet-app-name>
    <portlet id="com.ibm.wps.samples.HelloWorld" 
             href="WEB-INF/web.xml#com.ibm.wps.samples.HelloWorld.a0ae41f2d3c1001710b7b313e1a97"
             major-version="1" minor-version="0">
      <portlet-name>HelloWorld portlet</portlet-name>
      <cache>
        <expires>0</expires>
        <shared>NO</shared>
      </cache>
      <allows>
        <maximized/>
        <minimized/>
      </allows>
      <supports>
        <markup name="html">
          <view/>
        </markup>
      </supports>
    </portlet>
  </portlet-app>
  <concrete-portlet-app uid="com.ibm.wps.samples.HelloWorld.313e1a97f47.2">
    <portlet-app-name>HelloWorld application</portlet-app-name>
    <concrete-portlet href="#com.ibm.wps.samples.HelloWorld">
      <portlet-name>HelloWorld portlet</portlet-name>
      <default-locale>en</default-locale>
      <language locale="en">
        <title>HelloWorld portlet</title>
        <title-short></title-short>
        <description></description>
        <keywords></keywords>
      </language>
    </concrete-portlet>
  </concrete-portlet-app>
</portlet-app-def>

 

See also

Home |

 

WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.