Friday, June 7, 2013

Check Percentage of CPU usage - Linux

Hi folk,

A couple of days ago, I did not know that one of my CPU was running at 100% capacity because a process was "hung".





So, I had to make a Kill -9, but to my surprise, the next day I had the same problem.

Once I solved the problem I kept thinking, how many times did this happen with other process on my laptop and I have not noticed?

To stay informed I have created the following bash script to check the top 10 processes.

#!/bin/sh
# Check Percentage of CPU usage
# Jorge Iglesias

# Skip first lines from top command with head -17
# PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
# Select top ten proccess with -n 10
top -n1 -b | head -17 | tail -n 10 > top.txt

while read line
do
    ind=0
    pid=""

    for line in $line;
    do
        if [ $ind -eq 0 ]    # index of PID
        then
            pid=$line
          
        fi

        if [ $ind -eq 8 ]    # index of %CPU
        then
            min=80.0     # min value alert
            if [ 1 -eq `echo "${line} > ${min}" | bc` ]
            then
                notify-send -t 5000 -i error "Percentage of CPU usage" "The %CPU usage for process <b>id $pid</b> is <b>$line%</b> \n\nPlease review and kill the process."      
            fi
            break;         # break line, only read to %CPU value
        fi
        ((ind+=1))
    done
done < top.txt

rm top.txt                # delete temp file


I scheduled the script to run every 10 minutes and when it detects that a process up to 80% then is reported on screen.

 
You can watch the process using the top command.


Now, you decide if you really want to "kill" the process or not :-)

I hope this helps!!

Cheers.

Monday, May 6, 2013

Notify-send Java Class for Linux

Hi folk,

I will share this Java class that I use to display tools information on my Linux operating system.

Sample:




Notify-send is a little, simple On-Screen Display application. It uses the notify bubble pop-up Linux system.

 /**
 * Utils
 *
 * Created on Nov 25, 2010
 *
 * @version 1.0
 * @author Jorge Iglesias, (jorge.iglesias@es.ibm.com)
 *
 * @ Copyright IBM Software Services Rational Spain. 2011. All rights reserved.
 */

package com.ibm.issr.util.linux;

import java.io.IOException;

public class Notify {
  
    public static void sendInfo(String text) {
        send("info",text);
    }

    public static void sendError(String text) {
        send("error",text);
    }

    private static void send(String type, String text) {
        String[] command = new String[] { "notify-send", "-t", "20000", "-i", type, text };
        try {
            Runtime.getRuntime().exec(command);
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }
}


Monday, February 25, 2013

WebSphere launch commands utility for Linux Test Environment

Hi folk,

Right now, I'm working on a project where I have to do performance tests in J2EE applications with continually stopping and starting the application server.

I created a bash script based on a set of WAS command line for people with short memory, like me ;-)



I want to share the script that we use to facilitate our work. 

I hope this helps.
 
#!/bin/sh
# Launch Websphere Application Server - HTTPServer
# Jorge Iglesias

# Note: Launch with root permission
if [ "$(whoami)" != 'root' ]; then
    echo "You have no permission to run $0 as non-root user"
        exit 1;
fi

# Define variables
WAS_DMGR=dmgr
WAS_SERVER_NODE=nodeagent
WAS_SERVER=server1
PATH_WAS=/opt/IBM/WebSphere/AppServer
PATH_WAS_DMGR_PROFILE=${PATH_WAS}/profiles/Dmgr01
PATH_WAS_SERVER_PROFILE=${PATH_WAS}/profiles/AppSrv01
LOG_WAS_DMGR=${PATH_WAS_DMGR_PROFILE}/logs/$WAS_DMGR/SystemOut.log
LOG_WAS_SERVER_NODE=${PATH_WAS_SERVER_PROFILE}/logs/$WAS_SERVER_NODE/SystemOut.log
LOG_WAS_SERVER=${PATH_WAS_SERVER_PROFILE}/logs/$WAS_SERVER/SystemOut.log
WAS_USER=wasadmin
WAS_PWD=passw0rd
PATH_HTTPSERVER=/opt/IBM/HTTPServer

