ARIES-1783 Fix memory leak in EMSupplerImpl
diff --git a/jpa-support/src/main/java/org/apache/aries/jpa/support/impl/EMSupplierImpl.java b/jpa-support/src/main/java/org/apache/aries/jpa/support/impl/EMSupplierImpl.java
index 1956f01..36942ad 100644
--- a/jpa-support/src/main/java/org/apache/aries/jpa/support/impl/EMSupplierImpl.java
+++ b/jpa-support/src/main/java/org/apache/aries/jpa/support/impl/EMSupplierImpl.java
@@ -38,10 +38,10 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.coordinator.Coordination;
 import org.osgi.service.coordinator.Coordinator;
 import org.osgi.service.coordinator.Participant;
+import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,6 +63,7 @@
     private CountDownLatch emsToShutDown;
     private Coordinator coordinator;
     private String unitName;
+    private ServiceTracker<TransactionManager, TransactionManager> tmTracker;
 
     public EMSupplierImpl(String unitName, final EntityManagerFactory emf, Coordinator coordinator) {
         this.unitName = unitName;
@@ -70,6 +71,17 @@
         this.coordinator = coordinator;
         this.shutdown = new AtomicBoolean(false);
         this.emSet = Collections.newSetFromMap(new ConcurrentHashMap<EntityManager, Boolean>());
+
+        final Bundle bundle = FrameworkUtil.getBundle(this.getClass());
+        if (bundle != null) {
+            final BundleContext bundleContext = bundle.getBundleContext();
+            this.tmTracker = new ServiceTracker<TransactionManager, TransactionManager>(bundleContext,
+                    TransactionManager.class, null);
+            tmTracker.open();
+        }
+        else {
+            LOG.warn("Transaction manager will be not available.");
+        }
     }
 
     private EntityManager createEm(EntityManagerFactory emf) {
@@ -97,20 +109,22 @@
             coordination.addParticipant(new EmShutDownParticipant());
         }
         else {
-            final Bundle bundle = FrameworkUtil.getBundle(this.getClass());
-            if (bundle != null) {
-                final BundleContext bundleContext = bundle.getBundleContext();
-                ServiceReference<TransactionManager> tmRef = bundleContext.getServiceReference(TransactionManager.class);
-                TransactionManager tm = bundleContext.getService(tmRef);
-                try {
-                    final Transaction transaction = tm.getTransaction();
-                    if (transaction != null && transaction.getStatus() == Status.STATUS_ACTIVE) {
-                        em.joinTransaction();
-                    }
+            if (tmTracker == null) {
+                return em;
+            }
+            TransactionManager tm = tmTracker.getService();
+            if (tm == null) {
+                LOG.warn("Transaction manager is not available.");
+                return em;
+            }
+            try {
+                final Transaction transaction = tm.getTransaction();
+                if (transaction != null && transaction.getStatus() == Status.STATUS_ACTIVE) {
+                    em.joinTransaction();
                 }
-                catch( SystemException se ) {
-                    throw new IllegalStateException("Unable to check transaction status and join the transaction", se);
-                }
+            }
+            catch( SystemException se ) {
+                throw new IllegalStateException("Unable to check transaction status and join the transaction", se);
             }
         }
         return em;
@@ -179,6 +193,9 @@
      * @return true if clean close, false if timeout occured
      */
     public boolean close() {
+        if (tmTracker != null) {
+            tmTracker.close();
+        }
         synchronized (this) {
             shutdown.set(true);
             emsToShutDown = new CountDownLatch(emSet.size());