1.1 --- a/src/share/jaxws_classes/com/sun/xml/internal/ws/client/Stub.java Thu Apr 04 19:05:24 2013 -0700 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/client/Stub.java Tue Apr 09 14:51:13 2013 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -30,30 +30,41 @@ 1.11 import com.sun.xml.internal.stream.buffer.XMLStreamBuffer; 1.12 import com.sun.xml.internal.ws.addressing.WSEPRExtension; 1.13 import com.sun.xml.internal.ws.api.BindingID; 1.14 -import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties; 1.15 -import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties; 1.16 -import com.sun.xml.internal.ws.model.wsdl.WSDLProperties; 1.17 -import com.sun.xml.internal.ws.model.wsdl.WSDLServiceImpl; 1.18 import com.sun.xml.internal.ws.api.Component; 1.19 import com.sun.xml.internal.ws.api.ComponentFeature; 1.20 import com.sun.xml.internal.ws.api.ComponentFeature.Target; 1.21 import com.sun.xml.internal.ws.api.ComponentRegistry; 1.22 +import com.sun.xml.internal.ws.api.ComponentsFeature; 1.23 import com.sun.xml.internal.ws.api.EndpointAddress; 1.24 import com.sun.xml.internal.ws.api.WSBinding; 1.25 import com.sun.xml.internal.ws.api.WSService; 1.26 import com.sun.xml.internal.ws.api.addressing.AddressingVersion; 1.27 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; 1.28 import com.sun.xml.internal.ws.api.client.WSPortInfo; 1.29 +import com.sun.xml.internal.ws.api.message.AddressingUtils; 1.30 import com.sun.xml.internal.ws.api.message.Header; 1.31 import com.sun.xml.internal.ws.api.message.HeaderList; 1.32 +import com.sun.xml.internal.ws.api.message.MessageHeaders; 1.33 import com.sun.xml.internal.ws.api.message.Packet; 1.34 import com.sun.xml.internal.ws.api.model.SEIModel; 1.35 import com.sun.xml.internal.ws.api.model.wsdl.WSDLPort; 1.36 -import com.sun.xml.internal.ws.api.pipe.*; 1.37 +import com.sun.xml.internal.ws.api.pipe.ClientTubeAssemblerContext; 1.38 +import com.sun.xml.internal.ws.api.pipe.Engine; 1.39 +import com.sun.xml.internal.ws.api.pipe.Fiber; 1.40 +import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptorFactory; 1.41 +import com.sun.xml.internal.ws.api.pipe.SyncStartForAsyncFeature; 1.42 +import com.sun.xml.internal.ws.api.pipe.Tube; 1.43 +import com.sun.xml.internal.ws.api.pipe.TubelineAssembler; 1.44 +import com.sun.xml.internal.ws.api.pipe.TubelineAssemblerFactory; 1.45 +import com.sun.xml.internal.ws.api.server.Container; 1.46 +import com.sun.xml.internal.ws.api.server.ContainerResolver; 1.47 import com.sun.xml.internal.ws.binding.BindingImpl; 1.48 import com.sun.xml.internal.ws.developer.JAXWSProperties; 1.49 import com.sun.xml.internal.ws.developer.WSBindingProvider; 1.50 +import com.sun.xml.internal.ws.model.wsdl.WSDLDirectProperties; 1.51 import com.sun.xml.internal.ws.model.wsdl.WSDLPortImpl; 1.52 +import com.sun.xml.internal.ws.model.wsdl.WSDLPortProperties; 1.53 +import com.sun.xml.internal.ws.model.wsdl.WSDLProperties; 1.54 import com.sun.xml.internal.ws.resources.ClientMessages; 1.55 import com.sun.xml.internal.ws.util.Pool; 1.56 import com.sun.xml.internal.ws.util.Pool.TubePool; 1.57 @@ -66,6 +77,7 @@ 1.58 import javax.xml.ws.BindingProvider; 1.59 import javax.xml.ws.EndpointReference; 1.60 import javax.xml.ws.RespectBindingFeature; 1.61 +import javax.xml.ws.Response; 1.62 import javax.xml.ws.WebServiceException; 1.63 import javax.xml.ws.http.HTTPBinding; 1.64 import javax.xml.ws.wsaddressing.W3CEndpointReference; 1.65 @@ -76,7 +88,9 @@ 1.66 import java.util.Set; 1.67 import java.util.concurrent.CopyOnWriteArraySet; 1.68 import java.util.concurrent.Executor; 1.69 -import org.xml.sax.InputSource; 1.70 +import java.util.logging.Level; 1.71 +import java.util.logging.Logger; 1.72 +import javax.management.ObjectName; 1.73 1.74 /** 1.75 * Base class for stubs, which accept method invocations from 1.76 @@ -232,49 +246,64 @@ 1.77 } 1.78 1.79 private Stub(WSServiceDelegate owner, @Nullable Tube master, @Nullable WSPortInfo portInfo, QName portname, BindingImpl binding, @Nullable WSDLPort wsdlPort, EndpointAddress defaultEndPointAddress, @Nullable WSEndpointReference epr) { 1.80 - this.owner = owner; 1.81 - this.portInfo = portInfo; 1.82 - this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null); 1.83 - this.portname = portname; 1.84 - if (portname == null) { 1.85 - if (portInfo != null) 1.86 - this.portname = portInfo.getPortName(); 1.87 - else if (wsdlPort != null) 1.88 - this.portname = wsdlPort.getName(); 1.89 + Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); 1.90 + try { 1.91 + this.owner = owner; 1.92 + this.portInfo = portInfo; 1.93 + this.wsdlPort = wsdlPort != null ? wsdlPort : (portInfo != null ? portInfo.getPort() : null); 1.94 + this.portname = portname; 1.95 + if (portname == null) { 1.96 + if (portInfo != null) { 1.97 + this.portname = portInfo.getPortName(); 1.98 + } else if (wsdlPort != null) { 1.99 + this.portname = wsdlPort.getName(); 1.100 + } 1.101 + } 1.102 + this.binding = binding; 1.103 + 1.104 + ComponentFeature cf = binding.getFeature(ComponentFeature.class); 1.105 + if (cf != null && Target.STUB.equals(cf.getTarget())) { 1.106 + components.add(cf.getComponent()); 1.107 + } 1.108 + ComponentsFeature csf = binding.getFeature(ComponentsFeature.class); 1.109 + if (csf != null) { 1.110 + for (ComponentFeature cfi : csf.getComponentFeatures()) { 1.111 + if (Target.STUB.equals(cfi.getTarget())) 1.112 + components.add(cfi.getComponent()); 1.113 + } 1.114 + } 1.115 + 1.116 + // if there is an EPR, EPR's address should be used for invocation instead of default address 1.117 + if (epr != null) { 1.118 + this.requestContext.setEndPointAddressString(epr.getAddress()); 1.119 + } else { 1.120 + this.requestContext.setEndpointAddress(defaultEndPointAddress); 1.121 + } 1.122 + this.engine = new Engine(getStringId(), owner.getContainer(), owner.getExecutor()); 1.123 + this.endpointReference = epr; 1.124 + wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort); 1.125 + 1.126 + this.cleanRequestContext = this.requestContext.copy(); 1.127 + 1.128 + // ManagedObjectManager MUST be created before the pipeline 1.129 + // is constructed. 1.130 + 1.131 + managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this); 1.132 + 1.133 + if (master != null) { 1.134 + this.tubes = new TubePool(master); 1.135 + } else { 1.136 + this.tubes = new TubePool(createPipeline(portInfo, binding)); 1.137 + } 1.138 + 1.139 + addrVersion = binding.getAddressingVersion(); 1.140 + 1.141 + // This needs to happen after createPipeline. 1.142 + // TBD: Check if it needs to happen outside the Stub constructor. 1.143 + managedObjectManager.resumeJMXRegistration(); 1.144 + } finally { 1.145 + ContainerResolver.getDefault().exitContainer(old); 1.146 } 1.147 - this.binding = binding; 1.148 - 1.149 - ComponentFeature cf = binding.getFeature(ComponentFeature.class); 1.150 - if (cf != null && Target.STUB.equals(cf.getTarget())) { 1.151 - components.add(cf.getComponent()); 1.152 - } 1.153 - 1.154 - // if there is an EPR, EPR's address should be used for invocation instead of default address 1.155 - if (epr != null) 1.156 - this.requestContext.setEndPointAddressString(epr.getAddress()); 1.157 - else 1.158 - this.requestContext.setEndpointAddress(defaultEndPointAddress); 1.159 - this.engine = new Engine(toString(), owner.getExecutor()); 1.160 - this.endpointReference = epr; 1.161 - wsdlProperties = (wsdlPort == null) ? new WSDLDirectProperties(owner.getServiceName(), portname) : new WSDLPortProperties(wsdlPort); 1.162 - 1.163 - this.cleanRequestContext = this.requestContext.copy(); 1.164 - 1.165 - // ManagedObjectManager MUST be created before the pipeline 1.166 - // is constructed. 1.167 - 1.168 - managedObjectManager = new MonitorRootClient(this).createManagedObjectManager(this); 1.169 - 1.170 - if (master != null) 1.171 - this.tubes = new TubePool(master); 1.172 - else 1.173 - this.tubes = new TubePool(createPipeline(portInfo, binding)); 1.174 - 1.175 - addrVersion = binding.getAddressingVersion(); 1.176 - 1.177 - // This needs to happen after createPipeline. 1.178 - // TBD: Check if it needs to happen outside the Stub constructor. 1.179 - managedObjectManager.resumeJMXRegistration(); 1.180 } 1.181 1.182 /** 1.183 @@ -293,9 +322,10 @@ 1.184 BindingID bindingId = portInfo.getBindingId(); 1.185 1.186 TubelineAssembler assembler = TubelineAssemblerFactory.create( 1.187 - Thread.currentThread().getContextClassLoader(), bindingId); 1.188 - if (assembler == null) 1.189 - throw new WebServiceException("Unable to process bindingID=" + bindingId); // TODO: i18n 1.190 + Thread.currentThread().getContextClassLoader(), bindingId, owner.getContainer()); 1.191 + if (assembler == null) { 1.192 + throw new WebServiceException("Unable to process bindingID=" + bindingId); // TODO: i18n 1.193 + } 1.194 return assembler.createClient( 1.195 new ClientTubeAssemblerContext( 1.196 portInfo.getEndpointAddress(), 1.197 @@ -328,6 +358,7 @@ 1.198 } 1.199 } 1.200 1.201 + @Override 1.202 public WSPortInfo getPortInfo() { 1.203 return portInfo; 1.204 } 1.205 @@ -339,8 +370,9 @@ 1.206 public 1.207 @Nullable 1.208 OperationDispatcher getOperationDispatcher() { 1.209 - if (operationDispatcher == null && wsdlPort != null) 1.210 + if (operationDispatcher == null && wsdlPort != null) { 1.211 operationDispatcher = new OperationDispatcher(wsdlPort, binding, null); 1.212 + } 1.213 return operationDispatcher; 1.214 } 1.215 1.216 @@ -403,10 +435,13 @@ 1.217 packet.component = this; 1.218 configureRequestPacket(packet, requestContext); 1.219 Pool<Tube> pool = tubes; 1.220 - if (pool == null) 1.221 + if (pool == null) { 1.222 throw new WebServiceException("close method has already been invoked"); // TODO: i18n 1.223 + } 1.224 1.225 Fiber fiber = engine.createFiber(); 1.226 + configureFiber(fiber); 1.227 + 1.228 // then send it away! 1.229 Tube tube = pool.take(); 1.230 1.231 @@ -433,16 +468,20 @@ 1.232 1.233 // to make it multi-thread safe we need to first get a stable snapshot 1.234 Header[] hl = userOutboundHeaders; 1.235 - if (hl != null) 1.236 - packet.getMessage().getHeaders().addAll(hl); 1.237 + if (hl != null) { 1.238 + MessageHeaders mh = packet.getMessage().getHeaders(); 1.239 + for (Header h : hl) { 1.240 + mh.add(h); 1.241 + } 1.242 + } 1.243 1.244 requestContext.fill(packet, (binding.getAddressingVersion() != null)); 1.245 packet.addSatellite(wsdlProperties); 1.246 1.247 if (addrVersion != null) { 1.248 // populate request WS-Addressing headers 1.249 - HeaderList headerList = packet.getMessage().getHeaders(); 1.250 - headerList.fillRequestAddressingHeaders(wsdlPort, binding, packet); 1.251 + MessageHeaders headerList = packet.getMessage().getHeaders(); 1.252 + AddressingUtils.fillRequestAddressingHeaders(headerList, wsdlPort, binding, packet); 1.253 1.254 1.255 // Spec is not clear on if ReferenceParameters are to be added when addressing is not enabled, 1.256 @@ -478,30 +517,36 @@ 1.257 configureRequestPacket(request, requestContext); 1.258 1.259 final Pool<Tube> pool = tubes; 1.260 - if (pool == null) 1.261 + if (pool == null) { 1.262 throw new WebServiceException("close method has already been invoked"); // TODO: i18n 1.263 + } 1.264 1.265 final Fiber fiber = engine.createFiber(); 1.266 + configureFiber(fiber); 1.267 1.268 receiver.setCancelable(fiber); 1.269 1.270 // check race condition on cancel 1.271 - if (receiver.isCancelled()) 1.272 - return; 1.273 + if (receiver.isCancelled()) { 1.274 + return; 1.275 + } 1.276 1.277 FiberContextSwitchInterceptorFactory fcsif = owner.getSPI(FiberContextSwitchInterceptorFactory.class); 1.278 - if(fcsif != null) 1.279 + if (fcsif != null) { 1.280 fiber.addInterceptor(fcsif.create()); 1.281 + } 1.282 1.283 // then send it away! 1.284 final Tube tube = pool.take(); 1.285 1.286 Fiber.CompletionCallback fiberCallback = new Fiber.CompletionCallback() { 1.287 + @Override 1.288 public void onCompletion(@NotNull Packet response) { 1.289 pool.recycle(tube); 1.290 completionCallback.onCompletion(response); 1.291 } 1.292 1.293 + @Override 1.294 public void onCompletion(@NotNull Throwable error) { 1.295 // let's not reuse tubes as they might be in a wrong state, so not 1.296 // calling pool.recycle() 1.297 @@ -516,51 +561,79 @@ 1.298 !requestContext.containsKey(PREVENT_SYNC_START_FOR_ASYNC_INVOKE)); 1.299 } 1.300 1.301 + protected void configureFiber(Fiber fiber) { 1.302 + // no-op in the base class, but can be used by derived classes to configure the Fiber prior 1.303 + // to invocation 1.304 + } 1.305 + 1.306 + private static final Logger monitoringLogger = Logger.getLogger(com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".monitoring"); 1.307 + 1.308 + @Override 1.309 public void close() { 1.310 - if (tubes != null) { 1.311 + TubePool tp = (TubePool) tubes; 1.312 + if (tp != null) { 1.313 // multi-thread safety of 'close' needs to be considered more carefully. 1.314 // some calls might be pending while this method is invoked. Should we 1.315 // block until they are complete, or should we abort them (but how?) 1.316 - Tube p = tubes.take(); 1.317 + Tube p = tp.takeMaster(); 1.318 + p.preDestroy(); 1.319 tubes = null; 1.320 - p.preDestroy(); 1.321 } 1.322 - if (managedObjectManagerClosed) { 1.323 - return; 1.324 - } else { 1.325 - com.sun.xml.internal.ws.server.MonitorBase.closeMOM(managedObjectManager); 1.326 + if (!managedObjectManagerClosed) { 1.327 + try { 1.328 + final ObjectName name = managedObjectManager.getObjectName(managedObjectManager.getRoot()); 1.329 + // The name is null when the MOM is a NOOP. 1.330 + if (name != null) { 1.331 + monitoringLogger.log(Level.INFO, "Closing Metro monitoring root: {0}", name); 1.332 + } 1.333 + managedObjectManager.close(); 1.334 + } catch (java.io.IOException e) { 1.335 + monitoringLogger.log(Level.WARNING, "Ignoring error when closing Managed Object Manager", e); 1.336 + } 1.337 managedObjectManagerClosed = true; 1.338 } 1.339 - 1.340 } 1.341 1.342 + @Override 1.343 public final WSBinding getBinding() { 1.344 return binding; 1.345 } 1.346 1.347 + @Override 1.348 public final Map<String, Object> getRequestContext() { 1.349 - return requestContext.getMapView(); 1.350 + return requestContext.asMap(); 1.351 } 1.352 1.353 public void resetRequestContext() { 1.354 requestContext = cleanRequestContext.copy(); 1.355 } 1.356 1.357 + @Override 1.358 public final ResponseContext getResponseContext() { 1.359 return responseContext; 1.360 } 1.361 1.362 + @Override 1.363 public void setResponseContext(ResponseContext rc) { 1.364 this.responseContext = rc; 1.365 } 1.366 1.367 - public String toString() { 1.368 + private String getStringId() { 1.369 return RuntimeVersion.VERSION + ": Stub for " + getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); 1.370 } 1.371 1.372 + @Override 1.373 + public String toString() { 1.374 + return getStringId(); 1.375 + } 1.376 + 1.377 + @Override 1.378 public final WSEndpointReference getWSEndpointReference() { 1.379 - if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) 1.380 - throw new java.lang.UnsupportedOperationException(ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class<T> class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")); 1.381 + if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) { 1.382 + throw new java.lang.UnsupportedOperationException( 1.383 + ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference(Class<T> class)", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding") 1.384 + ); 1.385 + } 1.386 1.387 if (endpointReference != null) { 1.388 return endpointReference; 1.389 @@ -596,18 +669,23 @@ 1.390 } 1.391 1.392 1.393 + @Override 1.394 public final W3CEndpointReference getEndpointReference() { 1.395 - if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) 1.396 - throw new java.lang.UnsupportedOperationException(ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")); 1.397 + if (binding.getBindingID().equals(HTTPBinding.HTTP_BINDING)) { 1.398 + throw new java.lang.UnsupportedOperationException( 1.399 + ClientMessages.UNSUPPORTED_OPERATION("BindingProvider.getEndpointReference()", "XML/HTTP Binding", "SOAP11 or SOAP12 Binding")); 1.400 + } 1.401 return getEndpointReference(W3CEndpointReference.class); 1.402 } 1.403 1.404 + @Override 1.405 public final <T extends EndpointReference> T getEndpointReference(Class<T> clazz) { 1.406 return getWSEndpointReference().toSpec(clazz); 1.407 } 1.408 1.409 public 1.410 @NotNull 1.411 + @Override 1.412 ManagedObjectManager getManagedObjectManager() { 1.413 return managedObjectManager; 1.414 } 1.415 @@ -617,25 +695,29 @@ 1.416 // WSBindingProvider methods 1.417 // 1.418 // 1.419 + @Override 1.420 public final void setOutboundHeaders(List<Header> headers) { 1.421 if (headers == null) { 1.422 this.userOutboundHeaders = null; 1.423 } else { 1.424 for (Header h : headers) { 1.425 - if (h == null) 1.426 + if (h == null) { 1.427 throw new IllegalArgumentException(); 1.428 + } 1.429 } 1.430 userOutboundHeaders = headers.toArray(new Header[headers.size()]); 1.431 } 1.432 } 1.433 1.434 + @Override 1.435 public final void setOutboundHeaders(Header... headers) { 1.436 if (headers == null) { 1.437 this.userOutboundHeaders = null; 1.438 } else { 1.439 for (Header h : headers) { 1.440 - if (h == null) 1.441 + if (h == null) { 1.442 throw new IllegalArgumentException(); 1.443 + } 1.444 } 1.445 Header[] hl = new Header[headers.length]; 1.446 System.arraycopy(headers, 0, hl, 0, headers.length); 1.447 @@ -643,24 +725,29 @@ 1.448 } 1.449 } 1.450 1.451 + @Override 1.452 public final List<Header> getInboundHeaders() { 1.453 - return Collections.unmodifiableList((HeaderList) 1.454 - responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)); 1.455 + return Collections.unmodifiableList(((MessageHeaders) 1.456 + responseContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY)).asList()); 1.457 } 1.458 1.459 + @Override 1.460 public final void setAddress(String address) { 1.461 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, address); 1.462 } 1.463 1.464 + @Override 1.465 public <S> S getSPI(Class<S> spiType) { 1.466 for (Component c : components) { 1.467 S s = c.getSPI(spiType); 1.468 - if (s != null) 1.469 + if (s != null) { 1.470 return s; 1.471 + } 1.472 } 1.473 return owner.getSPI(spiType); 1.474 } 1.475 1.476 + @Override 1.477 public Set<Component> getComponents() { 1.478 return components; 1.479 }