Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
Ok, thanks for the feedback. /pierre Richard S. Hall wrote: Yes, that does make sense. You are correct that the listeners are snapshot'ed, so in this case you are more likely to see your own event. However, there is no guarantee that someone else didn't sneak in and make a request to PackageAdmin before you could do it. :-( But, assuming you know what is going on, I think this approach should be reasonably safe. - richard On 4/10/09 1:57 PM, Pierre De Rop wrote: I'm sorry, in the previous sample code, I forgot to remove the fwk listener after the refresh, so here is the good fix: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); FrameworkListener listener = new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }; _bctx.addFrameworkListener(listener); _pkgAdmin.refresh(null); // asynchronous latch.await(); _bctx.removeFrameworkListener(listener); for (Bundle b : bundles) { b.start(); } } } so, is it ok ? /pierre Pierre De Rop wrote: I have looked into the code of the package admin implementation, from the trunk, and I think I have found a working solution for my problem. Indeed, in the org.apache.felix.deploymentadmin.spi.StartBundleCommand class, the method execute just does the following, when refreshing synchronously: context.addFrameworkListener(listener); packageAdmin.refreshPackages(null); m_refreshMonitor.waitForRefresh(); context.removeFrameworkListener(listener); So, the trick consists in registering/unregistering a fwk listener before/after refreshing/waiting ... It works because the Bundle.update() method fires the PACKAGES_REFRESHED event on a snapshot of the currently registered framework listeners. So, now, instead of registering a global FrameworkListener, my BundleInstaller does the following, and it seems to work fine: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); _bctx.addFrameworkListener(new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }); _pkgAdmin.refresh(null); // asynchronous latch.await(); for (Bundle b : bundles) { b.start(); } } } Does this make sense ? /pierre Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
No. You don't need to worry about ClassCastExceptions as your bundle will be wired to the old revision of the bundle. Unless you don't import what you export :-) See http://felix.apache.org/site/apache-felix-osgi-faq.html for more on the why. regards, Karl On Fri, Apr 10, 2009 at 7:40 AM, Pierre De Rop pierre.de_...@alcatel-lucent.fr wrote: Richard, Before posting an issue into osgi-dev about this subject, I would like to check with you if it really makes sense to wait for the PACKAGES_REFRESHED ... Here is my use case: * bundle B1 exports B1Service * B2 imports and implements B1Service. When B2 starts: it registers B1Service into the registry: registerService(B1Service.class.getName(), this) * B1 tracks B1Service from the OSGi registry. * when B2 registers, then B1 catches the B1Service (implemented by B2) and then invokes some methods on it So, If I update B1, our bundle installer does the following: * stop B1 * update B1 * refresh B1 * wait for PACKAGES_REFRESHED event o This will ensure that B2 is fully RESTARTED * I then restart B1 o At this point: I know that B2 has been restarted and has already re-registered the new (updated) B1Service into the OSGi registry * So, when B1 starts, it finds the B1Service from the OSGi registry and invokes some methods from it ... So, as you see, if I don't wait for PACKAGES_REFRESHED event, then I can run into unexpected ClassCastException, because when B1 is restarted, it may discover from the registry an old version of the B1Service interface (the old version before the update) ... Am I correct ? If true, then I am wondering what does the FileInstall tool, from Peter Kriens ? Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org -- Karl Pauls karlpa...@gmail.com - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
All right, I will try to import what I export. Thanks for your suggestion; /pierre Karl Pauls wrote: No. You don't need to worry about ClassCastExceptions as your bundle will be wired to the old revision of the bundle. Unless you don't import what you export :-) See http://felix.apache.org/site/apache-felix-osgi-faq.html for more on the why. regards, Karl On Fri, Apr 10, 2009 at 7:40 AM, Pierre De Rop pierre.de_...@alcatel-lucent.fr wrote: Richard, Before posting an issue into osgi-dev about this subject, I would like to check with you if it really makes sense to wait for the PACKAGES_REFRESHED ... Here is my use case: * bundle B1 exports B1Service * B2 imports and implements B1Service. When B2 starts: it registers B1Service into the registry: registerService(B1Service.class.getName(), this) * B1 tracks B1Service from the OSGi registry. * when B2 registers, then B1 catches the B1Service (implemented by B2) and then invokes some methods on it So, If I update B1, our bundle installer does the following: * stop B1 * update B1 * refresh B1 * wait for PACKAGES_REFRESHED event o This will ensure that B2 is fully RESTARTED * I then restart B1 o At this point: I know that B2 has been restarted and has already re-registered the new (updated) B1Service into the OSGi registry * So, when B1 starts, it finds the B1Service from the OSGi registry and invokes some methods from it ... So, as you see, if I don't wait for PACKAGES_REFRESHED event, then I can run into unexpected ClassCastException, because when B1 is restarted, it may discover from the registry an old version of the B1Service interface (the old version before the update) ... Am I correct ? If true, then I am wondering what does the FileInstall tool, from Peter Kriens ? Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
On 4/10/09 1:40 AM, Pierre De Rop wrote: Richard, Before posting an issue into osgi-dev about this subject, I would like to check with you if it really makes sense to wait for the PACKAGES_REFRESHED ... Here is my use case: * bundle B1 exports B1Service * B2 imports and implements B1Service. When B2 starts: it registers B1Service into the registry: registerService(B1Service.class.getName(), this) * B1 tracks B1Service from the OSGi registry. * when B2 registers, then B1 catches the B1Service (implemented by B2) and then invokes some methods on it So, If I update B1, our bundle installer does the following: * stop B1 * update B1 * refresh B1 * wait for PACKAGES_REFRESHED event o This will ensure that B2 is fully RESTARTED * I then restart B1 o At this point: I know that B2 has been restarted and has already re-registered the new (updated) B1Service into the OSGi registry * So, when B1 starts, it finds the B1Service from the OSGi registry and invokes some methods from it ... So, as you see, if I don't wait for PACKAGES_REFRESHED event, then I can run into unexpected ClassCastException, because when B1 is restarted, it may discover from the registry an old version of the B1Service interface (the old version before the update) ... Your bundle will not see services is it not class cast compatible with. - richard Am I correct ? If true, then I am wondering what does the FileInstall tool, from Peter Kriens ? Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
I have looked into the code of the package admin implementation, from the trunk, and I think I have found a working solution for my problem. Indeed, in the org.apache.felix.deploymentadmin.spi.StartBundleCommand class, the method execute just does the following, when refreshing synchronously: context.addFrameworkListener(listener); packageAdmin.refreshPackages(null); m_refreshMonitor.waitForRefresh(); context.removeFrameworkListener(listener); So, the trick consists in registering/unregistering a fwk listener before/after refreshing/waiting ... It works because the Bundle.update() method fires the PACKAGES_REFRESHED event on a snapshot of the currently registered framework listeners. So, now, instead of registering a global FrameworkListener, my BundleInstaller does the following, and it seems to work fine: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); _bctx.addFrameworkListener(new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }); _pkgAdmin.refresh(null); // asynchronous latch.await(); for (Bundle b : bundles) { b.start(); } } } Does this make sense ? /pierre Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
I'm sorry, in the previous sample code, I forgot to remove the fwk listener after the refresh, so here is the good fix: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); FrameworkListener listener = new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }; _bctx.addFrameworkListener(listener); _pkgAdmin.refresh(null); // asynchronous latch.await(); _bctx.removeFrameworkListener(listener); for (Bundle b : bundles) { b.start(); } } } so, is it ok ? /pierre Pierre De Rop wrote: I have looked into the code of the package admin implementation, from the trunk, and I think I have found a working solution for my problem. Indeed, in the org.apache.felix.deploymentadmin.spi.StartBundleCommand class, the method execute just does the following, when refreshing synchronously: context.addFrameworkListener(listener); packageAdmin.refreshPackages(null); m_refreshMonitor.waitForRefresh(); context.removeFrameworkListener(listener); So, the trick consists in registering/unregistering a fwk listener before/after refreshing/waiting ... It works because the Bundle.update() method fires the PACKAGES_REFRESHED event on a snapshot of the currently registered framework listeners. So, now, instead of registering a global FrameworkListener, my BundleInstaller does the following, and it seems to work fine: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); _bctx.addFrameworkListener(new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }); _pkgAdmin.refresh(null); // asynchronous latch.await(); for (Bundle b : bundles) { b.start(); } } } Does this make sense ? /pierre Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org - To
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
Yes, that does make sense. You are correct that the listeners are snapshot'ed, so in this case you are more likely to see your own event. However, there is no guarantee that someone else didn't sneak in and make a request to PackageAdmin before you could do it. :-( But, assuming you know what is going on, I think this approach should be reasonably safe. - richard On 4/10/09 1:57 PM, Pierre De Rop wrote: I'm sorry, in the previous sample code, I forgot to remove the fwk listener after the refresh, so here is the good fix: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); FrameworkListener listener = new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }; _bctx.addFrameworkListener(listener); _pkgAdmin.refresh(null); // asynchronous latch.await(); _bctx.removeFrameworkListener(listener); for (Bundle b : bundles) { b.start(); } } } so, is it ok ? /pierre Pierre De Rop wrote: I have looked into the code of the package admin implementation, from the trunk, and I think I have found a working solution for my problem. Indeed, in the org.apache.felix.deploymentadmin.spi.StartBundleCommand class, the method execute just does the following, when refreshing synchronously: context.addFrameworkListener(listener); packageAdmin.refreshPackages(null); m_refreshMonitor.waitForRefresh(); context.removeFrameworkListener(listener); So, the trick consists in registering/unregistering a fwk listener before/after refreshing/waiting ... It works because the Bundle.update() method fires the PACKAGES_REFRESHED event on a snapshot of the currently registered framework listeners. So, now, instead of registering a global FrameworkListener, my BundleInstaller does the following, and it seems to work fine: public class BundleInstaller { BundleContext _bctx; PackageAdmin _pkgAdmin; // ... void update(Bundle[] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); } final CountDownLatch latch = new CountDownLatch(1); _bctx.addFrameworkListener(new FrameworkListener() { public void frameworkEvent(FrameworkEvent event) { if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) { latch.countDown(); } } }); _pkgAdmin.refresh(null); // asynchronous latch.await(); for (Bundle b : bundles) { b.start(); } } } Does this make sense ? /pierre Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
In case that a bundle is not used by other bundles it will be refreshed automagically (this is allowed by the spec) when it is updated. Unfortunately, I cant think of a way to achieve what you want to do off the top of my head - might be something to discuss at osgi-dev... regards, Karl On Thu, Apr 9, 2009 at 4:14 PM, Pierre De Rop pierre.de_...@alcatel-lucent.fr wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre -- Karl Pauls karlpa...@gmail.com - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org
Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?
Richard, Before posting an issue into osgi-dev about this subject, I would like to check with you if it really makes sense to wait for the PACKAGES_REFRESHED ... Here is my use case: * bundle B1 exports B1Service * B2 imports and implements B1Service. When B2 starts: it registers B1Service into the registry: registerService(B1Service.class.getName(), this) * B1 tracks B1Service from the OSGi registry. * when B2 registers, then B1 catches the B1Service (implemented by B2) and then invokes some methods on it So, If I update B1, our bundle installer does the following: * stop B1 * update B1 * refresh B1 * wait for PACKAGES_REFRESHED event o This will ensure that B2 is fully RESTARTED * I then restart B1 o At this point: I know that B2 has been restarted and has already re-registered the new (updated) B1Service into the OSGi registry * So, when B1 starts, it finds the B1Service from the OSGi registry and invokes some methods from it ... So, as you see, if I don't wait for PACKAGES_REFRESHED event, then I can run into unexpected ClassCastException, because when B1 is restarted, it may discover from the registry an old version of the B1Service interface (the old version before the update) ... Am I correct ? If true, then I am wondering what does the FileInstall tool, from Peter Kriens ? Richard S. Hall wrote: On 4/9/09 10:14 AM, Pierre De Rop wrote: Hello everyone, I just discovered that invoking Bundle.update() method may fire a framework event PACKAGES_REFRESHED event. In the trunk, I see, in Felix.java, line 1691, that the update method may invoke the refreshPackage(null) method, which then fires the event. To be clear, it only invokes refreshPackages() on the bundle being updated, not all bundles. I understand this issue this causes for you, but I am not sure of a solution. We could possibly add a configuration to turn off auto-refreshing, but this would really just tie you to Felix since other implementations may still auto-refresh. What you really need is for the call to refreshPackages() to return some sort of request ID so you can check for when your request is finished. - richard Is is a normal behavior ? So far, I was fairly certain that this event was only fired after invoking PackageAdmin.refreshPackages() methods. Actually, we are using our own bundle installer, which install/updates our bundles. And our bundle installer does the following, when it updates a bundle: class BundleInstaller implements FrameworkListener { boolean refreshing = false; void update(Bundle([] bundles) { for (Bundle b : bundles) { b.stop(); b.update(); // May fire a PACKAGES_REFRESHED event } synchronized (this) { this.refreshing = true; } *packageAdmin.refresh(null); // asynchronous * synchronized (this) { *while (refreshing) wait(); *// ensure that all bundles are refreshed before restarting updated bundles. } for (Bundle b : bundles) { b.start(); } } // Here, I listen to the framework event PACKAGES_REFRESHED void frameworkEvent(FrameworkEvent event) { switch (event.getType()) { case FrameworkEvent.PACKAGES_REFRESHED: synchronized (this) { this.refreshing = false; notify(); } } } } The problem here, is that the first loop of my method update invokes Bundle.update(), which may fire some unexpected PACKAGES_REFRESHED events ... I'm expecting only one, and my waiting loop exits after the first event received. So, what can I do in order to ensure that the PackageAdmin.refreshPackages(null) method has completed ? Thanks in advance; /pierre - To unsubscribe, e-mail: users-unsubscr...@felix.apache.org For additional commands, e-mail: users-h...@felix.apache.org