TAP5-2588: JPA patches provided by Dmitris Zenios
authorThiago H. de Paula Figueiredo <thiago@arsmachina.com.br>
Wed, 5 Dec 2018 23:47:17 +0000 (21:47 -0200)
committerThiago H. de Paula Figueiredo <thiago@arsmachina.com.br>
Wed, 5 Dec 2018 23:47:17 +0000 (21:47 -0200)
15 files changed:
tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/AnnotationAccessImpl.java
tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/AspectDecoratorImpl.java
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/CommitAfterWorker.java
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/EntityTransactionManagerImpl.java
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java [new file with mode: 0644]
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java [new file with mode: 0644]
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaInternalUtils.java
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImpl.java
tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/PersistenceContextSpecificEntityTransactionManager.java
tapestry-jpa/src/main/java/org/apache/tapestry5/jpa/modules/JpaModule.java
tapestry-jpa/src/test/conf/testng.xml
tapestry-jpa/src/test/java/org/apache/tapestry5/internal/jpa/JpaTransactionAdvisorImplTest.java
tapestry-jpa/src/test/java/org/example/app5/services/AppModule.java
tapestry-runner/build.gradle
tapestry-runner/src/main/java/org/apache/tapestry5/test/TomcatRunner.java

index b088cb9..f8c6155 100644 (file)
 
 package org.apache.tapestry5.ioc.internal;
 
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Flow;
+import org.apache.tapestry5.func.Mapper;
 import org.apache.tapestry5.ioc.AnnotationAccess;
 import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.internal.services.AnnotationProviderChain;
 import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 
+import java.lang.reflect.Method;
+
 /**
- * Standard AnnotationAccess for a specific type.
+ * Standard AnnotationAccess for an array of classes
  * 
  * @since 5.3
  */
 public class AnnotationAccessImpl implements AnnotationAccess
 {
-    private final Class type;
+    private final Class[] classes;
 
-    public AnnotationAccessImpl(Class type)
+    public AnnotationAccessImpl(Class ...types)
     {
-        this.type = type;
+        this.classes = types;
     }
 
     @Override
     public AnnotationProvider getClassAnnotationProvider()
     {
-        return InternalUtils.toAnnotationProvider(type);
+        return AnnotationProviderChain.create(F.flow(classes).removeNulls().map(InternalUtils.CLASS_TO_AP_MAPPER).toList());
     }
 
     @Override
-    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes)
-    {
-        return InternalUtils.toAnnotationProvider(InternalUtils.findMethod(type, methodName, parameterTypes));
+    public AnnotationProvider getMethodAnnotationProvider(String methodName, Class... parameterTypes) {
+        Flow<Class> searchClasses = F.flow(classes).removeNulls();
+        return AnnotationProviderChain.create(searchClasses.map(new Mapper<Class, Method>() {
+            @Override
+            public Method map(Class element) {
+                return InternalUtils.findMethod(element, methodName, parameterTypes);
+            }
+        }).map(InternalUtils.METHOD_TO_AP_MAPPER).toList());
     }
 
 }
index 18aa888..f37770e 100644 (file)
@@ -39,7 +39,7 @@ public class AspectDecoratorImpl implements AspectDecorator
     @Override
     public <T> AspectInterceptorBuilder<T> createBuilder(Class<T> serviceInterface, final T delegate, String description)
     {
-        return createBuilder(serviceInterface, delegate, new AnnotationAccessImpl(delegate.getClass()), description);
+        return createBuilder(serviceInterface, delegate, new AnnotationAccessImpl(delegate.getClass(),serviceInterface), description);
     }
 
     @Override
index 30046e8..7c1d63c 100644 (file)
 
 package org.apache.tapestry5.internal.jpa;
 
-import java.util.HashMap;
-import java.util.Map;
 
-import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 
-import org.apache.tapestry5.jpa.EntityManagerManager;
-import org.apache.tapestry5.jpa.EntityTransactionManager;
 import org.apache.tapestry5.jpa.annotations.CommitAfter;
 import org.apache.tapestry5.model.MutableComponentModel;
