It is valid to wire to uninstalled bundles since they still exist and it might even make more sense to do so, since other bundles are obviously still wired to the uninstalled bundle otherwise it wouldn't still exist. Wiring to a different bundle will definitely partition the class space since some bundles will be wired to the uninstalled bundle and newer bundles will be wired to a different provider of the same packages.

If you want to avoid this, you must call PackageAdmin.refreshPackages() (or "refresh" from Gogo) after uninstalling your bundles. That is the only way.

-> richard


On 06/11/2011 12:25 PM, Etienne Vrignaud wrote:
All,

I am using Felix 3.2.2 and I have a use case that ends up with a new
installed bundle wired to an already uninstalled bundle.

My use case is using 3 bundles in addition to all the Felix standards
bundles and other proprietary ones:
. lib1: contain Lib1API and Lib1Impl that implements Lib1API
. lib2: contain Lib2API and Lib2Impl that implements Lib2API (He is
not directly involved in my use case, but perhaps participate to the
issue)
. check: contain CheckImpl that use the Lib1API service and call the
doSomething() method of that service

     _| CheckImpl code snippet:
     _|    ...
     1|    ServiceReference reference =
bundleContext.getServiceReference(Lib1API.class.getName());
     2|    if (reference != null) {
     3|        logger.error("Lib1API_loader=" +
Lib1API.class.getClassLoader() + ", CheckImpl_loader=" +
CheckImpl.class.getClassLoader());
     4|        Object api = bundleContext.getService(reference);
     5|        String result = ((Lib1API)api).doSomething();
     6|        if (result != null) {
     6|            logger.error("doSomething() returned a result");
     7|        }
     8|    }
     _|    ...

My use case is:
     . start my product

     =Step1=
     . install the 3 bundles (lib1, lib2, check)
     . start them
     . create some configuration for them using the ConfigurationAdmin service
          Lib1Impl, Lib2Impl are published as service
          We can see on the log file that:
            - lib1 is bundle 100
            - lib2 is bundle 101
            - check is bundle 102
          my check bundle is able to get the Lib1API service and call
the doSomething() method
     . modify several times the configurations
     . delete the configurations
     . stop and uninstall the 3 bundles

     =Step2=
     . install the same bundles another time (lib1, lib2, check)
     . start them
     . create some configuration for them using the ConfigurationAdmin service
          Lib1Impl, Lib2Impl are published as service
          We can see on the log file that:
            - lib1 is bundle 103
            - lib2 is bundle 104
            - check is bundle 105 and wired to bundle 100
          my check bundle is able to get the Lib1API service, but when
he cast the retrieved service object to the Lib1API interface, a
ClassCastException occurs. On the CheckImpl code snippet it's on line
5.
          The check bundle is wired to bundle 100 that was previously
uninstalled, so on CheckImpl code snippet line 5 when the (Lib1API)
cast occurs there is an Exception, because the retreived service
object is implementing the interface coming from the bundle 103 and
not from bundle 100.
          This line is very strange:
                        2011-06-11 08:46:15,815 - [ProductThread-11] ERROR
(Logger.doLog:133) - WIRE: [105.0] package; (package=com.product.lib1)
->  [100.0], exporter=lib1 [100], state=1

     . stop my product

How is it possible that Felix wire the bundle 105 to the uninstalled bundle 100?
Could it be interesting to add a test in the Felix wiring algorithms
in order to explicitely avoid that?
Why uninstalled bundles are still "existing"/"visible" into the
framework? I did verify that before the class cast exception occurs,
the bundle cache on the disk is correct. No bundle 100 is present.

I have modified the Felix.java class in order to understand a little that issue.
Here is the diff:
4328a4329,4330
                    Bundle bundle = module.getBundle();
                    m_logger.log(Logger.LOG_DEBUG, "Module: " + module + ", bundle=" + 
bundle + ", state=" + bundle.getState());
4337c4339,4340
<                              m_logger.log(Logger.LOG_DEBUG, "WIRE: " + w);
---
                             Bundle exporter = w.getExporter().getBundle();
                             m_logger.log(Logger.LOG_DEBUG, "WIRE: " + w + ", exporter=" 
+ exporter + ", state=" + exporter.getState());
I have attached some extracts of the log that I have (product.log).
In order to get that log I have modified also the Felix framework
Logger class as provided in attachment. It was easier for me to be
sure that I got all the Felix log messages.

At this time, I did write a simple use case in order to reproduce that
issue. I tried to do the same things using only Felix and little stuff
around, but unfortunately I am not able to reproduce the
ClassCastException problem.
I am only able to reproduce that in my product.

I think that you will need more details in order to identify the
causes of that issue.
Could you indicate me what kind of additional traces you would like to have?
Is there somewhere that I can add some log lines to the Felix
framework in order to collect more information?

This issue is very critical for me, because I need to be able to
install some bundles, uninstall them and then finally decide to
reinstall all of them without having to restart our product.
Notice that the same usage in our product was not failing with the
3.0.2 version of the Felix framework. We have that issue since we have
migrated to the 3.2.2 version.

Thanks for your help,
/Etienne



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org

Reply via email to