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 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
---------------------------------------------------------------------
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
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org