# Funciones
OpenLogFile ()
{
    # Check params:
    # LOG_FILE: log file
    # LOG_FILE_TITLE: log file title

    proc=$(xlsclients -a | grep SystemOut.log)

    if [ -z "${proc}" ]
    then
    {
        TAIL_FILE="tail -f ${LOG_FILE}"
        gnome-terminal --title "${LOG_FILE_TITLE}" -e "${TAIL_FILE}" &
    }
    fi
}

CloseLogFile ()
{
    proc=$(xlsclients -a | grep gnome-terminal | grep SystemOut.log)

    if [ ! -z "${proc}" ]
    then
    {
        kill -9 `ps -eaf | grep gnome-terminal | grep SystemOut.log | awk '{ print $2 }'`
    }
    fi
}

InitServer ()
{
    # Check params:
    # TMP_CMD: command to exec
    # TMP_FILE: pid file
  
    echo "Starting server: $TMP_FILE"

    # exists PID file?  
    if [ -f $TMP_FILE ]
    then
    {
        PID=`cat $TMP_FILE`
         echo "Server with PID:"$PID

            echo "Restart server (y/n)?"

        printf "> "
        read quest
        case $quest in
          y)
            StartServer;;
        Y)
            StartServer;;
        N)
            ;;
          n)
            ;;
        esac

    }
    else
    {
        StartServer
    }  
    fi
}

StartServer()
{
    # Start server
    # &, run background
    # $TMP_CMD &      
    $TMP_CMD      
  
    IS_STARTED=0
    while [ $IS_STARTED = 0 ]
    do {
        # wait one second
        sleep 1
        if [ -f $TMP_FILE ]
        then
        {
            IS_STARTED=1
        }
        else
        {
            IS_STARTED=0
        }
        fi
    }
    done
}

StopServer ()
{
    # Check params:
    # TMP_CMD: command to exec
    # TMP_FILE: pid file

    echo "Stoping server: $TMP_FILE"

    # exists PID file?  
    if [ -f $TMP_FILE ]
    then
    {
        # Stop server
        # &, run background
        # $TMP_CMD &      
        $TMP_CMD      
      
        IS_STARTED=0
        while [ $IS_STARTED = 0 ]
        do {
            # wait one second
            sleep 1

            if [ -f $TMP_FILE ]
            then
            {
                IS_STARTED=0
            }
            else
            {
                IS_STARTED=1
            }
            fi
        }
        done
    }
    else
    {
         echo "Server stopped."
    }  
    fi
}

SetStartDmgrParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_DMGR"
    LOG_FILE=$LOG_WAS_DMGR
    TMP_CMD=$PATH_WAS_DMGR_PROFILE/bin/startManager.sh
    TMP_FILE=$PATH_WAS_DMGR_PROFILE/logs/$WAS_DMGR/$WAS_DMGR.pid
}

SetStartAppSrvNodeParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_SERVER_NODE"
    LOG_FILE=$LOG_WAS_SERVER_NODE
    TMP_CMD=$PATH_WAS_SERVER_PROFILE/bin/startNode.sh
    TMP_FILE=$PATH_WAS_SERVER_PROFILE/logs/$WAS_SERVER_NODE/$WAS_SERVER_NODE.pid
}

SetStartAppSrvParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_SERVER"
    LOG_FILE=$LOG_WAS_SERVER
    TMP_CMD="$PATH_WAS_SERVER_PROFILE/bin/startServer.sh server1"
    TMP_FILE=$PATH_WAS_SERVER_PROFILE/logs/$WAS_SERVER/$WAS_SERVER.pid
}

SetStopDmgrParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_DMGR"
    LOG_FILE=$LOG_WAS_DMGR
    TMP_CMD="$PATH_WAS_DMGR_PROFILE/bin/stopManager.sh -username $WAS_USER -password $WAS_PWD"
    TMP_FILE=$PATH_WAS_DMGR_PROFILE/logs/$WAS_DMGR/$WAS_DMGR.pid
}

SetStopAppSrvNodeParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_SERVER_NODE"
    LOG_FILE=$LOG_WAS_SERVER_NODE
    TMP_CMD="$PATH_WAS_SERVER_PROFILE/bin/stopNode.sh -username $WAS_USER -password $WAS_PWD"
    TMP_FILE=$PATH_WAS_SERVER_PROFILE/logs/$WAS_SERVER_NODE/$WAS_SERVER_NODE.pid
}

