Thorsten Schöning created AXIS2-5745:
----------------------------------------

             Summary: Changing a service name doesn't update its TypeTable 
struct
                 Key: AXIS2-5745
                 URL: https://issues.apache.org/jira/browse/AXIS2-5745
             Project: Axis2
          Issue Type: Bug
          Components: kernel
    Affects Versions: 1.6.2
         Environment: Windows 8.1 x86-64, Tomcat 7.0.68 x86-64
            Reporter: Thorsten Schöning


I have an implementation of ServiceLifeCycle in which I'm overriding startUp 
and change the name of my service in some special way to make my deployment 
easier. I'm simply implementing some kind of mandator mechanism based on 
exploded services and their unique name in the file system.

This worked pretty fine the last years, but today I encountered that Axis2 is 
handling structures internally in which the service name is used as some 
component of a key. Those structures were built before startUp was called and 
were not updated on a changed service name. My service generated an exception 
for some reason, Axis2 tried to handle that and failed itself with a NPE, which 
made debugging pretty hard of course because the original exception was lost.

The NPE was thrown in the following line 183 of RPCMessageReceiver and the not 
up to date structure was TypeTable for the service, that's why elementQName was 
null instead of a valid object. Gladly I was able to access that map in my 
ServiceLifeCycle implementation and update the generated keys and QNames with 
my new updated service name. I would have expected that if I'm able to change 
the service name, structs containing it would get updated automatically by Axis 
2, which at least for TypeTable currently isn't the case.

{CODE}
175            Class[] exceptionTypes = method.getExceptionTypes();
176            for (Class exceptionType : exceptionTypes){
177                if 
(exceptionType.getName().equals(cause.getClass().getName())){
178                    // this is an bussiness logic exception so handle it 
properly
179                    String partQName = inMessage.getAxisService().getName() 
+ getSimpleClassName(exceptionType);
180                    TypeTable typeTable = 
inMessage.getAxisService().getTypeTable();
181                    QName elementQName = 
typeTable.getQNamefortheType(partQName);
182                    SOAPFactory fac = getSOAPFactory(inMessage);
183                    OMElement exceptionElement = 
fac.createOMElement(elementQName);
184
185                    if 
(exceptionType.getName().equals(Exception.class.getName())){
186                        // this is an exception class. so create a element 
by hand and add the message
187                       OMElement innterExceptionElement = 
fac.createOMElement(elementQName);
188                       OMElement messageElement = 
fac.createOMElement("Message", inMessage.getAxisService().getTargetNamespace(), 
null);
189                       messageElement.setText(cause.getMessage());
{CODE}

http://grepcode.com/file/repo1.maven.org/maven2/org.apache.axis2/axis2-adb/1.6.2/org/apache/axis2/rpc/receivers/RPCMessageReceiver.java/#183

I'm currently unable to build Axis2 from src and am not sure where one would 
implement such a change, therefore can't provide patches, but instead I'll 
simply post my implemantation of the change for TypeTable in my 
ServiceLifeCycle:

{CODE}
private void updateSvcTypeTable(AxisService     service,
                                                                String          
oldSvcName,
                                                                String          
newSvcName)
{
        TypeTable                       tt                              = 
service.getTypeTable();
        @SuppressWarnings("unchecked")
        Map<String, QName>      schemaMap               = 
tt.getComplexSchemaMap();
        Map<String, QName>      addSchemaMap    = new HashMap<String, 
QName>(schemaMap.size());

        for (Iterator<Entry<String, QName>>     it = 
schemaMap.entrySet().iterator();
                                                                                
it.hasNext(); )
        {
                Entry<String, QName>    entry   = it.next();
                String                                  key             = 
entry.getKey();
                QName                                   value   = 
entry.getValue();

                if (!key.startsWith(oldSvcName))
                {
                        continue;
                }

                String newKeyRegExp             = String.format("^\\Q%s\\E", 
oldSvcName);
                String newValueRegExp   = String.format("}\\Q%s\\E", 
oldSvcName);
                String newKey                   = 
key.replaceFirst(newKeyRegExp, newSvcName);
                String newValue                 = 
value.toString().replaceFirst(newValueRegExp, "}".concat(newSvcName));

                addSchemaMap.put(newKey, QName.valueOf(newValue));
                it.remove();
        }
        schemaMap.putAll(addSchemaMap);
}
{CODE}

{CODE}
private void changeSvcName(AxisService service)
{
        logger.trace("Start: {}", service.getName());

        File    configDir       = this.getConfigDir(service);
        File    svcDir          = configDir.getParentFile().getParentFile();
        String  oldSvcName      = service.getName();
        String  newSvcName      = 
svcDir.getName().concat(".").concat(oldSvcName);

        service.setName(newSvcName);
        this.updateSvcTypeTable(service, oldSvcName, newSvcName);

        logger.trace("End: {}", service.getName());
}
{CODE}




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to