You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Daniel Kulp (JIRA)" <ji...@apache.org> on 2012/10/12 22:05:04 UTC
[jira] [Resolved] (CXF-4559) Part of SoapMessage content
interchange between two concurrent webservice calls
[ https://issues.apache.org/jira/browse/CXF-4559?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Daniel Kulp resolved CXF-4559.
------------------------------
Resolution: Invalid
Fix Version/s: Invalid
Assignee: Daniel Kulp
It's a bug in JAXB, not CXF and only when using one of Oracle/Sun's "extensions" to JAXB. When implemented as per JAXB spec, it works fine.
> Part of SoapMessage content interchange between two concurrent webservice calls
> -------------------------------------------------------------------------------
>
> Key: CXF-4559
> URL: https://issues.apache.org/jira/browse/CXF-4559
> Project: CXF
> Issue Type: Bug
> Affects Versions: 2.5.4, 2.5.5, 2.5.6
> Environment: Java 64-Bit Server 1.6.0_31
> Ubuntu 12.04 64-Bit
> Reporter: csupi
> Assignee: Daniel Kulp
> Priority: Critical
> Fix For: Invalid
>
> Attachments: ConcurrentTest.java
>
>
> I have a simple cxf webservice call with a DTO parameter. There is a HashMap and some other fields in the DTO.
> I realized that there are some cases where the content in the map is changed somewhere on the server side.
> I created a simple unit test. I put a String into the map and into a field where the map is. Create a webservice with jetty and create 15 clients to call my webservice 1000 times.
> After the test execution I realized that about in the 2% of the calls, the String in the map differs from the value in the field.
> Here is my unit test:
> {noformat}
> import java.io.Serializable;
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.HashMap;
> import java.util.UUID;
> import java.util.concurrent.Callable;
> import java.util.concurrent.ExecutionException;
> import java.util.concurrent.Executors;
> import java.util.concurrent.Future;
> import java.util.concurrent.atomic.AtomicInteger;
> import javax.jws.WebParam;
> import javax.jws.WebService;
> import javax.xml.bind.annotation.XmlAccessType;
> import javax.xml.bind.annotation.XmlAccessorType;
> import org.apache.cxf.interceptor.LoggingInInterceptor;
> import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
> import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
> import org.junit.Test;
> public class WebserviceEndpointIt {
> private static final int number_of_clients = 15;
> private final AtomicInteger badCounter = new AtomicInteger(0);
> private final AtomicInteger successCounter = new AtomicInteger(0);
> @XmlAccessorType(XmlAccessType.FIELD)
> public static class Event implements Serializable {
> private static final long serialVersionUID = 1L;
> private final HashMap<String, Object> map = new HashMap<String, Object>();
> private String expected;
> private String i;
> private String thread;
> }
> @WebService
> public interface MockWebservice {
> void doit(@WebParam(name = "message") Event message);
> }
> public class MockWebserviceImpl implements MockWebservice {
> @Override
> public void doit(final Event message) {
> /*
> * read the two strings from the FIELD and the MAP
> */
> final String expected = message.expected;
> final Object idFromMap = message.map == null ? null : message.map.get("expected");
> if (expected == null || idFromMap == null || !expected.equals(idFromMap)) {
> WebserviceEndpointIt.this.badCounter.incrementAndGet();
> } else {
> WebserviceEndpointIt.this.successCounter.incrementAndGet();
> }
> }
> }
> @Test
> public void testMyWebService() throws InterruptedException, ExecutionException {
> final MockWebservice endpoint = new MockWebserviceImpl();
> final JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
> svrFactory.setServiceClass(MockWebservice.class);
> svrFactory.setAddress("http://localhost:9000/myService");
> svrFactory.setServiceBean(endpoint);
> svrFactory.create();
> svrFactory.getInInterceptors().add(new LoggingInInterceptor());
> final Collection<Callable<Object>> clients = new ArrayList<Callable<Object>>();
> for (int i = 0; i < number_of_clients; i++) {
> final int thread = i;
> clients.add(new Callable<Object>() {
> @Override
> public Object call() throws Exception {
> final MockWebservice client = createClient();
> for (int i = 0; i < 1000; i++) {
> final Event message = new Event();
> final String id = Integer.valueOf(thread).toString() + "-" + Integer.valueOf(i).toString() + " "
> + UUID.randomUUID().toString();
> /*
> * put the same string into the MAP and the FIELD
> */
> message.map.put("expected", id);
> message.expected = id;
> message.map.put("thread", Integer.valueOf(thread));
> message.map.put("i", Integer.valueOf(i));
> message.thread = Integer.valueOf(thread).toString();
> message.i = Integer.valueOf(i).toString();
> client.doit(message);
> }
> return null;
> }
> });
> }
> for (final Future<Object> item : Executors.newFixedThreadPool(number_of_clients).invokeAll(clients)) {
> item.get();
> }
> System.out.println("bad: " + this.badCounter.get() + " success: " + this.successCounter.get());
> }
> private MockWebservice createClient() {
> final JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
> factory.setServiceClass(MockWebservice.class);
> factory.setAddress("http://localhost:9000/myService");
> final MockWebservice client = (MockWebservice) factory.create();
> return client;
> }
> }
> {noformat}
--
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