Andreas Veithen created AXIS-2880:
-------------------------------------
Summary: Type mappings should be registered in the locator instead
of the stub
Key: AXIS-2880
URL: https://issues.apache.org/jira/browse/AXIS-2880
Project: Axis
Issue Type: Bug
Components: Basic Architecture
Affects Versions: 1.4
Reporter: Andreas Veithen
Assignee: Andreas Veithen
Fix For: 1.4.1
The createCall method in a generated stub contains the following code:
// All the type mapping information is registered
// when the first call is made.
// The type mapping information is actually registered in
// the TypeMappingRegistry of the service, which
// is the reason why registration is only needed for the first call.
synchronized (this) {
if (firstCall()) {
// must set encoding style before registering serializers
_call.setEncodingStyle(null);
for (int i = 0; i < cachedSerFactories.size(); ++i) {
java.lang.Class cls = (java.lang.Class) cachedSerClasses.get(i);
javax.xml.namespace.QName qName =
(javax.xml.namespace.QName) cachedSerQNames.get(i);
java.lang.Object x = cachedSerFactories.get(i);
if (x instanceof Class) {
java.lang.Class sf = (java.lang.Class)
cachedSerFactories.get(i);
java.lang.Class df = (java.lang.Class)
cachedDeserFactories.get(i);
_call.registerTypeMapping(cls, qName, sf, df, false);
}
else if (x instanceof javax.xml.rpc.encoding.SerializerFactory) {
org.apache.axis.encoding.SerializerFactory sf =
(org.apache.axis.encoding.SerializerFactory)
cachedSerFactories.get(i);
org.apache.axis.encoding.DeserializerFactory df =
(org.apache.axis.encoding.DeserializerFactory)
cachedDeserFactories.get(i);
_call.registerTypeMapping(cls, qName, sf, df, false);
}
}
}
}
As noted in the comment, the type mapping is actually registered in the type
mapping registry of the service (implemented by the locator). This raises the
question why that registration is not done in the locator in the first place.
In fact, doing the registration before the first call in the stub has a couple
of issues:
* This is prone to concurrency issues as described in AXIS-2498.
* It unnecessarily increases the cost of creating a stub. Note that each stub
will actually attempt to perform the registration, but only the first one will
effectively modify the type mappings. Execution of the code shown above by
subsequently created stubs (from the same locator) will be a no-op because the
type mappings are already registered (and registerTypeMapping will silently
skip the registration).
* If the service has multiple ports, then the code (in the stub constructor)
that initializes the cachedSerClasses, cachedSerQNames, cachedSerFactories and
cachedDeserFactories fields is actually duplicated in each stub because the
same type mappings are registered in each stub (although with potentially
different encoding styles).
Note that if the code generator is changed so that type mappings are registered
in the locator, then the constructors of the stubs need to be changed:
public XxxStub() throws org.apache.axis.AxisFault {
this(null);
}
public XxxStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws
org.apache.axis.AxisFault {
this(service);
super.cachedEndpoint = endpointURL;
}
public XxxStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
if (service == null) {
super.service = new org.apache.axis.client.Service();
} else {
super.service = service;
}
...
}
Instead of creating a plain org.apache.axis.client.Service instance, the code
should create an instance of the locator. Note that this would still make a
difference for application code that directly creates a stub and passes a
reference to a Service that is not an instance of the locator. However, this is
a very unlikely scenario.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]