0 and 1’s

Process Explorer – Tool which provides Unix/Linux lsof command functionality for Windows

Posted in Uncategorized by Rama Krishna on September 15, 2009

lsof command available in Unix and Linux operating system provides insight to running program. As explained in previous blog, the command is helpful to find the list of jars loaded by a Java application.

To do the same on Windows operating system, use the Process Explorer program available at http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx.

Start the Process Explorer, select the process which you want to analyze and enter CTRL + L. This brings up a lower pane that displays all system resources accessed by the process including files, threads, directories, port, etc. Filter the type column and you will be able to find all currently open files used by the application.

The following image displays the list of jar files accessed by Eclipse IDE.

processExplorer

Reblog this post [with Zemanta]

WebService Client Target NameSpace clash

Posted in J2EE, Java, Uncategorized by Rama Krishna on September 28, 2008

When handling multiple web services, you may have encountered scenarios where two web services declare schema definition under same namespace. Having multiple elements defined under same name space is not a problem. But, defining a same element with different structure under same namespace but in different web service can create problem.

This situation can happen when there is no global repository for the schema definitions in a company. I will explain the situation in more detail.

Consider a company XYZ with web address www.xyz.com. The company has two enterprise applications A and B. The application A decides to expose business function as web services. Two different teams 1 and 2 in application A are working on building the web service.

Both the team use the same target namespace http://www.xyz.org/appA/.

Team 1 builds an web service WS-1. They create a element NewOperation.

The schema of the element NewOperation and part of the wsdl definition is listed below


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.xyz.org/appA/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile" targetNamespace="http://www.xyz.org/appA/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.xyz.org/appA/">
      <xsd:element name="NewOperation">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="in" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
   </wsdl:types>

Team 2 also builds an web service WS-2. They also create a element NewOperation.

The schema of the element NewOperation and part of the wsdl definition is listed below


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.xyz.org/appA/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NewWSDLFile" targetNamespace="http://www.xyz.org/appA/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.xyz.org/appA/">
      <xsd:element name="NewOperation">
        <xsd:complexType>
          <xsd:sequence>
              <xsd:element name="in" type="xsd:string" />
              <xsd:element name="in_1" type="xsd:string"></xsd:element>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
   </wsdl:types>

As you can see both the elements have the same name, but have different structure which is an not a good design. Since, both the team do not interact with other, they have failed to identify the flaw. Both, the team build server implementation of their web service and deploy each as EAR independent of the other. Both the teams do not face any issue, since both the server implementations are deployed independently.

Now, team in application B decides to use the web services provided by application A. They build client implementations for both the web services provided by A using standard build tools (clientgen from Weblogic). The build tools usually generate the java files (in a jar) binding the schema elements to classes created in the reverse namespace package (i.e., org.xyz.www.appA). They put the client jars of both the web service in the same classpath of the application B.

When they try to use the operations provided by the web service, they face exception related to serialization or deserialization whenever an operation involving the element NewOperation is involved. The exception can happen in either the WS-1 or WS-2 web service. This is because, a wrong class is used in the web service. As per java classpath rule, whenever NewOperation class needs to be loaded it finds only one version of the class depending on which client jar appears first. The other NewOperation class is never found by the application.

In order to resolve the issue, the team A needs to move the definition of the element NewOperation in one of the web service to a different target namespace. But this is a costly option, since WS-1 and WS-2 are already implemented and will require changes in the server implementation and also for all the clients using the web service.

The other option is for the client to use options provided in the build tools to generate class binding the schema definition in different package other than that generated by default for one of the web service.

This can done in Weblogic tool clientgen by adding the option typePackageName. Note the additional attribute typePackageName in the ant build script.


<clientgen wsdl="http://example.com/myapp/myservice.wsdl"
           packageName="myapp.myservice.client"
           clientJar="myapps/myService_client.jar"
       typePackageName="com.appB"
/>

Also the same can be done in Eclipse by checking the “Define custom mapping for namespace to package” option and defining the custom mapping when generating the client implementation of the web service.

This avoids the clash as the client implementations are generated under different package.

This problem needs to be avoided in first place when creating the web service. Each company needs to have a central repository where all the schema definitions are available to avoid duplication of element name under same target namespace.

Reblog this post [with Zemanta]

Take care when using SELECT SQL Statement with IN Clause

Posted in Java, sql by Rama Krishna on September 28, 2008

Consider the following code snippet


	public static String getMySqlStatement(ArrayList<String> dataValues) {
		if ((dataValues == null) || (dataValues.size() == 0)) {
			throw new IllegalArgumentException();
		}
		StringBuilder sql = new StringBuilder ("SELECT * FROM MY_TABLE WHERE MY_COLUMN IN (");
		StringBuilder colValues = new StringBuilder();
		for (String data: dataValues) {
			colValues.append("'").append(data).append("',");
		}
		//Remove the trailing comma(,) and add the final braces
		sql.append(colValues.substring(0, (colValues.length()-1))).append(")");
		return sql.toString();
	}

The method builds an Select query using the elements in the arraylist dataValues in the IN clause.
The SQL returned by the method executes normally when the size of dataValues is less then or equal to 1000. But, when the size of dataValues is greater than 1000, the SQL throws an exception.

This is because there is a limit on the number of parameters in the IN Clause. For Oracle 9i, the limit is 1000. The limit can vary based on database.

Hence, the above method does not work in all cases. It is required to build SQL queries based on the size of the parameters in the IN clause like breaking up into multiple SQL statements and then combining the results. The above method is modified to return multiple SQL statements if the number of parameters is greater than the limit(in this case 1000).


    public static ArrayList<String> getMySqlStatements(ArrayList<String> dataValues) {
        if ((dataValues == null) || (dataValues.size() == 0)) {
            throw new IllegalArgumentException();
        }
        final int IN_PARAMETER_LIMIT = 1000;
        ArrayList<String> sqlStatements = new ArrayList<String>();
        StringBuilder sql = new StringBuilder ("SELECT * FROM MY_TABLE WHERE MY_COLUMN IN (");
        StringBuilder colValues = null;
        for (int i=0, j=0, length= dataValues.size(); i < length; i++) {
            if (colValues == null) {
                colValues = new StringBuilder();
            }
            j++;
            String data = dataValues.get(i);
            colValues.append("'").append(data).append("',");
            if (j == IN_PARAMETER_LIMIT) {
                sqlStatements.add((sql.append(colValues.substring(0, (colValues.length()-1))).append(")")).toString());
                j=0;
                colValues = null;
            }
        }
        return sqlStatements;
    }

This error may not show up in normal circumstances unless the number of parameters is greater than 1000. To find bugs due to software limits, it is always required to unit test under maximum load conditions.

Tagged with: , ,