Activiti: обращение к веб-сервису из процесса

При имплементировании реальных сценариев зачастую процесс является частью программного комплекса. Представьте себе следующую ситуацию: где-то крутится SOAP сервис, возвращающий, как водится, при запросе некую информацию по определенному коду. И существует задача: как из процесса обратится к этому сервису, послать ему этот некий код и получить ответ?

Что у вас есть? Есть wsdl. Например, http://host:port/YourService?wsdl

Первым шагом мы получаем java-библиотеку для обращения к сервису. В терминале (или же в command line под Windows) запускаем:

wsimport -keep http://host:port/YourService?wsdl

Изучая код полученной библиотеки (а параметр keep нам создал и java-сорсы) мы видим, что обращение к сервису из java должно произойти следующим образом:

    YourService ys = new YourService(new java.net.URL("http://host:port/YourService?wsdl"));
    YourServiceServer port = ys.getYourServicePort();
    String response = port.requestData("Некий код");


Описываем свой класс WsDelegate, имплементирующий org.activiti.engine.delegate.JavaDelegate:

package ru.ossportal;
 
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.delegate.Expression;
 
import javax.xml.namespace.QName;

public class WsDelegate implements org.activiti.engine.delegate.JavaDelegate {
  private Expression wsdl, idf;
  private Expression returnValue;
 
 
  public void execute(DelegateExecution execution) throws Exception {
  	org.alfresco.repo.jscript.ScriptLogger logger = new org.alfresco.repo.jscript.ScriptLogger();
 
  	String wsdlString = (String)wsdl.getValue(execution);
  	String id = (String)idf.getValue(execution);
  	String returnVariableName = (String) returnValue.getValue(execution);
 
  	String response = "";  
 
		try {
			YourService ys = new YourService(new java.net.URL(wsdlString));
			YourServiceServer port = ys.getYourServicePort();
			response = port.requestData(id);
 
			if (returnValue!=null) execution.setVariable(returnVariableName, response);
		} catch (Exception e) {
			if (logger.isLoggingEnabled()) logger.error("Failed to handle request: " + e.toString());
			response = "Failed to handle request: " + e.toString();
			if (returnValue!=null) execution.setVariable(returnVariableName, response);
		}    
  }
}
 
 

 



Компилируем и вместе с полученной библиотекой помещаем в ALFRESCO_HOME/tomcat/webapps/alfresco/WEB-INF/class

Можно создать jar файл и поместить в ALFRESCO_HOME/tomcat/webapps/alfresco/WEB-INF/lib

В процессе же вызов веб-сервиса описывается следующим образом

<serviceTask id="callWS" name="Call WS" activiti:class="ru.ossportal.WsDelegate" >
  <extensionElements>
    <!-- Указываем адресс wsdl -->
    <activiti:field name="wsdl" expression="http://host:port/YourService?wsdl" />
    <!-- Передаем введеный ранее код -->
    <activiti:field name="idf" expression="${req_id}" />
    <!-- Возвращаемое значение -->
    <activiti:field name="returnValue" expression="response" />
  </extensionElements>
</serviceTask>

Переменная ${response}, в которой хранится ответ сервиса, будет доступна процессу.

А теперь опишем следующий сценарий:
1. юзер инициирует процесс "Запрос данных" и вводит в форме процесса некий код;
2. Если юзер является администратором альфрески или же состоит в группе "Services_User" на столе у юзера появляется задача с ответом от сервиса. Если же юзер не состоит в вышеперечисленных группах, на столе появляется задача "Запрет в допуске"

Имплементируем вот такой маршрут:



Полный текст процесса:

<?xml version="1.0" encoding="UTF-8" ?>
 