SetStopAppSrvParams ()
{
    LOG_FILE_TITLE="Fichero de trazas: $WAS_SERVER"
    LOG_FILE=$LOG_WAS_SERVER
    TMP_CMD="$PATH_WAS_SERVER_PROFILE/bin/stopServer.sh $WAS_SERVER -username $WAS_USER -password $WAS_PWD"
    TMP_FILE=$PATH_WAS_SERVER_PROFILE/logs/$WAS_SERVER/$WAS_SERVER.pid
}

StartWebserver ()
{
    echo "Start HTTPServer"
    TMP_CMD="$PATH_HTTPSERVER/bin/apachectl -k start"
    $TMP_CMD
}

StopWebserver ()
{
    echo "Stop HTTPServer"
    TMP_CMD="$PATH_HTTPSERVER/bin/apachectl -k stop"
    $TMP_CMD
}

ExitProcess ()
{
    # TODO
    # Check StopServer

    # TODO
    # Check CloseLogFile
      
    exit 1;
}

ShowMenu ()
{  
    # clear  
    echo ""
    echo "-------------------------"
    echo "* Process - Launch WAS Menu"
    echo "1 - Start dmgr-nodeagent-server1-httpserver"
        echo "2 - Start dmgr"
        echo "3 - Start nodeagent"
        echo "4 - Start server1"
        echo "5 - Stop dmgr"
        echo "6 - Stop nodeaget"
        echo "7 - Stop server1"
    echo "8 - Stop httpserver-server1-nodeagent-dmgr"
    echo "-------------------------"
        echo "10 - Start HTTPServer"
        echo "11 - Stop HTTPServer"
    echo ""

        echo "99 - Exit"

    printf "> "
    read num
    case $num in
      1)
        SetStartDmgrParams;      
        OpenLogFile;
         InitServer;

        SetStartAppSrvNodeParams;
        OpenLogFile;
         InitServer;

        SetStartAppSrvParams;
        OpenLogFile;
         InitServer;

         StartWebserver;;
    2)
        SetStartDmgrParams;      
        OpenLogFile;
         InitServer;;
    3)
        SetStartAppSrvNodeParams;
        OpenLogFile;
         InitServer;;
    4)
        SetStartAppSrvParams;
        OpenLogFile;
         InitServer;;
    5)
        SetStopDmgrParams;      
        CloseLogFile;
        StopServer;;
    6)
        SetStopAppSrvNodeParams;
        CloseLogFile;
        StopServer;;
    7)
        SetStopAppSrvParams;
        OpenLogFile;
         StopServer;;
    8)
         StopWebserver;

        SetStopAppSrvParams;
        CloseLogFile;
        StopServer;

        SetStopAppSrvNodeParams;
        CloseLogFile;
        StopServer;

        SetStopDmgrParams;      
        CloseLogFile;
        StopServer;;
    10)
         StartWebserver;;
    11)
         StopWebserver;;
      99)
        ExitProcess;;
    esac
  
    # back to menu
    ShowMenu
}

ShowMenu

Monday, January 7, 2013

Rational Team Concert - Manual failover techniques

Deploy each of the jts.war, ccm.war, admin.war on their respective Primary and Backup servers so that you can use idle standby as a strategy for failover in high availability environments.

The idle standby configuration enables recovery from failover to help ensure minimal impact on business operations during planned or unplanned server outages.

This post covers implementation of the idle standby configuration with Jazz™ Team Server using WebSphere® Application Server.

Important: Jazz Team Server applications allow only a single server to be active at any one time to a repository; therefore, the backup (or Idle) server is configured to never run asynchronous (or background) tasks. If a switch is made to the backup server, you must plan to bring the primary server back up as quickly as possible.

The topology diagram illustrates the configuration for basic high availability when using idle standby. In the following figure, the IBM® HTTP Server is used to direct incoming traffic to one of the two WebSphere Application Servers, Primary Server A or Backup Server B.


Note: For both cold standby or idle standby, you must ensure that the Primary server is completely stopped prior to failover. Also be sure that there are no running processes that are interacting with the database.

For the example:
Server:
- IBM HTTP Server 7.0 Fix Pack 23
Primary Server A:
- WebSphere Application Server 7.0 Fix Pack 23
Backup Server B:
- WebSphere Application Server 7.0 Fix Pack 23
 

