2017-09-14 11:40 GMT+02:00 Timothy Ward <tim.w...@paremus.com>: > Hi Alexander, > > As has been discussed on the Aries lists before, I have no problem with > someone creating a separate implementation of the Transaction Control > service which leverages the OSGi JTA Service Specification. The reason that > the current implementation doesn’t do this is twofold: > > > - By embedding a transaction manager the current Tx Control > implementation can avoid the javax.transaction split package from the JVM. > This makes the implementation easier to use and deploy because the user > doesn’t need to mess around with the boot class path, or worry about what > JTA version is available > - By embedding a transaction manager the current Tx control > implementation can rely on specific behaviours of the transaction manager > that it uses. This means that the Tx control implementation can support the > last resource gambit and XA recovery. > > Fwiw, as I already indicated, the pax-transx project provides a layer solving those problems, in addition of providing additional features and pluggability.
Would you be interested to incorporate it in Tx Control ? Guillaume > > If this is a proof of concept project then are you able to share it > somewhere (e.g. GitHub)? I’d like to help you get to the bottom of the NPE > that you’re seeing as I don’t think it should be possible for that to be > happening! > > Finally - yes the Aries user list is the best place to talk about this, > but I don’t want to move the conversation myself as I don’t know whether > you’re registered for that list, and don’t want you to miss my replies. > > Regards, > > Tim > > > On 14 Sep 2017, at 07:53, <alexander.sah...@brodos.de> < > alexander.sah...@brodos.de> wrote: > > Hi Tim. > > I'm using the 2.6.1 version of aries jpa support already. Normal > transaction control with blueprint and @Transactional annotation was > working fine. > > To have better control over startup dependencies and cope with > disappearing and appearing services during runtime we invest some time in > a Proof-Of-Concept for switching over to declarative services (DS). > Everything works fine so far - even restful services for DS with cxf-dosgi > works fine. Last bit to get it working is transaction management. With DS, > the @Transactional annotation is not working anymore due to the lack of > interceptors with DS. > > What do you think of the idea that tx-control should pick up a JTS > Transaction manager from the service registry instead of creating an own > one with new operator which is in fact tightly coupled. To implement loose > coupling here we should add a factory that may be configurable in the > factory config file. > > BTW, should we switch the discussion to aries group still? > > Best, Alexander. > > > >>> > Hi Alexander, > > That looks like it should be fine - what version of Aries JPA are you > using? There were some fixes made to Aries JPA in 2.4.0 to add support for > JPA 2.1 configuration properties which are needed by the transaction > control implementation, and I think that there were then more fixes in > 2.5.0 which are needed to get XA working with Hibernate. 2.6.1 is the > latest release version. > > Regards, > > Tim > > > On 13 Sep 2017, at 15:42, alexander.sah...@brodos.de wrote: > > Thanks Tim for the update. > > I tried the approach with providing a factory config in > karaf.dir/etc/org.apache.aries.tx.control.jpa.xa.cfg with config as: > osgi.unit.name=DSContext2 > osgi.jdbc.driver.class=org.h2.Driver > url=jdbc:h2:mem:article > user=sa > password= > > whilst having a mininmal persistence.xml like: > <persistence-unit name="DSContext" > > <properties> > <property name="hibernate.dialect" > value="org.hibernate.dialect.H2Dialect" /> > </properties> > </persistence-unit> > > (without the dialect I see another exception; Access to > DialectResolutionInfo cannot be null when 'hibernate.dialect' not set). > > Now I get further in the process (transaction enlistment works) but when > actually accessing the database, the entity manager throws a NPE while > trying to open the connection. In JPAEntityManagerProviderFactor > yImpl.EnlistingDataSource.enlistedConnection() while calling > supplier.call, the supplier.delegate member is null: > > org.osgi.service.transaction.control.TransactionException: There was a > problem getting hold of a database connection > at org.apache.aries.tx.control.jpa.xa.impl. > JPAEntityManagerProviderFactoryImpl$EnlistingDataSource. > enlistedConnection(JPAEntityManagerProviderFactoryImpl.java:241) ~[?:?] > at org.apache.aries.tx.control.jpa.xa.impl. > JPAEntityManagerProviderFactoryImpl$EnlistingDataSource.getConnection( > JPAEntityManagerProviderFactoryImpl.java:193) ~[?:?] > at org.hibernate.engine.jdbc.connections.internal. > DatasourceConnectionProviderImpl.getConnection( > DatasourceConnectionProviderImpl.java:122) ~[?:?] > at org.hibernate.internal.NonContextualJdbcConnectionAcc > ess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) ~[?:?] > at org.hibernate.resource.jdbc.internal. > LogicalConnectionManagedImpl.acquireConnectionIfNeeded( > LogicalConnectionManagedImpl.java:99) ~[?:?] > at org.hibernate.resource.jdbc.internal. > LogicalConnectionManagedImpl.getPhysicalConnection( > LogicalConnectionManagedImpl.java:129) ~[?:?] > at org.hibernate.engine.jdbc.internal.StatementPreparerImpl. > connection(StatementPreparerImpl.java:47) ~[?:?] > at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5. > doPrepare(StatementPreparerImpl.java:146) ~[?:?] > at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$ > StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) > ~[?:?] > at org.hibernate.engine.jdbc.internal.StatementPreparerImpl. > prepareQueryStatement(StatementPreparerImpl.java:148) ~[?:?] > at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1940) > ~[?:?] > at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1909) > ~[?:?] > at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1887) > ~[?:?] > at org.hibernate.loader.Loader.doQuery(Loader.java:932) ~[?:?] > at > org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349) > ~[?:?] > at org.hibernate.loader.Loader.doList(Loader.java:2615) ~[?:?] > at org.hibernate.loader.Loader.doList(Loader.java:2598) ~[?:?] > at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2430) > ~[?:?] > at org.hibernate.loader.Loader.list(Loader.java:2425) ~[?:?] > at > org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:335) > ~[?:?] > at > org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2153) > ~[?:?] > at org.hibernate.internal.AbstractSharedSessionContract.list( > AbstractSharedSessionContract.java:991) ~[?:?] > at > org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:147) > ~[?:?] > at org.hibernate.query.internal.AbstractProducedQuery.list( > AbstractProducedQuery.java:1410) ~[?:?] > at org.hibernate.query.internal.AbstractProducedQuery. > getSingleResult(AbstractProducedQuery.java:1459) ~[?:?] > at com.brodos.ds.persistence.h2.TestRepositoryImpl.lambda$ > checkHealth$0(TestRepositoryImpl.java:47) ~[?:?] > at org.apache.aries.tx.control.service.common.impl. > AbstractTransactionControlImpl$TransactionBuilderImpl.doWork( > AbstractTransactionControlImpl.java:161) [241:tx-control-service-xa:0.0.3] > at org.apache.aries.tx.control.service.common.impl. > AbstractTransactionControlImpl$TransactionBuilderImpl.required( > AbstractTransactionControlImpl.java:84) [241:tx > <https://maps.google.com/?q=84)+%5B241:tx&entry=gmail&source=g> > -control-service-xa:0.0.3] > at org.apache.aries.tx.control.service.common.impl. > AbstractTransactionControlImpl.required(AbstractTransactionControlImpl.java:263) > [241:tx-control-service-xa:0.0.3] > at > com.brodos.ds.persistence.h2.TestRepositoryImpl.checkHealth(TestRepositoryImpl.java:44) > [160:com.brodos.example.ds.DSContext-infrastructure:1.0.0.SNAPSHOT] > at > com.brodos.ds.service.impl.MainHealthCheck.checkHealth(MainHealthCheck.java:29) > [209:com.brodos.example.ds.DSContext-service:1.0.0.SNAPSHOT] > at com.brodos.ds.application.boundary.impl.HealthCheckImpl. > checkHealth(HealthCheckImpl.java:37) [212:com.brodos.example.ds. > DSContext-application:1.0.0.SNAPSHOT] > 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:497) ~[?:?] > at org.apache.cxf.service.invoker.AbstractInvoker. > performInvocation(AbstractInvoker.java:180) [84:org.apache.cxf.cxf-core:3. > 1.12] > at org.apache.cxf.service.invoker.AbstractInvoker. > invoke(AbstractInvoker.java:96) [84:org.apache.cxf.cxf-core:3.1.12] > at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189) > [85:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.12] > at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99) > [85:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.12] > at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1. > run(ServiceInvokerInterceptor.java:59) [84:org.apache.cxf.cxf-core:3.1.12] > at org.apache.cxf.interceptor.ServiceInvokerInterceptor. > handleMessage(ServiceInvokerInterceptor.java:96) > [84:org.apache.cxf.cxf-core:3.1.12] > at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept( > PhaseInterceptorChain.java:308) [84:org.apache.cxf.cxf-core:3.1.12] > at org.apache.cxf.transport.ChainInitiationObserver.onMessage( > ChainInitiationObserver.java:121) [84:org.apache.cxf.cxf-core:3.1.12] > at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke( > AbstractHTTPDestination.java:263) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.ServletController. > invokeDestination(ServletController.java:234) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.ServletController. > invoke(ServletController.java:208) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.ServletController. > invoke(ServletController.java:160) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.CXFNonSpringServlet. > invoke(CXFNonSpringServlet.java:189) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.AbstractHTTPServlet. > handleRequest(AbstractHTTPServlet.java:299) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at org.apache.cxf.transport.servlet.AbstractHTTPServlet. > doGet(AbstractHTTPServlet.java:223) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) > [69:javax.servlet-api:3.1.0] > at org.apache.cxf.transport.servlet.AbstractHTTPServlet. > service(AbstractHTTPServlet.java:274) [92:org.apache.cxf.cxf-rt- > transports-http:3.1.12] > at > org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) > [128:org.eclipse.jetty.servlet:9.3.14.v20161028] > at > org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:584) > [128:org.eclipse.jetty.servlet:9.3.14.v20161028] > at org.ops4j.pax.web.service.jetty.internal. > HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) > [150:org.ops4j.pax.web.pax-web-jetty:6.0.6] > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at > org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) > [125:org.eclipse.jetty.security:9.3.14.v20161028] > at org.eclipse.jetty.server.session.SessionHandler. > doHandle(SessionHandler.java:226) [127:org.eclipse.jetty.server: > 9.3.14.v20161028] > at org.eclipse.jetty.server.handler.ContextHandler. > doHandle(ContextHandler.java:1180) [127:org.eclipse.jetty.server: > 9.3.14.v20161028] > at org.ops4j.pax.web.service.jetty.internal. > HttpServiceContext.doHandle(HttpServiceContext.java:284) > [150:org.ops4j.pax.web.pax-web-jetty:6.0.6] > at > org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512) > [128:org.eclipse.jetty.servlet:9.3.14.v20161028] > at org.eclipse.jetty.server.session.SessionHandler. > doScope(SessionHandler.java:185) [127:org.eclipse.jetty.server: > 9.3.14.v20161028] > at org.eclipse.jetty.server.handler.ContextHandler. > doScope(ContextHandler.java:1112) [127:org.eclipse.jetty.server: > 9.3.14.v20161028] > at > org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at org.ops4j.pax.web.service.jetty.internal. > JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80) > [150:org.ops4j.pax.web.pax-web-jetty:6.0.6] > at > org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at org.eclipse.jetty.server.Server.handle(Server.java:534) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at > org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) > [127:org.eclipse.jetty.server:9.3.14.v20161028] > at > org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) > [119:org.eclipse.jetty.io:9.3.14.v20161028] > at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) > [119:org.eclipse.jetty.io:9.3.14.v20161028] > at > org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) > [119:org.eclipse.jetty.io:9.3.14.v20161028] > at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume. > executeProduceConsume(ExecuteProduceConsume.java:303) > [130:org.eclipse.jetty.util:9.3.14.v20161028] > at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume. > produceConsume(ExecuteProduceConsume.java:148) > [130:org.eclipse.jetty.util:9.3.14.v20161028] > at org.eclipse.jetty.util.thread.strategy. > ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) > [130:org.eclipse.jetty.util:9.3.14.v20161028] > at > org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) > [130:org.eclipse.jetty.util:9.3.14.v20161028] > at > org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) > [130:org.eclipse.jetty.util:9.3.14.v20161028] > at java.lang.Thread.run(Thread.java:745) [?:?] > Caused by: java.lang.NullPointerException > at org.apache.aries.tx.control.jpa.xa.impl. > JPAEntityManagerProviderFactoryImpl$EnlistingDataSource. > lambda$getConnection$4(JPAEntityManagerProviderFactoryImpl.java:193) > ~[?:?] > at org.apache.aries.tx.control.jpa.xa.impl. > JPAEntityManagerProviderFactoryImpl$EnlistingDataSource. > enlistedConnection(JPAEntityManagerProviderFactoryImpl.java:230) ~[?:?] > ... 78 more > > Best, Alexander > > > >>> > Hi Alexander, > > So what you’re doing is passing a *fully configured* EntityManagerFactory > to the resource provider factory. If you create the provider this way then > you are responsible for setting up *all* of the EntityManagerFactory’s > configuration, including how it’s going to integrate with transaction > control. For local transactions there is nothing to integrate with , but in > the general case this is actually quite hard to do, and I would advise not > trying to do it. > > As you can see the EntityManagerFactory version of the provider factory > <https://github.com/apache/aries/blob/ed8dbc79758766081203056cff27eb0bcbd7efb3/tx-control/tx-control-providers/jpa/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/JPAEntityManagerProviderFactoryImpl.java#L122> > does > quite a bit less setup on your behalf than the configuration-driven > version does > <https://github.com/apache/aries/blob/ed8dbc79758766081203056cff27eb0bcbd7efb3/tx-control/tx-control-providers/jpa/tx-control-provider-jpa-xa/src/main/java/org/apache/aries/tx/control/jpa/xa/impl/XAJPAEMFLocator.java#L72>. > If you were to > provide a factory configuration for the “org.apache.aries.tx.control.jpa.xa” > pid containing “osgi.unit.name=<your persistence unit’s name>” and any > necessary datasource configuration (i.e. that’s not coming from the > persistence xml) then you could inject the JPAEntityManagerProvider > directly as a service. > > More documentation about configuration-driven resources for Aries > Tx-Control is available at http://aries.apache.org/ > modules/tx-control/xaJPA.html#creating-a-resource-using-a- > factory-configuration > > Another thing that probably could be done would be to look at dynamically > installing the plugin when using the EntityManagerFactoryBuilder version of > the factory method. This, however, would need a patch to Aries Transaction > Control, and would still not make your existing code work. > > Regards, > > Tim > > > On 13 Sep 2017, at 10:59, <alexander.sah...@brodos.de> < > alexander.sah...@brodos.de> wrote: > > Hi Tim, > > I use a JPAEntityManagerProviderFactory (providerFactory) which I inject > as a service reference into my repository class. > Furthermore, I inject a EntityManagerFactory (emf) into the repository > class as well as the TransactionControl (txControl). > > The provider Factory is created by pax-jdbc (I use hibernate). > > This provider factory is then used to get the Entity manager like this: > > EntityManager em = providerFactory.getProviderFor(emf, > null).getResource(txControl); > > It fails giving an exception telling that transaction cannot be joined, > because it's not open. > > The wrapping call is like this: > txControl.build() > .required( > () -> repo.store(article)); > > Best, Alexander. > > > >>> > Hi Alexander, > > Do you have a code example of how you’re obtaining and using the > EntityManager? There should be no usage of the OSGiJtaPlatform from the > tx-control XA JPA resource provider, which means that there’s either a bug > in the resource provider, or something is misconfigured. If you are a > member of the Aries user mailing list then that would be a better place to > continue this discussion. > > Regards, > > Tim > > On 13 Sep 2017, at 09:21, Guillaume Nodet <gno...@apache.org> wrote: > > Fwiw, you should ask on the Aries mailing list, where tx-control is > developed. > > I've recently worked on a new project called pax-transx which provides an > abstraction layer on top of transaction managers so that some features can > be accessed in a common way. I think this should be used in tx-control > instead of wrapping the tm again and not being flexible. > Right now, tx-control uses its own instance of transaction manager and > there's no way around afaik, so you can't use the karaf transaction feature > if you want to use it. > Anyway, I'd gladly support you if you go to the aries mailing list to > raise this point ! > > 2017-09-13 9:52 GMT+02:00 <alexander.sah...@brodos.de>: > >> Hello. >> >> I'm trying to get tx-control with XA transactions running (local is >> working). >> I found that tx-control opens a JTA transaction using >> RecoveryWorkAroundTransactionManager (derived from geronimo's >> TransactionManager Implementation) explicitly instead of using the >> registered TransactionManager (aries in my case for karaf 4.0.9). When >> hibernate EntityManager implementation tries to join the transaction it >> fails because it uses the TransactionManager provided by OsgiJtaPlatform >> (from hibernate-osgi) which is of course the one registered in osgi >> ecosystem. >> >> I think that the tx-control implementation has to use the >> TransactionManager registered with OSGi. >> >> Has anyone got that thing ever running? >> >> Best Alexander. >> > > > > -- > ------------------------ > Guillaume Nodet > > > > > > -- ------------------------ Guillaume Nodet