You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2010/02/18 15:05:31 UTC

svn commit: r911407 - in /incubator/aries/trunk/jpa/jpa-container-context/src: main/java/org/apache/aries/jpa/container/context/ main/java/org/apache/aries/jpa/container/context/transaction/impl/ main/resources/OSGI-INF/blueprint/ test/java/org/apache/...

Author: timothyjward
Date: Thu Feb 18 14:05:31 2010
New Revision: 911407

URL: http://svn.apache.org/viewvc?rev=911407&view=rev
Log:
ARIES-154 : Add warnings and info to logs if no TransactionSynchronizationRegistry service is available

Modified:
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
    incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml
    incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/GlobalPersistenceManager.java Thu Feb 18 14:05:31 2010
@@ -66,6 +66,12 @@
       _logger.debug("Registering bundle {} as a client of persistence unit {} with properties {}.", 
           new Object[] {client.getSymbolicName() + "_" + client.getVersion(), unitName, properties});
     }
+    
+    if(!!!registry.jtaIntegrationAvailable())
+      _logger.warn("No JTA integration is currently available. The managed persistence context {} used by the bundle {} will operate " +
+      		"with no transaction context and be read only until a JTA Transaction Services implementation is available in" +
+      		"the runtime", new Object[] {unitName, client.getSymbolicName() + "_" + client.getVersion()});
+    
     //Find the framework for this bundle (we may be in a composite)
     Bundle frameworkBundle = client.getBundleContext().getBundle(0);
     PersistenceContextManager manager = null;

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManager.java Thu Feb 18 14:05:31 2010
@@ -32,11 +32,16 @@
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.metamodel.Metamodel;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * A <code>PersistenceContextType.TRANSACTION</code> {@link EntityManager} instance
  */
 public class JTAEntityManager implements EntityManager {
-
+  /** Logger */
+  private static final Logger _logger = LoggerFactory.getLogger("org.apache.aries.jpa.container.context");
+  
   /** The {@link EntityManagerFactory} that can create new {@link EntityManager} instances */
   private final EntityManagerFactory emf;
   /** The map of properties to pass when creating EntityManagers */
@@ -70,6 +75,9 @@
       if (reg.isTransactionActive()) {
         return reg.getCurrentPersistenceContext(emf, props);
       } else {
+        if(!!!reg.jtaIntegrationAvailable() && _logger.isDebugEnabled())
+          _logger.debug("No integration with JTA transactions is available. No transaction context is active.");
+        
         if (detachedManager == null) {
           EntityManager temp = emf.createEntityManager(props);
           

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistry.java Thu Feb 18 14:05:31 2010
@@ -20,6 +20,7 @@
 
 import java.util.IdentityHashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
@@ -27,6 +28,7 @@
 import javax.transaction.Synchronization;
 import javax.transaction.TransactionSynchronizationRegistry;
 
+import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,6 +63,12 @@
    * active transaction, and to register for post-commit cleanup. 
    */
   private TransactionSynchronizationRegistry tranRegistry;
+  
+  /** 
+   * A flag to indicate whether the {@link TransactionSynchronizationRegistry} is available. 
+   * The initial value is false, as defined by {@link AtomicBoolean#AtomicBoolean()}.
+   */
+  private final AtomicBoolean registryAvailable = new AtomicBoolean();
 
   /**
    * Get a PersistenceContext for the current transaction. The persistence context will 
@@ -82,7 +90,12 @@
     
     //Throw the error on to the client
     if(!!!isTransactionActive()) {
-      throw new TransactionRequiredException("No transaction currently active");
+      if(jtaIntegrationAvailable())
+        throw new TransactionRequiredException("No transaction currently active");
+      else {
+        throw new TransactionRequiredException("No JTA transaction services implementation is currently available. As a result the" +
+        		" JPA container cannot integrate with JTA transactions.");
+      }
     }
     EntityManager toReturn = null;
     
@@ -130,7 +143,7 @@
    */
   public final boolean isTransactionActive()
   {
-    return tranRegistry.getTransactionKey() != null;
+    return registryAvailable.get() && tranRegistry.getTransactionKey() != null;
   }
   
   /**
@@ -142,6 +155,43 @@
   }
 
   /**
+   * Returns true if we have access to a {@link TransactionSynchronizationRegistry} and
+   * can manage persistence contexts
+   * @return
+   */
+  public final boolean jtaIntegrationAvailable()
+  {
+    return registryAvailable.get();
+  }
+  
+  /**
+   * Called by the blueprint container to indicate that a new {@link TransactionSynchronizationRegistry}
+   * will be used by the runtime
+   * @param ref
+   */
+  public final void addRegistry(ServiceReference ref) {
+    boolean oldValue = registryAvailable.getAndSet(true);
+    if(oldValue) {
+      _logger.warn("The TransactionSynchronizationRegistry used to manage persistence contexts has been replaced." +
+      		" The new TransactionSynchronizationRegistry, {}, will now be used to manage persistence contexts." +
+      		" Managed persistence contexts may not work correctly unless the runtime uses the new JTA Transaction services implementation" +
+      		" to manage transactions.", new Object[] {ref});
+    } else {
+        _logger.info("A TransactionSynchronizationRegistry service is now available in the runtime. Managed persistence contexts will now" +
+        		"integrate with JTA transactions using {}.", new Object[] {ref});
+    }
+  }
+  
+  public final void removeRegistry(ServiceReference ref) {
+    registryAvailable.set(false);
+    _logger.warn("The TransactionSynchronizationRegistry used to manage persistence contexts is no longer available." +
+        " Managed persistence contexts will no longer be able to integrate with JTA transactions, and will behave as if" +
+        " no there is no transaction context at all times until a new TransactionSynchronizationRegistry is available." +
+        " Applications using managed persistence contexts may not work correctly until a new JTA Transaction services" +
+        " implementation is available.");
+  }
+  
+  /**
    * This class is used to close EntityManager instances once the transaction has committed,
    * and clear the persistenceContextRegistry of old persistence contexts.
    */

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/main/resources/OSGI-INF/blueprint/jpa.xml Thu Feb 18 14:05:31 2010
@@ -37,7 +37,9 @@
   <bean id="JtaPersistenceContextRegistry" 
     class="org.apache.aries.jpa.container.context.transaction.impl.JTAPersistenceContextRegistry">
     <property name="tranRegistry">
-      <reference interface="javax.transaction.TransactionSynchronizationRegistry"  availability="optional" />
+      <reference interface="javax.transaction.TransactionSynchronizationRegistry"  availability="optional">
+        <reference-listener ref="JtaPersistenceContextRegistry" bind-method="addRegistry" unbind-method="removeRegistry"/>
+      </reference>
     </property>
   </bean>
   

Modified: incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java?rev=911407&r1=911406&r2=911407&view=diff
==============================================================================
--- incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java (original)
+++ incubator/aries/trunk/jpa/jpa-container-context/src/test/java/org/apache/aries/jpa/container/context/transaction/impl/JTAPersistenceContextRegistryTest.java Thu Feb 18 14:05:31 2010
@@ -20,6 +20,8 @@
 
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -28,6 +30,7 @@
 
 import javax.persistence.EntityManager;
 import javax.persistence.EntityManagerFactory;
+import javax.persistence.TransactionRequiredException;
 import javax.transaction.Status;
 import javax.transaction.Synchronization;
 import javax.transaction.TransactionSynchronizationRegistry;
@@ -129,6 +132,19 @@
     
     contexts = new JTAPersistenceContextRegistry();
     contexts.setTranRegistry(Skeleton.newMock(reg, TransactionSynchronizationRegistry.class));
+    contexts.addRegistry(null);
+  }
+  
+  @Test
+  public void testIsTranActive()
+  {
+    reg.setTransactionKey(null);
+    
+    assertFalse(contexts.isTransactionActive());
+    
+    reg.setTransactionKey("");
+    
+    assertTrue(contexts.isTransactionActive());
   }
   
   @Test
@@ -202,7 +218,41 @@
     Skeleton.getSkeleton(em1b).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
     Skeleton.getSkeleton(em2a).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
     Skeleton.getSkeleton(em2b).assertCalledExactNumberOfTimes(new MethodCall(EntityManager.class, "close"), 1);
+  }
+  
+  @Test
+  public void testNoTranSyncRegistry() {
+    JTAPersistenceContextRegistry registry = new JTAPersistenceContextRegistry();
+    //blueprint will still call our setter
+    TransactionSynchronizationRegistry tranSyncReg = Skeleton.newMock(reg, TransactionSynchronizationRegistry.class);
+    registry.setTranRegistry(tranSyncReg);
     
+    reg.setTransactionKey(null);
+    
+    assertFalse(registry.jtaIntegrationAvailable());
+    assertFalse(registry.isTransactionActive());
+    
+    Skeleton.getSkeleton(tranSyncReg).assertSkeletonNotCalled();
+    
+    reg.setTransactionKey("");
+    
+    assertFalse(registry.jtaIntegrationAvailable());
+    assertFalse(registry.isTransactionActive());
+    
+    Skeleton.getSkeleton(tranSyncReg).assertSkeletonNotCalled();
+  }
+  
+  @Test(expected=TransactionRequiredException.class)
+  public void testGetNoTran() {
+    reg.setTransactionKey(null);
+    contexts.getCurrentPersistenceContext(emf1, props1);
+  }
+  
+  @Test(expected=TransactionRequiredException.class)
+  public void testGetNoTranSyncRegistry() {
+    reg.setTransactionKey("");
+    contexts.removeRegistry(null);
+    contexts.getCurrentPersistenceContext(emf1, props1);
   }
   
 }