Revert some refactoring that removed the bundle reference from the listener info
object, since there are some corner cases where the bundle context becomes
invalid and we can no longer reach the bundle. (FELIX-3056)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1152217 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index e0651f5..1e6f6c3 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3091,7 +3091,7 @@
         if (oldFilter != null)
         {
             final Collection removed = Collections.singleton(
-                new ListenerInfo(bundle._getBundleContext(),
+                new ListenerInfo(bundle, bundle._getBundleContext(),
                     ServiceListener.class, l, oldFilter, null, true));
             for (ServiceReference<org.osgi.framework.hooks.service.ListenerHook> sr : listenerHooks)
             {
@@ -3117,7 +3117,7 @@
 
         // Invoke the ListenerHook.added() on all hooks.
         final Collection added = Collections.singleton(
-            new ListenerInfo(bundle.getBundleContext(),
+            new ListenerInfo(bundle, bundle._getBundleContext(),
                 ServiceListener.class, l, newFilter, null, false));
         for (ServiceReference<org.osgi.framework.hooks.service.ListenerHook> sr : listenerHooks)
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index 30cdf80..5dc703c 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -224,7 +224,8 @@
             }
 
             // Add listener.
-            ListenerInfo info = new ListenerInfo(bc, clazz, l, filter, acc, false);
+            ListenerInfo info =
+                new ListenerInfo(bc.getBundle(), bc, clazz, l, filter, acc, false);
             listeners = addListenerInfo(listeners, info);
 
             if (clazz == FrameworkListener.class)
@@ -394,6 +395,7 @@
                         // The spec says to update the filter in this case.
                         Filter oldFilter = info.getParsedFilter();
                         ListenerInfo newInfo = new ListenerInfo(
+                            info.getBundle(),
                             info.getBundleContext(),
                             info.getListenerClass(),
                             info.getListener(),
@@ -746,7 +748,7 @@
             {
                 for (ListenerInfo info : entry.getValue())
                 {
-                    BundleContext bc = info.getBundleContext();
+                    Bundle bundle = info.getBundle();
                     EventListener l = info.getListener();
                     Filter filter = info.getParsedFilter();
                     Object acc = info.getSecurityContext();
@@ -755,16 +757,16 @@
                     {
                         if (type == Request.FRAMEWORK_EVENT)
                         {
-                            invokeFrameworkListenerCallback(bc.getBundle(), l, event);
+                            invokeFrameworkListenerCallback(bundle, l, event);
                         }
                         else if (type == Request.BUNDLE_EVENT)
                         {
-                            invokeBundleListenerCallback(bc.getBundle(), l, event);
+                            invokeBundleListenerCallback(bundle, l, event);
                         }
                         else if (type == Request.SERVICE_EVENT)
                         {
                             invokeServiceListenerCallback(
-                                bc.getBundle(), l, filter, acc, event, oldProps);
+                                bundle, l, filter, acc, event, oldProps);
                         }
                     }
                     catch (Throwable th)
@@ -772,11 +774,11 @@
                         if ((type != Request.FRAMEWORK_EVENT)
                             || (((FrameworkEvent) event).getType() != FrameworkEvent.ERROR))
                         {
-                            dispatcher.m_logger.log(bc.getBundle(),
+                            dispatcher.m_logger.log(bundle,
                                 Logger.LOG_ERROR,
                                 "EventDispatcher: Error during dispatch.", th);
                             dispatcher.fireFrameworkEvent(
-                                new FrameworkEvent(FrameworkEvent.ERROR, bc.getBundle(), th));
+                                new FrameworkEvent(FrameworkEvent.ERROR, bundle, th));
                         }
                     }
                 }
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ListenerInfo.java b/framework/src/main/java/org/apache/felix/framework/util/ListenerInfo.java
index e3a6403..b7ad8ae 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/ListenerInfo.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/ListenerInfo.java
@@ -27,6 +27,7 @@
 
 public class ListenerInfo implements ListenerHook.ListenerInfo
 {
+    private final Bundle m_bundle;
     private final BundleContext m_context;
     private final Class m_listenerClass;
     private final EventListener m_listener;
@@ -35,9 +36,13 @@
     private final boolean m_removed;
 
     public ListenerInfo(
-        BundleContext context, Class listenerClass, EventListener listener,
+        Bundle bundle, BundleContext context, Class listenerClass, EventListener listener,
         Filter filter, Object acc, boolean removed)
     {
+        // Technically, we could get the bundle from the bundle context, but
+        // there are some corner cases where the bundle context might become
+        // invalid and we still need the bundle.
+        m_bundle = bundle;
         m_context = context;
         m_listenerClass = listenerClass;
         m_listener = listener;
@@ -48,6 +53,7 @@
 
     public ListenerInfo(ListenerInfo info, boolean removed)
     {
+        m_bundle = info.m_bundle;
         m_context = info.m_context;
         m_listenerClass = info.m_listenerClass;
         m_listener = info.m_listener;
@@ -56,6 +62,11 @@
         m_removed = removed;
     }
 
+    public Bundle getBundle()
+    {
+        return m_bundle;
+    }
+
     public BundleContext getBundleContext()
     {
         return m_context;
@@ -109,21 +120,22 @@
         }
 
         ListenerInfo other = (ListenerInfo) obj;
-        return (other.m_context == m_context)
+        return (other.m_bundle == m_bundle)
+            && (other.m_context == m_context)
             && (other.m_listenerClass == m_listenerClass)
             && (other.m_listener == m_listener)
             && (m_filter == null ? other.m_filter == null : m_filter.equals(other.m_filter));
     }
 
-
     @Override
     public int hashCode()
     {
         int hash = 7;
-        hash = 71 * hash + (this.m_context != null ? this.m_context.hashCode() : 0);
-        hash = 71 * hash + (this.m_listenerClass != null ? this.m_listenerClass.hashCode() : 0);
-        hash = 71 * hash + (this.m_listener != null ? this.m_listener.hashCode() : 0);
-        hash = 71 * hash + (this.m_filter != null ? this.m_filter.hashCode() : 0);
+        hash = 59 * hash + (this.m_bundle != null ? this.m_bundle.hashCode() : 0);
+        hash = 59 * hash + (this.m_context != null ? this.m_context.hashCode() : 0);
+        hash = 59 * hash + (this.m_listenerClass != null ? this.m_listenerClass.hashCode() : 0);
+        hash = 59 * hash + (this.m_listener != null ? this.m_listener.hashCode() : 0);
+        hash = 59 * hash + (this.m_filter != null ? this.m_filter.hashCode() : 0);
         return hash;
     }
 }
\ No newline at end of file