1

I developed an application client side. I make rest call. When I do too many calls, my application crash. I understand that it's a problem of concurrency but I do not know how to fix the issue.

Here is the log error:

08-25 15:18:14.060: E/AndroidRuntime(3207): FATAL EXCEPTION: AsyncTask #1
08-25 15:18:14.060: E/AndroidRuntime(3207): java.lang.RuntimeException: An error occured while executing doInBackground()
08-25 15:18:14.060: E/AndroidRuntime(3207):     at android.os.AsyncTask$3.done(AsyncTask.java:278)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.lang.Thread.run(Thread.java:856)
08-25 15:18:14.060: E/AndroidRuntime(3207): Caused by: java.util.ConcurrentModificationException
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:569)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback.doWithRequest(RestTemplate.java:541)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:593)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:474)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:453)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:358)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at com.bpc.inno.nao.controller.services.NaoServicesClient$ServiceRequest.doInBackground(NaoServicesClient.java:138)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at android.os.AsyncTask$2.call(AsyncTask.java:264)
08-25 15:18:14.060: E/AndroidRuntime(3207):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
08-25 15:18:14.060: E/AndroidRuntime(3207):     ... 5 more

The error is there

@SuppressWarnings("unchecked")
@Override
protected K doInBackground(T... params) {
    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.setAccept(Arrays.asList(
                    new MediaType("application","xml"),
                    new MediaType("text", "xml")));
    HttpEntity<T> requestEntity = new HttpEntity<T>(
                    params[0], requestHeaders);
    try {
        ResponseEntity<K> response = mRestTemplate.postForEntity(
                        mUri, requestEntity, mResponseType);
                return response.getBody();
    } catch (ResourceAccessException ex) {
                Throwable cause = ex.getCause();
        if (cause != null && cause instanceof ConnectTimeoutException) {
            Log.e(TAG, "Request Timeout");
        }
        mError = true;
        return null;
    }
}

I do not know how to fix it. Do you?

Kara
  • 5,650
  • 15
  • 48
  • 55
user1728824
  • 95
  • 4
  • 10
  • block the UI while executing the task, for example show a progressDialog.. – Yazan Aug 25 '14 at 14:07
  • From `stackTrace` it looks as this line is faulty: `ResponseEntity response = mRestTemplate.postForEntity(mUri, requestEntity, mResponseType);` Is there a chance that some other `thread` is working on the same params? – Michał Schielmann Aug 25 '14 at 14:07
  • I think you are looking in the wrong place. The "concurrent" in the error message may not involve a second thread. It means that you are iterating over an ArrayList and that you change the contents of that list while you are iterating. – G. Blake Meike Aug 25 '14 at 14:16
  • What version of spring-rest ? – ben75 Aug 25 '14 at 14:16
  • I use 1.0.1.RELEASE of spring framework – user1728824 Aug 25 '14 at 14:31

2 Answers2

2

After a quick look into source code. The relevant line is here :

for (HttpMessageConverter<?> messageConverter : getMessageConverters())

So it seems that you are changing the messageConverters of mRestTemplate and at the same time (i.e. in another AsyncTask) : you are iterating on them.

My advices :

  • review your calls to mRestTemplate.setMessageConverters(...) to see you can fix something there.
  • if the problem is still there : don't share your restTemplate between threads (i.e. asyncTasks)

Note that there is a fix in trunk that will probably solve your problem with the next release : https://github.com/spring-projects/spring-framework/commit/1222ca38fb46a5c461fa41d2d4383469d10a2ede

ben75
  • 27,769
  • 7
  • 80
  • 130
1

Ensure the requestEntity that you create from params[0] is not modified elsewhere--perhaps some place after the async call in NaoServicesClient.

Also:

  • Contrary to @ben75's answer, Your ConcurrentModificationException error is indicative of another thread in your application trying to alter a List in the RequestEntity passed to mRestTemplate. Since you are processing asynchronously, another thread accessing the entity could be trying to modify the entity while the mRestTemplate is concurrently trying to process the entity.
  • For asynchronous RestTemplate processing, you should be using at least version 3.2.x or ideally version 4.x of the Spring Framework. Many APIs have been deprecated and fixed since 1.x and 2.x; I strongly recommend upgrading.
  • Also contrary to @ben75's answer, Spring recommends you share your RestTemplate between threads as it is thread-safe:

Conceptually, it is very similar to the JdbcTemplate, JmsTemplate, and the various other templates found in the Spring Framework and other portfolio projects. This means, for instance, that the RestTemplate is thread-safe once constructed

  • You should not be re-configuring your MessageConverters after Bean instantiation (if indeed you are actually doing this). The Spring Reference has concise examples.
JJ Zabkar
  • 3,322
  • 6
  • 35
  • 58