Not resolved Provider using TransactionControl and JPAEntityManagerProvider

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Piero
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar
Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Piero
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar

Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Piero
Hi,

I'm going more confused.....

I tried to comment the injection:
//    @Reference(target = "(osgi.unit.name=tasklist)")
//    void setProvider(JPAEntityManagerProvider provider) {
//        em = provider.getResource(txControl);
//    }

and to get the provider this way:
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
        try {
        Collection<ServiceReference<JPAEntityManagerProviderFactory>> refemfps
        = Activator.getContext().getServiceReferences(JPAEntityManagerProviderFactory.class, null);
        Collection<ServiceReference<EntityManagerFactory>> refemfs
    = Activator.getContext().getServiceReferences(EntityManagerFactory.class, "(osgi.unit.name=tasklist)");
JPAEntityManagerProviderFactory pf = Activator.getContext().getService(refemfps.iterator().next());
EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);
em = p.getResource(txControl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It worked (!!) and I get working the read methods:
    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

But the write methods fails:
    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        //Here txControl.activeTransaction()=false
        txControl.required(()-> {
                    //Here txControl.activeTransaction()=true
            em.persist(task);   //Here  TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently active
            em.flush();
        return null;
        });
        
    }


Now I really can't undertand: 
1) why the injection of  JPAEntityManagerProvider fails while it can be got with common BundleContext.getServiceReferences?
2) why I obtain a  TransactionRequiredException when I checked in debugger that  txControl.activeTransaction()=true inside the  txControl.required block?

Any help would be very useful.

Tnx





2018-08-19 14:11 GMT+02:00 Piero <[hidden email]>:
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar


Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Timothy Ward-2
Hi Piero,

Sorry to only get to this email chain now.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to
  • Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)
  • Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending on which implementation you choose and you need to specify:
    • osgi.unit.name=tasklist
    • osgi.jdbc.driver.class=com.mysql.jdbc.Driver
    • user=root
    • password=root
    • url=jdbc:<a href="mysql://localhost:3306/reactive" class="">mysql://localhost:3306/reactive
  •  Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

  •     @Reference(name=“alphabeticallyFirst”)
        TransactionControl txControl;
        
        @Reference(target = "(osgi.unit.name=tasklist)")
        void setProvider(JPAEntityManagerProvider provider) {
            em = provider.getResource(txControl);
        }

</tldr>

Now for the complete explanation...

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved in a big fight over who is supposed to be controlling what.

You have:

80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of a warning sign that things might not be correct.

94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.


 jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:<a href="mysql://localhost:3306/r" class="">mysql://localhost:3306/reactive" reactive


So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different transactions than are being set up by the Transaction Control runtime.

EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);

I’m assuming that you didn’t read the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking for a transaction using Java EE and finds nothing.


Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Best Regards,

Tim

On 20 Aug 2018, at 07:23, Piero <[hidden email]> wrote:

Hi,

I'm going more confused.....

I tried to comment the injection:
//    @Reference(target = "(osgi.unit.name=tasklist)")
//    void setProvider(JPAEntityManagerProvider provider) {
//        em = provider.getResource(txControl);
//    }

and to get the provider this way:
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
        try {
        Collection<ServiceReference<JPAEntityManagerProviderFactory>> refemfps
        = Activator.getContext().getServiceReferences(JPAEntityManagerProviderFactory.class, null);
        Collection<ServiceReference<EntityManagerFactory>> refemfs
    = Activator.getContext().getServiceReferences(EntityManagerFactory.class, "(osgi.unit.name=tasklist)");
JPAEntityManagerProviderFactory pf = Activator.getContext().getService(refemfps.iterator().next());
EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);
em = p.getResource(txControl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It worked (!!) and I get working the read methods:
    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

But the write methods fails:
    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        //Here txControl.activeTransaction()=false
        txControl.required(()-> {
                    //Here txControl.activeTransaction()=true
            em.persist(task);   //Here  TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently active
            em.flush();
        return null;
        });
        
    }


Now I really can't undertand: 
1) why the injection of  JPAEntityManagerProvider fails while it can be got with common BundleContext.getServiceReferences?
2) why I obtain a  TransactionRequiredException when I checked in debugger that  txControl.activeTransaction()=true inside the  txControl.required block?

Any help would be very useful.

Tnx





2018-08-19 14:11 GMT+02:00 Piero <[hidden email]>:
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:<a href="mysql://localhost:3306/r" class="">mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar



Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Piero
Hi Timothy,

Really many thanks for your kind and deep answer.

I realized now that, trying to solve the original problem (the missing injection of the JPAEntityManagerProvider) I added a lot of things that introduced so many other problems and conflicts.

So I returned to the original code fixing two original errors you showed to me: now I use an empty persistence unit and I didn't create a karaf DataSource.

Now I got the JPAEntityManagerProvider injected but, the execution of the statement
em = provider.getResource(txControl);

produces the stack trace:
23:00:39.896 ERROR [CM Configuration Updater (Update: pid=org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85)] [fake.test.xa.internal.TaskServiceImpl(2)] The setTxControl method has thrown an exception
java.lang.NoSuchMethodError: org.osgi.service.jpa.EntityManagerFactoryBuilder.getPersistenceProviderName()Ljava/lang/String;
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.setupTransactionManager(JPAEntityManagerProviderFactoryImpl.java:250) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.getProviderFor(JPAEntityManagerProviderFactoryImpl.java:220) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.XAJPAEMFLocator.lambda$getResourceProvider$0(XAJPAEMFLocator.java:51) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:56) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:28) ~[?:?]
        at fake.test.xa.internal.TaskServiceImpl.setTxControl(TaskServiceImpl.java:31) ~[?:?]
        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.apache.felix.scr.impl.inject.BaseMethod.invokeMethod(BaseMethod.java:229) ~[61:org.apache.felix.scr:2.0.12]
        ....

So, thanks to your help I made some step forward, but I still am not  able to get en EntityManager by the injected JPAEntityManagerProvider  and TransactionControl.

The other strange thing is that when I exit and restart Karaf, the JPAEntityManagerProvider disapears (and so the fake.test.xa bundle remains in WAITING state):
karaf@test()> diag 76
fake.test.xa (76)
-----------------
Status: Waiting
Declarative Services
fake.test.xa.internal.TaskServiceImpl (2)
  missing references: Provider