Installing and configuring a Jazz application on primary and backup servers

To install and configure copies of the RTC applications on the primary and backup servers, see Setting up a WebSphere® Application Server and Deploying the Rational solution for Collaborative Lifecycle Management applications on WebSphere Application Server.

For the example:
Primary Server A: server1
Backup Server B: server2


- After deploying the web applications, configure the primary server by following the steps: in Running the setup wizard (Custom setup).
Important: Do not run the Jazz Team Server setup wizard on the backup server. It must be run only on the primary server.
- Set the public URL to point to the IBM HTTP Server and not the application server.
- After installing and configuring the primary server, shut it down, and copy its configuration files into the backup server installation.

Configuring high availability for both primary and backup servers

Examples in this post are for the jts.war application. You can use the same procedure for the ccm.war and admin.war applications.

The jts.war application is typically installed with a single application server as its target. With the introduction of the Web server, the application container configuration must be modified to allow routing through the Web server. 

To modify the application:

  1. In the WebSphere Console, click the jts.war application link under Enterprise Applications.
  2. Select Manage Modules.
  3. Select the check box for the jts.war application module.
  4. In the list of clusters and servers, choose both the Web server and application server, and then click Apply.
  5. Click OK, and then click Save changes.
  6. Restart the jts.war application.
Reconfigure both the primary and backup Jazz™ Team Server instances to reference the same location for the full text index.
To keep the index up to date and available to both the primary and back up servers, update the com.ibm.team.fulltext.indexLocation and com.ibm.team.jfs.index.root.directory properties in the teamserver.properties files on both the primary and backup servers to store the index on a shared drive.

This property setting is an example of what you can see on Linux:
For JTS:
com.ibm.team.fulltext.indexLocation=/opt/FACTORY/rtc/conf/jts/sharedIndex/workitemindex
com.ibm.team.jfs.index.root.directory=sharedIndex

For CCM:
com.ibm.team.fulltext.indexLocation=/opt/FACTORY/rtc/conf/ccm/sharedIndex/workitemindex
com.ibm.team.jfs.index.root.directory=sharedIndex

Turning off asynchronous tasks on the backup server

To avoid any possible data contention between the two running Jazz Team Servers, asynchronous tasks must be turned off on the backup server.

Add the following line to the teamserver.properties file on the Backup server:
com.ibm.team.repository.scheduler.migration.mode.enabled=true

Restart the jts.war application on the backup server.

Note: Ensure that the preceding property is preserved on the backup server after any updates are applied to the asynchronous task that changes the configuration file on the primary server.

Note: When asynchronous tasks are turned off, the backup server will not run the asynchronous tasks. If circumstances dictate that the backup server is used as the primary server for an extended period of time, this property should be reset to false to enable the background tasks in the Advanced Properties. Make sure to set it to true before restarting the primary server.

Editing the Web server plugin_cfg.xml file for idle standby

Each time a WebSphere Application Server is configured to route requests through a Web server to an application server, the Web server plugin.xml file is updated with the connection information for that application server. Replace and then edit the following section of the plugin-cfg.xml file on the Web server to complete the configuration.
This plugin-cfg.xml file is located in the plugin\config\webserver1 folder of the Web server, where webserver1 is the name that you assigned.

Synchronizing the configuration files for the primary and backup servers

Customized server properties are not automatically synchronized between the primary and backup servers. In order to ensure that the backup servers have consistent configuration attributes, all customized settings must be propagated to the backup servers before they become active.
Periodically backing up from the primary server and restoring those files to the backup server are sufficient to keep customizable server properties in sync.

Note: If there are any configuration changes that require that you restart the primary server, then the backup server must also be restarted to get these changes.

This list includes configuration files that might need to be synchronized between the primary and backup servers.

 Jazz Team Server
        <JazzInstallDir>/server/conf/jts/teamserver.properties
        <JazzInstallDir>/server/conf/jts/log4j.properties

 CCM
        <JazzInstallDir>/server/conf/ccm/teamserver.properties
        <JazzInstallDir>/server/conf/ccm/log4j.properties

  ADMIN
        <JazzInstallDir>/server/conf/admin/friends.rtf
        <JazzInstallDir>/server/conf/admin/log4j.properties
        <JazzInstallDir>/server/conf/admin/admin.properties


