DFS client performance

All that time I did think that it is not possible to impress me if we are dealing with performance in Documentum, but on the last week my colleagues did that 🙂 Their problem was following: my colleagues had implemented integration service which heavily uses Documentum Foundation Services and on the last week they have started experiencing difficulties with performance, from java side their observations were looking like:

"Thread-1739" daemon prio=10 tid=0x00002aaac0f09000 nid=0x34bc runnable [0x000000004487f000]
   java.lang.Thread.State: RUNNABLE
	at org.jboss.modules.ModuleClassLoader.loadResourceLocal(ModuleClassLoader.java:305)
	at org.jboss.modules.ModuleClassLoader$1.loadResourceLocal(ModuleClassLoader.java:84)
	at org.jboss.modules.Module.getResources(Module.java:592)
	at org.jboss.modules.ModuleClassLoader.findResources(ModuleClassLoader.java:489)
	at org.jboss.modules.ConcurrentClassLoader.getResources(ConcurrentClassLoader.java:288)
	at java.lang.ClassLoader.getResources(ClassLoader.java:1181)
	at com.documentum.fc.client.impl.bof.classmgmt.DelayedDelegationClassLoader.getResources(DelayedDelegationClassLoader.java:103)
	at com.sun.xml.ws.util.ServiceFinder$LazyIterator.hasNext(ServiceFinder.java:351)
	at com.sun.xml.ws.util.ServiceFinder.toArray(ServiceFinder.java:225)
	at com.sun.xml.ws.client.WSServiceDelegate.parseWSDL(WSServiceDelegate.java:265)
	at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:228)
	at com.sun.xml.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:176)
	at com.sun.xml.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:104)
	at javax.xml.ws.Service.<init>(Service.java:77)
	at com.emc.documentum.fs.services.core.ObjectService.<init>(ObjectService.java:68)
	at sun.reflect.GeneratedConstructorAccessor530.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.newWebServiceClient(DfsSoapService.java:176)
	- locked <0x0000000709a71eb0> (a java.lang.Class for com.emc.documentum.fs.services.core.ObjectService)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.init(DfsSoapService.java:69)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.getBindingProvider(DfsSoapService.java:62)
	at com.emc.documentum.fs.rt.context.impl.HttpSessionInvocationHandler.invoke(HttpSessionInvocationHandler.java:54)
	at com.emc.documentum.fs.rt.context.impl.RemoteServiceInterfaceInvocationHandler.invoke(RemoteServiceInterfaceInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.ReturnedContentTransformationHandler.invoke(ReturnedContentTransformationHandler.java:45)
	at com.emc.documentum.fs.rt.context.impl.OperationOptionsHandler.invoke(OperationOptionsHandler.java:74)
	at com.emc.documentum.fs.rt.context.impl.ContextThreadLocalInvocationHandler.invoke(ContextThreadLocalInvocationHandler.java:48)
	at com.emc.documentum.fs.rt.context.impl.ServiceContextInvocationHandler.invoke(ServiceContextInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.FileRegistryCleanupHandler.invoke(FileRegistryCleanupHandler.java:24)
	at com.sun.proxy.$Proxy166.get(Unknown Source)

...

"Thread-1737" daemon prio=10 tid=0x00002aaac0aa1000 nid=0x34ba waiting for monitor entry [0x0000000044d84000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.newWebServiceClient(DfsSoapService.java:171)
	- waiting to lock <0x0000000709b6e710> (a java.lang.Class for com.emc.documentum.fs.services.core.QueryService)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.init(DfsSoapService.java:69)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.getBindingProvider(DfsSoapService.java:62)
	at com.emc.documentum.fs.rt.context.impl.HttpSessionInvocationHandler.invoke(HttpSessionInvocationHandler.java:54)
	at com.emc.documentum.fs.rt.context.impl.RemoteServiceInterfaceInvocationHandler.invoke(RemoteServiceInterfaceInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.ReturnedContentTransformationHandler.invoke(ReturnedContentTransformationHandler.java:45)
	at com.emc.documentum.fs.rt.context.impl.OperationOptionsHandler.invoke(OperationOptionsHandler.java:74)
	at com.emc.documentum.fs.rt.context.impl.ContextThreadLocalInvocationHandler.invoke(ContextThreadLocalInvocationHandler.java:48)
	at com.emc.documentum.fs.rt.context.impl.ServiceContextInvocationHandler.invoke(ServiceContextInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.FileRegistryCleanupHandler.invoke(FileRegistryCleanupHandler.java:24)
	at com.sun.proxy.$Proxy150.execute(Unknown Source)

...

"Thread-1736" daemon prio=10 tid=0x00002aaac141e000 nid=0x34b5 runnable [0x000000004054f000]
   java.lang.Thread.State: RUNNABLE
	at java.util.HashMap.initHashSeedAsNeeded(HashMap.java:337)
	at java.util.HashMap.inflateTable(HashMap.java:317)
	at java.util.HashMap.<init>(HashMap.java:296)
	at java.util.LinkedHashMap.<init>(LinkedHashMap.java:212)
	at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:270)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:117)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:70)
	at java.lang.reflect.Field.declaredAnnotations(Field.java:1128)
	- locked <0x00000007b23b6590> (a java.lang.reflect.Field)
	at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:1121)
	at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:197)
	at com.sun.xml.bind.v2.model.annotation.RuntimeInlineAnnotationReader.getAllFieldAnnotations(RuntimeInlineAnnotationReader.java:69)
	at com.sun.xml.bind.v2.model.annotation.RuntimeInlineAnnotationReader.getAllFieldAnnotations(RuntimeInlineAnnotationReader.java:53)
	at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.findFieldProperties(ClassInfoImpl.java:371)
	at com.sun.xml.bind.v2.model.impl.ClassInfoImpl.getProperties(ClassInfoImpl.java:301)
	at com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl.getProperties(RuntimeClassInfoImpl.java:176)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:243)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:100)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:209)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:95)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:315)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:270)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:100)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:209)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:95)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:315)
	at com.sun.xml.bind.v2.model.impl.TypeRefImpl.calcRef(TypeRefImpl.java:92)
	at com.sun.xml.bind.v2.model.impl.TypeRefImpl.getTarget(TypeRefImpl.java:69)
	at com.sun.xml.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:58)
	at com.sun.xml.bind.v2.model.impl.RuntimeTypeRefImpl.getTarget(RuntimeTypeRefImpl.java:51)
	at com.sun.xml.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:74)
	at com.sun.xml.bind.v2.model.impl.ElementPropertyInfoImpl$1.get(ElementPropertyInfoImpl.java:77)
	at java.util.AbstractList$Itr.next(AbstractList.java:358)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:255)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:100)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getClassInfo(ModelBuilder.java:209)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:95)
	at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.getClassInfo(RuntimeModelBuilder.java:81)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:315)
	at com.sun.xml.bind.v2.model.impl.RegistryInfoImpl.<init>(RegistryInfoImpl.java:99)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.addRegistry(ModelBuilder.java:357)
	at com.sun.xml.bind.v2.model.impl.ModelBuilder.getTypeInfo(ModelBuilder.java:327)
	at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:441)
	at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:288)
	at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1111)
	at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
	at com.sun.xml.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:106)
	at com.sun.xml.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:109)
	at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:159)
	at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:152)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:151)
	at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:94)
	at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:255)
	at com.sun.xml.ws.client.WSServiceDelegate.createSEIPortInfo(WSServiceDelegate.java:698)
	at com.sun.xml.ws.client.WSServiceDelegate.addSEI(WSServiceDelegate.java:686)
	at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:341)
	at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:324)
	at com.sun.xml.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:306)
	at javax.xml.ws.Service.getPort(Service.java:119)
	at com.emc.documentum.fs.services.core.QueryService.getQueryServicePort(QueryService.java:66)
	at sun.reflect.GeneratedMethodAccessor143.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:606)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.newWebServiceClient(DfsSoapService.java:179)
	- locked <0x0000000709b6e710> (a java.lang.Class for com.emc.documentum.fs.services.core.QueryService)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.init(DfsSoapService.java:69)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.getBindingProvider(DfsSoapService.java:62)
	at com.emc.documentum.fs.rt.context.impl.HttpSessionInvocationHandler.invoke(HttpSessionInvocationHandler.java:54)
	at com.emc.documentum.fs.rt.context.impl.RemoteServiceInterfaceInvocationHandler.invoke(RemoteServiceInterfaceInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.ReturnedContentTransformationHandler.invoke(ReturnedContentTransformationHandler.java:45)
	at com.emc.documentum.fs.rt.context.impl.OperationOptionsHandler.invoke(OperationOptionsHandler.java:74)
	at com.emc.documentum.fs.rt.context.impl.ContextThreadLocalInvocationHandler.invoke(ContextThreadLocalInvocationHandler.java:48)
	at com.emc.documentum.fs.rt.context.impl.ServiceContextInvocationHandler.invoke(ServiceContextInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.FileRegistryCleanupHandler.invoke(FileRegistryCleanupHandler.java:24)
	at com.sun.proxy.$Proxy150.execute(Unknown Source)

...

"EJB default - 5" prio=10 tid=0x0000000017f20000 nid=0x77a9 waiting for monitor entry [0x0000000043f75000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.newWebServiceClient(DfsSoapService.java:171)
	- waiting to lock <0x00000007098434a8> (a java.lang.Class for com.emc.documentum.fs.services.core.QueryService)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.init(DfsSoapService.java:69)
	at com.emc.documentum.fs.rt.context.impl.DfsSoapService.getBindingProvider(DfsSoapService.java:62)
	at com.emc.documentum.fs.rt.context.impl.HttpSessionInvocationHandler.invoke(HttpSessionInvocationHandler.java:54)
	at com.emc.documentum.fs.rt.context.impl.RemoteServiceInterfaceInvocationHandler.invoke(RemoteServiceInterfaceInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.ReturnedContentTransformationHandler.invoke(ReturnedContentTransformationHandler.java:45)
	at com.emc.documentum.fs.rt.context.impl.OperationOptionsHandler.invoke(OperationOptionsHandler.java:74)
	at com.emc.documentum.fs.rt.context.impl.ContextThreadLocalInvocationHandler.invoke(ContextThreadLocalInvocationHandler.java:48)
	at com.emc.documentum.fs.rt.context.impl.ServiceContextInvocationHandler.invoke(ServiceContextInvocationHandler.java:30)
	at com.emc.documentum.fs.rt.context.impl.FileRegistryCleanupHandler.invoke(FileRegistryCleanupHandler.java:24)
	at com.sun.proxy.$Proxy193.execute(Unknown Source)

Obviously, heavy calls are: com.sun.xml.ws.client.WSServiceDelegate#parseWSDL and com.sun.xml.bind.api.JAXBRIContext#newInstance, plus somebody in EMC made it more slower my placing synchronized keyword into com.emc.documentum.fs.rt.context.impl.DfsSoapService#newWebServiceClient method. Corresponding java code, written by my colleagues, was looking like:

public static QueryResult query(final String query,
        final String repository, final String userName,
        final String password) throws ServiceException {
    IServiceContext context = ContextFactory.getInstance().newContext();
    Identity identity = new RepositoryIdentity(repository, userName,
            password, null);
    context.setIdentities(Arrays.asList(identity));
    IQueryService service = ServiceFactory.getInstance().getRemoteService(
            IQueryService.class, context);
    return service.execute(new PassthroughQuery(Arrays.asList(repository),
            query), null, null);
}

I’m not sure whether the above pattern is optimal or not from performance perspective because documentations says nothing about thread-safety of DFS remote services, but at first glance com.emc.documentum.fs.rt.context.impl.DfsSoapService and com.emc.documentum.fs.rt.context.impl.HttpSessionInvocationHandler classes seem not to be thread-safe, so we can’t share the same instance of IQueryService among multiple threads, moreover, it seems that we can’t reuse instances of DFS remote services as well, so instantiating new instance of IQueryService on every request sounds reasonable, but performance sucks. After some trials and failures I have found following option to improve performance of DFS clients:

package pro.documentum.dfs.remote.cache;

import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.ws.Endpoint;
import javax.xml.ws.EndpointReference;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.spi.Invoker;
import javax.xml.ws.spi.Provider;
import javax.xml.ws.spi.ServiceDelegate;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.w3c.dom.Element;

/**
 * @author Andrey B. Panfilov <andrey@panfilov.tel>
 */
public class CachingProviderImpl extends Provider {

    private static final ConcurrentMap<DelegateKey, ServiceDelegate> CACHE;

    private static final Provider DELEGATE;

    static {
        CACHE = new ConcurrentHashMap<>();
        DELEGATE = getProviderLoader();
    }

    public CachingProviderImpl() {
        super();
    }

    private static Provider getProviderLoader() {
        ServiceLoader<Provider> loader = ServiceLoader.load(Provider.class);
        Iterator<Provider> iterator = loader.iterator();
        Provider provider = null;
        while (iterator.hasNext()) {
            provider = iterator.next();
            if (isSelf(provider)) {
                continue;
            }
            return provider;
        }
        provider = Provider.provider();
        if (isSelf(provider)) {
            throw new WebServiceException(
                    "Unable to createEndpointReference Provider");
        }
        return provider;
    }

    public static boolean isSelf(final Provider provider) {
        return provider instanceof CachingProviderImpl;
    }

    @Override
    public ServiceDelegate createServiceDelegate(
            final URL wsdlDocumentLocation, final QName serviceName,
            final Class<? extends Service> serviceClass) {
        DelegateKey key = new DelegateKey(wsdlDocumentLocation, serviceName,
                serviceClass);
        ServiceDelegate result = CACHE.get(key);
        if (result == null) {
            result = DELEGATE.createServiceDelegate(wsdlDocumentLocation,
                    serviceName, serviceClass);
            ServiceDelegate temp = CACHE.putIfAbsent(key, result);
            if (temp != null) {
                result = temp;
            }
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public ServiceDelegate createServiceDelegate(
            final URL wsdlDocumentLocation, final QName serviceName,
            final Class serviceClass, final WebServiceFeature... features) {
        if (features == null || features.length == 0) {
            return createServiceDelegate(wsdlDocumentLocation, serviceName,
                    serviceClass);
        }
        return DELEGATE.createServiceDelegate(wsdlDocumentLocation,
                serviceName, serviceClass, features);
    }

    @Override
    public Endpoint createEndpoint(final String bindingId,
            final Object implementor) {
        return DELEGATE.createEndpoint(bindingId, implementor);
    }

    @Override
    public Endpoint createAndPublishEndpoint(final String address,
            final Object implementor) {
        return DELEGATE.createAndPublishEndpoint(address, implementor);
    }

    @Override
    public EndpointReference readEndpointReference(final Source eprInfoset) {
        return DELEGATE.readEndpointReference(eprInfoset);
    }

    @Override
    public <T> T getPort(final EndpointReference endpointReference,
            final Class<T> serviceEndpointInterface,
            final WebServiceFeature... features) {
        return DELEGATE.getPort(endpointReference, serviceEndpointInterface,
                features);
    }

    @Override
    public W3CEndpointReference createW3CEndpointReference(
            final String address, final QName serviceName,
            final QName portName, final List<Element> metadata,
            final String wsdlDocumentLocation,
            final List<Element> referenceParameters) {
        return DELEGATE.createW3CEndpointReference(address, serviceName,
                portName, metadata, wsdlDocumentLocation, referenceParameters);
    }

    @Override
    public W3CEndpointReference createW3CEndpointReference(
            final String address, final QName interfaceName,
            final QName serviceName, final QName portName,
            final List<Element> metadata, final String wsdlDocumentLocation,
            final List<Element> referenceParameters,
            final List<Element> elements, final Map<QName, String> attributes) {
        return DELEGATE.createW3CEndpointReference(address, interfaceName,
                serviceName, portName, metadata, wsdlDocumentLocation,
                referenceParameters, elements, attributes);
    }

    @Override
    public Endpoint createAndPublishEndpoint(final String address,
            final Object implementor, final WebServiceFeature... features) {
        return DELEGATE
                .createAndPublishEndpoint(address, implementor, features);
    }

    @Override
    public Endpoint createEndpoint(final String bindingId,
            final Object implementor, final WebServiceFeature... features) {
        return DELEGATE.createEndpoint(bindingId, implementor, features);
    }

    @Override
    public Endpoint createEndpoint(final String bindingId,
            final Class<?> implementorClass, final Invoker invoker,
            final WebServiceFeature... features) {
        return DELEGATE.createEndpoint(bindingId, implementorClass, invoker,
                features);
    }

    class DelegateKey {

        private final URL _wsdlLocation;

        private final QName _serviceName;

        private final Class<? extends Service> _serviceClass;

        DelegateKey(final URL wsdlLocation, final QName serviceName,
                final Class<? extends Service> serviceClass) {
            _wsdlLocation = wsdlLocation;
            _serviceName = serviceName;
            _serviceClass = serviceClass;
        }

        public URL getWsdlLocation() {
            return _wsdlLocation;
        }

        public QName getServiceName() {
            return _serviceName;
        }

        public Class<? extends Service> getServiceClass() {
            return _serviceClass;
        }

        @Override
        public boolean equals(final Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof DelegateKey)) {
                return false;
            }
            DelegateKey that = (DelegateKey) o;
            return Objects.equals(_wsdlLocation, that._wsdlLocation)
                    && Objects.equals(_serviceName, that._serviceName)
                    && Objects.equals(_serviceClass, that._serviceClass);
        }

        @Override
        public int hashCode() {
            return Objects.hash(_wsdlLocation, _serviceName, _serviceClass);
        }

    }

}

META-INF/services/javax.xml.ws.spi.Provider:

pro.documentum.dfs.remote.cache.CachingProviderImpl

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s