     [file shared-setup.texi not included]

Assumptions
***********

 2. Instructions are given on how to restrict the Admin Console to web browsers running on the server machine. Instructions are not given for securing the Admin Console better than that because there is no simple way to do so unless you run WAS as root.

 3. We assume that this web server instance is configured to run on port 80.

     If you have administrative access to an iPlanet web server running on a different physical server, you can use that web server as your front-end by configuring the plugin there. (However, I won't be expending the effort to explain that procedure here unless somebody expresses the need to me.)

 4. We do not install or use any JMS/messaging capabilities.  It is extremely difficult, if not impossible, to get that working on Solaris with WAS running as non-root.

 5. We set up the main installation to run as a non-root user <MAIN_OWNER>, but use this instance only for testing (because if this instance gets messed up, it can be become permanently disabled, as well as other reasons). We will then create an alternative instance, and it is this instance which we will use for our real development work. The procedure can be repeated to make as many alternative instances as desired. These instances can easily be re-created if anything gets messed up. WAS shares binaries and runtime images among instances wherever possible. Alternative instance(s) are run by non-root user(s).  Each alternative instance can be run by a different user (this allows for multiple UNIX users to independently administer their own instance).

 6. We install the example applications for the main instance, but not for alternative instances. Run the main instance to see the example apps, or just install the ears into your alternative instance after it is running.

 7. The primary group of the <MAIN_OWNER> account should be <MAIN_OWNER>. I.e., the primary group name should be the same as the user name. This is most common convention when creating UNIX accounts. This requirement is made only to make these instructions easier for me to write and for you to understand-- things will work with any group name if you modify the corresponding commands accordingly. (If you create the account following the instructions below, you will be all set).

 8. I use perl, wget and other UNIX utilities in my examples.  These utilities are installed on all Nextel servers that I know of.  If you don't have them on your server--- get them.

 9. In general, the shell commands that I give will work with any normal UNIX shell. An exception is the setup of the environment files .profile and $ENV.  You can only depend on both of these files being sourced if the shell is Korn.  If you use some other shell, you will have to adjust the file names and syntax.

Introduction
************

This document is a HOWTO for installing and running WebSphere Application Server version 5.0 on Solaris and Linux in the Nextel Online Store environment.

Here are some abbreviations used in this document.

WAS
     WebSphere Application Server

IHS
     IBM HTTP Server.  Apache v. 1.3.26 configured by IBM and bundled with WAS

IWS
     iPlanet Web Server

When I user variables like $THIS or <THIS>, in general you have to type in the real values.  (If you know how to use the shell, then you can figure out how to set and export variables so you don't have to type out the real values).  Here are the variables that I use in this document.

$WAS_HOME
     Main directory where you install the WAS software. Default is something like /opt/IBM/WebSphere/AppServer. I like /usr/local/ws-5.0.

$USER_INSTALL_ROOT
     Root directory of an alternative WAS instance. For my personal instance, I like something like /home/bsimpson/ws-inst1.

<MAIN_OWNER>
     Unix user which will "own" the files under $WAS_HOME. (The default instance will run as this user). At Nextel, we usually use the account "websphere".

<INST_OWNER>
     Unix user who will "own" the files under $USER_INSTALL_ROOT.  This alternative instance will run as this user. For your first alternative instance, this will usually be your personal UNIX account.

<INST>
     Name (identifier) of the alternative instance. For example, "inst1".

<MAIN_NODE>
     Node name for the main WAS node/instance.  This is the instance that gets installed when the WAS software is installed. Do not confuse node name with host name, like the IBM docs often do. Your should have a unique node name for each WAS instance, yet you can have many WAS instances on one host. You could use the same node name for multiple instances if you never plan to configure them in a Network Deployment installation, but there is no good reason to.

<INST_NODE>
     Name of the node of your alternate instance. The value should be different from <MAIN_NODE>. For example, "nodeInst1" (I include the instance name in the instance node name, since there is a 1-to-1 correspondence).

<IWS_INST_HOME>
     Home directory for your IWS instance. (If you use default settings, this will be something like /opt/iplanet/server4/https-SOMENAME.nextel.com).

Where I just give a URL, that means to use your browser to go to the given URL.

Installing WAS Software and the Main Instance
*********************************************

Preparation
-----------

The WAS software, including the sample apps (but not any apps that you may add later) takes up under 400M.

For this section of this document only, I'll call this directory $SOFTWARE_DIR. It doesn't matter who owns these files and directories, as long as they are readable to <MAIN_OWNER>.

The paths in this section for stuff under $SOFTWARE_DIR may not be right on your system.  They work exactly as given right now, but you may get your distribution from a different source, or the layout of the distribution may change. So, you may have to use find (or similar) commands to find the files under $SOFTWARE_DIR, like

         find $SOFTWARE_DIR -name some.file

You need to find out if gsk is installed.  It is needed by the web server plugin.

Decide on a user for <MAIN_OWNER>.  If you are indecisive, then use "websphere"! If <MAIN_OWNER> doesn't exist yet, then create the account.

         useradd -d $WAS_HOME -c WebSphere -u 1601 -m -s /bin/ksh <MAIN_OWNER>

(where $WAS_HOME is the main directory into which you will install WAS--- the directory doesn't have to exist yet). Create your <INST_OWNER> account if it doesn't already exist, like

         useradd -d $USER_INSTALL_ROOT -c 'Blaine Simpson' -u 1801 -m -G <MAIN_OWNER> -s /bin/ksh <INST_OWNER>

(where $USER_INSTALL_ROOT is the directory into which you will install your alternative instance). If <INST_OWNER> is an existing user, then just add this user to the group <MAIN_OWNER>.

Make sure that $WAS_HOME has owner and group of <MAIN_OWNER>, and has the group-set bit set.

         ls -ld $WAS_HOME
         chmod g+rxs $WAS_HOME
         ls -ld $WAS_HOME

Now you have to decide on graphical or non-graphical software installation. Graphical is prettier and gives you progress meters, but it's easier to goof up.

The next several steps need to be performed as user <MAIN_OWNER>, so go ahead and log in as that user. (If you have changed his primary group, make sure to log out and back in to activate that change).

Graphical Install
-----------------

Invoke .  There is no need to "cd" to the directory since it can be run from anywhere.

("mqUnixInstallActionBean" appears in the log file if messaging is really installed... as will not happen unless you are root.)

Choose "Custom". Feature selection.  Leave all defaults, except

 1. Accept all defaults except where noted here.

 2. Change paths.  Set the main App Server install to whatever you chose for $WAS_HOME.

 3. Selecting or de-selecting messaging makes no difference. Messaging will not be installed regardless of what you do, since that requires root privileges.  The installation program does not notify you of this.

 4. I recommend that you name your main node "node" +  hostname with initial cap, like "nodeSaturn".  This is to avoid confusing hostname with node name. Hostname and node name are very different, since we will have multiple nodes installed on this host. This document hereafter uses <MAIN_NODE> to refer to the node name of the main WAS instance.

 5. For host name, you need to use the name of an address that will always be available locally.  I suggest that you allocate a static IP addr just for this purpose.  (Everything listens to IPADDR_ANY by default. The problem is just that some client programs connect using this host name, so if it's not available these administrative commands will fail). Use a short, unqualified hostname like "actuate", not a qualified hostname like "actuate.nextel.com".

 6. Log file is be written to /tmp/log.txt as the install runs (you may "tail -f" it from there) and is put in $WAS_HOME/logs when the installation completes. Be aware that the log file is not opened right away, so you have to wait for it before tail (or anything else) can read it.

 7. At the end, "install" will start the "First Steps" gui.  This is just a pretty wrapper to view release notes, run the verifier, etc.  Just close it (because any Admin needs to know how to run the important stuff without this Gui, and the other stuff is useless).

Non-Graphical Install
---------------------

 1. Download the appropriate response file, like

 2. Edit the file that you downloaded according to my commented instructions in the file.

 3. Run

              $SOFTWARE_DIR/sun/install -options /absolute/path/to/your/ws-response.file

     where "ws-response.file" is your modified copy of

 4. Log file is written to /tmp/log.txt as the install runs (you may "tail -f" it from there) and is put in $WAS_HOME/logs when the installation completes. Be aware that the log file is not opened right away, so you have to wait for it before tail (or anything else) can read it.

Post-install Configuration
--------------------------

     [file ant-upgrade.texi not included]

Edit the file $WAS_HOME/bin/setupCmdLine.sh.  Search for the "ulimit" command and append "2>&-" to it (this is needed for normal non-super users). Or, if you have the environmental variable $WAS_HOME set, then just cut and paste the following command.

         perl -pi.orig -we 's:$: 2>&-: if /^ulimit /;' $WAS_HOME/bin/setupCmdLine.sh

Overwrite the file $WAS_HOME/bin/startServer.sh with the patched version below. To preserve permissions, copy it over your existing copy, like this.

         cd /tmp
         wget http://admc.com/blaine/howtos/startServer.sh
         cp startServer.sh  $WAS_HOME/bin

This patch works around the problem that sudo invocations zero the $LD_LIBRARY_PATH variable, and Oracle JDBC drivers will not work without that variable set properly.

Do the same thing for $WAS_HOME/bin/startNode.sh.

         cd /tmp
         wget http://admc.com/blaine/howtos/startNode.sh
         cp startNode.sh  $WAS_HOME/bin

Back up, then edit the file $WAS_HOME/config/cells/<MAIN_NODE>/nodes/<MAIN_NODE>/servers/server1/server.xml. In the line containing 'EndPoint_3', change the value of host from "" to "localhost". This restricts use of the AdminConsole to your local server. Or, cut and paste the following command and change the <> variables to your values.

     perl -pi.orig -we 's:\"\":"localhost": if /\bEndPoint_3\b/;' $WAS_HOME/config/cells/<MAIN_NODE>/nodes/<MAIN_NODE>/servers/server1/server.xml

Run $WAS_HOME/bin/ivt.sh to verify the installation. (It should "fail to connect" and then successfully start the app server and pass the tests). (You won't be able to do this if you didn't have the ivtApp application installed, like I suggested).

Be aware that you will have to adjust file or directory permissions if $WAS_HOME/logs is on a NFS mounted directory, since the web server plugin needs to write to plugin log files in this directory as root.

Verify that the WAS admin console works.

         http://localhost:9090/admin

(Log in with any user name.  No password required.)

Verify that a sample application works.

         http://localhost:9080/PlantsByWebSphere

Verify that a sample application works through the web server plugin.

         http://localhost/PlantsByWebSphere

Shut down the instance.

         $WAS_HOME/bin/stopServer.sh server1

You are finished installing the software and the main instance.

Installing an Alternate Instance
********************************

An alternat WAS instance (not any apps that you may add later) takes up under 50M.

Creating the instance
---------------------

You need to make up an instance name and a node name for the new instance. This document will call these values <INST> and <INST_NODE>. <INST_NODE> should be different from <MAIN_NODE> so that these nodes can be differentiated if you ever put these instances under a Network Deployment. Note that <INST> is the "unqualified" instance name. The full instance name is <INST>_<INST_NODE>). You will need 6 available tcp/ip ports. (Since you're running as non-root, they must be > 1023). You also need to pick a $USER_INSTALL_ROOT, the directory in which to install this instance (commonly under your personal home directory somewhere). This document calls the UNIX user who will "own" and "run" the new instance <INST_OWNER>.

<INST_OWNER> should create the $USER_INSTALL_ROOT directory and open up permissions on it (or root could create it and chown it to <MAIN_OWNER>).

         mkdir $USER_INSTALL_ROOT
         chmod 777 $USER_INSTALL_ROOT

We are opening up the permissions because <MAIN_OWNER> needs to create the new instance there.  After it is created we will re-create it with <INST_OWNER> as the owner.

You have to be <MAIN_OWNER> to perform the following actions.

 1. Put $WAS_HOME/bin in your search path (wsinstance.sh depends on this).

 2. Download the file http://admc.com/blaine/howtos/wsinst-noq.props to the directory $WAS_HOME/bin/wsinstance, and rename it to portdef.props <INST_NODE>_<INST>_portdef.props, like

              cd $WAS_HOME/bin/wsinstance
              wget http://admc.com/blaine/howtos/wsinst-noq.props
              mv wsinst-noq.props $WAS_HOME/bin/wsinstance/<INST_NODE>_<INST>_portdef.props

N.b.

 1. This filename uses an inverted instance name.  The full instance name is <INST>_<INST_NODE>, but the props file uses <INST_NODE>_<INST>.

 2. The WS docs incorrectly state the the props file uses the former, but it actually uses the latter.

 3. (In general, always be careful of what order is required in different circumstances, because they do vary).

Now edit the new file and change the port numbers to any available ports that you want > 1023.

Many of these ports are very important. The bootstrap port (BOOTSTRAP_ADDRESS) must be supplied to the dumpNameSpace.sh command (with the -port switch). HTTP_TRANSPORT_ADMIN is the Administrative console port. (in this example, you'd use https://localhost:1302/admin for the Admin server). HTTP_TRANSPORT is the direct HTTP ports to use the App Server (as opposed to going through a standalone web server). The default ports for the default instance are listed at the bottom of http://publib7b.boulder.ibm.com/wasinfo1/en/info/aes/ae/rins_portnumber.html. (Don't use these ports, since that would prohibit the main instance from running at the same time as this new instance.)

From the directory $WAS_HOME/bin/wsinstance, run the command

         ./wsinstance.sh -name <INST> -path $USER_INSTALL_ROOT -host <INST_NODE> -create

(N.b. you specify the node name, not the host name.  The switch name and the WAS docs are wrong). Watch for error messages. (If you mess up, you must run

         ./wsinstance.sh -name <INST> -path $USER_INSTALL_ROOT -host <INST_NODE> -delete

to remove the bad instance before recreating).

Fix perms so that <INST_OWNER> can access what he needs. $WAS_HOME and the following subdirs of $WAS_HOME must be rx-able to <INST_OWNER>:

         bin, java, properties, deploytool, config, lib, classes, null, samples, web.

And the same for bin/setupCmdLine.sh. (Most of these will probably be ok since the instance user is in the group <MAIN_OWNER>, but that depends on the umask and env. when install was run).

Now you need to change ownership of the entire new $USER_INSTALL_ROOT directory branch to <INST_OWNER>.  There are many ways of doing this, depending on whether you have root privileges. It's easiest to run

         chown -R <INST_OWNER>:<INST_OWNER> $USER_INSTALL_ROOT

as root. If you don't have root perms, then become <INST_OWNER> and copy it, preserving the permissions, like

         mv -f $USER_INSTALL_ROOT $USER_INSTALL_ROOT.orig
         # Don't omit the trailing slash in the next command!
         rsync -avH $USER_INSTALL_ROOT.orig/ $USER_INSTALL_ROOT
         ls -l $USER_INSTALL_ROOT   # Just to verify

         # Then as user <MAIN_OWNER>...
         rm -rf $USER_INSTALL_ROOT.orig/*
         # And back as <INST_OWNER>...
         rmdir $USER_INSTALL_ROOT.orig

(Use "cp -R..." or "find... | cpio -pdm..." or something like that if you don't have rsync installed).  Yes, it is much easier if you have root privileges. Restore secure permissions on $USER_INSTALL ROOT.  Run

         chmod 755 $USER_INSTALL_ROOT

Make sure that $USER_INSTALL_ROOT/config and all parent directories are rx-able to all (<MAIN_OWNER> and the web server user need access). [EDITOR:  hmmn.  I don't think that <MAIN_OWNER> needs access.] In particular, if $USER_INSTALL_ROOT is under your home directory, make sure that your home directory is readable and executable to <MAIN_OWNER> and the web server user.

Instance Configuration
----------------------

Become <INST_OWNER>.  We will test things out, install a little .ear, and generate our web server plugin config file.

Back up, then edit the file $USER_INSTALL_ROOT/config/cells/<INST_NODE>/nodes/<INST_NODE>_<INST>/servers/server1/server.xml. In the line containing 'EndPoint_3', change the value of host from "" to "localhost". This restricts use of the AdminConsole to your local server. Or, cut and paste the following command and change the <> variables to your values.

     perl -pi.orig -we 's:\"\":"localhost": if /\bEndPoint_3\b/;' $USER_INSTALL_ROOT/config/cells/<INST_NODE>/nodes/<INST_NODE>_<INST>/servers/server1/server.xml

Export the variable $WAS_HOME

         # Substitute your real $WAS_HOME path.
         export WAS_HOME=$WAS_HOME     # If you're running korn or bash shell

Source $USER_INSTALL_ROOT/bin/setupCmdLine.sh

         . $USER_INSTALL_ROOT/bin/setupCmdLine.sh

and run

         $WAS_HOME/bin/startServer.sh server1
         # Next command is just to verify that JNDI is working
         $WAS_HOME/bin/dumpNameSpace.sh -port 1306 (where the number is the BOOTSTRAP_ADDRESS above).
         http://localhost:1302/admin (where the number is the HTTP_TRANSPORT_ADMIN above).

Log into the Admin Console with your browser using any user name. No password is required.

In the left panel, click on the + to the left of "Applications". Click on the "Install New Applications" link. Use the "Browse" button and navigate to select the file $WAS_HOME/config/cells/<INST_NODE>/applications/ivtApp.ear/ivtApp.ear. Click "Next", click "Next", click the summary "Step", click "Finish", click "Save to Master Configuration", click "Save". If things get stuck on the "Installing" screen, then

  * Don't worry, this always happens on under-powered servers (and sometimes on perfectly healthy ones).

  * Click on the Save menu item to the top left.

  * Click the "Save" button.

In the left panel, click on the + to the left of "Environment". Click on the first link under that, "Update Web Server Plugin". Click the "OK" button. Click the "Logout" menu item up top.

Make sure that the UNIX user who the web server runs as has read access to the file $USER_INSTALL_ROOT/config/cells/plugin-cfg.xml.

         ls -l $USER_INSTALL_ROOT/config/cells/plugin-cfg.xml

If you are running your web server on a port other than 80, you will need to change the value "80" to the correct port at the top of $USER_INSTALL_ROOT/config/cells/plugin-cfg.xml.

Manual Web Server Configuration
-------------------------------

Skip this subsection if you found the directives above in your web server config files. This section explains how to manually add the needed directives if the WAS installation program didn't add the lines to your web server config files.

Final verification
------------------

Restore the permissions of the web server configuration file(s) which you opened up back at the beginning.

Stop and restart the web server (as root).

If the startup fails with an error about writing to the log file, then this problem is most likely caused by a NFS mount of $IWS_INST_HOME/logs. (If you made the log file while mucking around, remove it). Open up permissions on that directory to 777, then start up the web server, then restore the permissions on the directory to 755. Since the web server user created the file when you started the server, it will have write permissions on the file for now on.

Use your browser to visit

         http://localhost:1303/ivt/ivtDate.jsp (to test IVT application)
         http://localhost/ivt/ivtDate.jsp (to test the web server plugin)

(Note that only applications available at this point at the IVT application which we just installed, and Admin Console application. Also note that the "ivt.sh" verified program does not work with alternative instances, even though we have the IVT application installed.)

Environment Setup
-----------------

This section is purely optional. It sets up your environment so that you can log in as <INST_OWNER> and immediately run (almost) all of the WAS commands without having to type in any environmental settings.

If <INST_OWNER> is a new account and has Korn as the login shell, just download http://admc.com/blaine/howtos/was.profile and http://admc.com/blaine/howtos/was.kshrc and rename them to .profile and .kshrc in <INST_OWNER>'s home directory. Then edit .profile to enter your local path(s) as the file says to.

If you use some other shell, or if you have existing .profile and/or .kshrc file(s) that you don't want to clobber, then merge the contents of the downloaded files into your existing .profile and .kshrc files.

After you do this, verify that you can log in as <INST_OWNER> and successfully run startServer.sh server1 and startServer.sh server1 (without making any manual environment settings).

You can follow the exact same procedure for <MAIN_OWNER> to make it convenient for people to log in as that user (or su or sudo) and manage the main instance.

If you have root privileges and you have completed the environmental setup explained above, then you use a WAS init script.  The remaining steps in this section need to be performed as root.  Download the init script and set execute permissions.

         cd /etc/init.d
         wget http://admc.com/blaine/howtos/was
         chmod 744 /etc/init.d/was

(The IBM-supplied init script, rc.was, doesn't work for a normal stand-alone node setup).

Edit /etc/init.d/was and type in the value for <INST_OWNER> as instructed. Verify that it works by running

         /etc/init.d/was restart

If you want this WAS instance to be automatically started and stopped during system bootups and shutdowns, then

See my HOWTO about using and adminstering WAS at http://admc.com/blaine/howtos/ws50.html.

Setting up Oracle Data Sources
******************************

(Just like all other operations in the Admin Console, after you make a set of changes, make sure you commit the changes by clicking a "Save" link, then the "Save" button.)

The instructions in the WebSphere docs for setting up shared libraries for DB drivers are wrong.  They work for the first-level shared libocijdkb9.so, but not for the others.  So, forget setting $LIBPATH or any other variables.  Don't even waste your time setting the Native Library Path for the Provider.  Just export ORACLE_HOME and LD_LIBRARY_PATH=$ORACLE_HOME/lib before starting WAS. (Alternatively, you could copy the 3 needed .so's to a system lib location or add $ORACLE_HOME/lib as a system lib location). Use Admin Console to perform the following actions. Environment/Manage-WebSphere-Variables.  Set

         ORACLE_JDBC_DRIVER_PATH to the value of $ORACLE_HOME/jdbc/lib.

Resources/JDBC Providers

 1. Add the Oracle JDBC oci8 Driver.  (Use whichever scope you prefer, but be aware that this determines the scope of all DataSources you create using this Provider).

 2. Make sure that Classpath is set to ${ORACLE_JDBC_DRIVER_PATH}/classes12.zip.

 3. Make sure that Implementation Classname is set to oracle.jdbc.pool.OracleConnectionPoolDataSource.

         Resources/JDBC Providers/Oracle JDBC oci8 Driver/DataSources

 1. New.  Set any name.  JNDI name should begin with "jdbc/".  If "Statement Cache Size" is empty, set it to "10".  Leave everything else at default settings and hit "Apply".

 2. Then hit "J2C Authentication Data Entries" (at bottom of the data source edit page) and create an alias for a name/password pair.

 3. Edit the DataSource to add this alias for Component-managed or Container-managed Authentication Alias.  (If you use the former, then your apps have to set "Res. Auth." to "Application"; if you use the latter, then your apps have to set "Res. Auth." to "Container-managed".

 4. Hit "Custom Properties" (at bottom of the data source edit page). Click on the link "URL".  Enter an Oracle oci8 URL like jdbc:oracle:oci8:@keeper.

Important Files
***************

You may want to put sym-links to these in a main directory like $USER_INSTALL_ROOT or your home directory.

         $USER_INSTALL_ROOT/config/cells/<MAIN_NODE>/nodes/<INST_NODE>_<INST>/servers/server1/server.xml
         $USER_INSTALL_ROOT/config/cells/<MAIN_NODE>/virtualhosts.xml.
         $USER_INSTALL_ROOT/logs/server1/SystemErr.log
         $USER_INSTALL_ROOT/logs/server1/SystemOut.log
         $USER_INSTALL_ROOT/config/cells/plugin-cfg.xml.

Contrary to common sense, SystemOut.log has most of WAS's "error" messages. It's unfortunate that this important log file gets cluttered with trace information every time that the Admin Console is used. (Note that many files in $USER_INSTALL_ROOT/logs are in binary format).