xa.command (3)
  missing references: TaskService

It needs I delete the config file etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg. restart the server and write again the file. Then the provider appears again:
karaf@test()> service:list JPAEntityManagerProvider
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider]
-------------------------------------------------------------------
 felix.fileinstall.filename = file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg
 osgi.jdbc.driver.class = com.mysql.jdbc.Driver
 osgi.unit.name = tasklist
 service.bundleid = 78
 service.factoryPid = org.apache.aries.tx.control.jpa.xa
 service.id = 117
 service.pid = org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85
 service.scope = singleton
 url = jdbc:mysql://localhost:3306/reactive
 user = root
Provided by :
 OSGi Transaction Control JPA Resource Provider - XA Transactions (78)
Used by:
 fake.test.xa (76)

Many Thanks again for your help


-----
org.apache.aries.tx.control.jpa.xa-tasklist.cfg:
osgi.jdbc.driver.class=com.mysql.jdbc.Driver
user=root
password=root
url=jdbc:mysql://localhost:3306/reactive


-----
TaskServiceImpl (extract):

@Component(immediate = true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;
JPAEntityManagerProvider provider;
EntityManager em;

@Reference
void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
if(this.provider!=null)
em = provider.getResource(txControl);
}

void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}

@Reference(target = "(osgi.unit.name=tasklist)")
void setProvider(JPAEntityManagerProvider provider) {
this.provider = provider;
if(this.txControl!=null)
em = provider.getResource(txControl);
}

void unsetProvider(JPAEntityManagerProvider provider) {
this.provider = null;
}
...

-----
persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"

    <persistence-unit name="tasklist" />

</persistence>


------
karaf@test()> list
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version             | Name
---+----------+-----+---------------------+---------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1            | Apache Karaf :: Diagnostic :: Boot
22 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: OSGi Services :: Event
43 | Active   |  80 | 1.9.2.1             | Apache ServiceMix :: Bundles :: jasypt
44 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Generic Driver Extender
45 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Config
46 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Pooling Support Base
47 | Active   |  80 | 1.0.0.201505202023  | org.osgi:org.osgi.service.jdbc
48 | Active   |  80 | 1.3.0               | ClassMate
49 | Active   |  80 | 5.1.34              | Oracle Corporation's JDBC Driver for MySQL
50 | Active   |  80 | 3.20.0.GA           | Javassist
51 | Active   |  80 | 3.0.0               | Expression Language 3.0 API
52 | Active   |  80 | 1.2.0               | CDI APIs
53 | Active   |  80 | 1.2                 | javax.interceptor API
54 | Active   |  80 | 2.1.0.v201304241213 | Java Persistence API 2.1
55 | Active   |  80 | 1.2                 | javax.transaction API
56 | Active   |  80 | 1.6.6               | Byte Buddy (without dependencies)
62 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: JDBC :: Core
65 | Active   |  80 | 2.7.7.5             | Apache ServiceMix :: Bundles :: antlr
66 | Active   |  80 | 1.6.1.5             | Apache ServiceMix :: Bundles :: dom4j
67 | Active   |  80 | 1.0.0.2             | Apache ServiceMix :: Bundles :: javax.inject
68 | Active   |  80 | 5.0.1.Final         | hibernate-commons-annotations
69 | Active   |  80 | 5.2.8.Final         | hibernate-core
70 | Active   |  80 | 5.2.8.Final         | hibernate-osgi
71 | Active   |  80 | 2.0.3.Final         | Java Annotation Indexer
72 | Active   |  80 | 3.3.0.Final         | JBoss Logging 3
73 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC MySQL Driver Adapter
74 | Active   |  80 | 0.2.0               | pax-transx-tm-api
75 | Active   |  80 | 0.2.0               | pax-transx-tm-geronimo
76 | Waiting  |  80 | 0.0.1.SNAPSHOT      | fake.test.xa
78 | Active   |  80 | 1.0.0               | OSGi Transaction Control JPA Resource Provider - XA Transactions
79 | Active   |  80 | 1.0.0               | Apache Aries OSGi Transaction Control Service - XA Transactions
81 | Active   |  80 | 2.7.1.SNAPSHOT      | Apache Aries JPA Specification 2.1 API

Il giorno mer 22 ago 2018 alle ore 10:59 Timothy Ward <[hidden email]> ha scritto:
Hi Piero,

Sorry to only get to this email chain now.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to
  • Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)
  • Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending on which implementation you choose and you need to specify:
  •  Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

  •     @Reference(name=“alphabeticallyFirst”)
        TransactionControl txControl;
        
        @Reference(target = "(osgi.unit.name=tasklist)")
        void setProvider(JPAEntityManagerProvider provider) {
            em = provider.getResource(txControl);
        }

</tldr>

Now for the complete explanation...

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved in a big fight over who is supposed to be controlling what.

You have:

80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of a warning sign that things might not be correct.

94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.


 jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive


So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different transactions than are being set up by the Transaction Control runtime.

EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);

I’m assuming that you didn’t read the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking for a transaction using Java EE and finds nothing.


Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Best Regards,

Tim

On 20 Aug 2018, at 07:23, Piero <[hidden email]> wrote:

Hi,

I'm going more confused.....

I tried to comment the injection:
//    @Reference(target = "(osgi.unit.name=tasklist)")
//    void setProvider(JPAEntityManagerProvider provider) {
//        em = provider.getResource(txControl);
//    }

and to get the provider this way:
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
        try {
        Collection<ServiceReference<JPAEntityManagerProviderFactory>> refemfps
        = Activator.getContext().getServiceReferences(JPAEntityManagerProviderFactory.class, null);
        Collection<ServiceReference<EntityManagerFactory>> refemfs
    = Activator.getContext().getServiceReferences(EntityManagerFactory.class, "(osgi.unit.name=tasklist)");
JPAEntityManagerProviderFactory pf = Activator.getContext().getService(refemfps.iterator().next());
EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);
em = p.getResource(txControl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It worked (!!) and I get working the read methods:
    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

But the write methods fails:
    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        //Here txControl.activeTransaction()=false
        txControl.required(()-> {
                    //Here txControl.activeTransaction()=true
            em.persist(task);   //Here  TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently active
            em.flush();
        return null;
        });
        
    }


Now I really can't undertand: 
1) why the injection of  JPAEntityManagerProvider fails while it can be got with common BundleContext.getServiceReferences?
2) why I obtain a  TransactionRequiredException when I checked in debugger that  txControl.activeTransaction()=true inside the  txControl.required block?

Any help would be very useful.

Tnx





2018-08-19 14:11 GMT+02:00 Piero <[hidden email]>:
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar



Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Timothy Ward-2
Hi,

That is substantial progress - the first error you are seeing is in the Aries Transaction Control logic for detecting which plugin it should try to deploy into the JPA provider. This requires version 1.1 of the OSGi JPA service (which added the getPersistenceProviderName() method to EntityManagerFactoryBuilder) to work. Now the Transaction Control implementation correctly imports the JPA spec package at [1.1,2) which means that the issue is that the JPA service implementation that you’re using claims to be supporting version 1.1, but actually isn’t. I can’t see the Aries JPA container (the reference implementation of the v1.1 JPA Service) deployed in your bundles, which bundle are you using to provide the JPA service?

The second error appears to be a bug in Karaf’s processing of configurations, and probably needs to be reported there.


Best Regards,

Tim

On 22 Aug 2018, at 22:07, Piero <[hidden email]> wrote:

Hi Timothy,

Really many thanks for your kind and deep answer.

I realized now that, trying to solve the original problem (the missing injection of the JPAEntityManagerProvider) I added a lot of things that introduced so many other problems and conflicts.

So I returned to the original code fixing two original errors you showed to me: now I use an empty persistence unit and I didn't create a karaf DataSource.

Now I got the JPAEntityManagerProvider injected but, the execution of the statement
em = provider.getResource(txControl);

produces the stack trace:
23:00:39.896 ERROR [CM Configuration Updater (Update: pid=org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85)] [fake.test.xa.internal.TaskServiceImpl(2)] The setTxControl method has thrown an exception
java.lang.NoSuchMethodError: org.osgi.service.jpa.EntityManagerFactoryBuilder.getPersistenceProviderName()Ljava/lang/String;
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.setupTransactionManager(JPAEntityManagerProviderFactoryImpl.java:250) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.getProviderFor(JPAEntityManagerProviderFactoryImpl.java:220) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.XAJPAEMFLocator.lambda$getResourceProvider$0(XAJPAEMFLocator.java:51) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:56) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:28) ~[?:?]
        at fake.test.xa.internal.TaskServiceImpl.setTxControl(TaskServiceImpl.java:31) ~[?:?]
        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.apache.felix.scr.impl.inject.BaseMethod.invokeMethod(BaseMethod.java:229) ~[61:org.apache.felix.scr:2.0.12]
        ....

So, thanks to your help I made some step forward, but I still am not  able to get en EntityManager by the injected JPAEntityManagerProvider  and TransactionControl.

The other strange thing is that when I exit and restart Karaf, the JPAEntityManagerProvider disapears (and so the fake.test.xa bundle remains in WAITING state):
karaf@test()> diag 76
fake.test.xa (76)
-----------------
Status: Waiting
Declarative Services
fake.test.xa.internal.TaskServiceImpl (2)
  missing references: Provider
xa.command (3)
  missing references: TaskService

It needs I delete the config file etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg. restart the server and write again the file. Then the provider appears again:
karaf@test()> service:list JPAEntityManagerProvider
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider]
-------------------------------------------------------------------
 felix.fileinstall.filename = file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg
 osgi.jdbc.driver.class = com.mysql.jdbc.Driver
 osgi.unit.name = tasklist
 service.bundleid = 78
 service.factoryPid = org.apache.aries.tx.control.jpa.xa
 service.id = 117
 service.pid = org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85
 service.scope = singleton
 url = jdbc:<a href="mysql://localhost:3306/reactive" class="">mysql://localhost:3306/reactive
 user = root
Provided by :
 OSGi Transaction Control JPA Resource Provider - XA Transactions (78)
Used by:
 fake.test.xa (76)

Many Thanks again for your help


-----
org.apache.aries.tx.control.jpa.xa-tasklist.cfg:
osgi.jdbc.driver.class=com.mysql.jdbc.Driver
user=root
password=root
url=jdbc:<a href="mysql://localhost:3306/reactive" class="">mysql://localhost:3306/reactive


-----
TaskServiceImpl (extract):

@Component(immediate = true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;
JPAEntityManagerProvider provider;
EntityManager em;

@Reference
void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
if(this.provider!=null)
em = provider.getResource(txControl);
}

void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}

@Reference(target = "(osgi.unit.name=tasklist)")
void setProvider(JPAEntityManagerProvider provider) {
this.provider = provider;
if(this.txControl!=null)
em = provider.getResource(txControl);
}

void unsetProvider(JPAEntityManagerProvider provider) {
this.provider = null;
}
...

-----
persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"

    <persistence-unit name="tasklist" />

</persistence>


------
karaf@test()> list
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version             | Name
---+----------+-----+---------------------+---------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1            | Apache Karaf :: Diagnostic :: Boot
22 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: OSGi Services :: Event
43 | Active   |  80 | 1.9.2.1             | Apache ServiceMix :: Bundles :: jasypt
44 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Generic Driver Extender
45 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Config
46 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Pooling Support Base
47 | Active   |  80 | 1.0.0.201505202023  | org.osgi:org.osgi.service.jdbc
48 | Active   |  80 | 1.3.0               | ClassMate
49 | Active   |  80 | 5.1.34              | Oracle Corporation's JDBC Driver for MySQL
50 | Active   |  80 | 3.20.0.GA           | Javassist
51 | Active   |  80 | 3.0.0               | Expression Language 3.0 API
52 | Active   |  80 | 1.2.0               | CDI APIs
53 | Active   |  80 | 1.2                 | javax.interceptor API
54 | Active   |  80 | 2.1.0.v201304241213 | Java Persistence API 2.1
55 | Active   |  80 | 1.2                 | javax.transaction API
56 | Active   |  80 | 1.6.6               | Byte Buddy (without dependencies)
62 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: JDBC :: Core
65 | Active   |  80 | 2.7.7.5             | Apache ServiceMix :: Bundles :: antlr
66 | Active   |  80 | 1.6.1.5             | Apache ServiceMix :: Bundles :: dom4j
67 | Active   |  80 | 1.0.0.2             | Apache ServiceMix :: Bundles :: javax.inject
68 | Active   |  80 | 5.0.1.Final         | hibernate-commons-annotations
69 | Active   |  80 | 5.2.8.Final         | hibernate-core
70 | Active   |  80 | 5.2.8.Final         | hibernate-osgi
71 | Active   |  80 | 2.0.3.Final         | Java Annotation Indexer
72 | Active   |  80 | 3.3.0.Final         | JBoss Logging 3
73 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC MySQL Driver Adapter
74 | Active   |  80 | 0.2.0               | pax-transx-tm-api
75 | Active   |  80 | 0.2.0               | pax-transx-tm-geronimo
76 | Waiting  |  80 | 0.0.1.SNAPSHOT      | fake.test.xa
78 | Active   |  80 | 1.0.0               | OSGi Transaction Control JPA Resource Provider - XA Transactions
79 | Active   |  80 | 1.0.0               | Apache Aries OSGi Transaction Control Service - XA Transactions
81 | Active   |  80 | 2.7.1.SNAPSHOT      | Apache Aries JPA Specification 2.1 API

Il giorno mer 22 ago 2018 alle ore 10:59 Timothy Ward <[hidden email]> ha scritto:
Hi Piero,

Sorry to only get to this email chain now.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to
  • Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)
  • Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending on which implementation you choose and you need to specify:
  •  Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

  •     @Reference(name=“alphabeticallyFirst”)
        TransactionControl txControl;
        
        @Reference(target = "(osgi.unit.name=tasklist)")
        void setProvider(JPAEntityManagerProvider provider) {
            em = provider.getResource(txControl);
        }

</tldr>

Now for the complete explanation...

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved in a big fight over who is supposed to be controlling what.

You have:

80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of a warning sign that things might not be correct.

94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.


 jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive


So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different transactions than are being set up by the Transaction Control runtime.

EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);

I’m assuming that you didn’t read the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking for a transaction using Java EE and finds nothing.


Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Best Regards,

Tim

On 20 Aug 2018, at 07:23, Piero <[hidden email]> wrote:

Hi,

I'm going more confused.....

I tried to comment the injection:
//    @Reference(target = "(osgi.unit.name=tasklist)")
//    void setProvider(JPAEntityManagerProvider provider) {
//        em = provider.getResource(txControl);
//    }

and to get the provider this way:
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
        try {
        Collection<ServiceReference<JPAEntityManagerProviderFactory>> refemfps
        = Activator.getContext().getServiceReferences(JPAEntityManagerProviderFactory.class, null);
        Collection<ServiceReference<EntityManagerFactory>> refemfs
    = Activator.getContext().getServiceReferences(EntityManagerFactory.class, "(osgi.unit.name=tasklist)");
JPAEntityManagerProviderFactory pf = Activator.getContext().getService(refemfps.iterator().next());
EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);
em = p.getResource(txControl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It worked (!!) and I get working the read methods:
    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

But the write methods fails:
    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        //Here txControl.activeTransaction()=false
        txControl.required(()-> {
                    //Here txControl.activeTransaction()=true
            em.persist(task);   //Here  TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently active
            em.flush();
        return null;
        });
        
    }


Now I really can't undertand: 
1) why the injection of  JPAEntityManagerProvider fails while it can be got with common BundleContext.getServiceReferences?
2) why I obtain a  TransactionRequiredException when I checked in debugger that  txControl.activeTransaction()=true inside the  txControl.required block?

Any help would be very useful.

Tnx





2018-08-19 14:11 GMT+02:00 Piero <[hidden email]>:
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar




Reply | Threaded
Open this post in threaded view
|

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Piero
Tim,

many thanks again for your advices.

Definitely it seemed to be a version conflict problem (as almost every problem in OSGi....).

Karaf 4.2.0 comes with a not too updated version of Eclipselink and it brings a version 2.6.1 of the  Apache Aries JPA Container adapter for EclipseLink.

I unistalled it and installed the last version of Aries Tx Ctrl with the JPA Container adapter Ver. 2.7.1-SNAPSHOT, and now it works. 

I am performing some test for massive data loading, with different granularity of transactions, nested tx, noRollback exceptions etc... and it seems to be a comfortable choice for a big project I'm carry on.

Unfortunally I have still some hang session updating the test bundle in Karaf, often with losing of the JPAEntityManagerProvider that appears again only after a lot of attempts, but I will submit the question to Karaf community, as you suggested. So for now, many thanks for your help.

This is the list of the bundles I'am working with currently:
19 | Resolved |  80 | 4.2.0.M1                | Apache Karaf :: Diagnostic :: Boot
21 | Active   |  80 | 4.2.0.M1                | Apache Karaf :: OSGi Services :: Event
42 | Active   |  80 | 1.9.2.1                 | Apache ServiceMix :: Bundles :: jasypt
43 | Active   |  80 | 1.2.0                   | OPS4J Pax JDBC Generic Driver Extender
44 | Active   |  80 | 1.2.0                   | OPS4J Pax JDBC Config
45 | Active   |  80 | 1.2.0                   | OPS4J Pax JDBC Pooling Support Base
46 | Active   |  80 | 1.0.0.201505202023      | org.osgi:org.osgi.service.jdbc
47 | Active   |  80 | 5.1.34                  | Oracle Corporation's JDBC Driver for MySQL
48 | Active   |  80 | 3.0.0                   | Expression Language 3.0 API
49 | Active   |  80 | 1.2.0                   | CDI APIs
50 | Active   |  80 | 1.2                     | javax.interceptor API
51 | Active   |  80 | 1.2                     | javax.transaction API
55 | Active   |  80 | 2.7.1.SNAPSHOT          | Apache Aries JPA Specification 2.1 API
59 | Active   |  80 | 4.2.0.M1                | Apache Karaf :: JDBC :: Core
62 | Active   |  80 | 1.0.0.2                 | Apache ServiceMix :: Bundles :: javax.inject
63 | Active   |  80 | 3.2.0.v201302191141     | EclipseLink ANTLR
64 | Active   |  80 | 5.0.1.v201405080102     | EclipseLink ASM
65 | Active   |  80 | 2.6.4.v20160829-44060b6 | EclipseLink Core
66 | Active   |  80 | 2.6.4.v20160829-44060b6 | EclipseLink JPA
67 | Active   |  80 | 2.6.4.v20160829-44060b6 | EclipseLink Hermes Parser
68 | Active   |  80 | 1.2.0                   | OPS4J Pax JDBC MySQL Driver Adapter
69 | Active   |  80 | 0.2.0                   | pax-transx-tm-api
70 | Active   |  80 | 0.2.0                   | pax-transx-tm-geronimo
71 | Active   |  80 | 1.0.0                   | Apache Aries OSGi Transaction Control Service - XA Transactions
72 | Active   |  80 | 1.0.0                   | OSGi Transaction Control JPA Resource Provider - XA Transactions
75 | Active   |  80 | 2.7.1.SNAPSHOT          | Apache Aries JPA Container adapter for EclipseLink
76 | Active   |  80 | 0.0.1.SNAPSHOT          | fake.test.xa


Il giorno gio 23 ago 2018 alle ore 11:07 Timothy Ward <[hidden email]> ha scritto:
Hi,

That is substantial progress - the first error you are seeing is in the Aries Transaction Control logic for detecting which plugin it should try to deploy into the JPA provider. This requires version 1.1 of the OSGi JPA service (which added the getPersistenceProviderName() method to EntityManagerFactoryBuilder) to work. Now the Transaction Control implementation correctly imports the JPA spec package at [1.1,2) which means that the issue is that the JPA service implementation that you’re using claims to be supporting version 1.1, but actually isn’t. I can’t see the Aries JPA container (the reference implementation of the v1.1 JPA Service) deployed in your bundles, which bundle are you using to provide the JPA service?

The second error appears to be a bug in Karaf’s processing of configurations, and probably needs to be reported there.


Best Regards,

Tim

On 22 Aug 2018, at 22:07, Piero <[hidden email]> wrote:

Hi Timothy,

Really many thanks for your kind and deep answer.

I realized now that, trying to solve the original problem (the missing injection of the JPAEntityManagerProvider) I added a lot of things that introduced so many other problems and conflicts.

So I returned to the original code fixing two original errors you showed to me: now I use an empty persistence unit and I didn't create a karaf DataSource.

Now I got the JPAEntityManagerProvider injected but, the execution of the statement
em = provider.getResource(txControl);

produces the stack trace:
23:00:39.896 ERROR [CM Configuration Updater (Update: pid=org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85)] [fake.test.xa.internal.TaskServiceImpl(2)] The setTxControl method has thrown an exception
java.lang.NoSuchMethodError: org.osgi.service.jpa.EntityManagerFactoryBuilder.getPersistenceProviderName()Ljava/lang/String;
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.setupTransactionManager(JPAEntityManagerProviderFactoryImpl.java:250) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProviderFactoryImpl.getProviderFor(JPAEntityManagerProviderFactoryImpl.java:220) ~[?:?]
        at org.apache.aries.tx.control.jpa.xa.impl.XAJPAEMFLocator.lambda$getResourceProvider$0(XAJPAEMFLocator.java:51) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:56) ~[?:?]
        at org.apache.aries.tx.control.jpa.common.impl.DelayedJPAEntityManagerProvider.getResource(DelayedJPAEntityManagerProvider.java:28) ~[?:?]
        at fake.test.xa.internal.TaskServiceImpl.setTxControl(TaskServiceImpl.java:31) ~[?:?]
        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.apache.felix.scr.impl.inject.BaseMethod.invokeMethod(BaseMethod.java:229) ~[61:org.apache.felix.scr:2.0.12]
        ....

So, thanks to your help I made some step forward, but I still am not  able to get en EntityManager by the injected JPAEntityManagerProvider  and TransactionControl.

The other strange thing is that when I exit and restart Karaf, the JPAEntityManagerProvider disapears (and so the fake.test.xa bundle remains in WAITING state):
karaf@test()> diag 76
fake.test.xa (76)
-----------------
Status: Waiting
Declarative Services
fake.test.xa.internal.TaskServiceImpl (2)
  missing references: Provider
xa.command (3)
  missing references: TaskService

It needs I delete the config file etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg. restart the server and write again the file. Then the provider appears again:
karaf@test()> service:list JPAEntityManagerProvider
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider]
-------------------------------------------------------------------
 felix.fileinstall.filename = file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/etc/org.apache.aries.tx.control.jpa.xa-tasklist.cfg
 osgi.jdbc.driver.class = com.mysql.jdbc.Driver
 osgi.unit.name = tasklist
 service.bundleid = 78
 service.factoryPid = org.apache.aries.tx.control.jpa.xa
 service.id = 117
 service.pid = org.apache.aries.tx.control.jpa.xa.4f16bf25-b79a-4153-9820-ead68d399c85
 service.scope = singleton
 user = root
Provided by :
 OSGi Transaction Control JPA Resource Provider - XA Transactions (78)
Used by:
 fake.test.xa (76)

Many Thanks again for your help


-----
org.apache.aries.tx.control.jpa.xa-tasklist.cfg:
osgi.jdbc.driver.class=com.mysql.jdbc.Driver
user=root
password=root


-----
TaskServiceImpl (extract):

@Component(immediate = true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;
JPAEntityManagerProvider provider;
EntityManager em;

@Reference
void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
if(this.provider!=null)
em = provider.getResource(txControl);
}

void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}

@Reference(target = "(osgi.unit.name=tasklist)")
void setProvider(JPAEntityManagerProvider provider) {
this.provider = provider;
if(this.txControl!=null)
em = provider.getResource(txControl);
}

void unsetProvider(JPAEntityManagerProvider provider) {
this.provider = null;
}
...

-----
persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"

    <persistence-unit name="tasklist" />

</persistence>


------
karaf@test()> list
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version             | Name
---+----------+-----+---------------------+---------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1            | Apache Karaf :: Diagnostic :: Boot
22 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: OSGi Services :: Event
43 | Active   |  80 | 1.9.2.1             | Apache ServiceMix :: Bundles :: jasypt
44 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Generic Driver Extender
45 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Config
46 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC Pooling Support Base
47 | Active   |  80 | 1.0.0.201505202023  | org.osgi:org.osgi.service.jdbc
48 | Active   |  80 | 1.3.0               | ClassMate
49 | Active   |  80 | 5.1.34              | Oracle Corporation's JDBC Driver for MySQL
50 | Active   |  80 | 3.20.0.GA           | Javassist
51 | Active   |  80 | 3.0.0               | Expression Language 3.0 API
52 | Active   |  80 | 1.2.0               | CDI APIs
53 | Active   |  80 | 1.2                 | javax.interceptor API
54 | Active   |  80 | 2.1.0.v201304241213 | Java Persistence API 2.1
55 | Active   |  80 | 1.2                 | javax.transaction API
56 | Active   |  80 | 1.6.6               | Byte Buddy (without dependencies)
62 | Active   |  80 | 4.2.0.M1            | Apache Karaf :: JDBC :: Core
65 | Active   |  80 | 2.7.7.5             | Apache ServiceMix :: Bundles :: antlr
66 | Active   |  80 | 1.6.1.5             | Apache ServiceMix :: Bundles :: dom4j
67 | Active   |  80 | 1.0.0.2             | Apache ServiceMix :: Bundles :: javax.inject
68 | Active   |  80 | 5.0.1.Final         | hibernate-commons-annotations
69 | Active   |  80 | 5.2.8.Final         | hibernate-core
70 | Active   |  80 | 5.2.8.Final         | hibernate-osgi
71 | Active   |  80 | 2.0.3.Final         | Java Annotation Indexer
72 | Active   |  80 | 3.3.0.Final         | JBoss Logging 3
73 | Active   |  80 | 1.2.0               | OPS4J Pax JDBC MySQL Driver Adapter
74 | Active   |  80 | 0.2.0               | pax-transx-tm-api
75 | Active   |  80 | 0.2.0               | pax-transx-tm-geronimo
76 | Waiting  |  80 | 0.0.1.SNAPSHOT      | fake.test.xa
78 | Active   |  80 | 1.0.0               | OSGi Transaction Control JPA Resource Provider - XA Transactions
79 | Active   |  80 | 1.0.0               | Apache Aries OSGi Transaction Control Service - XA Transactions
81 | Active   |  80 | 2.7.1.SNAPSHOT      | Apache Aries JPA Specification 2.1 API

Il giorno mer 22 ago 2018 alle ore 10:59 Timothy Ward <[hidden email]> ha scritto:
Hi Piero,

Sorry to only get to this email chain now.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to
  • Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)
  • Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending on which implementation you choose and you need to specify:
  •  Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

  •     @Reference(name=“alphabeticallyFirst”)
        TransactionControl txControl;
        
        @Reference(target = "(osgi.unit.name=tasklist)")
        void setProvider(JPAEntityManagerProvider provider) {
            em = provider.getResource(txControl);
        }

</tldr>

Now for the complete explanation...

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved in a big fight over who is supposed to be controlling what.

You have:

80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of a warning sign that things might not be correct.

94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.


 jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive


So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different transactions than are being set up by the Transaction Control runtime.

EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);

I’m assuming that you didn’t read the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking for a transaction using Java EE and finds nothing.


Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Best Regards,

Tim

On 20 Aug 2018, at 07:23, Piero <[hidden email]> wrote:

Hi,

I'm going more confused.....

I tried to comment the injection:
//    @Reference(target = "(osgi.unit.name=tasklist)")
//    void setProvider(JPAEntityManagerProvider provider) {
//        em = provider.getResource(txControl);
//    }

and to get the provider this way:
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
        try {
        Collection<ServiceReference<JPAEntityManagerProviderFactory>> refemfps
        = Activator.getContext().getServiceReferences(JPAEntityManagerProviderFactory.class, null);
        Collection<ServiceReference<EntityManagerFactory>> refemfs
    = Activator.getContext().getServiceReferences(EntityManagerFactory.class, "(osgi.unit.name=tasklist)");
JPAEntityManagerProviderFactory pf = Activator.getContext().getService(refemfps.iterator().next());
EntityManagerFactory emf = Activator.getContext().getService(refemfs.iterator().next());
Map<String, Object> pars = new HashMap<>();
pars.put("osgi.unit.name", "tasklist");
JPAEntityManagerProvider p = pf.getProviderFor(emf, pars);
em = p.getResource(txControl);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It worked (!!) and I get working the read methods:
    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

But the write methods fails:
    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        //Here txControl.activeTransaction()=false
        txControl.required(()-> {
                    //Here txControl.activeTransaction()=true
            em.persist(task);   //Here  TransactionRequiredException: Explicitly joining a JTA transaction requires a JTA transaction be currently active
            em.flush();
        return null;
        });
        
    }


Now I really can't undertand: 
1) why the injection of  JPAEntityManagerProvider fails while it can be got with common BundleContext.getServiceReferences?
2) why I obtain a  TransactionRequiredException when I checked in debugger that  txControl.activeTransaction()=true inside the  txControl.required block?

Any help would be very useful.

Tnx





2018-08-19 14:11 GMT+02:00 Piero <[hidden email]>:
Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

karaf@test()>  classes 84 | grep -i JPAEntityManagerProvider
org/apache/aries/tx/control/jpa/common/impl/AbstractJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/DelayedJPAEntityManagerProvider.class
org/apache/aries/tx/control/jpa/common/impl/InternalJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/common/impl/ResourceTrackingJPAEntityManagerProviderFactory.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$1.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.class
org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderImpl.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProvider.class
org/osgi/service/transaction/control/jpa/JPAEntityManagerProviderFactory.class


karaf@test()> headers 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84)
---------------------------------------------------------------------
Archiver-Version = Plexus Archiver
Bnd-LastModified = 1525104456341
Build-Jdk = 1.8.0_152
Built-By = timothyjward
Created-By = 1.8.0_152 (Oracle Corporation)
Implementation-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Implementation-Vendor = The Apache Software Foundation
Implementation-Vendor-Id = org.apache.aries.tx-control
Implementation-Version = 1.0.0
Manifest-Version = 1.0
Specification-Title = OSGi Transaction Control JPA Resource Provider - XA Transactions
Specification-Vendor = The Apache Software Foundation
Specification-Version = 1.0.0
Tool = Bnd-3.3.0.201609221906

Bundle-Activator = org.apache.aries.tx.control.jpa.xa.impl.Activator
Bundle-ManifestVersion = 2
Bundle-Name = OSGi Transaction Control JPA Resource Provider - XA Transactions
Bundle-SymbolicName = tx-control-provider-jpa-xa
Bundle-Version = 1.0.0

