Modifying the URL mapping of virtual portal context

It seems that if you change the url mapping of the VirtualPortalContext url then you will run into strange issues such as the createResourceURL() returning wrong URL, our team ran into this issue yesterday so i did little bit of debugging to see what happens.

I started by creating a new Virtual Portal test2, after creating the virtual portal i did create full export of the virtual portal as soon as the virtual portal was created. When i looked at the export i could see that it already had a URL mapping for test2, which is the context of the virtual portal like this


<url-mapping-context action="update" domain="rel" label="test2" objectid="C_VVILMKG108MAF0IS7PPFSE10S6">
<access-control externalized="false" owner="uid=wasadmin,o=defaultwimfilebasedrealm" private="false"/>
<portal-url resourceref="6_000000000000000000000000A0" update="set"/>
</url-mapping-context>


And this mapping is pointing to the 6_000000000000000000000000A0 node and when i checked the xmlaccess 6_000000000000000000000000A0 is pointing to the wps.content.root page like this

<content-node action="update" active="true" domain="rel" objectid="6_000000000000000000000000A0" ordinal="0" type="label" uniquename="wps.content.root">
<supported-markup markup="html" update="set"/>
<access-control externalized="false" owner="undefined" private="false"/>
</content-node>
<credential-segment action="update" adapter-type="default-customization" domain="cust" name="DefaultUserSegment" objectid="E_CGAH47L008IC40I4BOR2EO00U6" user-mapped="true">
<description>Default User Segment</description>
</credential-segment>
<credential-segment action="update" adapter-type="default-release" domain="rel" name="DefaultAdminSegment" objectid="E_CGAH47L008IC40I4BOR2EO00U1" user-mapped="false">
<description>Default Admin Segment</description>
</credential-segment>

Deleting virtual portal using the Configuration Task

You can use the Configuration Task to delete virtual portal, you will have to follow these steps to delete a virtual portal

  • Get list of virtual portal by executing

    ./ConfigEngine.sh list-all-virtual-portals

    Task, this task will print list of virtual portal, there names and object ids on the console like this



  • Once you have the objectid of the virtual portal you can use it to delete the virtual portal by executing following command

    ./ConfigEngine.sh delete-virtual-portal -D VirtualPortalObjectId=18_VVILMKG108MAF0IS7PPFSE10C6

    In this command the 18_VVILMKG108MAF0IS7PPFSE10C6 is the objectid that we got from the output of list-all-virtual-portals

Creating virtual portal using Portal Configuration Task

You can create a new virtual portal using portal configuration task, Follow these steps to create a new virtual portal.


  • Open /wp_profile/ConfigEngine/config/helpers/virtual_portal.properties file in the text editor and modify it like this

    # VirtualPortalTitle: Title of the Virtual Portal
    VirtualPortalTitle=Test Changed title

    # VirtualPortalRealm: Realm of the Virtual Portal
    VirtualPortalRealm=defaultWIMFileBasedRealm

    # VirtualPortalHost: Hostname of the Virtual Portal
    VirtualPortalHostName=

    # VirtualPortalContext: Context of the Virtual Portal
    VirtualPortalContext=test2

    # VirtualPortalNlsFile: File which contains language specific information for the Virtual Portal
    VirtualPortalNlsFile=

    # VirtualPortalObjectId: ObjectId of the Virtual Portal
    # The ObjectId is needed to modify, delete Virtual Portals and
    # can be obtained by running task list-all-virtual-portals
    # Note: Do not delete the default Virtual Portal (ObjectId ends with _0)
    VirtualPortalObjectId=


    I am creating a new virtual portal with portalcontext = test2.

  • Execute the following configuration task

    ./ConfigEngine.sh -DparentProperties=/software/IBM/WebSphere/wp_profile/ConfigEngine/config/helpers/virtual_portal.properties create-virtual-portal




It will create a virtual portal for you, now you can logout and login back into portal and you should be able to see newly created virtual portal

