2017-09-14 14:17 GMT+02:00 Timothy Ward <tim.w...@paremus.com>: > Note that this work should be done as part of a new transaction control > service implementation (there’s some common code which should help to speed > up implementing it), not as changes to the current implementation, which is > undergoing stabilisation as the Reference Implementation of the OSGi > Transaction control service. >
You mean a new module like the tx-control-service-xa inside https://github.com/apache/aries/tree/trunk/tx-control/tx-control-services Right ? > > Also this update still won’t avoid the need for the JPA resource provider > to have a custom plugin for transaction integration. The whole point of a > managed resource is that it integrates with the Transaction Control service > that gets passed to it, not by integrating with a third party service which > may, or may not, be involved. > > Alexander - is there any chance of seeing the proof of concept code? It > seems as though it’s pretty close to working with the existing bundles. > > Regards, > > Tim > > > On 14 Sep 2017, at 12:42, <alexander.sah...@brodos.de> < > alexander.sah...@brodos.de> wrote: > > I'll give it a try. Maybe with a little guidance of you guys. First of all > I'll try to inject a JTA TransactionManager into tx-control instead of the > internal one. If that is working, I'll let you know. > > > >>> > > On 14 Sep 2017, at 10:46, Guillaume Nodet <gno...@apache.org> wrote: > > > > 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 ? > > > This is not something that I have the time to do, but another > implementation of a transaction control service with a pluggable > transaction manager would be a great addition. > > > 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.JPAEntityManagerProv >> iderFactoryImpl$EnlistingDataSource.enlistedCo >> nnection(JPAEntityManagerProviderFactoryImpl.java:241) ~[?:?] >> at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProv >> iderFactoryImpl$EnlistingDataSource.getConnect >> ion(JPAEntityManagerProviderFactoryImpl.java:193) ~[?:?] >> at org.hibernate.engine.jdbc.connections.internal.DatasourceCon >> nectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) >> ~[?:?] >> at org.hibernate.internal.NonContextualJdbcConnectionAccess. >> obtainConnection(NonContextualJdbcConnectionAccess.java:35) ~[?:?] >> at org.hibernate.resource.jdbc.internal.LogicalConnectionManage >> dImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:99) >> ~[?:?] >> at org.hibernate.resource.jdbc.internal.LogicalConnectionManage >> dImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:129) ~[?:?] >> at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.con >> nection(StatementPreparerImpl.java:47) ~[?:?] >> at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.d >> oPrepare(StatementPreparerImpl.java:146) ~[?:?] >> at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$Sta >> tementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:172) >> ~[?:?] >> at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.pre >> pareQueryStatement(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(Ab >> stractSharedSessionContract.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.getSingle >> Result(AbstractProducedQuery.java:1459) ~[?:?] >> at com.brodos.ds.persistence.h2.TestRepositoryImpl.lambda$check >> Health$0(TestRepositoryImpl.java:47) ~[?:?] >> at org.apache.aries.tx.control.service.common.impl.AbstractTran >> sactionControlImpl$TransactionBuilderImpl.doWork( >> AbstractTransactionControlImpl.java:161) [241:tx-control-service-xa:0.0 >> .3] >> at org.apache.aries.tx.control.service.common.impl.AbstractTran >> sactionControlImpl$TransactionBuilderImpl.require >> d(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.AbstractTran >> sactionControlImpl.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.chec >> kHealth(HealthCheckImpl.java:37) [212:com.brodos.example.ds.DSC >> ontext-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.handleM >> essage(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(C >> hainInitiationObserver.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-tran >> sports-http:3.1.12] >> at org.apache.cxf.transport.servlet.ServletController.invokeDes >> tination(ServletController.java:234) [92:org.apache.cxf.cxf-rt-tran >> sports-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.handleR >> equest(AbstractHTTPServlet.java:299) [92:org.apache.cxf.cxf-rt-tran >> sports-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.HttpServiceServletH >> andler.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.JettyServerHandlerC >> ollection.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$ReadCall >> back.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.JPAEntityManagerProv >> iderFactoryImpl$EnlistingDataSource.lambda$getConnection$4(JPAEntityManag >> erProviderFactoryImpl.java:193) ~[?:?] >> at org.apache.aries.tx.control.jpa.xa.impl.JPAEntityManagerProv >> iderFactoryImpl$EnlistingDataSource.enlistedCo >> nnection(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/mod >> ules/tx-control/xaJPA.html#creating-a-resource-using-a-facto >> ry-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 > > > > -- ------------------------ Guillaume Nodet