Re: Why Bundle.update() method fires a PACKAGES_REFRESHED event ?

2009-04-11 Thread Pierre De Rop

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 ?

2009-04-10 Thread Karl Pauls
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 ?

2009-04-10 Thread Pierre De Rop

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 ?

2009-04-10 Thread Richard S. Hall

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 ?

2009-04-10 Thread Pierre De Rop
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 ?

2009-04-10 Thread Pierre De Rop
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 ?

2009-04-10 Thread Richard S. Hall
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 ?

2009-04-09 Thread Karl Pauls
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 ?

2009-04-09 Thread Richard S. Hall

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 ?

2009-04-09 Thread Pierre De Rop

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