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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <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---------------------------------------------------- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <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 |
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'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]>:
|
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
</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:
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.
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.
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.
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
|
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.unit.name=tasklist 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" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <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,
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
|
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:
|
Free forum by Nabble | Edit this page |