Exception while Instantiating class "com.org.example.EventApplication.EventNotification" Cannot load class

Hello All,
I have got a bpmn workflow, wherein I have two service tasks, at different level(different Bpmn’s one gets called via message correlation). My Bpmn’s are attached, please refer:

NotificationProcess.bpmn (3.3 KB) ParentMqttProcess.bpmn (3.2 KB)

My execution starts from ParentProcess.bpmn, wherein i have a service task, referring to a Java Class, this Java Class which is in a gradle project and the build.gradle goes like this:

apply plugin: 'java'

jar{
    archiveName = 'toolbox-services.jar'
}

configurations{
    runtimeDependency
    implementation.extendsFrom runtimeDependency
}

task copyJar(type: Copy, dependsOn: 'copyDependencies'){
    from jar
    into "$gradle.dockerDeployFolder"
}

task copyDependencies(type: Copy) {
    from configurations.runtimeDependency
    into "$gradle.dockerDeployFolder"
}

dependencies {

    runtimeDependency 'de.odysseus.juel:juel-api:2.2.7'
    runtimeDependency 'de.odysseus.juel:juel-spi:2.2.7'
    runtimeDependency 'de.odysseus.juel:juel-impl:2.2.7'
    implementation 'org.camunda.bpm.extension.springboot:camunda-bpm-spring-boot-starter-rest:2.1.2'
    implementation 'org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter-rest:3.0.0'
    implementation 'org.camunda.bpm.extension.springboot:camunda-bpm-spring-boot-starter-webapp:2.1.2'
    implementation 'org.camunda.bpm.extension.springboot:camunda-bpm-spring-boot-starter:2.2.0'
    runtimeDependency 'com.squareup.okhttp3:okhttp:3.9.0'
    compileOnly 'org.camunda.bpm:camunda-engine'
    compileOnly 'org.camunda.spin:camunda-spin-core'
    compileOnly 'org.camunda.bpm.dmn:camunda-engine-dmn'      
}

and the other service task is in a complete different package which is inside NotificationProcess.bpmn and has its own JAR when built, the gradle dependency goes like this.

plugins {
    id 'org.springframework.boot' version '2.1.5.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'java'
}

group = 'com.hv.bmc'
sourceCompatibility = '1.8'
springBoot {
    mainClassName = 'com.hv.bmc.EventNotificationApplication'
}
repositories {
    mavenCentral()
}

dependencies {
    compileOnly 'org.camunda.bpm:camunda-engine:7.10.0'
    implementation 'com.fasterxml.jackson.core:jackson-databind'
    implementation 'org.apache.commons:commons-lang3'
    compile 'com.squareup.okhttp3:okhttp:3.10.0'
    compile 'com.squareup.okio:okio:1.14.0'
    implementation 'com.googlecode.json-simple:json-simple:1.1.1'
    compileOnly 'org.camunda.bpm.dmn:camunda-engine-dmn:7.10.0'
    implementation 'org.springframework.boot:spring-boot-starter:2.1.5.RELEASE'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}

Now when my execution reaches NotificationProcess.bpmn, i am getting the following error:

org.camunda.commons.logging.BaseLogger.logError ENGINE-16004 Exception while closing command context: ENGINE-09008 Exception while instantiating class 'com.hv.bmc.EventNotificationApplication.EventNotificationGeneration': ENGINE-09017 Cannot load class 'com.hv.bmc.EventNotificationApplication.EventNotificationGeneration': com.hv.bmc.EventNotificationApplication.EventNotificationGeneration
 org.camunda.bpm.engine.ProcessEngineException: ENGINE-09008 Exception while instantiating class 'com.hv.bmc.EventNotificationApplication.EventNotificationGeneration': ENGINE-09017 Cannot load class 'com.hv.bmc.EventNotificationApplication.EventNotificationGeneration': com.hv.bmc.EventNotificationApplication.EventNotificationGeneration
        at org.camunda.bpm.engine.impl.util.EngineUtilLogger.exceptionWhileInstantiatingClass(EngineUtilLogger.java:81)
        at org.camunda.bpm.engine.impl.util.ClassDelegateUtil.instantiateDelegate(ClassDelegateUtil.java:53)
        at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior.getActivityBehaviorInstance(ClassDelegateActivityBehavior.java:111)
        at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior$1.call(ClassDelegateActivityBehavior.java:67)
        at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior$1.call(ClassDelegateActivityBehavior.java:64)
        at org.camunda.bpm.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.executeWithErrorPropagation(AbstractBpmnActivityBehavior.java:110)
        at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior.execute(ClassDelegateActivityBehavior.java:64)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:60)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:49)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueIfExecutionDoesNotAffectNextOperation(PvmExecutionImpl.java:1988)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:41)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:30)
        at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:95)
        at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:127)
        at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:107)
        at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:82)
        at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:640)
        at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:614)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$6.callback(PvmExecutionImpl.java:1927)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$6.callback(PvmExecutionImpl.java:1924)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueExecutionIfNotCanceled(PvmExecutionImpl.java:1994)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1943)
        at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1924)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:60)
        at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:30)

