[jira] [Commented] (CXF-4559) Part of SoapMessage content interchange between two concurrent webservice calls

2012-10-15 Thread csupi (JIRA)

[ 
https://issues.apache.org/jira/browse/CXF-4559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13476209#comment-13476209
 ] 

csupi commented on CXF-4559:


You are right. I tried it. It really looks like a JAXB issue.

thank you

> 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, 
> ConcurrentTestPrecreatedJAXBContext.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 map = new HashMap 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> clients = new 
> ArrayList>();
> for (int i = 0; i < number_of_clients; i++) {
> final int thread = i;
> clients.add(new Callable() {
> @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
>

[jira] [Commented] (CXF-4559) Part of SoapMessage content interchange between two concurrent webservice calls

2012-10-15 Thread Daniel Kulp (JIRA)

[ 
https://issues.apache.org/jira/browse/CXF-4559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13476181#comment-13476181
 ] 

Daniel Kulp commented on CXF-4559:
--


In your test, you are not just creating a new unmarshaller per thread, but you 
are creating an entire new JAXContext per thread.   That would be insanely 
expensive.  Change to:

{code:java}
JAXBContext ctx = JAXBContext.newInstance(Event.class);
final Unmarshaller[] marshaller = new Unmarshaller[NUMBER_OF_CLIENTS];
for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
marshaller[i] = ctx.createUnmarshaller();
}
{code}
to use a single JAXBContext, but per thread unmarshaller.   That would show the 
issue with 2.1.13.




> 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, 
> ConcurrentTestPrecreatedJAXBContext.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 map = new HashMap 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> clients = new 
> ArrayList>();
> for (int i = 0; i < number_of_clients; i++) {
> final int thread = i;
> clients.add(new Callable() {
> @Override
> public Object call() throws Exception {
>  

[jira] [Commented] (CXF-4559) Part of SoapMessage content interchange between two concurrent webservice calls

2012-10-15 Thread csupi (JIRA)

[ 
https://issues.apache.org/jira/browse/CXF-4559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13476010#comment-13476010
 ] 

csupi commented on CXF-4559:


Thanks for your quick reply.


I created a unit test for testing the JAXB before, and it was success without 
the XmlJavaTypeAdapter annotation.

I modified your test to looks like my JAXB test. The only difference between 
mine and yours is that I created the unmarshallers before the start of the 
threads.

I upload my modified test.

> 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 map = new HashMap 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> clients = new 
> ArrayList>();
> for (int i = 0; i < number_of_clients; i++) {
> final int thread = i;
> clients.add(new Callable() {
> @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.value

[jira] [Commented] (CXF-4559) Part of SoapMessage content interchange between two concurrent webservice calls

2012-10-12 Thread Daniel Kulp (JIRA)

[ 
https://issues.apache.org/jira/browse/CXF-4559?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13475097#comment-13475097
 ] 

Daniel Kulp commented on CXF-4559:
--

I just attached a "new" version of this that just uses pure JAXB calls, no CXF 
involved, to show that this is a JAXB problem.   It's also just a problem with 
very particular versions of JAXB.

If you run the testcase using JAXB 2.1.13, you will see the same error.  
However, if you downgrade to 2.1.11, you will not.  Thus, it looks like it's a 
bug in 2.1.13.   The bug doesn't seem to be present in 2.2.5 (which we use on 
Java7).

If you uncomment the @XmlJavaTypeAdapter annotation on the map, the test also 
passes on all the versions of JAXB.  TECHNICALLY, that is the correct solution. 
 Officially, JAXB does not handle Maps at all and an Adapter should be used to 
map it to a correct type.   My suggestion would be to use an adapter like that.



> 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
>Priority: Critical
> 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 map = new HashMap 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> clients = new 
> ArrayList>();
> for (int i = 0; i < number_of_clients; i++) {
> final int thread = i;
> clients.add(new Callable() {
>