Tuesday, December 09, 2008

Beyond Code : Distinguish Yourself

“The illiterate of the 21st century will not be those who cannot read and write, but those who cannot learn, unlearn, and relearn.”
- Alvin Toffler

I am a little late in posting this on my Blog ( very late, in these times of Twitter & Plurk ! ), but here's the good news :-

Rajesh Setty ( of the LifeBeyondCode Blog fame ) has decided to give away the PDF version one of his famous books - Beyond Code - FREE as a ThanksGiving gift to all his readers !

The news will definitely be stale by now, but I want to post this note on my blog for those who haven't caught the wave yet.

Well, beyond this, I have nothing more to tell - just download the PDF & happy reading !




Thursday, October 23, 2008

“Error (n, m): identifier OracleJspRuntime not found”
- Jdeveloper Error.

You might have noticed this error sometimes in your Project.

The solution to this error is simple – you just need to add Jdeveloper’s “JSP Runtime” standanrd library to your Project Classpath – here are the steps to do it in Jdeveloper 10.1.3 : -

1. Right click on the Project & select the “Project Properties” option.
2. You can see the “Project Properties window.
3. Select the “Libraries” option. You can see the various configuration options for Project Libraries.
4. Click on the “Add Library” button. You can see the “Add Library” window.
5. Select “JSP Runtime” from the list of libraries & click on the “Ok” button.
6. “Make” / “Rebuild” your project.
7. You can see that you no longer see this error.


Thanks once again to the people who have discussed this at Oracle Technology Network Forums & various Bloggers who have spoken about it.

I am just posting this in my Blog for my reference.

JDeveloper JSP files must reside in the server root directory or a subdirectory

“Error: JSP files must reside in the server root directory or a subdirectory”

- Jdeveloper Error

How often have you struggled to specify a different folder for your JSPs, instead of JDeveloper’s default folder “public_html”?

I struggled with this option today – I inherited an application source code that I had to analyze & look our for ways to improve readability of the code. The application source code had been developed without an IDE (!), using our favorite ANT as the build tool.

I easily imported this code into Jdeveloper 10.1.3 (using NEW -> Project from Source Code). However, I noticed that I frequently hit the error mentioned above.

After Googling a bit, I stumbled upon a few OTN forum posts. I found out that the solution is rather simple.

1. Click on the “Tools” option in the Jdeveloper Menu.
2. Select the “Project Properties” option from the drop down.
You can see the “Project Properties” Window.
3. Click on the “+” in the “Web Application” section to expand the options.
4. You can see the “HTML Root Directory” option.
5. Specify the Root Directory of your JSP Pages here & click on the Ok button.
6. “Make” or “ReBuild” your project now.
7. You can notice that you no longer see this error.


The supplied JDeveloper help pages are slightly confusing – they don not mention that the “HTML Root Directory” option is present under the “Web Application” section.

Tuesday, October 14, 2008

Oracle UCP : Hello World

" The Universal Connection Pool provides an enhanced common infrastructure for database connection pooling. It is usable within the OC4J context as well as by non-Java EE applications for connecting to Oracle and non-Oracle databases and other resources like JCA and LDAP connections. "


I am exploring Oracle Universal Connection Pool for a customer engagement. I was exploring the API & came up with a basic "Hello World" style introduction for the API.

I just wanted to share it here:-


import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import oracle.ucp.UniversalConnectionPoolException;
import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceImpl;


public class UCPHelloWorld
{

public UCPHelloWorld()
{

}// end of constructor

public static void main(String args[])
{
String strConnectionPoolName= null;
String strConnectionFactory = null;
String strDatabaseURL = null;
String strDatabaseUser = null;
String strUserPassword = null;
String strSQLQuery = null;
String strEmployeeName = null;

Connection objConnection = null;
Statement objStatement = null;
ResultSet objResultSet = null;

PoolDataSource objPoolDataSource= null;

strConnectionPoolName = "myConnectionPool";
strConnectionFactory = "oracle.jdbc.pool.OracleDataSource";
strDatabaseURL = "jdbc:oracle:thin:@localhost:1521/XE";
strDatabaseUser = "scott";
strUserPassword = "tiger";
strSQLQuery = "SELECT ENAME FROM EMP";
strEmployeeName = "ENAME";


try
{
objPoolDataSource = new PoolDataSourceImpl();

// Basic Connection Parameters
objPoolDataSource.setConnectionFactoryClassName(strConnectionFactory);
objPoolDataSource.setURL(strDatabaseURL);
objPoolDataSource.setUser(strDatabaseUser);
objPoolDataSource.setPassword(strUserPassword);
objPoolDataSource.setConnectionPoolName(strConnectionPoolName);

// Set the Pool Size
objPoolDataSource.setMinPoolSize(4);
objPoolDataSource.setMaxPoolSize(10);
objPoolDataSource.setConnectionWaitTimeout(2);
objPoolDataSource.setInitialPoolSize(4);

System.out.println("Before getting the Connection");

objConnection = objPoolDataSource.getConnection();
objStatement = objConnection.createStatement();
objResultSet = objStatement.executeQuery(strSQLQuery);

System.out.println("After getting the Connection");

while(objResultSet.next())
{

System.out.println(objResultSet.getString(strEmployeeName));

}// end of resultset

objResultSet.close();
objStatement.close();
objConnection.close();

}
catch (SQLException objSQLException)
{
objSQLException.printStackTrace();
}
}// end of main
}// end of UCPHelloWorld

Wednesday, July 09, 2008

LDAP Search : Search for a user in Oracle Internet Directory

The need to search for a user's entry in Oracle Internet directory (OID) crops up very often in various situations.

You can easily do this using JNDI. You need to usually take care of these things before we proceed with the code :-

1. You have access to Oracle Internet Directory.

2. You know the Distinguished Name ( DN ) of the entry that is the immediate parent of all the users.

3. You know the attribute used to search. E.g.: cn, mail, sn, etc.

4. You know that the attribute used to search has been "indexed" by Oracle Internet Directory.
You can then adapt this piece of code to suit your needs & look for users - the lines marked in red are important :-

String strSearchString = "sandeep";

String strLDAPUrl = "ldap://localhost:389";

String strUserRootDN = "cn=Users,dc=test,dc=com";
String strFilter = "cn="+strSearchString ;

Hashtable env = new Hashtable();

env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, strLDAPUrl);
env.put(Context.SECURITY_AUTHENTICATION, "simple");

// You know the credentials to search in OID
env.put(Context.SECURITY_PRINCIPAL, "cn=orcladmin");
env.put(Context.SECURITY_CREDENTIALS, "mySecretPassword");