<!-- Объявление необходимых пространств имен -->
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
 
	<!-- Начало описания процесса -->
	<process id="DataRequest" name="Запрос данных">
 
		<!-- Скрипт начального узла; работает на старте, прямо после того, как нажата кнопка Start Workflow -->
		<!-- Инициатор является владельцем дальнейших задач -->
		<!-- Проверяем принадлежность инициатора к группам в альфреске -->
		<!-- Формируем поле описания процесса -->
		<extensionElements>
			<activiti:executionListener event="start" class="org.alfresco.repo.workflow.activiti.listener.ScriptExecutionListener">
				<activiti:field name="script">
					<activiti:string>
					<![CDATA[
						var assignee = initiator.properties.userName;
						execution.setVariable('assignee', assignee);
						var groupName = "GROUP_Services_User";
						var admin = "GROUP_ALFRESCO_ADMINISTRATORS";
						var validGroup = 0;
						var groups = people.getContainerGroups(person)
						for (var i=0; i<groups.length; i++ ) {
							if (groups[i].properties["cm:authorityName"]==groupName || groups[i].properties["cm:authorityName"]==admin) {
								validGroup = 1;
								break;
							}
						}
						execution.setVariable('validGroup', validGroup);
						var date = new Date();
						var day = date.getDate();
						var month = date.getMonth() + 1;
						var year = date.getFullYear();
						var hours = date.getHours();
						var min = date.getMinutes();
						execution.setVariable('bpm_workflowDescription', "Запрос от "+year+"-"+month+"-"+day+" "+hours+":"+min);

                                                //UPDATED
                                                execution.setVariable('req_id', req_id);
					]]>
					</activiti:string>
				</activiti:field>
			</activiti:executionListener>
		</extensionElements>
 
		<!-- Начальный узел процесса -->
		<startEvent id="start" activiti:formKey="req:start"/>
 
		<!-- Переход от старта к развилке, проверяющей валидность группы -->
		<sequenceFlow id='flow1' sourceRef='start' targetRef='isGroup' />
 
		<!-- Развилка, проверяющая валидность группы -->
		<exclusiveGateway id="isGroup" name="Is valid group?" />
 
		<!-- Группа валидна. Переходим к вызову сервиса -->
		<sequenceFlow id='flow2' sourceRef='isGroup' targetRef='callWS' >
			<conditionExpression xsi:type="tFormalExpression">${validGroup==1}</conditionExpression>
		</sequenceFlow>
 
		<!-- Группа не валидна. Переходим к задаче запрета допуска -->
		<sequenceFlow id='flow3' sourceRef='isGroup' targetRef='accessDenied' >
			<conditionExpression xsi:type="tFormalExpression">${validGroup==0}</conditionExpression>
		</sequenceFlow>
 
		<!-- Задача запрета допуска. Владелец задачи инициатор -->
		<userTask id="accessDenied" name="Запрет в допуске" activiti:formKey="req:accessDenied" activiti:assignee="${assignee}">
			<extensionElements>
				<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
					<!-- Скрипт при создании задачи -->
					<!-- Формируем заново поле описания процесса -->
					<activiti:field name="script">
						<activiti:string>
							execution.setVariable('bpm_workflowDescription', "У Вас нет допуска на запрос.");
						</activiti:string>
					</activiti:field>
				</activiti:taskListener>
			</extensionElements>
		</userTask>
 
		<!-- Переход от задачи запрета допуска к окончанию процесса -->
		<sequenceFlow id='flow4' sourceRef='accessDenied' targetRef='end' />
 
		<!-- Задача вызова сервиса. -->
		<serviceTask id="callWS" name="Call WS" activiti:class="ru.ossportal.WsDelegate" >
			<extensionElements>
				<activiti:field name="wsdl" expression="http://host:port/YourService?wsdl" />
				<activiti:field name="idf" expression="${req_id}" />
				<activiti:field name="returnValue" expression="response" />
			</extensionElements>
		</serviceTask>
 
		<!-- Переход от вызова сервиса к показу результата -->
		<sequenceFlow id='flow5' sourceRef='callWS' targetRef='showResult' />
 
		<!-- Показать результат. Владелец задачи инициатор -->
		<userTask id="showResult" name="Посмотреть результат запроса" activiti:formKey="req:showResult" activiti:assignee="${assignee}">
			<!-- Скрипт при создании задачи -->
			<!-- Устанавливаем срок исполнения и приоритет, если те не указаны -->
			<!-- В соответствии со значением response формируем значение информирующего поля. -->
			<extensionElements>
				<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
					<activiti:field name="script">
						<activiti:string>
						<![CDATA[
							if (typeof bpm_workflowDueDate != 'undefined') task.dueDate = bpm_workflowDueDate;
							if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
							execution.setVariable('bpm_workflowDescription', bpm_workflowDescription);
 
							var r = response.search("Failed");
							if (r==-1) { 
								execution.setVariable('req_info', response);
							} else execution.setVariable('req_info',"Запрос не принят. Произошла следующая ошибка: "+response);
							]]>
						</activiti:string>
					</activiti:field>
				</activiti:taskListener>
			</extensionElements>
		</userTask>
 
		<!-- Переход от вызова сервиса к окончанию процесса -->
		<sequenceFlow id='flow6' sourceRef='showResult' targetRef='end' />
 
		<endEvent id="end" />
 
	</process>
 
