javaspring-bootjtabitronixredhat-bpm

Unable to lookup JNDI name [jdbc/jbpm-ds]


I am trying to develop jBPM spring boot application but getting Unable to lookup JNDI name [jdbc/jbpm-ds] error.

To achieve so, I have used jbpm-7.36.0.Final, Spring-Boot-2.2.6 and jbpm-spring-boot 7.36.0 Final along with spring boot Bitronix api. Below is my pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jta-bitronix</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <!-- <version>5.2.6.RELEASE</version> -->
    </dependency>
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.kie</groupId>
        <artifactId>jbpm-spring-boot-starter-basic</artifactId>
        <version>${runtime.version}</version>
    </dependency>
</dependencies>

In my application.properties file I have configured below values

#hibernate configuration
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.hbm2ddl.auto=update

#JTA enabled
spring.jta.enabled=true

#bitronix Non-XA transaction manager configuration
spring.datasource.xa.properties.url=jdbc:sqlserver://10.1.5.209:1433;databaseName=MRR3;
spring.datasource.xa.properties.uniqueName=jdbc/jbpm-ds
spring.datasource.xa.properties.username=sa
spring.datasource.xa.properties.password=password_123
spring.datasource.xa.properties.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.xa.data-source-class-name=bitronix.tm.resource.jdbc.lrc.LrcXADataSource

Below is the code snippet

    @Bean
    public StatefulKnowledgeSession newStatefulKnowledgeSession() throws Exception {
        RuntimeEnvironmentBuilder builder = null;
        if (usePersistence) {
            TransactionManager tm = TransactionManagerServices.getTransactionManager();

            entityManagerFactory = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");//Line where Exception occurs
            System.out.println(entityManagerFactory.getProperties());

            Environment env = EnvironmentFactory.newEnvironment();
            env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
            env.set(EnvironmentName.TRANSACTION_MANAGER, tm);

            builder = RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
                    .entityManagerFactory(entityManagerFactory)
                    .addEnvironmentEntry(EnvironmentName.TRANSACTION_MANAGER, tm);

            builder.knowledgeBase(readKnowledgeBase);

            StatefulKnowledgeSession ksession = JPAKnowledgeService
                    .newStatefulKnowledgeSession(readKnowledgeBase, null, env);

            return ksession;
            // builder =
            // RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
            // .entityManagerFactory(entityManagerFactory);
        }
    }

Sharing important log info

2020-05-11 23:41:12.122  INFO 18852 --- [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [
    name: org.jbpm.persistence.jpa
    ...] {} <>
2020-05-11 23:41:12.155  WARN 18852 --- [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'newStatefulKnowledgeSession' defined in class path resource [com/citiustech/mrr/controller/AbstractionProcessController.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.kie.internal.runtime.StatefulKnowledgeSession]: Factory method 'newStatefulKnowledgeSession' threw exception; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] {} <>
.
.
.
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:275)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:179)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:119)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:56)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
    at com.citiustech.mrr.controller.AbstractionProcessController.newStatefulKnowledgeSession(AbstractionProcessController.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 20 common frames omitted
Caused by: org.hibernate.engine.jndi.JndiException: Unable to lookup JNDI name [jdbc/jbpm-ds]
    at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:100)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:100)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    ... 39 common frames omitted
Caused by: javax.naming.NameNotFoundException: unable to find a bound object at name 'jdbc/jbpm-ds'
    at bitronix.tm.jndi.BitronixContext.lookup(BitronixContext.java:83)
    at bitronix.tm.jndi.BitronixContext.lookup(BitronixContext.java:67)
    at javax.naming.InitialContext.lookup(InitialContext.java:421)
    at org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:97)
    ... 48 common frames omitted

I am also interested to know if below understanding of mine is correct or not

  1. jBPM only supports JTA type transaction i.e. global transaction. You can't use RESOURCE_LOCAL transaction type while integrating jBPM.
  2. When I say transaction type RESOURCE_LOCAL, means only one datasource transaction will be shared across the application.
  3. jBPM RuntimeManager uses 'org.jbpm.domain' persistence unit name (Mandatory type) to handle all it's internal table operations.
  4. All the application specific transaction can be handled by a default persistence unit name i.e.'org.jbpm.persistence.jpa' . This can be override by a custom persistence context.
  5. JTA is further divided into two types XADatasource type and Non-XADatasource type. XADatasource should be use when datasource is in application server container. And Non-XADatasource is useful for EJB based application.
  6. XADatasource required below configuration

    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    and

    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform" />

  7. Non-XADatasource required below configuration

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    and

    <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>

  8. Is point 6 or 7 necessary, if so how to without using persistence.xml.

  9. What is the use of below property and what jar has this class

    spring.jpa.properties.hibernate.transaction.manager_lookup_class=org.hibernate.transaction.BTMTransactionManagerLookup


Solution

  • As suggested by @JRichardsz, I made below changes in my code to make it work with Spring Boot

    @Autowired
    private AbstractPlatformTransactionManager jtaPlatform;
    
    @PersistenceUnit(name = "org.jbpm.persistence.jpa")
    private EntityManagerFactory entityManagerFactory;
    
    @Bean
    public StatefulKnowledgeSession newStatefulKnowledgeSession() throws Exception {
        RuntimeEnvironmentBuilder builder = null;
        if (usePersistence) {
            builder = RuntimeEnvironmentBuilder.Factory.get().newDefaultBuilder()
                    .entityManagerFactory(entityManagerFactory)
                    .addEnvironmentEntry(EnvironmentName.TRANSACTION_MANAGER, jtaPlatform);
    
            builder.knowledgeBase(readKnowledgeBase);
    
            RuntimeManager manager = RuntimeManagerFactory.Factory.get().newSingletonRuntimeManager(builder.get());
    
            return (StatefulKnowledgeSession) manager.getRuntimeEngine(EmptyContext.get())
                    .getKieSession();
        } 
    }
    

    For me xa.properties works along with Bitronix, but if it does not work for you then you can switch to Spring provided datasource.