1 Reply Latest reply on Dec 18, 2009 6:17 AM by thomas.diesler

    Initial support for Bundle.update()

    thomas.diesler

      4.4.9 Updating Bundles


            The Bundle interface defines two methods for updating a bundle:


            •   update() – This method updates a bundle.
            •   update(InputStream) – This method updates a bundle from the spec-
                ified InputStream object.


            The update process supports migration from one version of a bundle to a
            newer version of the same bundle. The exports of an updated bundle must
            be immediately available to the Framework. If none of the old exports are
            used, then the old exports must be removed. Otherwise, all old exports must
            remain available for existing bundles and future resolves until the
            refreshPackages method is called or the Framework is restarted.
            After the update operation is complete, the framework must attempt to
            move the bundle to the same state as it was before the operation taking the
            activation policy into account, without changing the autostart setting. This
            is described in more detail in Restoring State After Refresh or Update on page
            103.


            An updater of a bundle must have AdminPermission[<bundle>,LIFECYCLE]
            for both the installed bundle as well as the new bundle. The parameters of
            AdminPermission are explained in Admin Permission on page 117.

        • 1. Re: Initial support for Bundle.update()
          thomas.diesler

          I added a test to BundeUnitTestCase that updates the bundle's version

           

             public void testUpdate() throws Exception
             {
                VirtualFile assemble1 = assembleBundle("bundle1", "/bundles/update/update-bundle1");
                VirtualFile assemble2 = assembleBundle("bundle2", "/bundles/update/update-bundle2");
                
                Manifest manifest = VFSUtils.getManifest(assemble2);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                new JarOutputStream(baos, manifest).close();
                ByteArrayInputStream updateStream = new ByteArrayInputStream(baos.toByteArray());
                
                // [JBVFS-130] VFSUtils.temp(assembledDirectory) cannot create tmp dir
                // assemble2 = VFSUtils.temp(assemble2);
                
                Bundle bundle = installBundle(assemble1);
                try
                {
                   int beforeCount = getBundleManager().getBundles().size();
                   
                   bundle.start();
                   assertBundleState(Bundle.ACTIVE, bundle.getState());
                   assertEquals("Bundle-Version", "1.0.0", bundle.getHeaders().get(Constants.BUNDLE_VERSION));
                   
                   bundle.update(updateStream);
                   assertBundleState(Bundle.ACTIVE, bundle.getState());
                   assertEquals("Bundle-Version", "1.0.1", bundle.getHeaders().get(Constants.BUNDLE_VERSION));
                   
                   int afterCount = getBundleManager().getBundles().size();
                   assertEquals("Bundle count", beforeCount, afterCount);
                }
                finally
                {
                   bundle.uninstall();
                }
             }
          
          

           

          Please note, that the update sematics is such that the same bundle instance must be updated. It would be incorrect to uninstall the old bundle and reinstall the new bundle.

           

          As a consequence, multiple DeploymentUnits must be associated with the same OSGiBundleState unless the DeploymentUnit itself can support the notion of update that is semantically equivalent to OSGi Bundle.update().

           

          Currently, OSGiBundleState supports a list of DeploymentUnits and OSGiBundleState.getDeploymentUnit() always gets the last that has succesfully been added as a result of an update. Bundle.uninstall() undeploys all associated DeploymentUnits.

           

          OSGiMetaData is no longer a property of the AbstractBundleState, but is associated with each DeploymentUnit.

           

          The effect of Bundle.update() on package exports (as described above) has not yet been tested.

           

          Here is the feature request for this functionality at the CL level

          https://jira.jboss.org/jira/browse/JBCL-135