Product Development in Brisbane

Archive for the ‘WebSphere Portal’ Category

Automating Deployment to IBM WebSphere Portal

Thursday, May 22nd, 2008

Having an automated deployment procedure is an important goal for any project. This post talks about the the steps taken in making E2 autodeploy to WebSphere Portal in Development.  The below process assumes that the application has been deployed once through other means.

After a friendly pointer from AJ to an article about automating websphere deployment, I decided that the time had come to revisit trying to automate the deployment of our EAR file for E2. I had done bits and pieces of thi in the past using a combination of the WebSphere scripting client, and the WebSphere ant tool (like ant but built with WebSphere bits and pieces). The killer constraint for me is that my client machine didn’t have access to any of the WebSphere binaries (perhaps unsuprisingly Apple and IBM have don’t perfectly interoperate).

In order to work around thi sproblem I ended up leveraging one of the classic protocols (telnet), the websphere scripting client, samba (to mount the application server drives), and a bit of ant to glue it all together. The process outlined below is focused around the deployment of the application E2Application to WebSphere portal.

Step 1: Enable telnet

In Windows Server 2003 this is relatively straightforward. Simply go to your control panel -> services -> Telnet go to the properties, make it automatic and start it.

Step 2: Write scripts to start and stop the app server

I did this using tcl and ended up with the following scripts (the pythonistas may like to use jython to do the same):

stopApplication.jacl  

set cell [$AdminControl getCell]
set node [$AdminControl getNode]
set appManager

   [$AdminControl queryNames
   cell=$cell,node=$node,type=ApplicationManager,process=WebSphere_Portal,*]
$AdminControl invoke $appManager stopApplication E2Application

startApplication.jacl  

set cell [$AdminControl getCell]
set node [$AdminControl getNode]
set appManager

    [$AdminControl queryNames
   cell=$cell,node=$node,type=ApplicationManager,process=WebSphere_Portal,*]
$AdminControl invoke $appManager startApplication E2Application

Step 3: Write the ant code to compile and copy the application

After the series of standard building tasks, we used a simple copy task to copy the files to the exploded WAR directory on the server. (something like: ${portal.home}/WebSphere/profiles/wp_profile/installedApps/{cell}/{application}.ear/{app_war}.war). Since I develop on a laptop I added in a combination of available and fail task to stop me from accidently creating directories if I hadn’t mounted m

Step 4: use ant to telnet to the server

Make use of the telnet ant task1 to telnet into the server, and run the stop and start server jacl scripts. My Ant targets (passwords scrubbed) are below (excuse the duplication):

<target name="startApplication">
   <telnet userid="Administrator" password="${portal_admin_password}" server="${portal_server}">
   <read>Administrator</read>
        <!– change to the IBM AppServer directory –>
        <write>cd \ibm\AppServer\bin</write>
        <read>AppServer\bin</read>
        <!– Execute the jacl –>
        <write>wsadmin -conntype SOAP -port 10033
                -username wasadmin -password **** -f startApplication.jacl
        </write>
        <!– wait for the connected to process message, which will occur on the successful completion of the script –>
        <read>Connected to process</read>
        <read>AppServer\bin</read>
    </telnet>
</target>


<target name="stopApplication">

    <telnet userid="Administrator" password="${portal_admin_password}" server="${portal_server}">
        <read>Administrator</read>
        <!– change to the IBM AppServer directory –>
        <write>cd \ibm\AppServer\bin</write>
        <read>AppServer\bin</read>
        <!– Execute the jacl –>
        <write>wsadmin -conntype SOAP -port 10033
                -username wasadmin -password **** -f stopApplication.jacl
        </write>
        <!– wait for the connected to process message, which will occur on the successful completion of the script –>
        <read>Connected to process</read>
        <read>AppServer\bin</read>
    </telnet>
</target>

Step 5

mix ingredients and enjoying being able to have a one click deploy to WebSphere Portal.

Appendix

For security paranoid people with time on their hands, it is possible to do this using ssh and scp. The key parts will be step 3 and step 4. In step 3 we are using folder share and the ant copy task currently. It could be done with scp. In step 4 the use of telnet could be replaced with ssh.

1 - The telnet task depends on the availability of the commons-net jar on the classpath. (click here to download commons-net).

Setting up Oracle XE to work with IBM WebSphere Portal IWWCM

Wednesday, May 21st, 2008