The class inside Notification Process bpmn is trying to access the process variables of that process, the code for NotificationProcess.bpmn goes like this:

     public void execute(DelegateExecution delegateExecution) throws Exception {
    boolean isNotify;
    JSONObject message = new JSONObject();
    message.put("username", "xyz");
    message.put("password", "password");
    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody formBody = RequestBody.create(JSON, message.toJSONString());
    Request request = new Request.Builder().url(GRAPHQL_URL + "/api/login").post(formBody).build();
    restClient = getUnsafeOkHttpClient();
    Response tokenResponse = restClient.newCall(request).execute();
    if (tokenResponse.code() == 200) {
        System.out.println("Nice Object " + delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents").toString());
        JSONObject mapOfEvents = new JSONObject();

        if (delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents") != null) {

            mapOfEvents = (JSONObject) delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents");
        }
        JSONObject singleEvent = new JSONObject();
        if (mapOfEvents.get(delegateExecution.getVariable("assetId")) != null) {

            singleEvent = (JSONObject) mapOfEvents.get(delegateExecution.getVariable("assetId"));
        }
        isNotify = (boolean) singleEvent.get("notificationTriggered");
        JSONParser jsonParser = new JSONParser();
        String responseString = tokenResponse.body().string();
        JSONObject responseJSON = (JSONObject) jsonParser.parse(responseString);
        String accessToken = "Bearer " + responseJSON.get("access_token");
        JSONObject query = new JSONObject();
        JSONObject variables = new JSONObject();
        JSONObject eventData = new JSONObject();
        eventData.put("createdDate", OffsetDateTime.now().toInstant().toEpochMilli());
        eventData.put("assetId", delegateExecution.getVariable("assetId"));
        eventData.put("severity", "CRITICAL");
        eventData.put("status", "OPEN");
        eventData.put("notify", isNotify);
        eventData.put("eventTypeId", delegateExecution.getVariable("eventTypeId"));
        variables.put("events", eventData);
        query.put("variables", variables);
        query.put("query", "mutation CreateEventsWithEventId($events: [EventInput!]!){createEventsWithEventId(events: $events){id}}");
        RequestBody createEvent = RequestBody.create(JSON, query.toJSONString());

        Request event = new Request.Builder()
                .addHeader("Authorization", accessToken)
                .url(GRAPHQL_URL + "/graphql")
                .post(createEvent)
                .build();
        Response createEventIdResponse = restClient.newCall(event).execute();
        JSONObject eventCreated = (JSONObject) jsonParser.parse(createEventIdResponse.body().string());
        JSONObject resultantData = (JSONObject) jsonParser.parse(eventCreated.get("data").toString());
        JSONArray getEventId = (JSONArray) jsonParser.parse(resultantData.get("createEventsWithEventId").toString());
        JSONObject eventId = (JSONObject) jsonParser.parse(getEventId.get(0).toString());
        variables.clear();
        query.clear();
        if (createEventIdResponse.code() == 200) {
            Map<String, String> recommendationOption = (Map<String, String>) delegateExecution.getVariable("recommendation_output");
            recommendationOption.remove("recommendedGroup");
            JSONArray needs = new JSONArray();
            JSONArray suggestions = new JSONArray();
            Set<String> suggestionOption = recommendationOption.keySet();
            int sequence = 0;
            for (String suggestion : suggestionOption) {
                JSONObject suggestionData = new JSONObject();
                suggestionData.put("sequence", ++sequence);
                suggestionData.put("operationText", recommendationOption.get(suggestion) + " " + suggestion);
                suggestionData.put("kpi", suggestion);
                suggestionData.put("operation", recommendationOption.get(suggestion).toLowerCase());
                suggestions.add(suggestionData);
            }
            JSONObject recommendations = new JSONObject();
            recommendations.put("name", "Option 1");
            recommendations.put("description", delegateExecution.getVariable("description"));
            recommendations.put("eventId", eventId.get("id").toString());
            recommendations.put("suggestions", suggestions);
            recommendations.put("needs", needs);
            variables.put("recommendations", recommendations);
            query.put("variables", variables);
            query.put("query", "mutation createRecommendations($recommendations: [RecommendationInput!]!) { createRecommendations(recommendations: $recommendations)}");
            RequestBody createRecommendation = RequestBody.create(JSON, query.toJSONString());
            Request recommendation = new Request.Builder()
                    .addHeader("Authorization", accessToken)
                    .url(GRAPHQL_URL + "/graphql")
                    .post(createRecommendation)
                    .build();

            Response createRecommendationResponse = restClient.newCall(recommendation).execute();
            variables.clear();
            query.clear();
            createRecommendationResponse.close();
        }
        tokenResponse.close();
        createEventIdResponse.close();
    }
}

I checked out other solution In about 60% cases can not resolve JavaDelegate in Service after Timer - #26 by aravindhrs, but I wonder if this works me out or not, moreover how can I disable job executor inside my NotificationProcess.bpmn. I am deploying both the jar inside my tomcat lib.

Thanks In Advance

Hi @aravindhrs,
I just tried the way you told, didnt work.
Can you please look into this:

Can you provide the complete java delegates used in service task

Hi @aravindhrs, Here is the service task code

package com.hv.bmc.EventNotificationApplication;

import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.OffsetDateTime;
import java.util.Map;
import java.util.Set;

@Component("eventService")
public class EventNotificationGeneration implements JavaDelegate {
    private String GRAPHQL_URL = "$Value";
    OkHttpClient restClient = new OkHttpClient();
    @Autowired
    ObjectMapper mapper;

    private static OkHttpClient getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain,
                                                       String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain,
                                                       String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            return new OkHttpClient.Builder()
                    .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
                    .hostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    }).build();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {
        boolean isNotify;

        JSONObject message = new JSONObject();
        message.put("username", "tim");
        message.put("password", "password");
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody formBody = RequestBody.create(JSON, message.toJSONString());
        Request request = new Request.Builder().url(GRAPHQL_URL + "/api/login").post(formBody).build();
        restClient = getUnsafeOkHttpClient();
        Response tokenResponse = restClient.newCall(request).execute();
        if (tokenResponse.code() == 200) {
            System.out.println("Nice Object " + delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents").toString());
            JSONObject mapOfEvents = new JSONObject();

            if (delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents") != null) {

                mapOfEvents = (JSONObject) delegateExecution.getProcessEngine().getRuntimeService().getVariable(delegateExecution.getVariable("rootId").toString(), "mapOfEvents");
            }
            JSONObject singleEvent = new JSONObject();
            if (mapOfEvents.get(delegateExecution.getVariable("assetId")) != null) {

                singleEvent = (JSONObject) mapOfEvents.get(delegateExecution.getVariable("assetId"));
            }
            isNotify = (boolean) singleEvent.get("notificationTriggered");
            JSONParser jsonParser = new JSONParser();
            String responseString = tokenResponse.body().string();
            JSONObject responseJSON = (JSONObject) jsonParser.parse(responseString);
            String accessToken = "Bearer " + responseJSON.get("access_token");
            JSONObject query = new JSONObject();
            JSONObject variables = new JSONObject();
            JSONObject eventData = new JSONObject();
            eventData.put("createdDate", OffsetDateTime.now().toInstant().toEpochMilli());
            eventData.put("assetId", delegateExecution.getVariable("assetId"));
            eventData.put("severity", "CRITICAL");
            eventData.put("status", "OPEN");
            eventData.put("notify", isNotify);
            eventData.put("eventTypeId", delegateExecution.getVariable("eventTypeId"));
            variables.put("events", eventData);
            query.put("variables", variables);
            query.put("query", "mutation CreateEventsWithEventId($events: [EventInput!]!){createEventsWithEventId(events: $events){id}}");
            RequestBody createEvent = RequestBody.create(JSON, query.toJSONString());

            Request event = new Request.Builder()
                    .addHeader("Authorization", accessToken)
                    .url(GRAPHQL_URL + "/graphql")
                    .post(createEvent)
                    .build();
            Response createEventIdResponse = restClient.newCall(event).execute();
            JSONObject eventCreated = (JSONObject) jsonParser.parse(createEventIdResponse.body().string());
            JSONObject resultantData = (JSONObject) jsonParser.parse(eventCreated.get("data").toString());
            JSONArray getEventId = (JSONArray) jsonParser.parse(resultantData.get("createEventsWithEventId").toString());
            JSONObject eventId = (JSONObject) jsonParser.parse(getEventId.get(0).toString());
            variables.clear();
            query.clear();
            if (createEventIdResponse.code() == 200) {
                Map<String, String> recommendationOption = (Map<String, String>) delegateExecution.getVariable("recommendation_output");
                recommendationOption.remove("recommendedGroup");
                JSONArray needs = new JSONArray();
                JSONArray suggestions = new JSONArray();
                Set<String> suggestionOption = recommendationOption.keySet();
                int sequence = 0;
                for (String suggestion : suggestionOption) {
                    JSONObject suggestionData = new JSONObject();
                    suggestionData.put("sequence", ++sequence);
                    suggestionData.put("operationText", recommendationOption.get(suggestion) + " " + suggestion);
                    suggestionData.put("kpi", suggestion);
                    suggestionData.put("operation", recommendationOption.get(suggestion).toLowerCase());
                    suggestions.add(suggestionData);
                }
                JSONObject recommendations = new JSONObject();
                recommendations.put("name", "Option 1");
                recommendations.put("description", delegateExecution.getVariable("description"));
                recommendations.put("eventId", eventId.get("id").toString());
                recommendations.put("suggestions", suggestions);
                recommendations.put("needs", needs);
                variables.put("recommendations", recommendations);
                query.put("variables", variables);
                query.put("query", "mutation createRecommendations($recommendations: [RecommendationInput!]!) { createRecommendations(recommendations: $recommendations)}");
                RequestBody createRecommendation = RequestBody.create(JSON, query.toJSONString());
                Request recommendation = new Request.Builder()
                        .addHeader("Authorization", accessToken)
                        .url(GRAPHQL_URL + "/graphql")
                        .post(createRecommendation)
                        .build();

                Response createRecommendationResponse = restClient.newCall(recommendation).execute();
                variables.clear();
                query.clear();
                createRecommendationResponse.close();
            }
            tokenResponse.close();
            createEventIdResponse.close();
        }
    }
}

Hi Arvindh
Can you have a look at this: