I have some app, what calls some jar library, what calls Felix framework and added some bundles from bundles dir.
The code of the "Show Help" button:
private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
for (Bundle qqq : context.getBundles()) {
if ("ihtika2.I_AboutForm".equals(qqq.getSymbolicName())) {
System.out.println("I_AboutForm state: "+qqq.getState());
}
}
try {
ServiceReference[] refs = context.getServiceReferences(
AboutFormInterface.class.getName(), "(Funct=*)");
if (refs == null) {
System.out.println("Not Found AboutForm on show");
} else {
AboutFormInterface AboutForm = (AboutFormInterface) context.getService(refs[0]);
AboutForm.showWindow(context);
}
} catch (Exception ex) {
Ini.logger.fatal("Error on showing AboutForm", ex);
}
}
In first click (before update) service founded correctly.
The code of the "Update" button:
try {
ServiceReference[] refs = context.getServiceReferences(
UpdaterInt.class.getName(), "(Funct=*)");
if (refs == null) {
System.out.println("Not Found UpdaterInt on demand");
} else {
UpdaterInt UpdaterLocal = (UpdaterInt) context.getService(refs[0]);
UpdaterLocal.update();
}
} catch (Exception ex) {
Ini.logger.fatal("Error on showing AboutForm", ex);
}
The code of the Updater's bundle:
public void update() {
System.out.println("Stage 1");
int x = 0;
Map<String, Bundle> bundlesList = new HashMap<String, Bundle>();
for (Bundle singleBundle : context.getBundles()) {
bundlesList.put(singleBundle.getLocation(), singleBundle);
System.out.println(singleBundle.getLocation());
}
System.out.println("+++++++++++++++++++++++++++++");
Map<String, Bundle> treeMap = new TreeMap<String, Bundle>(bundlesList);
for (String str : treeMap.keySet()) {
Bundle singleBundle = treeMap.get(str);
System.out.println(str + " " + singleBundle.getSymbolicName());
if (!"khartn.Updater".equals(singleBundle.getSymbolicName())
&& !"org.apache.felix.framework".equals(singleBundle.getSymbolicName())) {
try {
System.out.println("state0 " + singleBundle.getState());
singleBundle.stop();
System.out.println("state1 " + singleBundle.getState());
singleBundle.update();
System.out.println("state1.1 " + singleBundle.getState());
singleBundle.start();
synchronized (this) {
try {
this.wait(250);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("state2 " + singleBundle.getState());
} catch (BundleException ex) {
ex.printStackTrace();
}
System.out.println("***");
}
}
}
On update main JFrame updates correctly - it hided and shown. But on second click on "Show Help" Felix can't found service of the "Show Help". "Show Help" service registration code:
package ihtika2.i_aboutform;
import ihtika2.i_aboutform.service.AboutForm;
import ihtika2.i_aboutform.service.AboutFormInterface;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class Activator implements BundleActivator {
@Override
public void start(BundleContext context) throws Exception {
Hashtable<String, String> props = new Hashtable<String, String>();
props.put("Funct", "AboutForm");
System.out.println("Registering I_AboutForm");
context.registerService(AboutFormInterface.class.getName(), new AboutForm(), props);
}
@Override
public void stop(BundleContext context) throws Exception {
}
}
The string "Registering I_AboutForm" on update showed.
Why Felix can't found re-registered service?
The solution is the adding to the Updater's bundle code call to the
context.getBundle(0).adapt(FrameworkWiring.class).refreshBundles(bundles, null);
as this described in OSGi API Documentation:
If this bundle has exported any packages that are imported by another bundle, these packages must remain exported until the
FrameworkWiring.refreshBundles
method has been has been called or the framework is relaunched.