In order to make the Oracle XE database work with IBM WebSphere Portal IWWCM there are a number of steps to perform.

  1. Ensure that the database is accessible using the Oracle SID (see the early post Oracle SID!=Service name)
  2. Next you will need to increase the number of proceses that can be connected to the instance, as there are a large number of connection pools set up by the system, which the database will need to support. The following command worked in my environment:
        ALTER SYSTEM SET PROCESSES=150 SCOPE=SPFILE;
  3. After having performed these base setup commands and options, you can run the IWWCM migration scripts to migrate existing data.
  4. To ensure that the connection pooling works correctly, you will need to grant the following privileges to public:

    grant select on pending_trans$ to public;
    grant select on dba_2pc_pending to public;
    grant select on dba_pending_transactions to public;

  5. Finally, grant the following privilege to each user to which connections are made from the application server.
        grant execute on dbms_system to <user>;

After having performed these steps you will have an Oracle XE database that will work happily with IWWCM.

Oracle SID != SERVICE_NAME

Friday, January 4th, 2008

… or how to setup your Oracle XE database so that JDBC database urls will work like they traditionally have.

For many years Oracle has been telling everyone Oracle SID != SERVICE_NAME.

Java Developers have always smiled and nodded with this statement as the oracle thin client jdbc url would always be something like:

jdbc:oracle:thin:@server:1521:SERVICE_NAME, or
jdbc:oracle:thin:@server:1521:SID 

which would work because databases always either had the SID and SERVICE_NAME as the same, or there was some magic that the Oracle listeners did to make this work.

Somewhere in the past couple of releases of Oracle this transparent mapping has ceased to exist. In particular Oracle 10G XE out of the box doesn’t support this sort of option.

It seems the new preferred way of doing Oracle JDBC URLs is:
jdbc:oracle:thin:@server:1521/SERVICE_NAME.

I discovered this information while working with making a WebSphere Portal instance use Oracle as it’s data repository. The documentation for doing this suggested using the old school SID style of url.  I tried this first as it felt familiar, but things didn't work.  Changing the url to use the PORT/SERVICE_NAME approach looked to mostly work, but didn’t quite spread the changes to everywhere required. I needed to run WPSConfig connect-database to update all the hidden bits of configuration around the portal installation. Unfortunately, this failed as the wpsconfig script calls out to programs that expect the url to follow the old school syntax (the stack trace show an index-out-of-bounds exception while parsing connect srings). I then had to go in and update the configuration on the database to enable connection via the old SID style approach.

This was done by working on the listener.ora file
(C:\oraclexe\app\oracle\product\10.2.0\server\NETWORK\ADMIN) to add in a SID_LIST_LISTENER entry for the database.

This was simply to add:
(SID_DESC =
    (GLOBAL_NAME = XE)
    (SID_NAME = XE)
    (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
)

to the SID_LIST of the SID_LIST_LISTENER

I ended up with a SID_LIST_LISTENER that looks like this:

SID_LIST_LISTENER =
    (SID_LIST =
        (SID_DESC =
            (SID_NAME = PLSExtProc)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
            (PROGRAM = extproc)
        )
        (SID_DESC =
            (SID_NAME = CLRExtProc)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
            (PROGRAM = extproc)
        )
        (SID_DESC =
            (GLOBAL_NAME = XE)
            (SID_NAME = XE)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
        )
    )

This configuration works with an out of the box Oracle XE installation, and lets me use the jdbc:oracle:thin:@server:1521:SID.

Why Use a Sledgehammer When There is a Bulldozer Lying Around

Wednesday, October 17th, 2007

Or finding which websphere portal shared jar contains the class you need.

When trying to find which WebSphere portal jar file contains the PortletServiceHome class (for the unitiated there are 225 jars in the portal shared directory), I was pushing my very rusty shell scripting skills.  I pulled in Doug for some advice, and we were working through various sledgehammer approaches and talking to google about what to do.  We were playing with various combinations of pipes and shell commands to get the output of the find (or ls) to play with the jar tvf and grep.

AJ then piped in with just use grep, and he really meant.. just use grep, and take advantage of the fact that the contents of the jar will be listed in plain text in the jar.

The command I ended up with was (running in PortalServer/shared/app):

grep PortletServiceHome *.jar

Which returns:
Binary file wp.pe.api.standard.jar matches
Binary file wp.pe.rt.impl.jar matches

Then running jar -tvf across the first jar shows that this is what I need to compile against and work with when developing.

The bulldozer of a grep across jars is the best way to find which jar contains a class that you are looking for1.

1 - While this feels really inefficient, it is actually better than having to spawn off multiple the jar processes which other approaches would involve.