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, чтобы процесс заработал.

1120
Поблагодарили:
Прикрепленные файлыРазмер
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 аватар
Спасибо  Приятно, что была полезна :)