</definitions>

 


Модель процесса

<?xml version="1.0" encoding="UTF-8"?>
 
<model name="reg:workflowmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
 
 
  <imports>
    <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
    <import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" />
    <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
  </imports>
 
 
  <namespaces>
    <namespace uri="http://www.reg.ru/model/workflow/1.0" prefix="reg" />
  </namespaces>
 
 
  <types>
    <type name="reg:start">
      <parent>bpm:startTask</parent>
      <mandatory-aspects>
        <aspect>reg:id</aspect>
      </mandatory-aspects>
    </type>
 
    <type name="reg:showResult">
      <parent>bpm:workflowTask</parent>
      <overrides>
        <property name="bpm:packageItemActionGroup">
          <default>read_package_item_actions</default>
        </property>
      </overrides>
      <mandatory-aspects>
      	<aspect>reg:info</aspect>
      </mandatory-aspects>
    </type> 
 
 
    <type name="reg:accessDenied">
      <parent>bpm:workflowTask</parent>
      <overrides>
        <property name="bpm:packageItemActionGroup">
          <default>read_package_item_actions</default>
        </property>
      </overrides>
    </type> 
  </types>
 
 
  <aspects>
    <aspect name="reg:id">
      <title>Код запроса</title>
      <properties>
        <property name="reg:id">
          <type>d:text</type>
          <mandatory>false</mandatory>
        </property>
      </properties>
    </aspect>
 
    <aspect name="reg:info">
      <title>Информирующее поле</title>
      <properties>
        <property name="reg:info">
          <type>d:text</type>
          <mandatory>false</mandatory>
        </property>
      </properties>
    </aspect>
  </aspects>
 
</model>

 

 Важно знать, что в процессе должен быть хотя бы один userTask, чтобы процесс заработал.

3453
Прикрепленные файлыРазмер
diagram2.png13.19 кб

Комментарии

fufler аватар

 Спасибо, хороший пример.

Angelina аватар

Не за что. Я, правда, была неуверена, нужно ли писать, но  написала, поскольку сама в свое время так споткнулась с вызовами SOAP сервисов, помните, наверно, мою тему на форуме. В документации активити есть пример использования wsdl, но как-то он не сработал у меня. А так вот - импортом классов из wsdl - сработало Подумалось, может, кому-то будет тоже полезно.

 