-import org.apache.tapestry5.plastic.MethodAdvice;
 import org.apache.tapestry5.plastic.PlasticClass;
 import org.apache.tapestry5.plastic.PlasticMethod;
 import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
@@ -32,27 +26,22 @@ import org.apache.tapestry5.services.transform.TransformationSupport;
 
 public class CommitAfterWorker implements ComponentClassTransformWorker2
 {
-    private final Map<String, MethodAdvice> methodAdvices;
+    private final JpaAdvisorProvider jpaAdvisorProvider;
 
-    public CommitAfterWorker(EntityManagerManager manager,
-            EntityTransactionManager transactionManager)
+    public CommitAfterWorker(JpaAdvisorProvider jpaAdvisorProvider)
     {
-        methodAdvices = new HashMap<>(manager.getEntityManagers().size());
-        for (Map.Entry<String, EntityManager> entry : manager.getEntityManagers().entrySet())
-            methodAdvices.put(entry.getKey(),
-                    new CommitAfterMethodAdvice(transactionManager, entry.getKey()));
-        methodAdvices.put(null, new CommitAfterMethodAdvice(transactionManager, null));
+        this.jpaAdvisorProvider = jpaAdvisorProvider;
     }
 
     @Override
     public void transform(PlasticClass plasticClass, TransformationSupport support,
-            MutableComponentModel model)
+                          MutableComponentModel model)
     {
         for (final PlasticMethod method : plasticClass.getMethodsWithAnnotation(CommitAfter.class))
         {
             PersistenceContext annotation = method.getAnnotation(PersistenceContext.class);
 
-            method.addAdvice(methodAdvices.get(annotation == null ? null : annotation.unitName()));
+            method.addAdvice(jpaAdvisorProvider.getAdvice(annotation));
         }
     }
 }
index c0c639d..28500c4 100644 (file)
@@ -16,8 +16,6 @@ package org.apache.tapestry5.internal.jpa;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.persistence.EntityManager;
-
 import org.apache.tapestry5.ioc.Invokable;
 import org.apache.tapestry5.ioc.ScopeConstants;
 import org.apache.tapestry5.ioc.annotations.Scope;
@@ -38,28 +36,8 @@ public class EntityTransactionManagerImpl implements EntityTransactionManager
     {
         this.logger = logger;
         this.entityManagerManager = entityManagerManager;
-        transactionManagerMap = new HashMap<>(entityManagerManager.getEntityManagers().size());
-    }
-
-    private EntityManager getEntityManager(String unitName)
-    {
-        // EntityManager em = JpaInternalUtils.getEntityManager(entityManagerManager, unitName);
-        // FIXME we should simply incorporate the logic in JpaInternalUtils.getEntityManager to
-        // EntityManagerManager.getEntityManager(unitName)
-        if (unitName != null)
-            return entityManagerManager.getEntityManager(unitName);
-        else
-        {
-            Map<String, EntityManager> entityManagers = entityManagerManager.getEntityManagers();
-            if (entityManagers.size() == 1)
-                return entityManagers.values().iterator().next();
-            else
-                throw new RuntimeException(
-                        "Unable to locate a single EntityManager. "
-                                + "You must provide the persistence unit name as defined in the persistence.xml using the @PersistenceContext annotation.");
-        }
+        this.transactionManagerMap = new HashMap<>(entityManagerManager.getEntityManagers().size());
     }
