Automating portlet deployment on WebSphere Portal using Apache Maven

If you download sample code from my blog you will notice that i use Apache Maven as build tool, my source code is structured in Maven format and you will find a pom.xml file which is maven build script.

I like to make my development environment as simple as possible and automate deployment so that i can test my changes rapidly. So i did create this very basic approach for automating deployment of portlet to WebSphere Portal using xmlaccess + maven. This approach is very similar to how you can automate deployment of portlet to Apache Pluto. You can download sample AjaxPortlet from here

I follow these steps whenever i create a new project

  • I create a simple portlet.xml that does not have any id portlet application id like this

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
    http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
    <portlet>
    <portlet-name>AjaxPortlet</portlet-name>
    <display-name>Ajax Portlet</display-name>
    <portlet-class>com.webspherenotes.portlet.AjaxPortlet</portlet-class>
    <expiration-cache>0</expiration-cache>
    <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>view</portlet-mode>
    </supports>
    <portlet-info>
    <title>Ajax Portlet</title>
    <short-title>Ajax Portlet</short-title>
    <keywords>Ajax Portlet</keywords>
    </portlet-info>
    </portlet>
    </portlet-app>

    The value of portlet-name is important for deployment

  • Then i create a pom.xml file which is build script for for my portlet and has custom integration-test target that i use for deploying portlet

    <?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.performance</groupId>
    <modelVersion>4.0.0</modelVersion>
    <!-- Version of this app -->
    <version>1.0</version>
    <!-- Base name of the war file without .war ext -->
    <artifactId>AjaxPortlet</artifactId>
    <packaging>war</packaging>
    <name>${pom.artifactId}</name>
    <!-- Dependency Version Properties ======================================= -->
    <properties>
    <portlet-api.version>2.0</portlet-api.version>
    <servlet-api.version>2.4</servlet-api.version>
    <jsp-api.version>2.0</jsp-api.version>
    <wps.home>/software/IBM/WebSphere</wps.home>
    <wps.url>http://localhost:10040/wpcert/config</wps.url>
    <wps.admin.name>wasadmin</wps.admin.name>
    <wps.admin.password>wasadmin</wps.admin.password>
    <xmlaccess.path>/software/work/blog/performance/ajax/AjaxPortlet /UpdatePortlet.xml</xmlaccess.path>

    </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>
    </dependencies>

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

    <plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
    <execution>
    <phase>integration-test</phase>
    <configuration>
    <tasks>
    <property environment="env"/>
    <exec executable="/bin/bash" dir="${wps.home}/PortalServer/bin">
    <arg line="xmlaccess.sh -user ${wps.admin.name} -password $
    {wps.admin.password} -url ${wps.url} -in ${xmlaccess.path}"/>
    </exec>
    </tasks>
    </configuration>
    <goals>
    <goal>run</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
    <source>1.5</source>
    <target>1.5</target>
    </configuration>
    </plugin>
    </plugins>
    </build>
    </project>



    In this file you will have to set properties for following things

    • wps.home: Location of portal installation base on your machine

    • wps.url: Config URL for xmlaccess for your portal server it will be http://localhost:10040/wps/config by default

    • wps.admin.name: User name for WPS admin

    • wps.admin.password: Password for WPS admin

    • xmlaccess.path: Path of UpdatePortlet.xml, which is a xmlaccess file that i use for deploying my portlets


    In most of the cases when i create a new portlet only value that will change is xmlaccess.path to point to new updateportlet.xml which is already always in the same directory as that of pom.xml, i bet i can read that directory name using Apache Maven variable but i will have to get some time to find that out

    In my script i have a integration-test target which makes use of ant to execute xmlaccess script that updates the portlet, this ant script gets executed when i execute mvn integration-test

  • The final step is to create a UpdatePortlet.xml file like this

    <?xml version="1.0" encoding="UTF-8"?>
    <request
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="PortalConfig_1.4.xsd"
    type="update"
    create-oids="true">

    <!-- sample for updating a portlet from a new version of the WAR file -->
    <portal action="locate">

    <web-app action="update" active="true" uid="AjaxPortlet.war.webmod">
    <url>file:////software/work/blog/performance/ajax/AjaxPortlet/target/AjaxPortlet.war</url>
    <portlet-app action="update" active="true" uid="AjaxPortlet.war">
    <portlet action="update" active="true" objectid="thePortlet" name="AjaxPortlet">
    </portlet>
    </portlet-app>
    </web-app>

    </portal>
    </request>


    The UpdatePortlet.xml file needs information such as location of .war file, PortletName that i can get portlet.xml, .war file name that i can get from pom.xml and once i change the updateportlet.xml to use correct values i am all set



Once my initial setup is in place i execute the mvn integration-test command to install the portlet for first time or update it, when i do that it take some time to build and then deploy it looks like this

7 comments:

Dream World said...

Nice Blog Visit My Blog:::
Online Natural Photo
http://onlinenaturalphoto.blogspot.com

Vishwa said...

Really nice article Sunil. I was looking for the portlet deployment using Maven.

Thanks again!

- Vishwanath

Dream World said...

Superb blog
Visit My Blog::
Fashion World

Carlos Gavidia said...

Very nice Blog: I'm beggining in Portal Development and I always come here for tips. Continue blogging!

Niraj Hoondlani said...

I am using ANT and xmlaccess for deployment...however when i try to update a war file it says that the war file with the uid of that portlet already exists...please assist

Vinay Teza said...

i am also facing the same issues as Niraj..plz assist

Mahua De said...

How do I run xmlaccess on remote portal server?