Доброго времни суток.
Сделал почти все так же. Только сам процесс нарисовал в eclipse.
и в ява классе не обращался в WS а просто возвращаю строку Testik!!!!.
но процесс не запускается.  :-((((
Возращается ошибка :
16:25:24,092 DEBUG [org.alfresco.repo.workflow.activiti.properties.ActivitiPropertyConverter] Task priority value (50) was invalid so it was set to the default value of 2. Task:Call Web Service
16:25:24,100 DEBUG [org.alfresco.repo.jscript.ScriptLogger] org.alfresco.service.cmr.workflow.WorkflowException: 08240046  Не удалось запустить бизнес-процесс activiti$DataRequest:6:7512.
6:25:24,102 DEBUG [org.alfresco.repo.jscript.ScriptLogger] Returning 500 status code
описание форм:
   <!-- Настройки форм для маршрута datarequest -->
...
   <config evaluator="string-compare" condition="activiti$DataRequest">
    <forms>
     <form>
      <field-visibility>
       <show id="bpm:workflowDescription" />
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="" appearance="title" label-id="workflow.set.general" />
       <set id="assignee" appearance="title" label-id="workflow.set.assignee" />
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <set id="other" appearance="title" label-id="workflow.set.other" />
       <field id="bpm:workflowDescription" labelid="workflow.field.message" mandatory="false">
        <control template="/org/alfresco/components/form/controls/textarea.ftl">
         <control-param name="style">width: 95%</control-param>
        </control>
       </field>
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRStart">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRcallWS">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRaccessDenied">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
     </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRshowResult">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
По сообщению ошибки говориться что выставленныое значение в 50 признано не валидным и проставлено 2.
Что это может быть?
Помогите пожалуйста.
Angelina аватар
Судя по логу,  Вы действительно где-то пытаетесь присвоить task.priority значение 50, хотя в альфрескиной модели приоритет задач может иметь только три значения -1,2 и 3
К сожалению, я не могу сказать, где у Вас ошибка. То, что Вы показали - это вырисовка интерфейса share, а Вам надо смотреть в скрипт процесса, где именно вообще появляется это значение 50.
Доброго времени суток. После различных тестов выяснилось следующее:
java программа  запускается, но прерывается в определенном месте. В тексте программы указал.
package ru.kristall.w1;

//import java.io.File;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.delegate.Expression;

import javax.mail.*;
import javax.mail.internet.MimeMessage;

import ru.kristall.utils.*;

import javax.xml.namespace.QName;

public class WSSendEmail implements org.activiti.engine.delegate.JavaDelegate {
    private Expression wsdl, idf;
    private Expression returnValue;   

//    public void send2mail(String fName, String fuser, String tuser, String smtpHost, String username, String password,String thead, String ttext) throws Exception {
//      try {
//        int smtpPort = 25;                //port of smtp mail server
//        SmtpMessageSender messageSender = new SmtpMessageSender();
//        Session session = messageSender.createSession(smtpHost, smtpPort, username,password);
//        MimeMessage message = messageSender.createMimeMessage(session, thead, /*"from@mail.ru"*/ fuser,/*"to@mail.ru"*/ tuser, Message.RecipientType.TO);
//        messageSender.addText(message,ttext,"utf-8","plain");
////        if (fName!=null) messageSender.addAttachment(message, new File(fName));
//        messageSender.sendMimeMessage(message);
//      }
//      catch( Exception ee) {}
//    }
   
   
    public void execute(DelegateExecution execution) throws Exception {
          org.alfresco.repo.jscript.ScriptLogger logger = new org.alfresco.repo.jscript.ScriptLogger();
        logger.log("Execute my webScript !! 1");
//        send2mail("", "billing@kristallcom.ru", "boltaev@kristallcom.ru","192.168.11.49", "billing", "BGbilling", "Test", "Text into body");
       
          String wsdlString = (String)wsdl.getValue(execution);
        logger.log("Execute my webScript !! 2");



    Вот на этой строке прерывается программа.

          String id = (String)idf.getValue(execution);
        logger.log("Execute my webScript !! 3");
          String returnVariableName = (String) returnValue.getValue(execution);
        logger.log("Execute my webScript !! 4");
     
          String response = ""; 
     //
        //    try {
        //        YourService ys = new YourService(new java.net.URL(wsdlString));
        //        YourServiceServer port = ys.getYourServicePort();
        //        response = port.requestData(id);
        logger.log("Execute my webScript !! 5");
          response="Testik!!!";
        logger.log("Execute my webScript !! 6");
        if (returnValue!=null) execution.setVariable(returnVariableName, response);
        logger.log("Execute my webScript !! 7");
        //
        //        if (returnValue!=null) execution.setVariable(returnVariableName, response);
        //    } catch (Exception e) {
        //        if (logger.isLoggingEnabled()) logger.error("Failed to handle request: " + e.toString());
        //        response = "Failed to handle request: " + e.toString();
        //        if (returnValue!=null) execution.setVariable(returnVariableName, response);
        //    }   
      }
}

Видно что прерывание идет при отсутствии заначения в переменной. idf
Скорее всего я не правильно написал формы и пытаюсь передать значения. Подскажите пожалуйста где я ошибся.
Вот формы:
   <!-- Настройки форм для маршрута datarequest -->
...
   <config evaluator="string-compare" condition="activiti$DataRequest">
    <forms>
     <form>
      <field-visibility>
       <show id="bpm:workflowDescription" />
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="" appearance="title" label-id="workflow.set.general" />
       <set id="assignee" appearance="title" label-id="workflow.set.assignee" />
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <set id="other" appearance="title" label-id="workflow.set.other" />
       <field id="bpm:workflowDescription" labelid="workflow.field.message" mandatory="false">
        <control template="/org/alfresco/components/form/controls/textarea.ftl">
         <control-param name="style">width: 95%</control-param>
        </control>
       </field>
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRStart">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRcallWS">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRaccessDenied">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
   <config evaluator="task-type" condition="mwf:DRshowResult">
    <forms>
     <form>
      <field-visibility>
       <show id="reg:id" />
       <show id="reg:info" />
      </field-visibility>
      <appearance>
       <set id="items" appearance="title" label-id="workflow.set.items" />
       <field id="reg:id" set="items" />
       <field id="reg:info" set="items" />
      </appearance>
     </form>
    </forms>
   </config>
...
   <!-- -->

Вот описание модели процесса:
<?xml version="1.0" encoding="UTF-8"?>
<model name="reg:workflowmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
  <imports>
    <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
    <import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm" />
    <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
  </imports>
  <namespaces>
    <namespace uri="http://www.reg.ru/model/workflow/1.0" prefix="reg" />
  </namespaces>
  <types>
    <type name="reg:DRStart">
      <parent>bpm:startTask</parent>
      <mandatory-aspects>
        <aspect>reg:id</aspect>
      </mandatory-aspects>
    </type>
    <type name="reg:DRshowResult">
      <parent>bpm:workflowTask</parent>
      <overrides>
        <property name="bpm:packageItemActionGroup">
          <default>read_package_item_actions</default>
        </property>
      </overrides>
      <mandatory-aspects>
      <aspect>reg:info</aspect>
      </mandatory-aspects>
    </type>.
    <type name="reg:DRaccessDenied">
      <parent>bpm:workflowTask</parent>
      <overrides>
        <property name="bpm:packageItemActionGroup">
          <default>read_package_item_actions</default>
        </property>
      </overrides>
    </type>.
  </types>
  <aspects>
   <aspect name="reg:id">
    <title>Код запроса</title>
    <properties>
     <property name="reg:id">
      <type>d:text</type>
      <mandatory>false</mandatory>
     </property>
    </properties>
   </aspect>
   <aspect name="reg:info">
    <title>Информирующее поле</title>
    <properties>
     <property name="reg:info">
      <type>d:text</type>
      <mandatory>false</mandatory>
     </property>
    </properties>
   </aspect>
  </aspects>
</model>

в описании процесса :
    <serviceTask id="DRcallWS" name="Call Web Service" activiti:class="ru.kristall.w1.WSSendEmail" >
     <extensionElements>
      <activiti:field name="wsdl" expression="http://host:port/YourService?wsdl" />

Вот с этой передачей проблемы

      <activiti:field name="idf" expression="${req_id}" />


      <activiti:field name="returnValue" expression="response" />
     </extensionElements>
    </serviceTask>

Angelina аватар
Олег, а почему Вы описываете в конфигурации вид сервис-таска? В настройке формы я вижу вот это:"   <config evaluator="task-type" condition="mwf:DRcallWS">" Зачем оно? Тем более, что в модели этого нет (да и не нужно для сервис таска) Правда, сама ошибка с этим не связана.

Сам код вроде правилен да и в процессе также нормально. Остается понять, не пустая ли сама переменная req_id. Вы ее описали в моделе, но существует ли он на момент передачи сервис таску? 

Ясно, у меня в тексте нет нигде передачи этой переменной, поэтому Вы ошиблись. Смотрите, выражение ${req_id} означает всего лишь ссылку на переменную, которая у нас есть на старте, но нет на момент вызова сервиса. Т е до этого ее нужно определить.

Т е в данонм конкретном случае до сервис-таска в процессе у вас в стартовом ивенте  должна быть такая строка:
execution.setVariable('req_id', req_id);

Я сейчас поправлю текст. А то это будет вводить в заблуждение начинающих в Альфреско
Angelina, Вы просто Волшебница!!!!!!

Все заработало, даже подложенные свои библиотеки подключились. Все заработало.
Очень полезная статья!
Для начинающих полностью описывает процесс построения рабочего процесса Так же и подключения java классов.
Angelina аватар
Спасибо  Приятно, что была полезна :)