[jboss-osgi-commits] JBoss-OSGI SVN: r97857 - in projects/jboss-osgi/projects/runtime/framework/trunk: src/main/java/org/jboss/osgi/framework/bundle and 7 other directories.

jboss-osgi-commits at lists.jboss.org jboss-osgi-commits at lists.jboss.org
Tue Dec 15 14:45:08 EST 2009


Author: thomas.diesler at jboss.com
Date: 2009-12-15 14:45:06 -0500 (Tue, 15 Dec 2009)
New Revision: 97857

Added:
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/a/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/a/FailOnStartActivator.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/META-INF/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/META-INF/MANIFEST.MF
Modified:
   projects/jboss-osgi/projects/runtime/framework/trunk/pom.xml
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java
Log:
[JBOSGI-204] Failure in Bundle.start() uninstalls the bundle
WIP

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/pom.xml
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/pom.xml	2009-12-15 19:02:16 UTC (rev 97856)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/pom.xml	2009-12-15 19:45:06 UTC (rev 97857)
@@ -658,6 +658,12 @@
               <value>${project.build.directory}/test-libs</value>
             </property>
           </systemProperties>
+          <excludes>
+            <!-- http://community.jboss.org/thread/145863 -->
+            <exclude>org/jboss/test/osgi/service/ServiceMixUnitTestCase.class</exclude>
+            <!-- [JBOSGI-204] Failure in Bundle.start() uninstalls the bundle -->
+            <exclude>org/jboss/test/osgi/bundle/BundleLifecycleTestCase</exclude>
+          </excludes>
         </configuration>
       </plugin>
     </plugins>

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java	2009-12-15 19:02:16 UTC (rev 97856)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java	2009-12-15 19:45:06 UTC (rev 97857)
@@ -224,13 +224,13 @@
       return osgiMetaData;
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public Dictionary getHeaders()
    {
       return getHeaders(null);
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public Dictionary getHeaders(String locale)
    {
       checkAdminPermission(AdminPermission.METADATA);
@@ -408,7 +408,7 @@
       return getBundleManager().getServiceReferences(this, clazz, filter, true);
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings({ "rawtypes" })
    public ServiceRegistration registerService(String clazz, Object service, Dictionary properties)
    {
       if (clazz == null)
@@ -416,7 +416,7 @@
       return registerService(new String[] { clazz }, service, properties);
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties)
    {
       checkValidBundleContext();

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java	2009-12-15 19:02:16 UTC (rev 97856)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java	2009-12-15 19:45:06 UTC (rev 97857)
@@ -129,7 +129,7 @@
       return null;
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public Enumeration getEntryPaths(String path)
    {
       checkInstalled();
@@ -158,7 +158,7 @@
       return null;
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public Enumeration findEntries(String path, String filePattern, boolean recurse)
    {
       if (path == null)
@@ -232,7 +232,7 @@
       return getDeploymentUnit().getClassLoader().getResource(name);
    }
 
-   @SuppressWarnings("unchecked")
+   @SuppressWarnings("rawtypes")
    public Enumeration getResources(String name) throws IOException
    {
       checkInstalled();
@@ -281,12 +281,51 @@
     * 
     * @throws Throwable for any error
     */
-   public void startInternal() throws Throwable
+   public void startInternal() throws BundleException
    {
-      // Bundle extenders catch the STARTING event and might expect a valid context
+      // If this bundle's state is UNINSTALLED then an IllegalStateException is thrown. 
+      if (getState() == Bundle.UNINSTALLED)
+         throw new IllegalStateException("Bundle already uninstalled: " + this);
+      
+      // [TODO] If this bundle is in the process of being activated or deactivated then this method must wait for activation or deactivation 
+      // to complete before continuing. If this does not occur in a reasonable time, a BundleException is thrown to indicate this bundle was 
+      // unable to be started.
+      
+      // If this bundle's state is ACTIVE then this method returns immediately. 
+      if (getState() == Bundle.ACTIVE)
+         return;
+
+      // [TODO] If the START_TRANSIENT option is not set then set this bundle's autostart setting to Started with declared activation  
+      // if the START_ACTIVATION_POLICY option is set or Started with eager activation if not set. When the Framework is restarted 
+      // and this bundle's autostart setting is not Stopped, this bundle must be automatically started.
+      
+      // If this bundle's state is not RESOLVED, an attempt is made to resolve this bundle. If the Framework cannot resolve this bundle, 
+      // a BundleException is thrown.
+      if (getState() != Bundle.RESOLVED)
+      {
+         try
+         {
+            getBundleManager().resolveBundle(this, true);
+         }
+         catch (RuntimeException ex)
+         {
+            throw new BundleException("Cannot resolve bundle: " + this, ex);
+         }
+      }
+      
+      // [TODO] If the START_ACTIVATION_POLICY option is set and this bundle's declared activation policy is lazy then:
+      //    * If this bundle's state is STARTING then this method returns immediately.
+      //    * This bundle's state is set to STARTING.
+      //    * A bundle event of type BundleEvent.LAZY_ACTIVATION is fired.
+      //    * This method returns immediately and the remaining steps will be followed when this bundle's activation is later triggered.
+      
+      
+      // This bundle's state is set to STARTING
+      // A bundle event of type BundleEvent.STARTING is fired
       createBundleContext();
       changeState(STARTING);
 
+      // The BundleActivator.start(org.osgi.framework.BundleContext) method of this bundle's BundleActivator, if one is specified, is called. 
       try
       {
          OSGiMetaData metaData = getOSGiMetaData();
@@ -301,6 +340,7 @@
             if (result instanceof BundleActivator == false)
                throw new BundleException(bundleActivatorClassName + " is not an implementation of " + BundleActivator.class.getName());
 
+            // Attach so we can call BundleActivator.stop() on this instance
             BundleActivator bundleActivator = (BundleActivator)result;
             unit.addAttachment(BundleActivator.class, bundleActivator);
 
@@ -312,77 +352,125 @@
 
          changeState(ACTIVE);
       }
+      
+      // If the BundleActivator is invalid or throws an exception then:
+      //   * This bundle's state is set to STOPPING.
+      //   * A bundle event of type BundleEvent.STOPPING is fired.
+      //   * Any services registered by this bundle must be unregistered.
+      //   * Any services used by this bundle must be released.
+      //   * Any listeners registered by this bundle must be removed.
+      //   * This bundle's state is set to RESOLVED.
+      //   * A bundle event of type BundleEvent.STOPPED is fired.
+      //   * A BundleException is then thrown.
       catch (Throwable t)
       {
+         // This bundle's state is set to STOPPING
+         // A bundle event of type BundleEvent.STOPPING is fired
          changeState(STOPPING);
-         // TODO stop the bundle
+         
+         // Any services registered by this bundle must be unregistered.
+         // Any services used by this bundle must be released.
+         // Any listeners registered by this bundle must be removed.
+         stopInternal();
+         
          destroyBundleContext();
          changeState(RESOLVED);
-         throw t;
+         
+         // A bundle event of type BundleEvent.STOPPED is fired
+         
+         if (t instanceof BundleException)
+            throw (BundleException)t;
+         
+         throw new BundleException("Cannot start bundle: " + this, t);
       }
    }
 
    /**
     * Stop Internal
-    * 
-    * [TODO] Start Level Service & STOP_TRANSIENT? [TODO] locks [TODO] options
-    * 
-    * @throws Throwable for any error
     */
-   public void stopInternal() throws Throwable
+   public void stopInternal() throws BundleException
    {
+      // If this bundle's state is UNINSTALLED then an IllegalStateException is thrown. 
+      if (getState() == Bundle.UNINSTALLED)
+         throw new IllegalStateException("Bundle already uninstalled: " + this);
+
+      // [TODO] If this bundle is in the process of being activated or deactivated then this method must wait for activation or deactivation 
+      // to complete before continuing. If this does not occur in a reasonable time, a BundleException is thrown to indicate this bundle 
+      // was unable to be stopped.
+      
+      // [TODO] If the STOP_TRANSIENT option is not set then then set this bundle's persistent autostart setting to to Stopped. 
+      // When the Framework is restarted and this bundle's autostart setting is Stopped, this bundle must not be automatically started. 
+
+      // If this bundle's state is not STARTING or ACTIVE then this method returns immediately
+      if (getState() != Bundle.STARTING && getState() != Bundle.ACTIVE)
+         return;
+
+      // This bundle's state is set to STOPPING
+      // A bundle event of type BundleEvent.STOPPING is fired
+      int priorState = getState();
       changeState(STOPPING);
 
+      // If this bundle's state was ACTIVE prior to setting the state to STOPPING, 
+      // the BundleActivator.stop(org.osgi.framework.BundleContext) method of this bundle's BundleActivator, if one is specified, is called. 
+      // If that method throws an exception, this method must continue to stop this bundle and a BundleException must be thrown after completion 
+      // of the remaining steps.
       Throwable rethrow = null;
-      try
+      if (priorState == Bundle.ACTIVE)
       {
-         BundleActivator bundleActivator = getDeploymentUnit().getAttachment(BundleActivator.class);
-         BundleContext bundleContext = getBundleContext();
-         if (bundleActivator != null && bundleContext != null)
-         {
-            try
+            BundleActivator bundleActivator = getDeploymentUnit().getAttachment(BundleActivator.class);
+            BundleContext bundleContext = getBundleContext();
+            if (bundleActivator != null && bundleContext != null)
             {
-               bundleActivator.stop(bundleContext);
-            }
-            catch (Throwable t)
-            {
-               rethrow = t;
-            }
-         }
-
-         for (ControllerContext context : getUsedContexts(this))
-         {
-            int count = getUsedByCount(context, this);
-            while (count > 0)
-            {
                try
                {
-                  getBundleManager().ungetContext(this, context);
+                  bundleActivator.stop(bundleContext);
                }
                catch (Throwable t)
                {
-                  log.debug("Error ungetting service: " + context, t);
+                  rethrow = t;
                }
-               count--;
             }
-         }
+      }
+      
+      // Any services registered by this bundle must be unregistered
+      getBundleManager().unregisterContexts(this);
 
-         // unregister bundle's contexts
-         getBundleManager().unregisterContexts(this);
-
-         if (getState() != STOPPING)
-            throw new BundleException("Bundle has been uninstalled: " + getCanonicalName());
-      }
-      finally
+      // Any services used by this bundle must be released
+      for (ControllerContext context : getUsedContexts(this))
       {
-         if (getState() == STOPPING)
-            changeState(RESOLVED);
-         destroyBundleContext();
-         getDeploymentUnit().removeAttachment(BundleActivator.class);
+         int count = getUsedByCount(context, this);
+         while (count > 0)
+         {
+            try
+            {
+               getBundleManager().ungetContext(this, context);
+            }
+            catch (Throwable t)
+            {
+               log.debug("Error ungetting service: " + context, t);
+            }
+            count--;
+         }
       }
 
+      // [TODO] Any listeners registered by this bundle must be removed
+      
+      // If this bundle's state is UNINSTALLED, because this bundle was uninstalled while the 
+      // BundleActivator.stop method was running, a BundleException must be thrown
+      if (getState() == Bundle.UNINSTALLED)
+         throw new BundleException("Bundle uninstalled during activator stop: " + this);
+      
+      // This bundle's state is set to RESOLVED
+      destroyBundleContext();
+      changeState(RESOLVED);
+      
+      if (priorState != STOPPING)
+         throw new BundleException("Bundle has been uninstalled: " + getCanonicalName());
+
+      // [TODO] A bundle event of type BundleEvent.STOPPED is fired
+      
       if (rethrow != null)
-         throw rethrow;
+         throw new BundleException("Error during stop of bundle: " + this, rethrow);
    }
 
    public void update(InputStream in) throws BundleException

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java	2009-12-15 19:45:06 UTC (rev 97857)
@@ -0,0 +1,72 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.osgi.bundle;
+
+import junit.framework.Test;
+
+import org.jboss.test.osgi.FrameworkTest;
+import org.jboss.test.osgi.bundle.support.a.FailOnStartActivator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+/**
+ * BundleLifecycleTestCase.
+ *
+ * @author thomas.Diesler at jboss.com
+ * @since 15-Dec-2009
+ */
+public class BundleLifecycleTestCase extends FrameworkTest
+{
+   public static Test suite()
+   {
+      return suite(BundleLifecycleTestCase.class);
+   }
+
+   public BundleLifecycleTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testExceptionOnStart() throws Exception
+   {
+      Bundle bundle = assembleBundle("fail-on-start", "/bundles/lifecycle/fail-on-start", FailOnStartActivator.class);
+      try
+      {
+         assertBundleState(Bundle.INSTALLED, bundle.getState());
+
+         try
+         {
+            bundle.start();
+            fail("BundleException expected");
+         }
+         catch (BundleException ex)
+         {
+            assertBundleState(Bundle.RESOLVED, bundle.getState());
+         }
+      }
+      finally
+      {
+         //bundle.uninstall();
+         //assertBundleState(Bundle.UNINSTALLED, bundle.getState());
+      }
+   }
+}

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/a/FailOnStartActivator.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/a/FailOnStartActivator.java	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/support/a/FailOnStartActivator.java	2009-12-15 19:45:06 UTC (rev 97857)
@@ -0,0 +1,44 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2009, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.osgi.bundle.support.a;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * A BundleActivator that fails on start.
+ *
+ * @author thomas.Diesler at jboss.com
+ * @since 15-Dec-2009
+ */
+public class FailOnStartActivator implements BundleActivator
+{
+
+   public void start(BundleContext context) throws Exception
+   {
+      throw new IllegalStateException("fail on start");
+   }
+
+   public void stop(BundleContext context) throws Exception
+   {
+   }
+}

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/META-INF/MANIFEST.MF
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/META-INF/MANIFEST.MF	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/fail-on-start/META-INF/MANIFEST.MF	2009-12-15 19:45:06 UTC (rev 97857)
@@ -0,0 +1,4 @@
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.jboss.test.osgi.failstart
+Bundle-Activator: org.jboss.test.osgi.bundle.support.a.FailOnStartActivator
+



More information about the jboss-osgi-commits mailing list