Verifying the server setup for manual failover ability

To verify the manual failover ability of the WebSphere Application Server, stop the primary server and start the backup server.




Login to see the status summary in JTS:




Detecting failure on the primary server

Important: You must ensure that the primary server is completely stopped before switching over to the failover server. Also be sure that there are no running processes that are interacting with the database.

To achieve high availability, you must know when the primary server is down. This knowledge is especially important for this basic high-availability solution, which does not support automatic failover of the primary server to the backup server.

The process of detecting a failed server is a critical and time-sensitive task. Several factors can indicate that a server has failed, such as network problems, configuration problems, application overloading, or user error. Whatever solution you choose to detect server failures, you must ensure that the alert is as rapid as possible.

Additional information

All documentation contained in the post, is based on the online help on Installing the Rational solution for CLM (Manual failover techniques).

Thursday, September 20, 2012

How to delete a profile from a IBM WebSphere Application Server

1) Location:

<root>\AppServer\bin\manageprofiles.bat

syntax:

manageprofiles.bat -delete -profileName <profile_name> (case sensitive commands)

Note: This used to be wasprofile.bat in version 6.0.x and is depricated in 6.1. The Windows service for the profile will have been set to disabled now.

2) Delete the profile folder

e.g <root>\ApplicationServer\profiles\<profile_name>

3) Validate the profile registry and lists the non-valid profiles that it purges

manageprofiles.bat -validateAndUpdateRegistry


4) Remove the Windows service that is set to run the profile.

WASService.exe -remove service_name

e.g If the service name is "IBM Websphere Application Server V6.1 - <computername>Node<xx>"

Then the command will be:

WASService.exe -remove "<computername>Node<xx>"

Note: The same procedure applies to Linux running the correct script

Wednesday, September 19, 2012

Get Parent workitem on save precondition

Nice snippet found in jazz.net!!
 
