Getting idl2java Ant Task up and running
This blog is about using idl2java Ant task to generate Java artifacts from CORBA IDL file. The idl2java Ant task is provided by OpenORB, an open source CORBA implementation.
Any CORBA project starts with a idl file that describes the interface or service. Then, we use a tool to generate language specific client and server artifacts. The tool can be a command line executable or a Ant task.
The following idl file represents a simple attendance service.
module tracker {
interface attendance {
long addEmployee(in string empName);
string removeEmployee(in long empId);
void enterEmp(in long empId, in string empName);
string empReport(in long empId);
};
};
The Ant Task idl2java is contained in openorb_orb_tools-<version>.jar. So, i add the jar to the Apache Ant Classpath. The task defination class is org.openorb.compiler.taskdefs.Idl2Java. I add the task defination.
The Ant build file is a very simple one. It invokes the idl2java task with two attributes, one points to the directory which contains the idl file and another points to the directory where the generated source files are dumped.
<project>
<property name="idlDir" value="idl">
</property>
<property name="srcDir" value="src">
</property>
<target name="idl2java_task">
<idl2java srcdir="${idlDir}" destdir="${srcDir}" verbose="false">
</idl2java>
</target>
</project>
The Ant task idl2java has extensive set of options available. Check the documentation for more details.
Execute the Ant task and the build fails with the following error.
Buildfile: C:\java\myProjWorkSpace001\CORBAProj\build.xml
idl2java_task:
BUILD FAILED
java.lang.NoClassDefFoundError: org/openorb/util/launcher/CompoundClassLoader
Total time: 188 milliseconds
As per error message, a class is missing. The documentation does not mention of any additional jar that needs to be added. I decided to check more on this missing class in additional jars that accompany the OpenORB distribution. But, none of them have it. Then, i checked out in website http://www.findjar.com and found that the jar tmporb-tools-1.0-DEAD.jar had the class. The website http://www.findjar.com provided a maven link for the jar, but i got 404 error. Searched in Google and found a maven repository which had it.
I added this jar to the Ant Classpath and executed the build script again. The ant task executed successfully and the Java artifacts coresponding to the idl are generated.
C:\java\myProjWorkSpace001\CORBAProj\src>cd tracker C:\java\myProjWorkSpace001\CORBAProj\src\tracker>ls -ltr total 22 a----- 3444 26-Nov-109 00:33 attendanceHelper.java a----- 531 26-Nov-109 00:33 attendanceOperations.java a----- 1809 26-Nov-109 00:33 attendancePOATie.java a----- 7360 26-Nov-109 00:33 _attendanceStub.java a----- 3359 26-Nov-109 00:33 attendancePOA.java a----- 1244 26-Nov-109 00:33 attendanceHolder.java a----- 222 26-Nov-109 00:33 attendance.java
Next, to move ahead with implementation.
Process Explorer – Tool which provides Unix/Linux lsof command functionality for Windows
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.

WebService Client Target NameSpace clash
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]](http://img.zemanta.com/reblog_e.png?x-id=448f7c6f-20ee-4302-a5d0-d23cf2d6e726)
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=72dd77e7-6c5f-4aa6-b684-a68d5b1d4f12)

![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=567a04c6-e9c5-4145-9c97-ede5f8d425e3)


leave a comment