If you dont want to use the helper files then you can also specify all the required properties on command line like this

./ConfigEngine.sh create-virtual-portal -DVirtualPortalTitle=TestWPCert -DVirtualPortalRealm=defaultWIMFileBasedRealm -DVirtualPortalContext=testwpcert





Note:The task creates the virtual portal itself, but it does not create any default content for the virtual portal or grant any access permissions to the virtual portal administrators. You need to perform these tasks separately after creating the virtual portal, for example by using the XML configuration interface.

When you create a virtual portal using Manage Virtual Portal portlet it will also populate the newly created virtual portal using the xmlaccess file that you specified

Configuration Task for creating virutal Portal

The ConfigEngine.sh Interface provides set of tasks that can be used for managing Virtual portals using command line


  • create-virtual-portal: Creating a new virtual portal

  • modify-virtual-portal: Modifying existing virtual portal

  • delete-virtual-portal: Deleting virtual portal

  • list-all-virtual-portal: Printing list of virtual portal



These configuration tasks can be used as alternative to the Manage Virtual Portal Portlet.

Using Dojo and Dijit in the portlet

I made changes in the ValidationCacheSamplePortlet that i built in the last section to demonstrate how to use dojo and dijit in the portlet. As you can see i am including Dojo 1.3.2 from AOL CDN


<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<style type="text/css">
@import src="http://o.aolcdn.com/dojo/1.3.2/dijit/themes/tundra/tundra.css";
@import src=""http://o.aolcdn.com/dojo/1.3.3/dojo/resources/dojo.css";
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.3.2
/dojo/dojo.xd.js" djConfig="parseOnLoad:true">
</script>
<portlet:defineObjects />
<script type="text/javascript">
dojo.require("dijit.form.Button");
dojo.require("dojo.parser");
</script>

<button dojoType="dijit.form.Button" id="btn">Resource
<script type="dojo/method" event="onClick">
dojo.xhrGet({
url: "<portlet:resourceURL/>",
load: function(data, ioargs){
dojo.byId("resourceResponse").innerHTML = data;
},
error: function(error,ioargs){
alert(error);
}
});
</script>
</button>

<div id="resourceResponse" />

Sample Resource Serving Portlet

This is a sample portlet that can be deployed in any Portlet Container and demonstrates how to make a Ajax Resource Call to the portlet without using any JavaScript framework like dojo. The JavaScript code is lengthy then if you use JavaScript framework. But sometimes you cant/dont want to use JavaScript framework for 1 call.

First i did build a JSR 286 compliant ValidationCacheSamplePortlet portlet like this.

public class ValidationCacheSamplePortlet extends GenericPortlet{
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering ValidationCacheSamplePortlet.doView()");
response.setContentType("text/html");
getPortletContext().getRequestDispatcher("/validation.jsp").include(request, response);
System.out.println("Exiting ValidationCacheSamplePortlet.doView()");
}
public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
System.out.println("Entering ValidationCacheSamplePortlet.serveResource()");
response.setContentType("text/html");
response.getWriter().println("Hello from ValidationCacheSamplePortlet.serveResource");
System.out.println("Exiting ValidationCacheSamplePortlet.serveResource()");
}
}


The ValidationCacheSamplePortlet is very simple in the doView() method it is passing control to validate.jsp for generating response markup and in the serveResource() method is returning Hello from ValidationCacheSamplePortlet.serveResource String.

This is how the validation.jsp looks like, it has a button Resource button, when you click on that button it is making a HTTP GET call to <portlet:resourceURL/> and displaying the response using alert.


