Skip to content

Commit

Permalink
[incubator-kie-issues-1278] Support for codegen in project class load…
Browse files Browse the repository at this point in the history
…ing handler descriptors. (error event) (apache#3537)
  • Loading branch information
elguardian authored and rgdoliveira committed Jun 10, 2024
1 parent bd66a1f commit ec8e2de
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jbpm.bpmn2.services;

import org.kie.kogito.process.workitem.WorkItemExecutionException;

public class AlwaysThrowingComponent {

public void throwException() {
throw new WorkItemExecutionException("MY_ERROR");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jbpm.bpmn2.services;

public class LoggingComponent {

public void logException(Throwable exception) {
System.out.println(exception);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:bpsim="http://www.bpsim.org/schemas/1.0" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:drools="http://www.jboss.org/drools" id="_QqMV0EhdEDm-BsDfCQnCnA" exporter="jBPM Process Modeler" exporterVersion="2.0" targetNamespace="http://www.omg.org/bpmn20">
<bpmn2:error id="error1" errorCode="error1"/>
<bpmn2:process id="EndError" drools:packageName="com.example" drools:version="1.0" drools:adHoc="false" name="EndError" isExecutable="true" processType="Public">
<bpmn2:process id="EndError" drools:packageName="org.jbpm.bpmn2.error" drools:version="1.0" drools:adHoc="false" name="EndError" isExecutable="true" processType="Public">
<bpmn2:sequenceFlow id="_F0C4E1CF-5937-41F8-8B29-AB8A882C4ABE" sourceRef="_2503B623-FE50-4341-B4FA-CD5174B306C2" targetRef="_9D44A52D-5F79-4F07-8438-7ED84AA4ED51">
<bpmn2:extensionElements>
<drools:metaData name="isAutoConnection.source">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<bpmn2:interface id="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD_ServiceInterface" name="org.jbpm.services.LoggingComponent" implementationRef="org.jbpm.bpmn2.services.LoggingComponent">
<bpmn2:operation id="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD_ServiceOperation" name="logException" implementationRef="logException"/>
</bpmn2:interface>
<bpmn2:process id="ErrorVariable" drools:packageName="com.example" drools:version="1.0" drools:adHoc="false" name="ErrorVariable" isExecutable="true" processType="Public">
<bpmn2:process id="ErrorVariable" drools:packageName="org.jbpm.bpmn2.error" drools:version="1.0" drools:adHoc="false" name="ErrorVariable" isExecutable="true" processType="Public">
<bpmn2:property id="theException" itemSubjectRef="_theExceptionItem" name="theException"/>
<bpmn2:sequenceFlow id="_52EEDF72-07C7-46FE-BB5C-9513565AB210" sourceRef="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD" targetRef="_62803D2E-7500-4772-99F8-12CF68FB029A"/>
<bpmn2:sequenceFlow id="_96D31184-08C6-4DC9-B405-4FC97B477DCC" sourceRef="_62803D2E-7500-4772-99F8-12CF68FB029A" targetRef="_D318B115-D923-4448-AA4E-CACCCDEB9DD5"/>
Expand All @@ -47,7 +47,7 @@
<bpmn2:incoming>_52EEDF72-07C7-46FE-BB5C-9513565AB210</bpmn2:incoming>
<bpmn2:outgoing>_96D31184-08C6-4DC9-B405-4FC97B477DCC</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:serviceTask id="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD" drools:serviceimplementation="Java" drools:serviceinterface="org.jbpm.bpmn2.servicesLoggingComponent" drools:serviceoperation="logException" name="Error Handling" implementation="Java" operationRef="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD_ServiceOperation">
<bpmn2:serviceTask id="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD" drools:serviceimplementation="Java" drools:serviceinterface="org.jbpm.bpmn2.services.LoggingComponent" drools:serviceoperation="logException" name="Error Handling" implementation="Java" operationRef="_E5B0E78B-0112-42F4-89FF-0DCC4FCB6BCD_ServiceOperation">
<bpmn2:extensionElements>
<drools:metaData name="elementname">
<drools:metaValue><![CDATA[Error Handling]]></drools:metaValue>
Expand Down
43 changes: 33 additions & 10 deletions jbpm/jbpm-tests/src/test/java/org/jbpm/bpmn2/ErrorEventTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
import java.util.List;
import java.util.Map;

import org.jbpm.bpmn2.error.EndErrorModel;
import org.jbpm.bpmn2.error.EndErrorProcess;
import org.jbpm.bpmn2.error.ErrorVariableModel;
import org.jbpm.bpmn2.error.ErrorVariableProcess;
import org.jbpm.bpmn2.handler.ServiceTaskHandler;
import org.jbpm.bpmn2.handler.SignallingTaskHandlerDecorator;
import org.jbpm.bpmn2.objects.ExceptionOnPurposeHandler;
Expand All @@ -32,10 +36,15 @@
import org.jbpm.process.instance.event.listeners.RuleAwareProcessEventListener;
import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler;
import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler;
import org.jbpm.test.utils.EventTrackerProcessListener;
import org.jbpm.test.utils.ProcessTestHelper;
import org.jbpm.workflow.instance.WorkflowProcessInstance;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.kie.api.event.process.ProcessNodeLeftEvent;
import org.kie.kogito.Application;
import org.kie.kogito.handlers.AlwaysThrowingComponent_throwException__8DA0CD88_0714_43C1_B492_A70FADE42361_Handler;
import org.kie.kogito.handlers.LoggingComponent_logException__E5B0E78B_0112_42F4_89FF_0DCC4FCB6BCD_Handler;
import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener;
import org.kie.kogito.internal.process.event.KogitoProcessEventListener;
import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
Expand Down Expand Up @@ -440,22 +449,36 @@ public void testEndErrorWithSubprocess() throws Exception {

@Test
public void testEndError() throws Exception {
kruntime = createKogitoProcessRuntime("error/EndError.bpmn2");
Application app = ProcessTestHelper.newApplication();
EventTrackerProcessListener eventTrackerProcessListener = new EventTrackerProcessListener();
ProcessTestHelper.registerProcessEventListener(app, eventTrackerProcessListener);
org.kie.kogito.process.Process<EndErrorModel> processDefinition = EndErrorProcess.newProcess(app);
org.kie.kogito.process.ProcessInstance<EndErrorModel> instance = processDefinition.createInstance(processDefinition.createModel());
instance.start();

KogitoProcessInstance processInstance = kruntime.startProcess("EndError");
assertThat(eventTrackerProcessListener.tracked()).anyMatch(ProcessTestHelper.triggered("start"));
assertThat(eventTrackerProcessListener.tracked()).anyMatch(ProcessTestHelper.triggered("task"));
assertThat(instance.status()).isEqualTo(KogitoProcessInstance.STATE_ABORTED);

assertNodeTriggered(processInstance.getStringId(), "start", "task");

assertThat(processInstance.getState()).isEqualTo(KogitoProcessInstance.STATE_ABORTED);
}

@Test
public void testErrorVariable() throws Exception {
kruntime = createKogitoProcessRuntime("error/ErrorVariable.bpmn2");
kruntime.getKogitoWorkItemManager().registerWorkItemHandler("Service Task", new WorkItemExecutionErrorWorkItemHandler("MY_ERROR"));
KogitoProcessInstance processInstance = kruntime.startProcess("ErrorVariable");
Object theException = processInstance.getVariables().get("theException");
assertThat(theException).isInstanceOf(WorkItemExecutionException.class);

Application app = ProcessTestHelper.newApplication();
ProcessTestHelper.registerHandler(app, "Service Task", new WorkItemExecutionErrorWorkItemHandler("MY_ERROR"));
ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.services.AlwaysThrowingComponent_throwException__8DA0CD88_0714_43C1_B492_A70FADE42361_Handler",
new AlwaysThrowingComponent_throwException__8DA0CD88_0714_43C1_B492_A70FADE42361_Handler());
ProcessTestHelper.registerHandler(app, "org.jbpm.bpmn2.services.LoggingComponent_logException__E5B0E78B_0112_42F4_89FF_0DCC4FCB6BCD_Handler",
new LoggingComponent_logException__E5B0E78B_0112_42F4_89FF_0DCC4FCB6BCD_Handler());
org.kie.kogito.process.Process<ErrorVariableModel> processDefinition = ErrorVariableProcess.newProcess(app);
ErrorVariableModel model = processDefinition.createModel();
model.setTheException("theException");
org.kie.kogito.process.ProcessInstance<ErrorVariableModel> instance = processDefinition.createInstance(model);
instance.start();

assertThat(instance.variables().getTheException()).isInstanceOf(WorkItemExecutionException.class);
assertThat(instance.status()).isEqualTo(KogitoProcessInstance.STATE_COMPLETED);
}

class ExceptionWorkItemHandler implements KogitoWorkItemHandler {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jbpm.tools.maven;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ClassLoaderHelper {
private static Logger LOGGER = LoggerFactory.getLogger(ClassLoaderHelper.class);

public static ClassLoader getClassLoader(MavenProject project) {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {

Set<URL> classPathUrls = new HashSet<>();

// adding the projects classes itself
List<String> classpathElements = project.getCompileClasspathElements();
classpathElements.add(project.getBuild().getOutputDirectory());
classpathElements.add(project.getBuild().getTestOutputDirectory());
for (final String classpathElement : classpathElements) {
LOGGER.info("adding classpath element {} to classloader", classpathElement);
classPathUrls.add(new File(classpathElement).toURI().toURL());
}

return new URLClassLoader(classPathUrls.stream().toArray(URL[]::new), contextClassLoader);
} catch (final Exception e) {
return contextClassLoader;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ public class ProcessCodeGenerationSupport {

private Path rootOutputFolder;

public ProcessCodeGenerationSupport(Path sourceFolder, Path outputFolder) {
public ProcessCodeGenerationSupport(Path sourceFolder, Path outputFolder, ClassLoader classLoader) {
this.printer = new DefaultPrettyPrinter();
this.bpmnSemanticModules = new SemanticModules();
this.bpmnSemanticModules.addSemanticModule(new BPMNSemanticModule());
this.bpmnSemanticModules.addSemanticModule(new BPMNExtensionsSemanticModule());
this.bpmnSemanticModules.addSemanticModule(new BPMNDISemanticModule());
this.processCodeGenerator = new ProcessToExecModelGenerator("StaticProcessTemplate.java", Thread.currentThread().getContextClassLoader());
this.processCodeGenerator = new ProcessToExecModelGenerator("StaticProcessTemplate.java", classLoader);
this.rootSourceFolder = sourceFolder;
this.rootOutputFolder = outputFolder;
}
Expand Down Expand Up @@ -212,6 +212,9 @@ private void generateJavaCode(KogitoWorkflowProcess process) throws IOException
writeCompilationUnit(modelMetadata.generateUnit());
writeCompilationUnit(inputMdelMetadata.generateUnit());
writeCompilationUnit(outputModelMetadata.generateUnit());
for (CompilationUnit handler : metadata.getGeneratedHandlers().values()) {
writeCompilationUnit(handler);
}
}

private void writeCompilationUnit(CompilationUnit unit) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class ProcessCodegenMojo extends AbstractMojo {
public void execute() throws MojoExecutionException {
Path sourceFolder = Paths.get(project.getBasedir().toString(), resources);
Path outputFolder = Paths.get(project.getBuild().getDirectory(), "generated-sources", "jbpm");
ProcessCodeGenerationSupport codeGenSupport = new ProcessCodeGenerationSupport(sourceFolder, outputFolder);
ProcessCodeGenerationSupport codeGenSupport = new ProcessCodeGenerationSupport(sourceFolder, outputFolder, ClassLoaderHelper.getClassLoader(project));
codeGenSupport.execute();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void execute() throws MojoExecutionException {

Path sourceTestFolder = Paths.get(project.getBasedir().toString(), resources);
Path outputTestFolder = Paths.get(project.getBuild().getDirectory(), "generated-test-sources", "jbpm");
ProcessCodeGenerationSupport codeGenSupport = new ProcessCodeGenerationSupport(sourceTestFolder, outputTestFolder);
ProcessCodeGenerationSupport codeGenSupport = new ProcessCodeGenerationSupport(sourceTestFolder, outputTestFolder, ClassLoaderHelper.getClassLoader(project));
codeGenSupport.execute();
}

Expand Down

0 comments on commit ec8e2de

Please sign in to comment.