Provide-Capability =
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
                osgi.xa.enabled=true,
        osgi.service;
                uses:=org.osgi.service.transaction.control.jpa;
                objectClass=org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;
                osgi.xa.enabled=true
....
karaf@test()> services 84

OSGi Transaction Control JPA Resource Provider - XA Transactions (84) provides:
-------------------------------------------------------------------------------
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
[org.osgi.service.cm.ManagedServiceFactory]




2018-08-19 8:42 GMT+02:00 Piero <[hidden email]>:
Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

It seems the bundle hangs waiting for this missing service provider:
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider)

Is anyone so kind to explain me what is missing?

I included the list of features and bundle installed on karaf as well.

I created the datasource this way:
    jdbc:ds-create -dbName reactive -dn mysql -dc com.mysql.jdbc.Driver -u root -p root -url "jdbc:mysql://localhost:3306/reactive" reactive

Thanks in advance


API-------------------------------------------------------------------

package fake.test.xa.api;

import java.util.Collection;

import javax.jws.WebService;

public interface TaskService {
    Task getTask(Integer id);

    void addTask(Task task) throws Exception;

    void updateTask(Task task)  throws Exception;

    void deleteTask(Integer id)  throws Exception;
    
    Collection<Task> getTasks();
}

IMPL-------------------------------------------------------------------------------------

package fake.test.xa.internal;

import java.util.Collection;
import java.util.Date;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;

import fake.test.xa.api.Task;
import fake.test.xa.api.TaskService;

@Component(immediate=true)
public class TaskServiceImpl implements TaskService {

TransactionControl txControl;

EntityManager em;
    @Reference
    void setTxControl(TransactionControl txControl) {
this.txControl = txControl;
}
    void unsetTxControl(TransactionControl txControl) {
this.txControl = null;
}
    
    @Reference(target = "(osgi.unit.name=tasklist)")
    void setProvider(JPAEntityManagerProvider provider) {
        em = provider.getResource(txControl);
    }

@Activate
private void activate(BundleContext ctx) {
        System.out.println("Starting the service "+ getClass().getName() +" at "+new Date());
}
@Deactivate
private void deactivate(BundleContext ctx) {
        System.out.println("Stopping the service"+ getClass().getName() +" at "+new Date());    
}

    @Override
    public Task getTask(Integer id) {
        return  txControl.supports(() -> em.find(Task.class, id));
    }

    @Override
    public void addTask(Task task) throws Exception {
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Adding task " + task.getId());
                
        txControl.required(()-> {
            em.persist(task);
            em.flush();
        return null;
        });
        
    }

    public Collection<Task> getTasks() {
    return txControl.supports(() -> {
            CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
            return em.createQuery(query.select(query.from(Task.class))).getResultList();
        });
    }

    @Override
    public void updateTask(Task task) throws Exception{
        if (task.getId() == null) {
            throw new Exception("Id property must be set");
        }
        System.err.println("Updating task " + task.getId());
        
        if(null==getTask(task.getId())) {
        throw new Exception("Task never registered before");
        }
        
        txControl.required(() -> {
        em.merge(task);
        em.flush();
        return null;
        });
        
    }

    @Override
   public void deleteTask(Integer id) throws Exception {
        System.err.println("Deleting task " + id);
        
        txControl.required(() -> {
    Task task = getTask(id);
            if (task  == null) {
            throw new RuntimeException("Task with id="+id+" not found");
            }
            em.remove(task);
    em.flush();
        return null;
        });
        
    }


}

PERSISTENCE.XML----------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="tasklist" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=reactive)</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>

</persistence>


POM.XML----------------------------------------------------

<modelVersion>4.0.0</modelVersion>

<groupId>fake</groupId>
<artifactId>test.xa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>fake.test.xa</name>
<packaging>bundle</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<java.version>1.8</java.version>
<osgi.version>6.0.0</osgi.version>
<osgi.compendium.version>5.0.0</osgi.compendium.version>

<aries.jpa.version>2.2.0</aries.jpa.version>

<dosgi.version>2.3.0</dosgi.version>
<aQute.version>1.50.0</aQute.version>
<enroute.version>2.0.0</enroute.version>

<karaf.shell.console.version>4.0.3</karaf.shell.console.version>

<maven.bundle.plugin.version>3.3.0</maven.bundle.plugin.version>
<maven-resources-plugin.version>3.0.2</maven-resources-plugin.version>

<transaction.version>2.0.0</transaction.version>
<transaction-api.version>1.2</transaction-api.version>
<jdbc.version>1.2.1</jdbc.version>
<aries.tx.control.version>1.0.0</aries.tx.control.version>

<baseline.skip>true</baseline.skip>

<topDirectoryLocation>..</topDirectoryLocation>
</properties>

<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.cmpn</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>

<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
<version>${aQute.version}</version>
</dependency>

<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.enroute.base.api</artifactId>
<version>${enroute.version}</version>
</dependency>

<dependency>
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
<version>${karaf.shell.console.version}</version>
</dependency>

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${transaction-api.version}</version>
</dependency>

<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.api</artifactId>
<version>${aries.jpa.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.jpa</groupId>
<artifactId>org.apache.aries.jpa.support</artifactId>
<version>${aries.jpa.version}</version>
</dependency>


<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>

<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-service-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
<dependency>
<groupId>org.apache.aries.tx-control</groupId>
<artifactId>tx-control-provider-jpa-xa</artifactId>
<version>${aries.tx.control.version}</version>
</dependency>
</dependencies>




<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>

<pluginManagement>
<plugins>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.plugin.version}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>-bnd.bnd</_include>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Service-Component>*</Service-Component>
<Bundle-Activator>fake.test.xa.internal.Activator</Bundle-Activator>
<!-- <Export-Package>fake.test.xa.*;version=${project.version} </Export-Package> -->
<Import-Package>*</Import-Package>
<Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
</instructions>
</configuration>
</plugin>

</plugins>
</build>
</project>

-----------------------------------------------------------------


karaf@test()> diag 98
fake.test.xa (98)
-----------------
Status: Waiting
Declarative Services
xa.command (9)
  missing references: TaskService
fake.test.xa.internal.TaskServiceImpl (8)
  missing references: Provider
  