<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<portlet:defineObjects />
<script type="text/javascript">
function createXMLHttpRequestObject() {
var xmlHttp;
try {
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
} catch (e) {
}
}
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
var xmlHttp = createXMLHttpRequestObject();
function makeResourceCall(){
if (xmlHttp){
try{
xmlHttp.open("GET", "<portlet:resourceURL/>", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}catch (e){
alert("Can't connect to server:\n" + e.toString());
}
}
}

function handleRequestStateChange(){
if (xmlHttp.readyState == 4){
if (xmlHttp.status == 200){
alert(xmlHttp.responseText);
}
}
}
</script>
<input type="button" onclick="JavaScript:makeResourceCall()" value="Resource Call" />
<div id="resourceResponse"></div>


Maven script to build Flex portlet

As you might have seen in the last few days i am working on using Flex inside the portlet and i did built quite a few portlets to demonstrate how that works.

The building and deployment was very painful, first i had to make changes in the .mxml export it as .swf from Flex builder into the WebContent folder of my portlet then export portlet with new .swf and install it on portal.

In order to simplify this process i built a mvn script which can be used to build .mxml in .swf, copy it into the WebContent folder, package the portlet and then deploy it in the pluto, this is the script that i am using.



<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<!-- Change this to something akin to your java package structure -->
<groupId>com.webspherenotes.portlet</groupId>
<modelVersion>4.0.0</modelVersion>
<!-- Version of this app -->
<version>0.1-alpha1</version>
<!-- Base name of the war file without .war ext -->
<artifactId>HelloWorldPortlet</artifactId>
<packaging>war</packaging>
<name>${pom.artifactId}</name>
<!-- Dependency Version Properties ======================================= -->
<properties>
<pluto.version>2.0.0</pluto.version>
<portlet-api.version>2.0</portlet-api.version>
<servlet-api.version>2.4</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<junit.version>3.8.1</junit.version>
<pluto.home>C:/software/pluto-2.0.0</pluto.home>
<flex.home>C:/software/AdobeFlashBuilder/sdks/4.0.0</flex.home>
<flex.mxml.path>C:/flex/HelloFlex/src/HelloWorld.mxml</flex.mxml.path>
<flex.swf.name>HelloWorld.swf</flex.swf.name>
</properties>
<dependencies>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>${portlet-api.version}</version>
<scope>provided</scope><!-- Prevents addition to war file -->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.portals.pluto</groupId>
<artifactId>pluto-util</artifactId>
<version>${pluto.version}</version>
<scope>provided</scope>
</dependency>
<!-- Any other build or deployment dependancies go here -->
</dependencies>
<build>
<finalName>${pom.name}</finalName>
<plugins>

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<configuration>
<tasks>
<property environment="env"/>
<!-- This assumes that you have set a CATALINA_HOME environmental variable
<property name="pluto.home" value="C:/software/pluto-2.0.0"/>-->
<copy file="target/${pom.name}.war" todir="${pluto.home}/webapps"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- configure to use Java 6 to compile (change to your JDK) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<!-- configure maven-war-plugin to use updated web.xml -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.portals.pluto</groupId>
<artifactId>maven-pluto-plugin</artifactId>
<version>${pluto.version}</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<tasks>
<property name="FLEX_HOME" value="${flex.home}"/>
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<mxmlc file="${flex.mxml.path}" keep-generated-actionscript="false"
output="${project.build.directory}/${project.name}/${flex.swf.name}">
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
<include name="../bundles/{locale}" />
</compiler.library-path>
</mxmlc>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Maven build script for compiling and deploying portlet on the Apache Pluto

Apache Pluto is reference implementation of the JSR 286 specification. You can think about it as Apache Tomcat of the portal world.

Recently i did install Pluto 2.0 on my machine which is very simple all you have to do is download Pluto and extract it in say c:/software folder. After doing that you can go in c:/software/pluto2.0.0/bin directory and execute catalina.bat start. Once the server is started you can access it http://localhost:8080/pluto/portal using tomcat + tomcat as user id and password.


What i like most about pluto is that it can work with small memory and you can restart it in less than few seconds. Other advantage of using Pluto is you can use a maven script like this and when you execute mvn integration-test it will deploy the portlet on your pluto server, you will have to add it to page using its admin UI but once that is done you can update your portlet by executing mvn integration-test and the new code will be deployed and ready for testing.

I like to use Pluto for building small sample portlets which are JSR 286 compliant and does not need any IBM WebSphere specific features, once the portlet development is done is verified on pluto i deploy it on WebSphere Portal


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<!-- Change this to something akin to your java package structure -->
<groupId>com.webspherenotes.portlet</groupId>
<modelVersion>4.0.0</modelVersion>
<version>1.0</version>
<artifactId>HelloWorldPortlet</artifactId>
<packaging>war</packaging>
<name>${pom.artifactId}</name>
<!-- Dependency Version Properties ======================================= -->
<properties>
<pluto.version>2.0.0</pluto.version>
<portlet-api.version>2.0</portlet-api.version>
<servlet-api.version>2.4</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<junit.version>3.8.1</junit.version>
<pluto.home>C:/software/pluto-2.0.0</pluto.home>

</properties>
<dependencies>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<version>${portlet-api.version}</version>
<scope>provided</scope><!-- Prevents addition to war file -->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.portals.pluto</groupId>
<artifactId>pluto-util</artifactId>
<version>${pluto.version}</version>
<scope>provided</scope>
</dependency>

</dependencies>
<build>
<finalName>${pom.name}</finalName>
<plugins>

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<configuration>
<tasks>
<property environment="env"/>
<!-- This assumes that you have set a CATALINA_HOME environmental variable
<property name="pluto.home" value="C:/software/pluto-2.0.0"/>-->
<copy file="target/${pom.name}.war" todir="${pluto.home}/webapps"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- configure to use Java 6 to compile (change to your JDK) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<!-- configure maven-war-plugin to use updated web.xml -->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.portals.pluto</groupId>
<artifactId>maven-pluto-plugin</artifactId>
<version>${pluto.version}</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>


</plugins>
</build>

</project>


Before we use this maven script create a .xml file like this in the META-INF folder of your web app and dont forget to use directory structure used by Maven for structuring your code

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/HelloWorld" docBase="HelloWorld" crossContext="true"/>

Ant script for building Flash application

This is the ant script that i use for compiling my Flex application into .swf file


<?xml version="1.0" encoding="utf-8"?>
<project name="My App Builder" basedir=".">

<property name="FLEX_HOME" value="C:/software/AdobeFlashBuilder/sdks/4.0.0"/>
<property name="FLEX_MXML_PATH" value="C:/flex/HelloFlex/src/JSONDataExchange.mxml"/>
<property name="FLEX_SWF_PATH" value="C:/flex/HelloFlexPortlet/WebContent/HelloFlex.swf"/>

<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<target name="main">
<mxmlc file="${FLEX_MXML_PATH}" keep-generated-actionscript="true" output="${FLEX_SWF_PATH}">
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
<include name="libs" />
<include name="../bundles/{locale}" />
</compiler.library-path>
</mxmlc>
</target>
</project>


You need to have either the Adobe Flex builder or the Flex SDK installed on your machine. This script requires following three variables


  1. FLEX_HOME Location where FLEX SDK is installed on your machine. If you have Flex builder 4.0, it has both SDK 4.0 and SDK 3.5 and you can point to either of them

  2. FLEX_MXML_PATHFully qualified path of the .mxml file that has your Flex application

  3. FLEX_SWF_PATHFully qualified path of the .swf file that you want to generate. In my case i am generating the .swf file inside my Web application so that i can package it in the .war file

How to use the Portlet Specification 2.0 Tag library in WebSphere Portal 6.1

If your building a JSR 286 compliant portlet and want to use one of the new tags introduced in JSR 286 such as resourceURL then you will have to include the http://java.sun.com/portlet_2_0 tag library in your JSP like this


<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<portlet:defineObjects />
<a href='<portlet:resourceURL />'>Resource URL </a>


By default when you create a portlet JSP in RAD 7.5 it always adds Portlet Specification 1.0 related tag library like this <%@taglib uri="http://java.sun.com/portlet" prefix="portlet"%> and with this you cannot use newer tags