AnsweredAssumed Answered

Java Service Task and HttpClient

Question asked by martinfranz on Nov 2, 2014
Latest reply on Nov 10, 2014 by jbarrez
Hi all,

I try to write a custom java service task which uses one http client to make one call per service task to an external custom api.

PoolingHttpClientConnectionManager > CloseableHTTPClient > Java Service task (async) > 100 * HttpPost / HttpGet

The problem with this is: When I execute more than about 20 of these service tasks at the same time (Timer Event) activiti "crashes". I don't see any errors but i am not able to login again. The activiti explorer is like "freezed". The loading indicator turns red and never stops spinning.
From that point i need to delete the database and install activiti again.

I stack with this problem for many days know and I don't have any idea what could be the problem.

What I have tested so far:
Started 100 threads in a small unit test using a pooled connection manager in order to call the target api 100 times concurrently - no problems on client an server side. Where the client was my mac osx java runtime. No tomcat around.

Maybe you have any ideas? Thanks a lot :-)

This is my setup for the service task:


// relevant parts

     <!– Application Context Provider –>
     <bean id="applicationContextProvider"

          <!– A service provider which holdes the base url to the external api –>
     <bean id="fm3RestServiceProvider"
           <property name="serviceUrl" value="http://myurl/api/" />

       <!– A custom pooled http client usded in the java service task –>
       <bean id="pooledHttpClient" class="com.sw.activiti.service.http.client.PooledHttpClient">
         <property name="maxTotal" value="1000" />
         <property name="defaultMaxPerRoute" value="50" />


public class PooledHttpClient implements InitializingBean {

   private int maxTotal;
   private int defaultMaxPerRoute;
   public int getMaxTotal() {
      return maxTotal;

   public void setMaxTotal(int maxTotal) {
      this.maxTotal = maxTotal;

   public int getDefaultMaxPerRoute() {
      return defaultMaxPerRoute;

   public void setDefaultMaxPerRoute(int defaultMaxPerRoute) {
      this.defaultMaxPerRoute = defaultMaxPerRoute;

   private PoolingHttpClientConnectionManager connectionManager;
   private CloseableHttpClient httpclient;
   public PoolingHttpClientConnectionManager getConnectionManager() {
      return connectionManager;

   public CloseableHttpClient getHttpclient() {
      return httpclient;

   public void afterPropertiesSet() throws Exception {
      this.connectionManager = new PoolingHttpClientConnectionManager();
      this.httpclient = HttpClients.custom().setConnectionManager(this.connectionManager).build();



The java service task - ThreadSaveFM3RestServiceTask

public class ThreadSaveFM3RestServiceTask implements JavaDelegate {

    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
    private Expression api_key;

    private Expression rest_url;
    private Expression json_string;

    private Expression http_method;
   public void execute(DelegateExecution execution) throws Exception {

      String final_api_key = (String)api_key.getValue(execution);
      String final_rest_url = (String)rest_url.getValue(execution);
      String final_json_string = (String)json_string.getValue(execution);
      String final_method = (String)http_method.getValue(execution);

      ApplicationContext ctx = ApplicationContextProvider.getApplicationContext();
                ServiceProvider fm3RestServiceProvider = (FM3RestServiceProviderImpl) ctx.getBean("fm3RestServiceProvider");
      PooledHttpClient pooledHttpClient = (PooledHttpClient) ctx.getBean("pooledHttpClient");
      try { 
            // prepare the request
            HttpEntityEnclosingRequestBase request = null;
               request = new HttpPost(fm3RestServiceProvider.getServiceUrl() + final_rest_url);
               request = new HttpPut(fm3RestServiceProvider.getServiceUrl() + final_rest_url);
            // prepare headers
            request.addHeader("Accept", "application/json");
            request.addHeader("Content-Type", "application/json; charset=utf-8");
            request.addHeader("Authorization", "ApiKey " + final_api_key);
            // prepare the body      
            StringEntity entity = new StringEntity(final_json_string, "UTF-8");   
            CloseableHttpResponse response = pooledHttpClient.getHttpclient().execute(request);
            if (response.getStatusLine().getStatusCode() != 200)
               LOGGER.debug("FM3RestServiceTask request status: " + response.getStatusLine().getStatusCode());            
            try { 

               HttpEntity responseEntity = response.getEntity(); 
            } finally { 

               LOGGER.debug("FM3RestServiceTask close response");
      } catch (ClientProtocolException e)
         LOGGER.debug("FM3RestServiceTask ClientProtocolException: " + e.getMessage());
      } catch (IOException e)
         LOGGER.debug("FM3RestServiceTask IOException: " + e.getMessage());

      } finally
         LOGGER.debug("FM3RestServiceTask done");

The usage of the service task in a process definition

    <serviceTask id="servicetask1" name="FM3 Rest Service Task" activiti:async="true" activiti:class="">
        <activiti:field name="rest_url">
        <activiti:field name="api_key">
        <activiti:field name="json_string">
          <activiti:string><![CDATA[{"terminStatus3":70,"terminStatus3Info":"Ressource ueberfaellig"}]]></activiti:string>
        <activiti:field name="http_method">