try
{

DirContext ctx = new InitialDirContext(env);
Attributes attrs = ctx.getAttributes(strUserRootDN,strFilter,new String[]{"mail"});

Attribute attr = attrs.get("mail");
System.out.println(attr.get());

ctx.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
You can easily modify this piece of code to search for users in a group, etc.

Tuesday, July 08, 2008

Oracle Application Server 10.1.2 : SSO Session and Application Session

We had successfully configured an application deployed in Oracle AS 10.1.3.x to use Oracle AS 10.1.2 SSO. We were trying to develop "single sign off" and we hit a bug.

We just figured out that the Oracle AS 10.1.2 Session and the Java Application Session are different.

The Oracle AS 10.1.2 Session is maintained by the SSO_ID cookie. As long as the SSO_ID cookie is present in the browser, the Oracle AS SSO "session" is maintained. The SSO session is killed only if the SSO_ID cookie is destroyed. The SSO_ID cookie is "killed" only when we issue this dynamic directive:-

response.setError(499, "Oracle SSO");

However, the java application session ( a HTTP Session) still lingers on. Hence, in order to clear the java application session, we need to invalidate it explicitly using this :-

session.invalidate();

The moral of the story - for a true "Single Sign Off", we need to invalidate the SSO "session" and the Java Application Session.

Oracle AS 10.1.2 Logout using Dynamic Directives

You can log out a user from Oracle AS 10.1.2,by using these two dynamic directives :-

response.setHeader("Osso-Return-Url", "/Your_Application_Home_page");
response.setError(499, "Oracle SSO");


The first dynamic directive informs the Oracle AS Single Sign On Server about the page that needs to be displayed after logout.

The second dynamic directive informs the Oracle AS Single Sign On Server that the user needs to be logged out immediately.

The two dynamic directives need to be used together. If the first one is left out, the SSO Server simply redirects the user to the Oracle Application Server Home Page on which the application is deployed.

Friday, July 04, 2008

Oracle AS SSO : How to get important user information from SSO and OID

The Oracle AS 10.1.2 Single Sign on places useful user information in the HTTP request Headers. The partner application can access these request headers & get this useful information.

We can use this information provided by the Oracle AS 10.1.2 Single Sign on and query the underlying Oracle Internet Directory ( OID ) directly to obtain useful user information.

The three critical assumptions that we need to make at this point are :-

1. We are able to get the OSSO-User-Dn value from the request header.

2. We are able to connect to the OID anonymously, to read the user information ( so that we need to unnecessarily authenticate again. ).

3. We have access to the underlying OID ( usually, the OID is protected by a DMZ layer & ports may need to be opened at the firewall ).


We can proceed to write a simple JNDI code ( simple garden variety code, obtained from the Sun JNDI Tutorial Trail ) to get important user information from OID :-

DirContext objRootContext = null;
Hashtable objHashtable = null;
Attributes objUserAttributes = null;
Attribute objEmail = null;
Attribute objPhone = null;
String strEmail = null;
String strPhone = null;

objHashtable = new Hashtable();

// Let's get the User DN from Single Sign On.
// CRITICAL ASSUMPTION : We get the User DN value from the SSO.
strUserDN = request.getHeader(“Osso-User-Dn”);

// Let's connect to the OID used by Oracle AS Single Sign on
// CRITICAL ASSUMPTION : We can access the OID objHashtable.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
objHashtable.put(Context.PROVIDER_URL,"ldap://localhost:389/");
objHashtable.put(Context.SECURITY_PRINCIPAL,strUserDN);
// CRITICAL ASSUMPTION : The OID should provide anonymous access.
objHashtable.put(Context.SECURITY_CREDENTIALS,"");

// Let's lookup the user from the root node.
objRootContext = new InitialDirContext(objHashtable);
objRootContext = (DirContext) objRootContext.lookup(strUserDN);

// Let's get all the attributes
objUserAttributes = objRootContext.getAttributes("");

// Let's pull out only the attributes we are interested in.
objEmail = objUserAttributes.get("mail");
objPhone = objUserAttributes.get("phone");

if(objEmail!=null)
{
strEmail = (String) objEmail.get();
}

if(objPhone!=null)
{
strPhone = (String) objPhone.get();
}
We can now comfortably get the user information & use it further downstream in our applications.

Oracle AS SSO : How to get the User DN in a Java Application?

The Oracle AS 10.1.2 Single Sign on places useful user information in the HTTP request Headers. The partner application can access these request headers & get this useful information.

The authenticated user's distinguished name ( DN ) is a very important attribute. The DN can be used to pull out more information about the user from Oracle Internet Directory - e.g : the email address, the phone number, etc.

You can easily get the user dn of the authenticated user from the request , by using this code snippet :-

String strUserDN = request.getHeader(“Osso-User-Dn”);
The DN can then be coupled with a simple JNDI Code to retrieve other attributes.

Thursday, July 03, 2008

Oracle AS 10.1.2 SSO Failure - Unable to process request

" Oracle SSO Failure - Unable to process request
Either the requested URL was not specified in terms of a fully-qualified host name or OHS single sign-on is incorrectly configured. "

We his this error immediately after registering a Partner Application with Oracle As 10.1.2 Single Sign on. It took sometime for us to understand the problem & fix it.

The solution to the problem is detailed in the Metalink Note:311921.1. I'll just provide a brief summary here for people who do not have access to Oracle Metalink.

The URL used to register the Partner Application with Oracle As 10.1.2 Single Sign On contains the fully qualified hostname - with the domain name.

E.g: http://host.domain.com/osso_login_success


However, the URL used to test the application did not contain the fully qualified hostname - we even tried with the IP Address in the URL

E.g: http://host/osso_login_success

or

E.g: http://10.10.10.10/osso_login_success


Oracle As 10.1.2 Single Sign On mandates that the URL registered as the Partner Application should be only used. We cannot use any other URL formats to access the application.

We then tried with the URL:-

E.g: http://host.domain.com/myAppContext


We used the URL used in the registration in our browsers & it worked.

Oracle AS 10.1.3 : Use Oracle AS 10.1.2 SSO

I was trying to configure Oracle Application Server 10.1.3.x to to use Oracle Application Server 10.1.2 Single Sign On.

I wanted to use Oracle Application Server 10.1.2 Single Sign On to protect an application deployed on Oracle Application Server 10.1.3.x. I checked out the available documents & Googled around a lot & collected this information. The information presented here isn't something new, but just a collection of information from various sources & my own experience.

The steps to achieve this are quite straight forward :-

0. Ensure that you have oss013 script in your Oracle App Server 10.1.3

You need to have the osso1013 script under the folder $ORACLE_HOME_1013/Apache/Apache/bin.

You will have this script only if you had selected the SOA Suite Advanced Instlallation type & opted for "J2EE and Web server"

1. Generate the Oracle AS Single Sign On Configuration File.

You can do this by running the ssoreg script present in the $ORACLE_HOME_1012/sso/bin. The syntax of the command is :-

ssoreg.bat
-oracle_home_path $ORACLE_HOME_1012
-config_mod_osso TRUE
-site_name Any_Name_for_your_application
-remote_midtier
-config_file .conf
-mod_osso_url http://your_1013_app_server_home_page:port
You can open a command window / terminal & execute this command from $ORACLE_HOME_1012/sso/bin.

You have completed this step successfully, if you see this message on your command window / terminal :-

Check /$ORACLE_HOME_1012/sso/log/ssoreg.log for details of this registration
SSO registration tool finished successfully.

After this step, you should see Any_Name_for_your_application_osso.conf at $ORACLE_HOME/sso/bin.

You should also see your application registered as a Partner Application in the Oracle SSO Administration Page at :-

http://Your_1012_http_server_hostname:http_port/pls/orasso


The key points to remember at this step are :-

a. Ensure that the is Oracle Application Server 10.1.3 Home Page and not URL for your application
b. Always check the generated Log File to ensure that there are no errors.

2. Copy the generated Oracle AS Single Sign On Configuration File to the 10.1.3 Server.

You need to copy the generated Any_Name_for_your_application_osso.conf to your Oracle Application Server 10.1.3 system.

You can copy this to your $ORACLE_HOME_1013/Apache/Apache/bin folder.

3. Register the 10.1.3 Server with the 10.1.2 SSO.

You can navigate to the $ORACLE_HOME_1013/Apache/Apache/bin folder, open a command window / terminal and execute this command:

osso1013 Any_Name_for_your_application_osso.conf

You have completed this step successfully if you see this message on your command window / terminal :-

$ORACLE_HOME_1013/Apache/Apache/conf/httpd.conf successfully updated.
$ORACLE_HOME_1013/Apache/Apache/conf/mod_osso.conf successfully updated.
4. Protect your Application

You can now open mod_osso.conf under $ORACLE_HOME_1013/Apache/Apache/conf and add an entry to protect your application :-

<
Location /Your_app_context
>

require valid-user
AuthType Basic
>

5. Restart the HTTP Server

That's it !

You can now enter your application's URL & you can see the Single Sign On Page asking your to enter the credentials.

Tuesday, July 01, 2008

Oracle 10.1.3.x JavaSSO : LDAP Configuration Checklist

" In AS 10.1.3.x Oracle came up with the JavaSSO. Seems to be (from a high level perspective) a poor man's version of the SSO from the AS 10.1.2.x. "

Andreas

I have to agree with Andreas. The JavaSSO solution bundled with the Oracle Application Server 10.1.3.x is definitely a poor man's SSO, with a few basic options & very little available documentation.

I am with Oracle Application Server 10.1.3.x JavaSSO & was trying to configure it with an Oracle Internet Directory. I hit a lot of "gotchas" & had to spend a lot of time wading through the documentation to get it working.

I guess I need a small "checklist" to summarize the steps I took to get it to work :-

1. Configure the OID as a Security Provider in the OC4J.
2. Start the JavaSSO application ( it is switched off by default ).
3. Configure JavaSSO to use the OID Security Provider.
4. Configure your application's web.xml & list the security settings.
4. Deploy the Application - ensure that the "Enable JavaSSO" option is checked at deploy time. You can do it later too from the administration console.
5. Ensure that the deployed uses the OID Security Provider.
6. Configure the deployed application as a Partner Application in JavaSSO.


I'll provide more information on some of these steps in future posts.



BGInfo : Caputre your Winows server's configuration

" BGInfo automatically displays relevant information about a Windows computer on the desktop's background, such as the computer name, IP address, service pack version, and more. "


BGInfo is a damn cool utility for Windows ! It quickly captures your system's current configuration & sets the information as your Desktop background. The Tool is very easy to install & use.

I found this tool to be very useful when you work with Server systems on Windows. I have worked on a few Projects where the Server is usually a Desktop innocently lying unused in a corner. The system is then cannibalized & converted into a "Server" & the required software installed in it. Hence, its very important to capture certain important system parameters & verify that the software you are about to install is certified for the existing hardware / network / OS configuration. BGInfo comes to your rescue in such situations.

You can also use BGInfo as a command line utility - it ever accepts a few command line options. I found the command line option /RTF very useful. According to the BGInfo Help Information,

/rtf Causes BGInfo to write its output text to an RTF file. All formatting information and colors are included.

You can use it in this manner :-


bginfo /rtf:D:\myConfiguration.rtf


You can then navigate to the D:\ drive on your system to find a neat RTF file with all the required information.

Boot Time: 7/1/2008 10:01 AM

CPU: Dual 2.00 GHz Intel Core2 Duo

Default Gateway: 101.178.223.184

DHCP Server: 101.178.223.180

DNS Server: 101.178.223.181

Free Space: C:\ 40.12 GB NTFS, D:\ 33.89 GB NTFS

Host Name: MYCOMP-LAP

IP Address: 101.178.223.189

Logon Domain: mycomp-lap

Logon Server: mycomp -lap

User Name: mycomp



I found BGInfo to be very useful & use it on every Windows-based "Server" that I get my hands on !

Thursday, June 26, 2008

Oracle TopLink or EclipseLink ?

" Oracle TopLink will be Oracle's distribution of EclipseLink included with support with all editions of our Application Server as well as for standalone usage for customers who want commercial support and maintenance."



I just read this interesting thread on the OTN TopLink Forum. Oracle TopLink &will henceforth become EclipseLink.

I have been having this question every since I read about the EclipseLink Project. However, I got the answer today after reading the thread on the forum.

The interesting part about this is that the EclipseLink project now has contributions from people with different backgrounds. The product will be developed by people from different compaines & affiliations.

I am sure this "open sourcing" of TopLink ( EclipseLink ) will take it to new levels.

I wish the best for the TopLink team & the community !

Tuesday, June 24, 2008

Apache Tiles : Error : TilesContainer not initialized

We have been trying to get a simple web application that uses Apache Tiles Framework 2.0.5 to work in JDeveloper 10.1.3 .3.0.

However, we kept hitting a generic error :-

javax.servlet.jsp.JspException: TilesContainer not initialized
at org.apache.tiles.jsp.taglib.ContainerTagSupport.doStartTag
(ContainerTagSupport.java:72)
at org.apache.tiles.jsp.taglib.RenderTagSupport.doStartTag
(RenderTagSupport.java:138)
at _pets._jspService(_pets.java:48)
[/pets.jsp]
at com.orionserver[Oracle Containers for J2EE 10g (10.1.3.1.1) ].http.OrionHttpJspPage.service(OrionHttpJspPage.java:59)
at oracle.jsp.runtimev2.JspPageTable.service(JspPageTable.java:462)
at oracle.jsp.runtimev2.JspServlet.internalService(JspServlet.java:598)
at oracle.jsp.runtimev2.JspServlet.service(JspServlet.java:522)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
My friend Sriram & myself struggled to resolve this error & we were just able to resolve it.

I believe the error occurs because of these three reasons :-

1. Incorrect / Missing DTD reference in the tiles-defs.xml
2. Incorrect / Missing XML Elements in the tiles-defs.xml
3. Missing retrotranslator-runtime-n.n.n.jar in WEB-INF/lib
I am sure there are many other reasons for the error - I have just presented a quick checklist of the problems that we encountered.

The third option is still a mystery to us. I mean, why do we need to use the RetroTranslator Library when we are using JDK 1.5 ?

We are still trying to figure that one out. I'll post an update if we unravel this last mystery.

Monday, June 23, 2008

Apache Directory Server : Default Settings

" We strive to increase LDAP awareness, comfort and adoption to bring forth what we call the Modern LDAP Renaissance. "



I just downloaded and installed the Apache Directory Server. It took less than 5 minutes to install the server & start it.

The Apache Directory Server is one of the best LDAP Servers that I have used, during prototyping stages. It's very easy to install & very fast in operation.

However, I did observe in a couple of customer engagements that I had to look a bit through the documentation to get a list of the default configuration. I just want to list the default configuration that I use frequently here, to save a bit of time :-

Defalut Host : localhost
Default Port : 10389
Admin user : uid=admin, ou=system
Admin pass : secret
Base DN : ou=system
Initial context Factory : com.sun.jndi.ldap.LdapCtxFactory


Overall, the Apache Directory Project is simply too good !

WebLogic Server 10 : Deployment : OutOfMemory Error

I created a connection to WebLogic Server 10 in my JDeveloper 10.1.3. Now, I am using this connection to deploy a simple Web Application that contains a single JSP.

However, I keep hitting this bug frequently :-

[BasicOperation.deriveAppName():140] : appname established as: webapp1
weblogic.deploy.api.tools.deployer.DeployerException: Java heap space
at weblogic.deploy.api.tools.deployer.Jsr88Operation.postExecute(Jsr88Operation.java:563)
at weblogic.deploy.api.tools.deployer.DeployOperation.execute(DeployOperation.java:48)
at weblogic.deploy.api.tools.deployer.Deployer.perform(Deployer.java:139)
at weblogic.deploy.api.tools.deployer.Deployer.runBody(Deployer.java:88)
at weblogic.utils.compiler.Tool.run(Tool.java:158)
at weblogic.utils.compiler.Tool.run(Tool.java:115)
at weblogic.Deployer.run(Deployer.java:70)
at weblogic.Deployer.main(Deployer.java:54)
Caused by: java.lang.OutOfMemoryError: Java heap space
[ServerConnectionImpl.close():334] : Closing DM connection
[ServerConnectionImpl.close():354] : Unregistered all listeners
[ServerConnectionImpl.closeJMX():374] : Closed JMX connection
[ServerConnectionImpl.closeJMX():386] : Closed Runtime JMX connection
[ServerConnectionImpl.closeJMX():398] : Closed Edit JMX connection
**** weblogic.deploy returned with non-zero exit status: 1
**** weblogic.deploy returned with non-zero exit status: 1
Elapsed time for deployment: 46 seconds
#### Deployment incomplete. #### Jun 20, 2008 5:53:41 PM


The error clearly tells that the Java process used for the deployment is out of memory & is unable to deploy the application.

I have to increase the heap size of the java process that is used to deploy the application in JDeveloper.

I looked at the deployment profile for my application & noticed this command for WebLogic 9.x :-

${java} ${jvm.max.heap.size}
-classpath ${weblogic.jar} weblogic.Deployer
-adminurl t3://${hostname}:${port}
-user ${username} -password ${password}
-debug -verbose -deploy -upload
-source ${ear.file} -name ${j2ee.app.name}


However, at the time of deployment, I noticed that the heap size was not used for the Java process :-

javaw.exe -classpath weblogic.jar weblogic.Deployer -adminurl t3://localhost:7001 -user weblogic -password **** -debug -verbose -deploy -upload -source webapp1.ear -name webapp1

weblogic.Deployer invoked with options: -adminurl t3://localhost:7001 -user weblogic -debug -verbose -deploy -upload -source webapp1.ear -name webapp1


Hence, I hardcoded the heap size in the command in the Deployment Settings like this :-

${java} -Xms256m -Xmx512m
-classpath ${weblogic.jar} weblogic.Deployer
-adminurl t3://${hostname}:${port}
-user ${username} -password ${password}
-debug -verbose -deploy -upload
-source ${ear.file} -name ${j2ee.app.name}


At the time of depoyment, I noticed that the heap size as now being used correctly :-

javaw.exe -Xms256m -Xmx512m -classpath weblogic.jar weblogic.Deployer -adminurl t3://localhost:7001 -user weblogic -password **** -debug -verbose -deploy -upload -source webapp1.ear -name webapp1

weblogic.Deployer invoked with options: -adminurl t3://localhost:7001 -user weblogic -debug -verbose -deploy -upload -source webapp1.ear -name webapp1

After making this change, I was able to get a clean deployment from my JDeveloper 10.1.3.

.
.
.
[BasicOperation.execute():425] : Initiating deploy operation for app, webapp1, on targets:
Task 2 initiated: [Deployer:149026]deploy application webapp1 on examplesServer.
Task 2 completed: [Deployer:149026]deploy application webapp1 on examplesServer.
Target state: deploy completed on Server examplesServer
.
.
.
[ServerConnectionImpl.close():354] : Unregistered all listeners
[ServerConnectionImpl.closeJMX():374] : Closed JMX connection
[ServerConnectionImpl.closeJMX():386] : Closed Runtime JMX connection
[ServerConnectionImpl.closeJMX():398] : Closed Edit JMX connection
Elapsed time for deployment: 1 minute, 45 seconds
---- Deployment finished. ---- Jun 24, 2008 11:23:54 AM

Friday, June 20, 2008

WebLogic Server 10 : Deployment : Increase Server JVM Heap Space

I had to increase the WebLogic Server's JVM Memory Arguments to circument a problem.

The JVM Memory arguments are in the file " setDomainEnv.cmd " in the folder $WEBLOGIC_HOME\wlserver_10.0\samples\domains\wl_server\bin\

You can open the file in any Text Editor and scroll down to this line :-

set MEM_ARGS=-Xms256m -Xmx512m


You can alter the memory arguments to solve the problem. The combination that worked for me is tis :-

set MEM_ARGS=-512 -Xmx512m

WebLogic Server 10 : is the HTTP server a weblogic Server

I just hit a CommunicationException in my JDeveloper 10.1.3 :-

"
Caused by: javax.naming.CommunicationException [Root exception is java.net.ConnectException: http://localhost:7001: Destination unreachable; nested exception is: java.net.ProtocolException: Tunneling result unspecified - is the HTTP server at host: 'localhost' and port: '7001' a WebLogic Server?; No available router to destination] at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:40) at weblogic.jndi.WLInitialContextFactoryDelegate.toNamingException(WLInitialContextFactoryDelegate.java:773) at weblogic.jndi.WLInitialContextFactoryDelegate.getInitialContext(WLInitialContextFactoryDelegate.java:363) at weblogic.jndi.Environment.getContext(Environment.java:307) at weblogic.jndi.Environment.getContext(Environment.java:277) at weblogic.jndi.Environment.createInitialContext(Environment.java:200) at weblogic.jndi.Environment.getInitialContext(Environment.java:184) at weblogic.jndi.Environment.getInitialContext(Environment.java:162) at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getContext(ServerConnectionImpl.java:330) at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.getEnvironment(ServerConnectionImpl.java:302) at weblogic.deploy.api.spi.deploy.internal.ServerConnectionImpl.init(ServerConnectionImpl.java:141) ... 11 more
"


I was trying to deploy an application from JDeveloper 10.1.3 to WebLogic Server 10. First, I created a connection to the WebLogic Server 10 using these connection settings :-


I then created a deployment profile for my Web Application. I right-clicked on the Deployment Profile and selected the option to directly deploy to my WebLogic Server. However, I kept getting this error.

I did some Googling & came across this post on the OTN JDeveloper Forums :-

http://forums.oracle.com/forums/thread.jspa?messageID=2134174&#2134174

To summarize Deepak's solution from the post,

"

JDeveloper 10.1.3.3 configures a connection with WebLogic server with the t3 protocol.The deployment profile has the connection protocol specified as http. Modify the connection protocol in the deployment profile.

1. In the Deployment Profile Properties window select the Platform>WebLogic 9.x node.
2. In the WebLogic 9.x Deploy command modify:
-adminurl http://${hostname}:${port}  

to
-adminurl t3://${hostname}:${port}  
"


I made this change in my Deployment Profile & it worked immediately.

WebLogic Server 10 : JDeveloper : Cannot instantiate class: weblogic.jndi.WLInitialContextFactory

"

Cannot instantiate class: weblogic.jndi.WLInitialContextFactory

"

I was trying to create a connection to WebLogic Server 10 from JDeveloper 10.1.3 & I encountered this error. The Connection Wizard threw this error when I wanted to test the connection.

The problem is simple - JDeveloper cannot find the class WLInitialContextFactory required to connect to my WebLogic Server.

The class is present in the JAR File weblogic.jar. The JAR file is present in the folder $WEBLOGIC_HOME/wlserver_10.0\server\lib.

I simply copied the weblogic.jar file from $WEBLOGIC_HOME\wlserver_10.0\server\lib and put it in JDEVELOPER_HOME\jdev\lib\ext

JDeveloper was able to find the JAR File & proceed with the connection without any hitch.

WebLogic Server 10 : Error 403--Forbidden

"

Error 403--Forbidden
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.4.4 403 Forbidden

The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. This status code is commonly used when the server does not wish to reveal exactly why the request has been refused, or when no other response is applicable.

"

I hit this error immediately after deploying and starting the application. The error is quire eloquent, but in my humble opinion, is not very clear about the reasons for the error.

I clicked on the "Testing" link for the application & simply clicked on the "Test Point" URL mentioned on the page :-

http://10.177.226.140:7001/webapp1

I worked on this for sometime & then it hit me :-

I have to supply the complete URL for my JSP.

I tried the complete URL & it worked.

http://10.177.226.140:7001/webapp1/First.jsp

I am just posting this for future reference to newcomers like me.

WebLogic Server 10 : 503--Service Unavailable

"

Error 503--Service Unavailable
From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:
10.5.4 503 Service Unavailable

The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay may be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.

Note: The existence of the 503 status code does not imply that a server must use it when becoming overloaded. Some servers may wish to simply refuse the connection.

"

I hit this error after deploying an application & trying out the URL for my JSP.

I have primarily worked on OC4J & expected that the steps would be pretty much the same. However, I hit this bug & was scracthing my head for quite sometime - until I realized it.

The Application has to be started after the deployment.

The application is not started by default ( as in OC4J ) & thus, was unavailable to service the requests.

I am just posting this for future reference to newcomers like me.

WebLogic Server 10 : Authentication Denied

"
Authentication Denied

The username or password has been refused by WebLogic Server. Please try again.

"
I just installed the WebLogic Server 10 & was excited to see the Welcome Screen pop-up on my browser. I then clicked on the "Start the Administration Console" button & the login page popped up.

I tried a couple of usernames and passwords, but I kept getting this error.



I finally tried this combination & it clicked :-

UserName : weblogic
Password : weblogic

Hurray ! I got into the WebLogic Server Administration Console.

Thursday, June 05, 2008

Problems in Configuration and Logging

" ...........
...........
Lock-Nah: The Book Of The Dead gives life.
Meela: And The Book Of The Living takes life away.
...........
...........
"


The dialogue between Lock-Nah and Meelah, from the movie The Mummy Returns sums up the state of the configuration files used in a software system. Often, I have observed that the most well-intentioned configuration files either end up as a "Book of the Dead" or as a "Book of the Living".

Configuration & Logging have always been the bone of contention & the heart of any discussion on software architecture. The questions always come up & hang in the air :-

- How will I configure that ?
- Where is the metadata for this ?
- How do I log this ?
- Can we use a universal format for the all the logging ?
- Where do I log the Exception Stack Traces ?
- .....
- .....
- .....

I just chanced upon this Blog entry by Dan Pritchett . The article talks about Metadata & the various decisions that need to be made while using Metadata. The article is nicely organized & well written.

Dan talks about two aspects of Metadata - Configuration & Telemetry ( Logging, actually ).

Configuration

Dan has clearly articulated the problem associated with distributed configurations, synchronizing between the configurations, etc. I have faced these issues many times in the past, especially with systems that contain lots of configuration files.

The key to get the system operational is to "turn the knobs" in the correct combination. Often, this kind of configuration mechanism falls into the realm of black magic : often, only a seasoned veteran master-architect can cast the correct arcane spell to tame the beast. The multitude of configuration files simply lay all the precise documentation to waste. The problem becomes even more complex when the system is replicated accross multiple servers : the arguments now move into a new space - how to maintain a "common" configuration & extend it to a specific "granular" configuration required by a single server.

Telemetry

Dan also touches upon the topic of Telemetry ( a term I haven't heard since my college days ! ). How do you measure / monitor the health of a system remotely ? Well, the only source of this information is the log files. The problem is simple - consider a System X that has parts A, B and C, & these parts emit log information in specific formats. How do you aggregate the information from these three different formats into a single format that can show up in a remote dashboard ?

I think these questions must be addressed very early in a Project. The questions raised by this article are extremely important & could save countless hours of effort involved during maintanence & debugging.

Overall, a very good article from Dan Pritchett. It's a must read for people who earn their pay by designing software systems.

Tuesday, April 08, 2008

Thinking Of Mathematics

"The world is too full of factors to discourage students who cannot see from pursuing a career in science and math; hopefully this article can serve to at least minimally offset that imbalance."


I was reading "Thinking Of Mathematics — An Essay On Eyes-free Computing" [ PDF version ] & found it inspiring. T. V. Raman's analysis of "Eyes-free mathematics" & his application of Herman Helmholtz's theories to attempt & understand his own creative thinking are excellent.

T.V Raman was unable to see since the age of 14. He narrates his thought process on problem solving, modeled on Herman Helmholtz's three stages of creativity: saturation, incubation and illumination. He shares his experiences on solving interesting problems like a Mental Calendar, Solving The Rubik’s Cube, etc.

The essay is truly a wonderful & inspiring read.

Wednesday, April 02, 2008

ORA-01940: cannot DROP a user that is currently logged in

" ORA-01940: cannot DROP a user that is currently logged in "

ORA-01940

We were trying to drop a user ( schema ) in our local Oracle Database & we suddenly hit the ORA-01940 error.

We closed all the SQL Clients ( Oracle SQL Developer, SQL* Plus, TOAD ) that we were using, but still the error persisted. We were quite flummoxed - until, we googled and landed on this article from Burleson Consulting.

We followed the advice in the article & quitely killed the "stale" sessions. We could then drop the schema and recreate it.

I have always admired the articles from Burleson Consulting & found the explanation of the ORA-01940 error very informative.

Tuesday, April 01, 2008

Groovy test ride

" Groovy is an agile and dynamic language for the Java Virtual Machine "


I have been following the Java scripting languages landscape for quite sometime now. I am simply overwhelmed with the sheer number of scriprting languages that can be run off the JVM. I was keenly following one such scripting language with interest - Groovy. I finally decided to take Groovy for a test ride, after reading a lot of interesting stuff on blogs & articles. I decided to try a simple example & see what I can learn from my experiment.

What's the Scenario ?

I have two database tables - EMP ( to keep details of employees ) and DEPT ( to keep details of departments ). I want to pull out details of an employee from the EMP ( Employee Number, Employee Name, Salary ) and DEPT ( Department Name ) tables and store it in another table named EMP_REPORT ( Employee Number, Employee Name, Salary, Department Name )

What am I going to use ?

  • Microsoft Windows XP [Version 5.1]
  • Java 1.5
  • Groovy 1.5.4
  • Oracle Database 10g Enterprise Edition Release 10.1.0.4.2
  • Oracle SQL Developer 1.2.1
What are the logical steps ?

1. Connect : to the Database.
2. Query : the tables EMP and DEPT using a SQL SELECT statement.
3. Results : get the Result Ser
3. Iterate : the result set and get each record.
4. Add : each record to the EMP_RECORDS table.

What about installation ?

The installation procedure for Groovy is very easy - download & unzip. If you have set the JAVA_HOME environment variable to point to your JDK installation directory, you can just proceed to Groovy's /bin directory and double click on GroovyConsole.bat. You can see a simple IDE that allows you to execute your Groovy code. You can use CTRL + R to execute the code and CTRL+W to clear the output window.

... and...What does the Groovy code look like ?

import groovy.sql.Sql
import groovy.xml.MarkupBuilder

def source = Sql.newInstance(
"jdbc:oracle:thin:user/password@host:port:sid",
"oracle.jdbc.driver.OracleDriver"
)

def target = Sql.newInstance(
"jdbc:oracle:thin:user/password@host:port:sid",
"oracle.jdbc.driver.OracleDriver"
)

def sourceEmployees = source.dataSet("EMP E,DEPT D WHERE E.DEPTNO=D.DEPTNO")
def targetEmployees = target.dataSet("EMP_REPORT")

sourceEmployees.each
{
targetEmployees.add( ID : it.empno , NAME : it.ename , SAlARY : it.sal , DEPARTMENT : it.dname )
}

My thoughts ?

Well, that was quite easy ! It took less that 10 minutes for me to setup Groovy & try the code. I only faced one problem - Groovy complained that it couldn't find the Database Driver class oracle.jdbc.driver.OracleDriver. I simply put ojdbc14.jar into my JAVA_HOME/jre/ext/lib folder as a workaround.

I found Groovy to be simple & much closer to Java than the other scripting languages touted for the JVM. I think I'll probably use it for prototyping something in Java/JEE in the future.

Monday, March 31, 2008

Asking questions on Forums

“The important thing is never to stop questioning.”
Albert Einstein

I was reading Shay Shmeltzer's and Hector Rivera Madrid's post on the generals rules on posting on User Forums. I don't want to summarize a list of my own as these gentlemen have already prepared a wonderful list of do's and don'ts.

I still have a bookmark to an old article - How to ask questions the smart way. The article is still being revised and maintained.

To summarize Shay's intentions :-

" I think there are some things that posters to the forums can do to make the whole experience of using the forums a lot better. "

Friday, March 21, 2008

Holi - 2008


It's Holi ! The festival of colors ! It's time to get drenched in a variety of colors !

Originally, Holi started out as a festival to celebrate good harvests. Now, it's more of a festival to have a good time :).

The day also marks Good Friday.

I am sitting at office trying to complete a pending task & suddenly, my colleagues smeared colors on my face. I am totally covered in colors & my laptop is sharing the same fate.

Well, I am looking forward to more fun & frolic during the weekend !

Self Appraisal

Another "gem" that I received in today's mail - thanks Vijay !:-

A little boy went into a drug store, reached for a soda carton and pulled it over to the telephone. He climbed onto the carton so that he could reach the buttons on the phone and proceeded to punch in eight digits (phone numbers).

The store-owner observed and listened to the conversation:

Boy: 'Lady, Can you give me the job of cutting your lawn?

Woman: (at the other end of the phone line): 'I already have someone to cut my lawn.'

Boy: 'Lady, I will cut your lawn for half the price of the person who cuts your lawn now.'

Woman: I'm very satisfied with the person who is presently cutting my lawn.

Boy: (with more perseverance): Lady, I'll even sweep our curb and your sidewalk, so on Sunday you will have the prettiest lawn in all of Palm beach, Florida.'

Woman: No, thank you.

With a smile on his face, the little boy replaced the receiver. The store-owner, who was listening to all this, walked over to the boy.

Store Owner: 'Son... I like your attitude; I like that positive spirit and would like to offer you a job.'

Boy: 'No thanks,

Store Owner: But you were really pleading for one.

Boy: No Sir, I was just checking my performance at the job I already have. I am the one who is working for that lady, I was talking to, and I was doing my 'Self Appraisal'

ORA-01000 maximum open cursors exceeded

" java.sql.SQLException : ORA-01000: maximum open cursors exceeded "

-- ORA-01000

I was recently asked my a colleague to help in resolving the ORA-01000 error. At a first glance, everything looked fine in the Java Code & it was baffling - it took sometime for enlightenment to illuminate the nature of the problem and one possible solution.

The program inherited by my colleague had two Java classes - Class A and Class B. Class A calls a method named insert() in Class B to save data into the database. Class A passed an ArrayList of Java Beans to the Class B's insert() method.

The logic to save the data was a plain - vanilla for loop :-

for ( int i = 0 ; i < number ; i++)
{

psSaveData = conOraleConnection.prepareStatement(insertSQL);
..........
..........
psSaveData.setString(1,dataBean.getId());
psSaveData.setString(2,dataBean.getName());
psSaveData.setString(3,dataBean.getAge());
..........
..........
psSaveData.executeUpdate();
}

Now, this piece of code was failing after the first 1000 rows !

We took sometime to methodically analyze the problem using an approach outlined at this link from BEA's Website. However, the problem persisted - either we missed something obvious or we were looking at something new. And then it occured to us :-

psSaveData = conOraleConnection.prepareStatement(insertSQL);

We finally figured out that the problem was caused by the statement marked in red. The line was actually telling the Oracle Database to precompile the same statement 1000 time !!

How does this matter ?

The Oracle Database contains a SQL Engine to deal with all SQL statements. The SQL Engine generally follows a two step process to execute a SQL Statement:-
  • parse : to check for syntax and semantic correctness.
  • execution plan : an optimized plan that details the instructions to execute the SQL statement.
The SQL Statement and the corresponding execution plan are stored together in a structure called a "Cursor". The Cursor is then stored in a special area of database memory called the "Shared Pool".

You can get handle to a cursor from a variety of languages like PL/SQL, Java, etc. You can then :-
  • Open the cursor.
  • Fetch the results
  • Close the cursor.
The Oracle database opens an "implicit cursor" for every SQL Statement that it encounters. Hence, a cursor is opened for every SELECT, INSERT, etc. statement that is issued to the SQL Engine.

Hence, you only need to prepare the "blueprint" once and execute it multiple times. The piece of code marked in red was preparing the "blueprint" 1000 times - as a result, 1000 cursors were opened !

We simply moved this line out of the for loop and solved one bottleneck.

We also noticed that the plain-vanilla JDBC Insert statement was not suitable for batch inserts. Well, that's another story :)


Thursday, March 20, 2008

Inspirations from Frogs

I was Googling around for something & came across this wonderful site about frogs. A page on the site is dedicated to "Frog Fables" - an eclectic of parables with a frog / toad as the topic of discussion.

I personally liked the story of "The Boiled Frog". I found it surprising that a frog's natural instincts are fine tuned to detect sudden changes in an environment, but not the slow changes that ultimately lead to the same change in the environment.

Well, this quote from the page, summarizes the story :-

" This parable is often used to illustrate how humans have to be careful to watch slowly changing trends in the environment, not just the sudden changes. Its a warning to keep us paying attention not just to obvious threats but to more slowly developing ones. "

Monday, March 17, 2008

Appending zeros in front of a number

I recently helped a colleague who had this simple requirement - to append zeros in front of a Number in a Java Method.

The purpose of the Method was to scan numbers between 1 and 999 and ensure that every number has three digits - the ones that have only two digits are appended by zeros.

The problem has multiple solutions & we were looking for the simplest possible solution. We tried a lot of solutions, starting with a simple for loop that counted the number of digits and appended zeros in front of it. We also looked at the Java API to see if a solution is already present.

However, we finalized two solutions that were very simple & elegant :-

Solution #1 ( JDK 1.5 onwards )

String.format("%03d", 1);
String.format("%03d", 10);
String.format("%03d", 100);


Solution #2 ( pre - JDK 1.5 )

NumberFormat objNumberFormat = new DecimalFormat("000");
objNumberFormat .format(Integer.parseInt( "1"));
objNumberFormat .format(Integer.parseInt( "10"));
objNumberFormat .format(Integer.parseInt( "100"));

We used Solution #2 to make the code reusable between JDK versions.

Thursday, March 13, 2008

What is domain knowledge ?

"Domain knowledge is defined as the collective knowledge gained through education, training, or a series of assignments in a functional area"

- Compensating for Incomplete Domain Knowledge

I frequently encounter profiles of candidates who claim to have knowledge in many domains in a very short time - sometimes, even less that two years. I usually view these profiles with suspect & many times, my suspicion was confirmed during conversations with the candidates. The candidates merely mention the domain of the clients they have worked with - often, they are unable to answer simple domain related questions or explain business needs that prompted the solutions they implemented.

I found that the definition I have mentioned in the beginning of his article captures the essence of Domain Knowledge. I would like to present my views about Domain Knowledge in this article.

Domain Knowledge is often gained through conversations with the business users. Often, Domain Knowledge is :-
  • Informal
  • Ill Structured
  • Incomplete
How is this kind of knowledge important ? What makes some of the IT companies & head hunters scourge for people with this kind of Domain Knowledge ?

Domain Knowledge is a key component in understanding :-
  • the problem space
  • the proposed solution
  • the slightly "bigger picture " - how the proposed solution formed a piece of the bigger puzzle.
Domain Knowledge is important as it helps you to communicate confidently with the business users in a particular domain. It helps you communicate to the business users in their language.

Example: if the users want to see a "tank", do they want to see an Armored Tank or a Septic Tank ?

You'd definitely be more confident in your solutions, if you knew precisely what the users expect to achieve from your solution - a few of these are :-
  • save time
  • co-ordinate better with their peers.
  • focus more on higher level activities after automating the trivial ones.
Domain Knowledge is also narrow - you may only focus on one minute part of a bigger piece in a huge puzzle. However, a good understanding of the minute part will serve as a foundation to explore the bigger piece & venture into the huge puzzle.

Example: if you are confident about your understanding of the Recruitment Loop ( contact - schedule interview - propose offer - recruit ), you could easily move into other functions such as Trend Analysis, Vendor Management, etc.

Example: if you are confident about your understanding of the HL7 Healthcare Messaging Protocol, you could comfortably move up to understanding Patient Demographics, etc.

Domain Knowledge is thus very helpful in understanding the needs of the business users better & providing solutions that closely match their needs.

I would definitely love to hear about different opinions on this topic.

Tuesday, March 11, 2008

Learn Programming in 10 Years


" Learn thoroughly whatever is to be learnt;
Then, let the conduct be worthy of this learning "


I just came across a wonderful article titled "Teach Yourself Programming in Ten Years" crafted by Peter Norvig. I would recommend the article for anyone looking at a career in the IT Industry.

It takes a lot of effort, discipline, sacrifice & experience to learn & understand a subject, let alone master it. An artifact that claims to offer a "shortcut" to learning in a particular subject in a very short time, is simply dubious in it's claim.

You may probably get an insight into the subject being discussed, but learning takes its own time. You my need to encounter many "aha!" moments to ultimately arrive at an understanding of a small part of the subject.

I feel that the books that claim - "learn x in y days/hours" are best to simply get a "foot in the door". You can get hooked to the topic and the books do justice in enticing your interest in the topics. I would recommend these books if you need to quickly get an outline of a subject and start work on it - and, probably plan to learn on the fly.

A good example is the software books with similar titles - you can quickly learn the syntax & replicate some of the code recipes shown in the book & achieve small-time victories.

However, if you are looking for a long term solution, there is no shortcut.

Many thanks to Thiruvalluvar and Peter Norvig !

Which Programming Language is good ?

"...One Ring to rule them all, One Ring to find them,
One Ring to bring them all and in the darkness bind them...."


The topic has been debated numerous times in the past, in various Forums, Newsgroups, mailing lists, coffee tables,etc. - but, it still goes on. The answer has always been the same - you need to choose the right tool for the right job. The mythical "Silver Bullet" does not exist & there will never be one.

You need to decide the tool to use for a particular job & use that tool correctly. It's no use trying to debate over the "best" language & these discussions are simply absurd.

I think this "old" article by Tim Daneliuk summarizes the thought process that goes on in these kind of debates.

Moral of the story : There is no Silver Bullet. There is no One Ring.

Monday, March 03, 2008

Pitfalls of JSF

Java Server Faces ( JSF ) is yet another Java Web Framework that promises to simplify the development of JEE-based web applications.

It deviates from the traditional "request-driven" approach adopted by MVC frameworks such as Struts & attempts to achieve the same with a component-driven model.

I am a fan of this Component-driven model & am still nostalgic about some of the work I did in Visual Basic, Oracle Forms, etc. many eons ago.

However, JSF, in its current version has a lot of pitfalls - some of the pitfalls are unique to JSF & drastically hinder the productivity gains that were promised in the JSF specification.

I was reading an interesting article on TheServerSide.com about the pitfalls of JSF . The article by Dennis Byrne was well written & covered some of the most important pain points in JSF.

I particular liked his last topic where he sympathizes with Portlet Developers. I found this sentence very emphatic :-

" I feel sorry for Portlet developers. I really do. These people are always on the mailing lists and forums with problem after problem and it's never their fault. If any group of people has been bent over by the standards bodies, it is Portlet application developers. "

Truly, a very good article that captures some burning issues that can keep a developer up all night.

Wednesday, February 27, 2008

God does exist

Another "gem" that I received in today's mail :-

A man went to a barbershop to have his hair cut and his beard trimmed. As the barber began to work, they began to have a good conversation. They talked about so many things and various subjects.

When they eventually touched on the subject of God, the barber said: "I don't believe that God exists."

"Why do you say that?" asked the customer. "Well, you just have to go out in the street to realize that God doesn't exist.

Tell me, if God exists, would there be so many sick people? Would there be abandoned children?

If God existed, there would be neither suffering nor pain. I can't imagine a loving God who would allow all of these things." The customer thought for a moment, but didn't respond because he didn't want to start an argument. The barber finished his job and the customer left the shop.

Just after he left the barbershop, he saw a man in the street with long, stringy, dirty hair and an untrimmed beard. He looked dirty and unkempt. The customer turned back and entered the barber shop again and he said to the barber:

"You know what? Barbers do not exist."

"How can you say that?" asked the surprised barber.

"I am here, and I am a barber. And I just worked on you!"

"No!" the customer exclaimed. "Barbers don't exist because if they did, there would be no people with dirty long hair and untrimmed beards, like that man outside."

"Ah, but barbers DO exist! That's what happens when people do not come to me."

"Exactly!" affirmed the customer. "That's the point! God, too, DOES exist!

That's what happens when people do not go to Him and don't look to Him for help.

That's why there's so much pain and suffering in the world."

The Hinderer

Another "gem" that I received in today's email :-

One day all the employees reached the office and they saw a big advice on the door on which it was written:

"Yesterday the person who has been hindering your growth in this company passed away. We invite you to join the funeral in the room that has been prepared in the gym".

In the beginning, they all got sad for the death of one of their colleagues, but after a while they started getting curious to know who was that man who hindered the growth of his colleagues and the company itself.

The excitement in the gym was such that security agents were ordered to control the crowd within the room.
The more people reached the coffin, the more the excitement heated up. Everyone thought: "Who is this guy who was hindering my progress? Well, at least he died!".

One by one the thrilled employees got closer to the coffin, and when they looked inside it they suddenly became speechless. They stood nearby the coffin, shocked and in silence, as if someone had touched the deepest part of their soul.

There was a mirror inside the coffin: everyone who looked inside it could see him/herself.

There was also a sign next to the mirror that said:
"There is only one person who is capable to set limits to your growth: it is YOU.
You are the only person who can revolutionize your life. You are the only person who can influence your happiness, your realization and your success. You are the only person who can help yourself.

Your life does not change when your boss changes, when your friends change, when your parents change, when your partner changes, when your company changes. Your life changes when YOU change, when you go beyond your limiting beliefs, when you realize that you are the only one responsible for your life.

"The most important relationship you can have is the one you have with yourself"
Examine yourself, watch yourself. Don't be afraid of difficulties, impossibilities and losses: be a winner, build yourself and your reality.

The world is like a mirror: it gives back to anyone the reflection of the thoughts in which one has strongly believed.

The world and your reality are like mirrors lying in a coffin, which show to any individual the death of his divine capability to imagine and create his happiness and his success.

It's the way you face Life that makes the difference

Tuesday, February 26, 2008

Different Attitude

Another "gem" that I received in today's mail :-

A Cold December night in West Orange, New Jersey. Thomas Edison's factory was humming with activity. Work was proceeding on a variety of fronts as the great inventor was trying to turn more of his dreams into practical realities. Edison's plant, made of concrete and steel, was deemed "fireproof". As you may have already guessed, it wasn't!

On that frigid night in 1914, the sky was lit up by a sensational blaze that had burst through the plant roof. Edison's 24-year-old son, Charles, made a frenzied search for his famous inventor-father. When he finally found him, he was watching the fire. His white hair was blowing in the wind. His face was illuminated by the leaping flames. "My heart ached for him," said Charles. "Here he was, 67 years old, and everything he had worked for was going up in flames. When he saw me, he shouted, 'Charles! Where's your mother?' When I told him I didn't know, he said, 'Find her! Bring her here! She'll never see anything like this as long as she lives.'"

Next morning, Mr. Edison looked at the ruins of his factory and said this of his loss: "There's value in disaster. All our mistakes are burned up. Thank God, we can start anew."

What a wonderful perspective on things that seem at first to be so disastrous. A business failure, personal dream gone sour . . . whether these things destroy an individual depends largely on the attitude he or she takes toward them. Sort out why it happened, and learn something from the blunders.

Think of different approaches that can be taken !

Monday, February 25, 2008

Soldier and the Spider

Another "gem" that I received in today's mail :-

During World War II, a US marine was separated from his unit on a Pacific island. The fighting had been intense, and in the smoke and the crossfire he had lost touch with his comrades.

Alone in the jungle, he could hear enemy soldiers coming in his direction.
Scrambling for cover, he found his way up a high ridge to several small caves in the rock. Quickly he crawled inside one of the caves. Although safe for the moment, he
realized that once the enemy soldiers looking for him swept up the ridge, they would quickly search all the caves and he would be killed.

As he waited, he prayed, Lord, if it be your will, please protect me.
Whatever your will though, I love you and trust you. Amen.
After praying, he lay quietly listening to the enemy begin to draw close.

He thought, well, I guess the Lord isn't going to help me out of this one.
Then he saw a spider begin to build a web over the front of his cave.

As he watched, listening to the enemy searching for him all the while, the spider layered strand after strand of web across the opening of the cave.

Hah, he thought. What I need is a brick wall and what the Lord has sent me is a spider web. God does have a sense of humor.

As the enemy drew closer he watched from the darkness of his hideout and could see them searching one cave after another. As they came to his, he got ready to make his last stand. To his amazement, however, after glancing in the direction of his cave, they moved on.

Suddenly, he realized that with the spider web over the entrance, his cave looked as if no one had entered for quite a while. Lord, forgive me, prayed the young man. I had forgotten that in you a spider's web is stronger than a brick wall.

We all face times of great trouble. When we do, it is so easy to forget the victories that God would work in our lives, sometimes in the most surprising ways.

Remember: Whatever is happening in your life, with God, a mere spiders web can become a brick wall of protection. Believe He is with you always and you will see His great power and love for you.

Network Troubleshooting - 6 : Application Issues

I believe that after eliminating the possibilities of problems at the previous steps, the only remaining option at this step is to troubleshoot the application. You may need to scrounge through log files, check application consoles, etc.

However, the possibility of a problem occurring due to the underlying network is extremely minimal at this level - even if it does, it's probably due to some idiosyncrasies of the Operating System or the Application Platform.

Network Troubleshooting - 5 : NETSTAT

You need to now move on to the Remote System & check if the program / process is listening on a particular port that you are trying to connect to.

Netstat (network statistics) is a command-line tool that displays network connections (both incoming and outgoing), routing tables, and a number of network interface statistics.

- Wikipedia


You can use the simple NETSTAT command on the remote system to check the open Network ports, active connections, etc . You just need to open a Command Prompt ( Terminal in LINUX ) & type :-

( LINUX )

netstat -an | grep port_name

OR

( WINDOWS )

netstat -an | findstr port_name

You should see a bunch of Network statistics like this :-

TCP 0.0.0.0:1521 0.0.0.0:0 LISTENING
TCP 127.30.22.11:1521 10.177.239.210:2527 ESTABLISHED
TCP 127.30.22.11:25271 10.177.239.210:1521 ESTABLISHED
TCP 127.30.22.110:28802 10.177.145.53:1521 ESTABLISHED


If you don't get this response, you can conclude on these :-

1. The program / process on the remote system that should be "listening" on the port is not running.

Now, it's time to call up the IT Help Desk & tell them that there's a problem with Network Access.

At the end of this exercise, you have :-

* tried some basic troubleshooting steps.
* identified the source of the problem.
* communicated effectively to the IT Support Staff.

You can now confidently communicate with the IT Support Staff & they'd be more than happy to work with an "educated" colleague.

Network Troubleshooting - 4 : TELNET

A TCP/IP standard for remote terminal connection to another machine.

- Wikipedia


You can use the simple TELNET command to ensure that you can communicate with the remote system, by opening a connection to a port on the remote system. You just need to open a Command Prompt ( Terminal in LINUX ) & type :-

telnet ip_address port

OR

telnet hostname port

You should see a blank screen that allows you to type commands.

If you don't get this response, you can conclude on these :-

1. The program / process on the remote system that should be "listening" on the port is not running.
2. The remote system is protected by a "firewall" that's preventing access.

Now, it's time to call up the IT Help Desk & tell them that there's a problem with Network Access.

At the end of this exercise, you have :-

* tried some basic troubleshooting steps.
* identified the source of the problem.
* communicated effectively to the IT Support Staff.

You can now confidently communicate with the IT Support Staff & they'd be more than happy to work with an "educated" colleague.

Network Troubleshooting - 3 : PING

Ping!

Ping is a computer network tool used to test whether a particular host is reachable across an IP network.

- Wikipedia


You can use the simple PING command to ensure that you can communicate with the other system. You just need to open a Command Prompt ( Terminal in LINUX ) & type :-

ping ip_address

OR

ping hostname

You should see a reply from the Network Card like this :-

Pinging sandeep-personal [127.0.0.1] with 32 bytes of data:

Reply from 127.30.22.11: bytes=32 time 1ms TTL=128
Reply from 127.30.22.11: bytes=32 time 1ms TTL=128
Reply from 127.30.22.11: bytes=32 time 1ms TTL=128
Reply from 127.30.22.11: bytes=32 time 1ms TTL=128

If you don't get this response, you can conclude on these :-

1. Your system is not connected to the same network as the remote system.
2. The remote system is not connected to the same network as your system.
3. Your system / the remote system is protected by a "firewall" that's preventing access.

Now, it's time to call up the IT Help Desk & tell them that there's a problem with Network Access.

At the end of this exercise, you have :-

* tried some basic troubleshooting steps.
* identified the source of the problem.
* communicated effectively to the IT Support Staff.

You can now confidently communicate with the IT Support Staff & they'd be more than happy to work with an "educated" colleague.

Revision Control for Rows

Revision Control deals with managing multiple revisions of an entity. The core functionality in any Revision Control system is to ensure that the previous version is not lost. Revision Control is a vast topic that merits hours of study & practice.

I definitely don't have the breadth of knowledge or experience to comment on various "must-have" features, etc. However, I did encounter an interesting scenario where I put Revision Control to practice for information stored in rows of a Database Table.

We can achieve Revision Control for rows in a Database Table in a simple way - with two columns. We can use one column to store the Row version and another to "flag" the row that contains the latest version.

I am using an Oracle XE Database & Oracle SQL Developer to model the tables, fashion out the queries, etc. You could do the same with any other Database & your favorite tools.

Here, I consider the example of an Item "on display" at a shop. The Product is available in multiple version ( different colors ), but only one "version" of the product is currently on display ( the item ).

First, I'll model the database table. I have made a few assumptions to arrive at this model :-

Assumption # 1 :- All the rows are linked by a common identifier ( in my case, the Product ID ).
Assumption # 2 :- At any given point of time, only one version of the product is "active".
Assumption # 3 :- Each "version" is saved into the database. Any "undo" will simply revert back to the previous saved version.
Assumption # 4 :- Each "undo" or "redo" is saved into the database as the current version.

Here's a table that shows this design :-

CREATE TABLE ITEM
(
ITEM_ID NUMBER PRIMARY KEY,
ITEM_PRODUCT_ID NUMBER,
ITEM_DESCRIPTION VARCHAR2(100),
ITEM_COLOR VARCHAR2(10),
ITEM_VERSION NUMBER,
ITEM_CURRENT_VERSION VARCHAR2(1) CONSTRAINT check_ver_flag CHECK(ITEM_CURRENT_VERSION IN ('Y','N'))
);


Here's the data that I stuffed into the table :-

INSERT INTO ITEM VALUES (1,566,'Smiley Dolls','Red',1,'N');
INSERT INTO ITEM VALUES (2,566,'Smiley Dolls','Blue!',2,'N');
INSERT INTO ITEM VALUES (3,566,'Smiley Dolls','Yellow',3,'Y');
INSERT INTO ITEM VALUES (4,566,'Smiley Dolls','Cyan',4,'N');

COMMIT;


Now, to dish out the queries...

Which is the current version of the Product ?

SELECT ITEM_DESCRIPTION, ITEM_COLOR FROM ITEM WHERE ITEM_CURRENT_VERSION = 'Y';

ITEM_DESCRIPTION ITEM_COLOR
------------------- ----------
Smiley Dolls Yellow

1 rows selected


Can we "undo" the current version & revert to the previous saved version ?

SELECT a.ITEM_DESCRIPTION, a.ITEM_COLOR FROM ITEM A, ITEM B
WHERE A.ITEM_VERSION = B.ITEM_VERSION-1 AND B.ITEM_CURRENT_VERSION = 'Y'


ITEM_DESCRIPTION ITEM_COLOR
----------
Smiley Dolls Blue!

1 rows selected


( After this, we set the current version flag to "Y" )

Revision Control can be achieved in this simple manner.

Sunday, February 24, 2008

Parent Child Relations in a Database Table

Parent - Child relationships ( hierarchical relationships ) are very common & often crop often during database designs.

You can expect to find Parent -Child relationships while modeling employee-manager, office-outlets & other similar concepts. I recently encountered the need for a parent - child relationship in a need to model a product-sub product concept.

You can find a lot of literature that talks about this topic in detail. I just want to add my 2 cents..

The hierarchical relationships are best explained by examples. Here, I consider a popular fast food chain of outlets ( "Yummies" ) that has outlets across the city.
Al the outlets in a particular part of the city "report" to a single outlet - the "parent" outlet.

All these "parent" outlets in turn "report" to a single "parent" outlet - something like a "head office".

The "report"s could be anything - daily sales figures, inventory status, customer feedback, staff shortages, etc. However, at this point of time, the main focus is to model the relationship of a parent-child outlet chain.

I am using an Oracle XE Database & Oracle SQL Developer to model the tables, fashion out the queries, etc. You could do the same with any other Database & your favourite tools.

First, I'll model the database table. I have made a couple of assumptions to arrive at this model :-

Assumption #1 : Each child outlet has a single parent outlet.
Assumption #2 : Each outlet has a parent outlet, except the "root" outlet ( head office ) .

Here's the table structure that I have designed :-

CREATE TABLE OUTLET
(
OUTLET_ID NUMBER PRIMARY KEY,
OUTLET_NAME VARCHAR2(30) NOT NULL,
OUTLET_PARENT NUMBER
);


The OUTLET_ID of the "parent" outlet is stored in the "child" outlet's OUTLET_PARENT.

Here's the data I stuffed into the table :-

INSERT INTO OUTLET VALUES(1,'Yummies M G Rd',null);
INSERT INTO OUTLET VALUES(2,'Yummies BSK ',1);
INSERT INTO OUTLET VALUES(3,'Yummies BSK I Stage ',2);
INSERT INTO OUTLET VALUES(4,'Yummies BSK II Stage ',2);
INSERT INTO OUTLET VALUES(5,'Yummies BSK III Stage ',2);
INSERT INTO OUTLET VALUES(6,'Yummies Food World ',3);

COMMIT;


Now, to dish out the queries...

Which outlet is the "mother of all outlets" ? ( root outlet / head office )

The outlet that has no parent ( OUTLET_PARENT is null ) is the "mother of all outlets".

SELECT * FROM OUTLET WHERE OUTLET_PARENT IS NULL;

OUTLET_ID OUTLET_NAME OUTLET_PARENT
--------- ------------------ ---------------
1 Yummies M G Rd


1 rows selected

Which are the outlets under the root outlet ?

SELECT
a.outlet_id,
a.outlet_name,
a.outlet_parent,
b.outlet_parent
FROM outlet a,
outlet b
WHERE b.outlet_id = a.outlet_parent
AND b.outlet_parent IS NULL;


OUTLET_ID OUTLET_NAME OUTLET_PARENT OUTLET_PARENT_1
--------- ------------------ --------------- ---------------
2 Yummies BSK 1


I can now dish out various queries that involve parent-child relationships on the chain of outlets.

The model described above works best only if the two critical assumptions are satisfied. If not, you may need to explore alternate ways to achieve this relationship - e.g.: moving the relationship data ( OUTLET_ID, OUTLET_PARENT) to a separate table, etc.