I am new to Java and Maven/Spring. I am building a project to run a BPMN process in Camunda using a delegate. I have written the code, built the dependencies and am trying to build the project. When I put my JAR file into a Camunda container (I have Camunda deployed on a Linux server) I keep getting an error: Unknown property used in expression: ${sqlDataRetrievalDelegate}. Cause: Cannot resolve identifier 'sqlDataRetrievalDelegate'.
It seems to me that my Spring is not scanning and creating the Bin, what am I doing wrong? Help please.
Here's my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.camunda.bpm.getstarted</groupId>
<artifactId>loan-approval-spring-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<camunda.spring-boot.version>7.19.0</camunda.spring-boot.version>
<spring-boot.version>2.7.10</spring-boot.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<mssql.jdbc.version>9.2.1.jre11</mssql.jdbc.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>${camunda.spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.6</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>${mssql.jdbc.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>com.myapp.sqlDataRetrievalDelegate</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Here's my JAVA code:
package com.myapp;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Arrays;
import java.util.List;
@Component("sqlDataRetrievalDelegate")
public class sqlDataRetrievalDelegate implements JavaDelegate {
private static final Logger logger = LoggerFactory.getLogger(sqlDataRetrievalDelegate.class);
@Override
public void execute(DelegateExecution execution) {
logger.info("Executing SQL data retrieval delegate...");
String jdbcUrl = "jdbc:sqlserver://10.100.11.11:1433;databaseName=DBtestData";
String username = "camunda_sql1111";
String password = "12345678";
List<String> tags = Arrays.asList("MATR_TAG00001.SIM", "MATR_TAG00002.SIM", "MATR_TAG00003.SIM", "MATR_TAG00004.SIM");
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
String query = buildQuery(tags);
try (PreparedStatement stmt = conn.prepareStatement(query)) {
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
String tagName = rs.getString("TagName");
String timeStamp = rs.getString("TimeStamp");
double value = rs.getDouble("Value");
execution.setVariable("tagNameVariable", tagName);
execution.setVariable("timeStampVariable", timeStamp);
execution.setVariable("valueVariable", value);
}
}
}
} catch (Exception e) {
logger.error("Failed to execute SQL delegate", e);
throw new RuntimeException("Failed to execute SQL delegate", e);
}
}
private String buildQuery(List<String> tags) {
StringBuilder queryBuilder = new StringBuilder("SELECT TagName, TimeStamp, Value FROM OPENQUERY (PHD_OLEDB, 'SELECT * FROM phd.phd_data WHERE tagname IN (");
for (int i = 0; i < tags.size(); i++) {
queryBuilder.append("''").append(tags.get(i)).append("''");
if (i < tags.size() - 1) {
queryBuilder.append(",");
}
}
queryBuilder.append(") AND raw_data = true')");
return queryBuilder.toString();
}
}
These are the logs I see in IDEA:
PS C:\Users\FilippovAn\untitled1> mvn -e spring-boot:run
[INFO] Error stacktraces are turned on.
[INFO] Scanning for projects...
[INFO]
[INFO] --------< org.camunda.bpm.getstarted:loan-approval-spring-boot >--------
[INFO] Building loan-approval-spring-boot 0.0.1-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] >>> spring-boot:2.7.10:run (default-cli) > test-compile @ loan-approval-spring-boot >>>
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ loan-approval-spring-boot ---
[WARNING] Using platform encoding (Cp1251 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 2 resources from src\main\resources to target\classes
[INFO]
[INFO] --- compiler:3.11.0:compile (default-compile) @ loan-approval-spring-boot ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ loan-approval-spring-boot ---
[WARNING] Using platform encoding (Cp1251 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory C:\Users\FilippovAn\untitled1\src\test\resources
[INFO]
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ loan-approval-spring-boot ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] <<< spring-boot:2.7.10:run (default-cli) < test-compile @ loan-approval-spring-boot <<<
[INFO]
[INFO]
[INFO] --- spring-boot:2.7.10:run (default-cli) @ loan-approval-spring-boot ---
[INFO] Attaching agents: []
Error: Main method not found in class com.myapp.sqlDataRetrievalDelegate, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.102 s
[INFO] Finished at: 2023-08-18T11:30:12+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.7.10:run (default-cli) on project loan-approval-spring-boot: Application finished with exit code:
1 -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.7.10:run (default-cli) on project loan-approval-s
pring-boot: Application finished with exit code: 1
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:333)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:568)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
Caused by: org.apache.maven.plugin.MojoExecutionException: Application finished with exit code: 1
at org.springframework.boot.maven.RunMojo.runWithForkedJvm (RunMojo.java:103)
at org.springframework.boot.maven.AbstractRunMojo.doRunWithForkedJvm (AbstractRunMojo.java:291)
at org.springframework.boot.maven.AbstractRunMojo.run (AbstractRunMojo.java:255)
at org.springframework.boot.maven.AbstractRunMojo.execute (AbstractRunMojo.java:225)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:77)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:568)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
These are the logs I see in Camunda:
2023-08-15 12:15:02.465 WARN 10 --- [aTaskExecutor-3] org.camunda.bpm.engine.jobexecutor : ENGINE14006 Exception while executing job acf3efa9-3b64-11ee-8bf4-0242ac120002:
org.camunda.bpm.engine.ProcessEngineException: Unknown property used in expression: ${sqlDataRetrievalDelegate}. Cause: Cannot resolve identifier 'sqlDataRetrievalDelegate'
In your pom.xml in the configuration of the spring-boot-maven-plugin you specifiy you mainClass to be com.myapp.sqlDataRetrievalDelegate (by the way in Java the common practice is to start the class name with upper case so com.myapp.SqlDataRetrievalDelegate).
For a spring boot application you need an application class (see https://spring.io/guides/gs/spring-boot/).
So e.g. define the mainClass to be com.myapp.Application and that class should look like this:
package com.myapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
This will also enable the component scan and pick up your delegate bean.