Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

java - Is this JAX-WS client call thread safe?

Since initialization of the WS client service and port takes ages I like to initialize them once at startup and reuse the same instance of the port. Initalization would look something like this:

private static RequestContext requestContext = null;

static
{
    MyService service = new MyService(); 
    MyPort myPort = service.getMyServicePort(); 

    Map<String, Object> requestContextMap = ((BindingProvider) myPort).getRequestContext();
    requestContextMap = ((BindingProvider)myPort).getRequestContext(); 
    requestContextMap.put(BindingProvider.USERNAME_PROPERTY, uName); 
    requestContextMap.put(BindingProvider.PASSWORD_PROPERTY, pWord); 

    rc = new RequestContext();
    rc.setApplication("test");
    rc.setUserId("test");
}

The call somewhere in my class:

myPort.someFunctionCall(requestContext, "someValue");

My question: Will this call be thread-safe?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

According to the CXF FAQ:

Are JAX-WS client proxies thread safe?

Official JAX-WS answer: No. According to the JAX-WS spec, the client proxies are NOT thread safe. To write portable code, you should treat them as non-thread safe and synchronize access or use a pool of instances or similar.

CXF answer: CXF proxies are thread safe for MANY use cases. The exceptions are:

  • Use of ((BindingProvider)proxy).getRequestContext() - per JAX-WS spec, the request context is PER INSTANCE. Thus, anything set there will affect requests on other threads. With CXF, you can do:

    ((BindingProvider)proxy).getRequestContext().put("thread.local.request.context","true");
    

    and future calls to getRequestContext() will use a thread local request context. That allows the request context to be threadsafe. (Note: the response context is always thread local in CXF)

  • Settings on the conduit - if you use code or configuration to directly manipulate the conduit (like to set TLS settings or similar), those are not thread safe. The conduit is per-instance and thus those settings would be shared. Also, if you use the FailoverFeature and LoadBalanceFeatures, the conduit is replaced on the fly. Thus, settings set on the conduit could get lost before being used on the setting thread.

  • Session support - if you turn on sessions support (see jaxws spec), the session cookie is stored in the conduit. Thus, it would fall into the above rules on conduit settings and thus be shared across threads.
  • WS-Security tokens - If use WS-SecureConversation or WS-Trust, the retrieved token is cached in the Endpoint/Proxy to avoid the extra (and expensive) calls to the STS to obtain tokens. Thus, multiple threads will share the token. If each thread has different security credentials or requirements, you need to use separate proxy instances.

For the conduit issues, you COULD install a new ConduitSelector that uses a thread local or similar. That's a bit complex though.

For most "simple" use cases, you can use CXF proxies on multiple threads. The above outlines the workarounds for the others.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...