Repository: tomee Updated Branches: refs/heads/master fdf704e40 -> d81d45b6c
TOMEE-1903 ensure JTA components can be looked up by CDI Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d81d45b6 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d81d45b6 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d81d45b6 Branch: refs/heads/master Commit: d81d45b6c4bd62f9b4d9ab67f1fe5b44ff5b1d7b Parents: fdf704e Author: Romain manni-Bucau <rmannibu...@gmail.com> Authored: Tue Aug 16 09:48:15 2016 +0200 Committer: Romain manni-Bucau <rmannibu...@gmail.com> Committed: Tue Aug 16 09:48:15 2016 +0200 ---------------------------------------------------------------------- .../arquillian/tests/jta/CdiJndiTest.java | 57 ++++++++++++++++++++ .../arquillian/tests/jta/TheExtension.java | 53 ++++++++++++++++++ .../openejb/config/AnnotationDeployer.java | 5 +- .../tomee/catalina/TomcatWebAppBuilder.java | 32 ++++++++--- 4 files changed, 136 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/d81d45b6/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/CdiJndiTest.java ---------------------------------------------------------------------- diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/CdiJndiTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/CdiJndiTest.java new file mode 100644 index 0000000..999c772 --- /dev/null +++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/CdiJndiTest.java @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openejb.arquillian.tests.jta; + +import org.apache.openejb.OpenEJB; +import org.apache.openejb.loader.SystemInstance; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import javax.enterprise.inject.spi.Extension; +import javax.inject.Inject; +import javax.transaction.TransactionSynchronizationRegistry; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(Arquillian.class) +public class CdiJndiTest { + @Deployment + public static Archive<?> app() { + return ShrinkWrap.create(WebArchive.class, "CdiJndiTest.war") + .addClasses(TheExtension.class) + .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") + .addAsServiceProvider(Extension.class, TheExtension.class); + } + + @Inject + private TheExtension extension; + + @Test + public void check() { + assertNotNull(extension.getMgr()); + assertNotNull(extension.getRegistry()); + assertEquals(OpenEJB.getTransactionManager(), extension.getMgr()); + assertEquals(SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class), extension.getRegistry()); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/d81d45b6/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/TheExtension.java ---------------------------------------------------------------------- diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/TheExtension.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/TheExtension.java new file mode 100644 index 0000000..cd56361 --- /dev/null +++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-webprofile-tests/src/test/java/org/apache/openejb/arquillian/tests/jta/TheExtension.java @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openejb.arquillian.tests.jta; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterDeploymentValidation; +import javax.enterprise.inject.spi.Extension; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import static org.junit.Assert.fail; + +// reproduces camel-cdi +public class TheExtension implements Extension { + private Object mgr; + private Object registry; + + private void captureJtaComponents(@Observes final AfterDeploymentValidation adv) { + // here we need JTA lookups to work. These lookup are often done by spring in practise + try { + mgr = InitialContext.doLookup("java:comp/TransactionManager"); + } catch (final NamingException e) { + fail(); + } + try { + registry = InitialContext.doLookup("java:comp/TransactionSynchronizationRegistry"); + } catch (final NamingException e) { + fail(); + } + } + + public Object getMgr() { + return mgr; + } + + public Object getRegistry() { + return registry; + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/d81d45b6/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java b/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java index a151887..6157278 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java @@ -1285,7 +1285,6 @@ public class AnnotationDeployer implements DynamicDeployer { return ejbModule; } - try { if (ejbModule.getFinder() == null) { ejbModule.setFinder(FinderFactory.createFinder(ejbModule)); @@ -1504,7 +1503,7 @@ public class AnnotationDeployer implements DynamicDeployer { Beans beans = ejbModule.getBeans(); final boolean deployComp; - if (beans == null && !ejbModule.getEjbJar().getEnterpriseBeansByEjbName().isEmpty() + if (beans == null && !ejbJar.getEnterpriseBeansByEjbName().isEmpty() && isActivateCdiForEjbOnlyModules(ejbModule)) { logger.info("Activating CDI in ACTIVATED mode in module '" + ejbModule.getModuleUri() + "' cause EJB were found\n" + " add openejb.cdi.activated=false in application.properties to switch it off or\n" + @@ -1573,7 +1572,7 @@ public class AnnotationDeployer implements DynamicDeployer { || Boolean.parseBoolean(SystemInstance.get().getProperty("openejb.cdi.activated-on-ejb", "false" /*spec should be true but mem + bck compat*/)); } - // quick heuristic to guess if cdi is there, avoid to need more mem when useless + // quick heuristic to guess if cdi is needed, avoid to need more mem when useless private boolean hasAtInject(final EjbModule ejbModule) { final IAnnotationFinder finder = ejbModule.getFinder(); return finder != null && http://git-wip-us.apache.org/repos/asf/tomee/blob/d81d45b6/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java index 4abb4d2..330c9bd 100644 --- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java +++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java @@ -1153,6 +1153,30 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare ContextInfo contextInfo = getContextInfo(standardContext); ClassLoader classLoader = standardContext.getLoader().getClassLoader(); + // bind jta before the app starts to ensure we have it in CDI + final Thread thread = Thread.currentThread(); + final ClassLoader originalLoader = thread.getContextClassLoader(); + thread.setContextClassLoader(classLoader); + + final String listenerName = standardContext.getNamingContextListener().getName(); + ContextAccessController.setWritable(listenerName, standardContext.getNamingToken()); + try { + final Context comp = Context.class.cast(ContextBindings.getClassLoader().lookup("comp")); + + // bind TransactionManager + final TransactionManager transactionManager = SystemInstance.get().getComponent(TransactionManager.class); + safeBind(comp, "TransactionManager", transactionManager); + + // bind TransactionSynchronizationRegistry + final TransactionSynchronizationRegistry synchronizationRegistry = SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class); + safeBind(comp, "TransactionSynchronizationRegistry", synchronizationRegistry); + } catch (final NamingException e) { + // no-op + } finally { + thread.setContextClassLoader(originalLoader); + ContextAccessController.setReadOnly(listenerName); + } + if (contextInfo == null) { final AppModule appModule = loadApplication(standardContext); appModule.getProperties().put("loader.from", "tomcat"); @@ -1694,14 +1718,6 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare } } - // bind TransactionManager - final TransactionManager transactionManager = SystemInstance.get().getComponent(TransactionManager.class); - safeBind(comp, "TransactionManager", transactionManager); - - // bind TransactionSynchronizationRegistry - final TransactionSynchronizationRegistry synchronizationRegistry = SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class); - safeBind(comp, "TransactionSynchronizationRegistry", synchronizationRegistry); - if (SystemInstance.get().getComponent(ORB.class) != null) { safeBind(comp, "ORB", new SystemComponentReference(ORB.class)); }