IBM Support

Generating a Web Service from a JavaBean that uses custom exceptions, the "convert" method defined in <Name>DeserProxy.java calls a constructor that is not defined

Troubleshooting


Problem

In IBM® Rational® Application Develper for WebSphere® Software, when you develop a Web Service from a JavaBean™, making use of custom defined exceptions, you might encounter a compilation error if the service uses a hierarchy of exceptions related by inheritance, and the constructor of the child exception does not have all the parameters of the constructor in the parent exception.

Cause

The compilation error can be reproduced performing the following steps:
1. In Windows->Preferences->Web Services->Code Generation->IBM WebSphere Runtime
check the property:
Do not overwrite overloadable Java classes
This is important because it means that the custom exception classes will be used. If this option is not checked, default exception classes are created by default when generating the service, and the compilation error does not occur.

2. Create a new Dynamic Web Project associated to the WebSphere v6 runtime, J2EE™ version 1.4.

3. Create a new exception class with a constructor with 2 parameters defined as:

package myexception;

public class SuperException extends Exception {
	protected int firstParameter;
	protected String secondParameter;

	public int getFirstParameter() {
		return firstParameter;
	}

	public void setFirstParameter(int firstParameter) {
		this.firstParameter = firstParameter;
	}

	public String getSecondParameter() {
		return secondParameter;
	}

	public void setSecondParameter(String secondParameter) {
		this.secondParameter = secondParameter;
	}
	public SuperException(int arg0,String arg1){
		firstParameter=arg0;
		secondParameter=arg1;
	}
	public SuperException(){}
}

4. Create a child exception class that has a constructor with only one parameter
and that invokes the constructor of the superclass with constant arguments:
package myexception;

public class ChildException extends SuperException {
	private long childParameter;
	public ChildException(){}
	public ChildException(long arg2){
		super(10,"ConstantString");
		childParameter=arg2;
	}
	public long getChildParameter() {
		return childParameter;
	}
	public void setChildParameter(long childParameter) {
		this.childParameter = childParameter;
	}
}

5. Create a class that uses the two exceptions above:
package mybeans;

import myexception.ChildException;
import myexception.SuperException;

public class B1 {
 public int op1(int x)throws SuperException{
 	if (x>100)throw new SuperException(100,"X greater than 100");
 	return x+100;
 }
 public int op2(int x)throws ChildException{
 	if (x>100)throw new ChildException(100);

 return x*100;	
 }
}

6. Select the class B1 and choose:
Web Services->Create Web Service
Type: JavaBean Web Service
Accept all defaults and finish (Use Document/Literal)

7. You will get an error:
Deployment from com.ibm.etools.webservice.was.deployer.WSDeployer had errors: 
Deployment error: 
org.eclipse.core.runtime.CoreException: Deployment error:
	at com.ibm.etools.webservice.was.deployer.WSDeployer.runWSDeploy(Unknown Source)
	at com.ibm.etools.webservice.was.deployer.WSDeployer.execute(Unknown Source)
	at com.ibm.wtp.j2ee.deploy.J2EEDeployOperation.deploy(Unknown Source)
	at com.ibm.wtp.j2ee.deploy.J2EEDeployOperation.execute(Unknown Source)
	at com.ibm.wtp.common.operation.WTPOperation.doRun(Unknown Source)
	at com.ibm.wtp.common.operation.WTPOperation$1.run(Unknown Source)
	at org.eclipse.core.internal.resources.Workspace.run(Unknown Source)
	at org.eclipse.core.internal.resources.Workspace.run(Unknown Source)
	at com.ibm.wtp.common.operation.WTPOperation.run(Unknown Source)
	at com.ibm.ws.rd.websphere.jobs.J2EEDeployOperationJob$1.run(Unknown Source)
	at org.eclipse.core.internal.resources.Workspace.run(Unknown Source)
	at com.ibm.ws.rd.websphere.jobs.J2EEDeployOperationJob.invokeDeploymentFramework(Unknown Source)
	at com.ibm.ws.rd.websphere.jobs.J2EEDeployOperationJob.run(Unknown Source)
	at org.eclipse.core.internal.jobs.Worker.run(Unknown Source)


8. If you examine the generated code you will see the following problem:
package myexception;

public class ChildException_DeserProxy  extends myexception.SuperException_DeserProxy  {
    private long childParameter;

    public ChildException_DeserProxy() {
    }

    public long getChildParameter() {
        return childParameter;
    }

    public void setChildParameter(long childParameter) {
        this.childParameter = childParameter;
    }

    public java.lang.Object convert() {
      return new myexception.ChildException(
        getFirstParameter(),
        getSecondParameter(),
        getChildParameter());
    }
}

The "convert" method assumes that the class ChildException has a constructor containing all parameters needed to initialize the superclass SuperClass plus the parameter owned by the class ChildException.
This is a consequence of the following definition that was created in the wsdl file:

 <schema targetNamespace="http://myexception"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:impl="http://mybeans"
xmlns:intf="http://mybeans"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <complexType name="ChildException">
    <complexContent>
     <extension base="tns2:SuperException">
      <sequence>
       <element name="childParameter" type="xsd:long"/>
      </sequence>
     </extension>
    </complexContent>
   </complexType>
   <complexType name="SuperException">
    <sequence>
     <element name="firstParameter" type="xsd:int"/>
     <element name="secondParameter" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <element name="ChildException" nillable="true" type="tns2:ChildException"/>
   <element name="SuperException" nillable="true" type="tns2:SuperException"/>
  </schema>
 </wsdl:types>

Resolving The Problem



Add to the class ChildException one more constructor with the form:

	public ChildException(int arg0, String arg1, long arg2){
		super(10,"ConstantString");
		childParameter=arg2;
	}

This will achieve the same result of the original code, however it might not be desirable to effectively discard two of the three elements from the incoming fault message and replacing their values by constant values embedded into the implementation.

JAX-RPC 1.1 does not restrict a service specific exception to having a single constructor, however, it does require that a service specific exception have a constructor equipped with parameters in a one-to-one relationship with all gettable properties on the exception, complexType extensions and inheritance notwithstanding:

Section 4.3.6: "Each element inside the xsd:complexType is mapped to a getter method and a parameter in the constructor of the Java™ exception.".

Section 5.5.5: "Multiple fields (each with a getter method and corresponding parameter in the constructor) in the Java exception class are mapped to elements of the xsd:complexType."

JAX-RPC 1.1 relies on the exception class' constructor (versus setters) in order to deserialize the [three] elements of the fault message into the [three] properties of the class. In the absence of the correct constructor, a JAX-RPC compliant runtime cannot deserialize the necessary state into the Bean.

This issue arises because the requirements for the creation of Web services bottom-up from Java as specified in JAX-RPC 1.1 JAX-RPC 2.0 (see JSR 224 in the Related URL section) has resolved this situation in part by removing any expectations on the constructor for conventional (versus JAXB-enabled) exception classes.



Related Information

[{"Product":{"code":"SSRTLW","label":"Rational Application Developer for WebSphere Software"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":"Web Services Development","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"6.0;6.0.0.1","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}},{"Product":{"code":"SSYK2S","label":"Rational Software Architect Designer"},"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Component":" ","Platform":[{"code":"","label":"Multi-Platform"}],"Version":"V6.0;V6.0.0.1","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}}]

Document Information

Modified date:
10 September 2020

UID

swg21215797