-
     /*
      * (non-Javadoc)
      * @see net.satago.tapestry5.jpa.EntityTransactionManager#runInTransaction(java.lang.String,
@@ -91,7 +69,7 @@ public class EntityTransactionManagerImpl implements EntityTransactionManager
         if (!transactionManagerMap.containsKey(unitName))
         {
             PersistenceContextSpecificEntityTransactionManager transactionManager = new PersistenceContextSpecificEntityTransactionManager(
-                    logger, getEntityManager(unitName));
+                    logger, JpaInternalUtils.getEntityManager(entityManagerManager,unitName));
             transactionManagerMap.put(unitName, transactionManager);
             return transactionManager;
         }
diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProvider.java
new file mode 100644 (file)
index 0000000..108d55f
--- /dev/null
@@ -0,0 +1,9 @@
+package org.apache.tapestry5.internal.jpa;
+
+import org.apache.tapestry5.plastic.MethodAdvice;
+
+import javax.persistence.PersistenceContext;
+
+public interface JpaAdvisorProvider {
+    MethodAdvice getAdvice(PersistenceContext context);
+}
diff --git a/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java b/tapestry-jpa/src/main/java/org/apache/tapestry5/internal/jpa/JpaAdvisorProviderImpl.java
new file mode 100644 (file)
index 0000000..51b50b4
--- /dev/null
@@ -0,0 +1,20 @@
+package org.apache.tapestry5.internal.jpa;
+
+import org.apache.tapestry5.jpa.EntityTransactionManager;
+import org.apache.tapestry5.plastic.MethodAdvice;
+
+import javax.persistence.PersistenceContext;
+
+public class JpaAdvisorProviderImpl implements JpaAdvisorProvider {
+    private final MethodAdvice shared;
+    private final EntityTransactionManager transactionManager;
+
+    public JpaAdvisorProviderImpl(EntityTransactionManager transactionManager) {
+        this.shared = new CommitAfterMethodAdvice(transactionManager, null);
+        this.transactionManager = transactionManager;
+    }
+    @Override
+    public MethodAdvice getAdvice(PersistenceContext context) {
+        return context == null ? shared : new CommitAfterMethodAdvice(transactionManager,context.unitName());
+    }
+}
index d612e74..aff8e21 100644 (file)
@@ -78,10 +78,15 @@ public class JpaInternalUtils
     }
 
     public static EntityManager getEntityManager(EntityManagerManager entityManagerManager,
-                                                 PersistenceContext annotation)
-    {
+                                                 PersistenceContext annotation) {
         String unitName = annotation == null ? null : annotation.unitName();
+        return getEntityManager(entityManagerManager, unitName);
+    }
+
 
+    public static EntityManager getEntityManager(EntityManagerManager entityManagerManager,
+                                                 String unitName)
+    {
         if (InternalUtils.isNonBlank(unitName))
             return entityManagerManager.getEntityManager(unitName);
 
index 1803722..7d7437c 100644 (file)
 package org.apache.tapestry5.internal.jpa;
 
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
 
-import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
 
 import org.apache.tapestry5.ioc.MethodAdviceReceiver;
-import org.apache.tapestry5.jpa.EntityManagerManager;
-import org.apache.tapestry5.jpa.EntityTransactionManager;
+
 import org.apache.tapestry5.jpa.JpaTransactionAdvisor;
 import org.apache.tapestry5.jpa.annotations.CommitAfter;
-import org.apache.tapestry5.plastic.MethodAdvice;
 
 public class JpaTransactionAdvisorImpl implements JpaTransactionAdvisor
 {
-    private final Map<String, MethodAdvice> methodAdvices;
+    private final JpaAdvisorProvider jpaAdvisorProvider;
 
-    public JpaTransactionAdvisorImpl(EntityManagerManager manager,
-            EntityTransactionManager transactionManager)
+    public JpaTransactionAdvisorImpl(JpaAdvisorProvider jpaAdvisorProvider)
     {
-        methodAdvices = new HashMap<>(manager.getEntityManagers().size());
-        for (Map.Entry<String, EntityManager> entry : manager.getEntityManagers().entrySet())
-            methodAdvices.put(entry.getKey(),
-                    new CommitAfterMethodAdvice(transactionManager, entry.getKey()));
-        methodAdvices.put(null, new CommitAfterMethodAdvice(transactionManager, null));
+        this.jpaAdvisorProvider = jpaAdvisorProvider;
     }
 
     @Override
@@ -49,11 +39,8 @@ public class JpaTransactionAdvisorImpl implements JpaTransactionAdvisor
         {
             if (m.getAnnotation(CommitAfter.class) != null)
             {
-                PersistenceContext annotation = receiver.getMethodAnnotation(m,
-                        PersistenceContext.class);
-
-                receiver.adviseMethod(m,
-                        methodAdvices.get(annotation == null ? null : annotation.unitName()));
+                PersistenceContext annotation = receiver.getMethodAnnotation(m, PersistenceContext.class);
+                receiver.adviseMethod(m, jpaAdvisorProvider.getAdvice(annotation));
             }
         }
     }
index ed53f2b..43405f2 100644 (file)
@@ -67,6 +67,7 @@ public class PersistenceContextSpecificEntityTransactionManager
 
     public <T> T invokeInTransaction(Invokable<T> invokable)
     {
+        final EntityTransaction transaction = getTransaction();
         if (transactionBeingCommitted)
         {
             // happens for example if you try to run a transaction in @PostCommit hook. We can only
@@ -79,7 +80,7 @@ public class PersistenceContextSpecificEntityTransactionManager
             }
             else
             {
-                rollbackTransaction(getTransaction());
+                rollbackTransaction(transaction);
                 throw new RuntimeException(
                         "Current transaction is already being committed. Transactions started @PostCommit are not allowed to return a value");
             }
@@ -95,7 +96,6 @@ public class PersistenceContextSpecificEntityTransactionManager
             }
         }
 
-        final EntityTransaction transaction = getTransaction();
         try
         {
             T result = invokable.invoke();
@@ -104,15 +104,11 @@ public class PersistenceContextSpecificEntityTransactionManager
             {
                 // Success or checked exception:
 
-                if (transaction.isActive())
+                boolean isActive = transaction.isActive();
+                if (isActive)
                 {
                     invokeBeforeCommit(transaction);
-                }
-
-                // FIXME check if we are still on top
-
-                if (transaction.isActive())
-                {
+                    // FIXME check if we are still on top
                     transactionBeingCommitted = true;
                     transaction.commit();
                     transactionBeingCommitted = false;
index 723b38a..f78b71c 100644 (file)
@@ -23,17 +23,7 @@ import javax.persistence.spi.PersistenceUnitInfo;
 
 import org.apache.tapestry5.ValueEncoder;
 import org.apache.tapestry5.internal.InternalConstants;
-import org.apache.tapestry5.internal.jpa.CommitAfterWorker;
-import org.apache.tapestry5.internal.jpa.EntityApplicationStatePersistenceStrategy;
-import org.apache.tapestry5.internal.jpa.EntityManagerManagerImpl;
-import org.apache.tapestry5.internal.jpa.EntityManagerObjectProvider;
-import org.apache.tapestry5.internal.jpa.EntityManagerSourceImpl;
-import org.apache.tapestry5.internal.jpa.EntityPersistentFieldStrategy;
-import org.apache.tapestry5.internal.jpa.EntityTransactionManagerImpl;
-import org.apache.tapestry5.internal.jpa.JpaTransactionAdvisorImpl;
-import org.apache.tapestry5.internal.jpa.JpaValueEncoder;
-import org.apache.tapestry5.internal.jpa.PackageNamePersistenceUnitConfigurer;
-import org.apache.tapestry5.internal.jpa.PersistenceContextWorker;
+import org.apache.tapestry5.internal.jpa.*;
 import org.apache.tapestry5.internal.services.PersistentFieldManager;
 import org.apache.tapestry5.ioc.Configuration;
 import org.apache.tapestry5.ioc.LoggerSource;
@@ -84,6 +74,7 @@ public class JpaModule
         binder.bind(PersistenceUnitConfigurer.class, PackageNamePersistenceUnitConfigurer.class).withSimpleId();
         binder.bind(EntityManagerSource.class, EntityManagerSourceImpl.class);
         binder.bind(EntityTransactionManager.class, EntityTransactionManagerImpl.class);
+        binder.bind(JpaAdvisorProvider.class,JpaAdvisorProviderImpl.class);
 
     }
 
index 025f946..9267615 100644 (file)
@@ -8,47 +8,49 @@
        the specific language governing permissions and limitations under the License. -->
 
 <suite name="Tapestry JPA" parallel="false" thread-count="10"
-       annotations="1.5" verbose="2">
-<!--   <test name="Tapestry JPA Integration Tests" enabled="true"> -->
-<!--           <parameter name="tapestry.web-app-folder" value="src/test/app1" /> -->
-<!--           <packages> -->
-<!--                   <package name="org.apache.tapestry5.jpa.integration.app1" /> -->
-<!--           </packages> -->
-<!--   </test> -->
-
-<!--   <test name="Single Persistence Unit Integration Tests" enabled="true"> -->
-<!--           <parameter name="tapestry.web-app-folder" value="src/test/app2" /> -->
-<!--           <packages> -->
-<!--                   <package name="org.apache.tapestry5.jpa.integration.app2" /> -->
-<!--           </packages> -->
-<!--   </test> -->
+          annotations="1.5" verbose="2">
+       <test name="Tapestry JPA Integration Tests" enabled="true">
+               <parameter name="tapestry.web-app-folder" value="src/test/app1" />
+               <packages>
+                       <package name="org.apache.tapestry5.jpa.integration.app1" />
+               </packages>
+       </test>
 
-<!--   <test name="JNDI DataSource Integration Tests" enabled="true"> -->
-<!--           <parameter name="tapestry.web-app-folder" value="src/test/app3" /> -->
-<!--           <parameter name="tapestry.servlet-container" value="tomcat6" /> -->
-<!--           <packages> -->
-<!--                   <package name="org.apache.tapestry5.jpa.integration.app3" /> -->
-<!--           </packages> -->
-<!--   </test> -->
+       <test name="Single Persistence Unit Integration Tests" enabled="true">
+               <parameter name="tapestry.web-app-folder" value="src/test/app2" />
+               <packages>
+                       <package name="org.apache.tapestry5.jpa.integration.app2" />
+               </packages>
+       </test>
 
-<!--   <test name="Explicit Provider Class Name In Persistence Unit Integration Tests" enabled="true"> -->
-<!--           <parameter name="tapestry.web-app-folder" value="src/test/app5" /> -->
-<!--           <packages> -->
-<!--                   <package name="org.apache.tapestry5.jpa.integration.app5" /> -->
-<!--           </packages> -->
-<!--   </test> -->
+       <test name="JNDI DataSource Integration Tests" enabled="true">
+               <parameter name="tapestry.web-app-folder" value="src/test/app3" />
+               <parameter name="tapestry.servlet-container" value="tomcat6" />
+               <packages>
+                       <package name="org.apache.tapestry5.jpa.integration.app3" />
+               </packages>
+       </test>
 
-<!--   <test name="Tapestry JPA Unit Tests" enabled="false"> -->
-<!--           <packages> -->
-<!--                   <package name="org.apache.tapestry5.internal.jpa" /> -->
-<!--           </packages> -->
-<!--   </test> -->
-       
        <test name="Tapestry JPA Integration Tests with Annotations in Service Implementation" enabled="true">
                <parameter name="tapestry.web-app-folder" value="src/test/app6" />
                <packages>
                        <package name="org.apache.tapestry5.jpa.integration.app6" />
                </packages>
        </test>
-       
+
+       <test name="Tapestry JPA Unit Tests" enabled="true">
+               <packages>
+                       <package name="org.apache.tapestry5.internal.jpa" />
+               </packages>
+       </test>
+
+       <!-- Put this last since it modifies
+    PersistenceProviderResolverHolder.setPersistenceProviderResolver
+    which affects other test suites -->
+       <test name="Explicit Provider Class Name In Persistence Unit Integration Tests" enabled="true">
+               <parameter name="tapestry.web-app-folder" value="src/test/app5" />
+               <packages>
+                       <package name="org.apache.tapestry5.jpa.integration.app5" />
+               </packages>
+       </test>
 </suite>
index 6d3eb40..92ffd33 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.tapestry5.jpa.EntityManagerManager;
 import org.apache.tapestry5.jpa.EntityTransactionManager;
 import org.apache.tapestry5.jpa.JpaTransactionAdvisor;
 import org.apache.tapestry5.jpa.annotations.CommitAfter;
+import org.slf4j.LoggerFactory;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -66,10 +67,9 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     public void undecorated()
     {
         final VoidService delegate = newMock(VoidService.class);
-        final EntityManagerManager manager = newMock(EntityManagerManager.class);
         final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
-
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder(
                 VoidService.class, delegate, "foo.Bar");
 
@@ -87,14 +87,20 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     @Test
     public void persistence_unit_name_missing()
     {
-        final VoidService delegate = newMock(VoidService.class);
-        final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
         Map<String, EntityManager> managers = CollectionFactory.newMap();
         managers.put("A", newMock(EntityManager.class));
         managers.put("B", newMock(EntityManager.class));
 
+        final VoidService delegate = newMock(VoidService.class);
+        final EntityManagerManager manager = newMock(EntityManagerManager.class);
+        expect(manager.getEntityManagers()).andReturn(managers);
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder(
                 VoidService.class, delegate, "foo.Bar");
 
@@ -121,15 +127,24 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     @Test
     public void persistence_unit_name_missing_single_unit_configured()
     {
-        final VoidService delegate = newMock(VoidService.class);
-        final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
-        final EntityTransaction transaction = newMock(EntityTransaction.class);
         EntityManager em = newMock(EntityManager.class);
         Map<String, EntityManager> managers = CollectionFactory.newMap();
         managers.put("A", em);
 
+        final VoidService delegate = newMock(VoidService.class);
+        final EntityManagerManager manager = newMock(EntityManagerManager.class);
+        expect(manager.getEntityManagers()).andReturn(managers);
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
+
+        final EntityTransaction transaction = newMock(EntityTransaction.class);
+
+
         final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder(
                 VoidService.class, delegate, "foo.Bar");
 
@@ -150,14 +165,23 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     @Test
     public void persistence_unit_missing()
     {
-        final VoidService delegate = newMock(VoidService.class);
-        final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
         Map<String, EntityManager> managers = CollectionFactory.newMap();
         managers.put("A", newMock(EntityManager.class));
         managers.put("B", newMock(EntityManager.class));
 
+        final VoidService delegate = newMock(VoidService.class);
+        final EntityManagerManager manager = newMock(EntityManagerManager.class);
+        expect(manager.getEntityManagers()).andReturn(managers);
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
+
+
         final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder(
                 VoidService.class, delegate, "foo.Bar");
 
@@ -184,14 +208,20 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     @Test
     public void persistence_unit_missing_single_unit_configured()
     {
-        final VoidService delegate = newMock(VoidService.class);
-        final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
-        final EntityTransaction transaction = newMock(EntityTransaction.class);
         EntityManager em = newMock(EntityManager.class);
         Map<String, EntityManager> managers = CollectionFactory.newMap();
         managers.put("A", em);
+        final VoidService delegate = newMock(VoidService.class);
+        final EntityManagerManager manager = newMock(EntityManagerManager.class);
+        expect(manager.getEntityManagers()).andReturn(managers);
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
+        final EntityTransaction transaction = newMock(EntityTransaction.class);
 
         final AspectInterceptorBuilder<VoidService> builder = aspectDecorator.createBuilder(
                 VoidService.class, delegate, "foo.Bar");
@@ -215,8 +245,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final VoidService delegate = newMock(VoidService.class);
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
 
@@ -243,8 +279,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final VoidService delegate = newMock(VoidService.class);
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
 
@@ -271,8 +313,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final VoidService delegate = newMock(VoidService.class);
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
 
@@ -297,8 +345,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final Performer delegate = newMock(Performer.class);
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
         final RuntimeException re = new RuntimeException("Unexpected.");
@@ -333,8 +387,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final Performer delegate = newMock(Performer.class);
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
         final SQLException se = new SQLException("Checked.");
@@ -374,8 +434,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final ReturnTypeService delegate = newTestService();
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
 
@@ -400,8 +466,14 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
     {
         final ReturnTypeService delegate = newTestService();
         final EntityManagerManager manager = newMock(EntityManagerManager.class);
-        final EntityTransactionManager transactionManager = newMock(EntityTransactionManager.class);
-        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(manager, transactionManager);
+        expect(manager.getEntityManagers()).andReturn(CollectionFactory.newMap());
+
+        replay();
+        final EntityTransactionManager transactionManager = new EntityTransactionManagerImpl(
+                LoggerFactory.getLogger(EntityTransactionManagerImpl.class),manager);
+        verify();
+        final JpaAdvisorProvider provider = new JpaAdvisorProviderImpl(transactionManager);
+        final JpaTransactionAdvisor advisor = newJpaTransactionAdvisor(provider);
         final EntityManager entityManager = newMock(EntityManager.class);
         final EntityTransaction transaction = newMock(EntityTransaction.class);
 
@@ -462,10 +534,9 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
         transaction.rollback();
     }
 
-    private JpaTransactionAdvisor newJpaTransactionAdvisor(final EntityManagerManager manager,
-            EntityTransactionManager transactionManager)
+    private JpaTransactionAdvisor newJpaTransactionAdvisor(final JpaAdvisorProvider provider)
     {
-        return new JpaTransactionAdvisorImpl(manager, transactionManager);
+        return new JpaTransactionAdvisorImpl(provider);
     }
 
     private ReturnTypeService newTestService()
@@ -533,20 +604,4 @@ public class JpaTransactionAdvisorImplTest extends IOCTestCase
         @PersistenceContext(unitName = UNIT_NAME)
         void perform() throws SQLException;
     }
-
-    public interface Service
-    {
-       void perform();
-    }
-
-    public class ServiceImpl implements Service {
-       @Override
-       @CommitAfter
-       @PersistenceContext(unitName = UNIT_NAME)
-        public void perform()
-       {
-
-       }
-    }
-
 }
index 05d2488..e3f380a 100644 (file)
@@ -34,6 +34,7 @@ public class AppModule
     static
     {
 
+        //This will also affect test suites run after this one.Its better to run this suite last
         PersistenceProviderResolverHolder.setPersistenceProviderResolver(
                 new PersistenceProviderResolver()
                 {
index f905c70..3f7a6ff 100644 (file)
@@ -10,6 +10,7 @@ dependencies {
 
     compile "org.apache.tomcat:tomcat-catalina:${versions.tomcat}"
     compile "org.apache.tomcat:tomcat-coyote:${versions.tomcat}"
+    compile "org.apache.tomcat:tomcat-jasper:${versions.tomcat}"
 
     compile "org.apache.tomcat:tomcat-dbcp:${versions.tomcat}"
     compile "commons-cli:commons-cli:1.2"
index f382330..a37b580 100644 (file)
@@ -15,7 +15,6 @@
 package org.apache.tapestry5.test;
 
 import org.apache.catalina.connector.Connector;
-import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.startup.Tomcat;
 
 import java.io.File;
@@ -50,9 +49,12 @@ public class TomcatRunner implements ServletContainerRunner
         if (!tmpDir.endsWith(fileSeparator))
             tmpDir = tmpDir + fileSeparator;
         tomcatServer.setBaseDir(tmpDir + "tomcat");
-
+        tomcatServer.setPort(port);
         tomcatServer.addWebapp("/", expandedPath);
 
+        //Enable jndi lookups
+        tomcatServer.enableNaming();
+
         tomcatServer.getConnector().setAllowTrace(true);
 
         // SSL support
@@ -68,6 +70,7 @@ public class TomcatRunner implements ServletContainerRunner
         }
 
         tomcatServer.start();
+        startDaemonAwaitThread();
     }
 
     /**
@@ -82,6 +85,7 @@ public class TomcatRunner implements ServletContainerRunner
         {
             // Stop immediately and not gracefully.
             tomcatServer.stop();
+            tomcatServer.destroy();
         }
         catch (Exception ex)
         {
@@ -117,4 +121,19 @@ public class TomcatRunner implements ServletContainerRunner
         return new File(TapestryRunnerConstants.MODULE_BASE_DIR, moduleLocalPath).getPath();
     }
 
+    // Unlike Jetty, all Tomcat threads are daemon threads. We create a
+    // blocking non-daemon to stop immediate shutdown
+    private void startDaemonAwaitThread() {
+        Thread awaitThread = new Thread() {
+
+            @Override
+            public void run() {
+                TomcatRunner.this.tomcatServer.getServer().await();
+            }
+
+        };
+        awaitThread.setContextClassLoader(getClass().getClassLoader());
+        awaitThread.setDaemon(false);
+        awaitThread.start();
+    }
 }