karaf@test()> feature:list -i
Name                         | Version     | Required | State   | Repository               | Description
-----------------------------+-------------+----------+---------+--------------------------+--------------------------------------------------
aries-proxy                  | 4.2.0.M1    |          | Started | standard-4.2.0.M1        | Aries Proxy
feature                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Features Support
shell                        | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Shell
deployer                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Karaf Deployer
bundle                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Bundle support
config                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide OSGi ConfigAdmin support
diagnostic                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Diagnostic support
instance                     | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Instance support
jaas                         | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide JAAS support
log                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Log support
package                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Package commands and mbeans
service                      | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide Service support
system                       | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide System support
kar                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide KAR (KARaf archive) support
ssh                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a SSHd server on Karaf
management                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Provide a JMX MBeanServer and a set of MBeans in
eventadmin                   | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | OSGi Event Admin service specification for event-
scr                          | 4.2.0.M1    | x        | Started | standard-4.2.0.M1        | Declarative Service support
wrap                         | 2.5.3       | x        | Started | standard-4.2.0.M1        | Wrap URL handler
pax-transx-tm-api            | 0.2.0       |          | Started | pax-transx-0.2.0         |
pax-transx-tm-geronimo       | 0.2.0       |          | Started | pax-transx-0.2.0         |
hibernate-orm                | 5.2.8.Final |          | Started | hibernate-osgi           | Combines all Hibernate core dependencies and requ
transaction-api              | 1.2.0       |          | Started | enterprise-4.2.0.M1      |
transaction-manager-geronimo | 3.1.3       |          | Started | enterprise-4.2.0.M1      | Geronimo Transaction Manager
transaction                  | 2.0.0       | x        | Started | enterprise-4.2.0.M1      | OSGi Transaction Manager
hibernate                    | 5.2.8.Final | x        | Started | enterprise-4.2.0.M1      | Hibernate JPA engine support
jndi                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | OSGi Service Registry JNDI access
jdbc                         | 4.2.0.M1    | x        | Started | enterprise-4.2.0.M1      | JDBC service and commands
pax-jdbc-spec                | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides OSGi JDBC Service spec
pax-jdbc                     | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Service support
pax-jdbc-config              | 1.2.0       |          | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Config support
pax-jdbc-mysql               | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC MySQL DataSourceFactory
pax-jdbc-pool-dbcp2          | 1.2.0       | x        | Started | org.ops4j.pax.jdbc-1.2.0 | Provides JDBC Pooling DataSourceFactory
jpa                          | 2.6.1       | x        | Started | aries-jpa-2.6.1          | OSGi Persistence Container


karaf@test()> list -u
START LEVEL 100 , List Threshold: 50
ID | State    | Lvl | Version            | Update location
---+----------+-----+--------------------+----------------------------------------------------------------------------------------------------------------------------
20 | Resolved |  80 | 4.2.0.M1           | mvn:org.apache.karaf.diagnostic/org.apache.karaf.diagnostic.boot/4.2.0.M1
22 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf/org.apache.karaf.event/4.2.0.M1
43 | Active   |  80 | 1.9.2.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.2_1
44 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc/1.2.0
45 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-config/1.2.0
46 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-common/1.2.0
47 | Active   |  80 | 1.0.0.201505202023 | mvn:org.osgi/org.osgi.service.jdbc/1.0.0
48 | Active   |  80 | 1.3.0              | mvn:com.fasterxml/classmate/1.3.0
49 | Active   |  80 | 5.1.34             | mvn:mysql/mysql-connector-java/5.1.34
50 | Active   |  80 | 3.20.0.GA          | mvn:org.javassist/javassist/3.20.0-GA
51 | Active   |  80 | 3.0.0              | mvn:javax.el/javax.el-api/3.0.0
52 | Active   |  80 | 1.2.0              | mvn:javax.enterprise/cdi-api/1.2
53 | Active   |  80 | 1.2                | mvn:javax.interceptor/javax.interceptor-api/1.2
55 | Active   |  80 | 1.2                | mvn:javax.transaction/javax.transaction-api/1.2
56 | Active   |  80 | 1.6.6              | mvn:net.bytebuddy/byte-buddy/1.6.6
67 | Active   |  80 | 4.2.0.M1           | mvn:org.apache.karaf.jdbc/org.apache.karaf.jdbc.core/4.2.0.M1
69 | Active   |  80 | 2.7.7.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/2.7.7_5
70 | Active   |  80 | 1.6.1.5            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.dom4j/1.6.1_5
71 | Active   |  80 | 1.0.0.2            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.javax-inject/1_2
73 | Active   |  80 | 5.0.1.Final        | mvn:org.hibernate.common/hibernate-commons-annotations/5.0.1.Final
74 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-core/5.2.8.Final
75 | Active   |  80 | 5.2.8.Final        | mvn:org.hibernate/hibernate-osgi/5.2.8.Final
76 | Active   |  80 | 2.0.3.Final        | mvn:org.jboss/jandex/2.0.3.Final
77 | Active   |  80 | 3.3.0.Final        | mvn:org.jboss.logging/jboss-logging/3.3.0.Final
79 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-mysql/1.2.0
80 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-api/0.2.0
81 | Active   |  80 | 0.2.0              | mvn:org.ops4j.pax.transx/pax-transx-tm-geronimo/0.2.0
82 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-service-xa/1.0.0
83 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jdbc-xa/1.0.0
84 | Active   |  80 | 1.0.0              | mvn:org.apache.aries.tx-control/tx-control-provider-jpa-xa/1.0.0
92 | Active   |  80 | 2.7.1.SNAPSHOT     | mvn:org.apache.aries.jpa.javax.persistence/javax.persistence_2.1/2.7.1-SNAPSHOT
94 | Active   |  80 | 2.1.1              | mvn:org.apache.commons/commons-dbcp2/2.1.1
95 | Active   |  80 | 2.4.2              | mvn:org.apache.commons/commons-pool2/2.4.2
96 | Active   |  80 | 3.2.4.1            | mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.cglib/3.2.4_1
97 | Active   |  80 | 1.2.0              | mvn:org.ops4j.pax.jdbc/pax-jdbc-pool-dbcp2/1.2.0
98 | Waiting  |  80 | 0.0.1.SNAPSHOT     | file:/C:/KARAF/apache-karaf-4.2.0.M1/instances/test/deploy/test.xa-0.0.1-SNAPSHOT.jar