public IWorkItemHandle findParent(AdvisableOperation operation) throws TeamRepositoryException {
Object data = operation.getOperationData();

if (data instanceof ISaveParameter) // from Workitem -> save operation
{
ISaveParameter saveParameter = (ISaveParameter) data;
IWorkItemReferences ref = saveParameter.getNewReferences();
List<IEndPointDescriptor> types = ref.getTypes();
for (IEndPointDescriptor desc : types)
{
if (desc.getId().equalsIgnoreCase("parent")) // "parent" is an RTC/Jazz string ID
{
List<IReference> refList = ref.getReferences(desc);

if (refList.size() > 0)
{
IReference iRef = refList.get(0); // Only one parent
Object obj = iRef.resolve();
if (obj instanceof IWorkItemHandle) // Only looking for Workitems.
{
return (IWorkItemHandle) obj;
}
else
return null;
}
else
return null;
}
}
}
return null;


The WorkItemEndPoints are only a subset. 

Example for requirements: Use the WorkItemLinkTypes and the ILinkRegistry.
ILinkTypeRegistry.INSTANCE.getLinkType(WorkItemLinkTypes.IMPLEMENTS_REQUIREMENT).getTargetEndPointDescriptor() 

Monday, September 17, 2012

RTC - Import plugins for Jetty based launches

Always the same thing happens to me when I prepare a development environment for RTC. Where are the plugins for Jetty?

There are three plugins you will need to import (one from the RTC SDK and two from your installed server).




Anyway, with this diagram I hope I never forget import the plugins!


Wednesday, July 25, 2012

Search files within a ZIP archive using zipgrep tool

Bash script that search files within a ZIP archive for lines matching given string or pattern using zipgrep tool.

#!/bin/sh
# zipgrep Util 0.1
# Result ziprep by directory file
# @Jorge Iglesias

# Note: root users
if [ "$(whoami)" != 'root' ]; then
    echo "You have no permission to run $0 as non-root user"
        exit 1;
fi

clear
echo "zipgrep Util 0.1"
echo "Jorge Iglesias"
echo "----------------"

echo "Input pattern"
printf "> "
read pattern

echo "Input directory grep"
printf "> "
read directory

echo "Input directory output results"
printf "> "
read directoryOut

# Control will enter here if $DIRECTORY doesn't exist.
if [ ! -d "$directoryOut" ]; then
    mkdir $directoryOut
fi

cd $directory


index=0

for file in `dir -d *` ; do
    index=$((index+1))
    zipgrep $pattern $file > $directoryOut/$file.out
    # Control file size and delete files with size 0
    fileSize=$(stat -c "%s" $directoryOut/$file.out)
    if [ $fileSize = 0 ]; then {
        index=$((index-1))
        rm $directoryOut/$file.out
    }
    fi
done

echo "Pattern found in $index files."

Monday, July 23, 2012

How to convert .ico files to .png - Linux

# convert start_server.ico start_server.png
bash: convert: command not found...
Install package 'ImageMagick' to provide command 'convert'? [N/y]
 * Running..
 * Resolving dependencies..
 * Waiting for authentication..
 * Waiting in queue..
 * Resolving dependencies..
 * Downloading packages..
 * Testing changes..
 * Installing packages..
 * Scanning applications..

# convert start_server.ico start_server.png

Wednesday, July 11, 2012

Setting up a WebSphere Application Server 8.0 for Collaborative Lifecycle Management 4.0

Environment:
- Windows 7 Enterprise sp1 64 bit
- IBM WebSphere Application Server 8.0.0.3
- IBM Rational Team Concert 4.0

Using the Integrated Solutions Console for the server Ensure you have completed the following tasks:

- The Java 2 Security option must be turned off. If this option is turned on in WAS, the web application will not start.
  1. Click Security > Global security.
  2. Under Java 2 security, clear the check box for Use Java 2 security to restrict application access to local resources.
  3. Ensure that the Enable administrative security and Enable application security check boxes are selected.

  

- Ensure that the Use available authentication data when an unprotected URI is accessed application server security setting is selected.
  1. Click Security > Global security > Web and SIP security > General settings.
  2. Click the Use available authentication data when an unprotected URI is accessed check box.
  3. Click OK and Save directly to the master configuration.



Note: This document does not provide details for configuring WebSphere authentication or SSL, which is a complex topic. Detailed information about the various authentication and encryption options is covered in the WebSphere Application Server InformationCenter.

Procedure
  1. Jazz Team Server requires several specific settings on the Java Virtual Machine in which it runs. To set these properties click Servers > Server Types > WebSphere application servers > Server1
  2. Under Server Infrastructure, click Java and Process Management > Process definition.
  3. Under Additional Properties, click Java Virtual Machine.
  4. Add the value 4096 to Initial Heap.
  5. Add the value 4096 to Maximum Heap Size. (The figure here is only a suggestion; set the value according to your environment. A typical medium-size team can use a value of 4096 MB, providing 4 GB of heap memory for the Jazz Team Server process on a 64-bit computer. It is important to use the same amount for Initial and Maximum heap sizes)
  6. In the Generic JVM arguments field, type the following line (for Windows):
    
    
    -Xmx4g -Xms4g -Xmn512m
    -Xgcpolicy:gencon -Xcompressedrefs
    -Xgc:preferredHeapBase=0x100000000
     
  7. Click Apply, and then click Save directly to the master configuration.
  8. Add these custom properties:  
- Name: JAZZ_HOME, Value: file:///JazzInstallDir/server/conf
- Name: java.awt.headless, Value: true- Name: org.eclipse.emf.ecore.plugin.EcorePlugin.doNotLoadResourcesPlugin, Value: true
- Name: log4j.configuration, Value: file:///JazzInstallDir/server/conf/startup_log4j.properties



Note: If you are connecting to an Oracle database or SQL Server database, you have to add:
- Name: ORACLE_JDBC_DRIVER_FILE, Value: Absolute path to the JDBC driver/ojdbc6.jar
- Name: SQLSERVER_JDBC_DRIVER_FILE, Value: Absolute path to the JDBC driver/sqljdbc4.jar

Click Save directly to the master configuration and restart the application server.

Information source:
-  IBM Rational Help - Setting up a WebSphere Application Server



Thursday, June 21, 2012

Open Services Gateway Initiative (OSGi)

"OSGi is a component framework specification that brings modularity to the Java platform. OSGi enables the creation of highly cohesive, loosely coupled modules that can be composed into larger applications. What’s more, each module can be individually developed, tested, deployed, updated, and managed with minimal or no impact to the other modules."
Craig Walls,
Modular Java