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

jboss-osgi-commits at lists.jboss.org jboss-osgi-commits at lists.jboss.org
Mon Dec 14 16:07:04 EST 2009


Author: thomas.diesler at jboss.com
Date: 2009-12-14 16:07:03 -0500 (Mon, 14 Dec 2009)
New Revision: 97806

Modified:
   projects/jboss-osgi/projects/osgitck/trunk/build.xml
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/launch/OSGiFramework.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/FrameworkEventsPlugin.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/internal/FrameworkEventsPluginImpl.java
Log:
TCK framework.launch

Modified: projects/jboss-osgi/projects/osgitck/trunk/build.xml
===================================================================
--- projects/jboss-osgi/projects/osgitck/trunk/build.xml	2009-12-14 21:04:38 UTC (rev 97805)
+++ projects/jboss-osgi/projects/osgitck/trunk/build.xml	2009-12-14 21:07:03 UTC (rev 97806)
@@ -29,8 +29,8 @@
 
     <property file="${basedir}/ant.properties" />
 
-  	<!-- Setup property defaults -->
-  	<property environment="env"/>
+    <!-- Setup property defaults -->
+    <property environment="env" />
     <property name="hudson.username" value="${env.USER}" />
     <property name="osgitck.export" value="/home/${hudson.username}/svn/osgitck/r4v42" />
     <property name="osgitck.tar.file" value="${osgitck.export}/../osgitck-r4v42.tar" />
@@ -38,11 +38,11 @@
     <property name="hudson.root" value="/home/${hudson.username}/workspace/osgitck" />
 
     <echo>************************************************</echo>
-    <echo message="hudson.username=${hudson.username}"/>
-    <echo message="aQute.bnd.version=${aQute.bnd.version}"/>
-    <echo message="framework.version=${framework.version}"/>
-    <echo message="osgitck.export=${osgitck.export}"/>
-    <echo message="osgitck.tar.file=${osgitck.tar.file}"/>
+    <echo message="hudson.username=${hudson.username}" />
+    <echo message="aQute.bnd.version=${aQute.bnd.version}" />
+    <echo message="framework.version=${framework.version}" />
+    <echo message="osgitck.export=${osgitck.export}" />
+    <echo message="osgitck.tar.file=${osgitck.tar.file}" />
     <echo>************************************************</echo>
 
     <!-- Check if the osgitck export is available -->
@@ -61,7 +61,7 @@
 
     <!-- Check if the osgitck dir is available -->
     <available property="osgitck.dir.available" file="${osgitck.dir}" />
-    
+
   </target>
 
   <!-- ================================================================== -->
@@ -70,50 +70,51 @@
 
   <!-- Tar the OSGi TCK-->
   <target name="tar-osgitck" depends="init" unless="osgitck.tar.available">
-    <fail message="Cannot find osgitck export: ${osgitck.export}" unless="osgitck.export.available"/>
-    <tar basedir="${osgitck.export}" destfile="${osgitck.tar.file}" longfile="gnu" excludes="**/.svn"/>
+    <fail message="Cannot find osgitck export: ${osgitck.export}" unless="osgitck.export.available" />
+    <tar basedir="${osgitck.export}" destfile="${osgitck.tar.file}" longfile="gnu" excludes="**/.svn" />
   </target>
 
   <!-- Untar the OSGi TCK-->
   <target name="untar-osgitck" depends="tar-osgitck" unless="osgitck.dir.available">
-    <mkdir dir="${osgitck.dir}"/>
-    <untar src="${osgitck.tar.file}" dest="${osgitck.dir}"/>
+    <mkdir dir="${osgitck.dir}" />
+    <untar src="${osgitck.tar.file}" dest="${osgitck.dir}" />
     <available property="osgitck.dir.available" file="${osgitck.dir}" />
   </target>
 
   <!-- Setup the TCK to use the RI (equinox) -->
-  <target name="setup.ri" description="Setup the TCK using the RI (Equinox)" depends="init,untar-osgitck">
-    
+  <target name="setup.ri" description="Setup the TCK using the RI (Equinox)" depends="untar-osgitck">
+
     <!-- Copy the aQute.bnd -->
-    <fail message="Cannot find: ${osgitck.dir}" unless="osgitck.dir.available" />
     <copy file="${aQute.bnd.jar}" tofile="${osgitck.dir}/licensed/repo/biz.aQute.bnd/biz.aQute.bnd-latest.jar" overwrite="true" />
-  	
-  	<!-- Build the TCK -->
+
+    <!-- Build the TCK -->
     <ant dir="${osgitck.dir}/osgi.ct" target="clean" />
     <ant dir="${osgitck.dir}/osgi.ct" target="publish" />
   </target>
 
   <!-- Setup the TCK to use the JBoss OSGi Framework -->
-  <target name="setup.jboss" description="Setup the TCK using the JBoss OSGi Framework" depends="init,untar-osgitck">
-    
+  <target name="setup.jboss" description="Setup the TCK using the JBoss OSGi Framework" depends="untar-osgitck,update-framework">
+
     <!-- Overlay the TCK setup -->
-    <fail message="Cannot find: ${osgitck.dir}" unless="osgitck.dir.available" />
     <copy todir="${osgitck.dir}" overwrite="true">
       <fileset dir="${basedir}/overlay" />
     </copy>
 
-    <!-- Copy the OSGi Framework -->
-    <mkdir dir="${osgitck.dir}/licensed/repo/org.jboss.osgi.framework" />
-    <copy file="${jboss.osgi.framework.jar}" tofile="${osgitck.dir}/licensed/repo/org.jboss.osgi.framework/org.jboss.osgi.framework-1.0.0.jar" overwrite="true" />
-
     <!-- Copy the aQute.bnd -->
     <copy file="${aQute.bnd.jar}" tofile="${osgitck.dir}/licensed/repo/biz.aQute.bnd/biz.aQute.bnd-latest.jar" overwrite="true" />
-  	
-  	<!-- Build the TCK -->
+
+    <!-- Build the TCK -->
     <ant dir="${osgitck.dir}/osgi.ct" target="clean" />
     <ant dir="${osgitck.dir}/osgi.ct" target="publish" />
   </target>
 
+  <!-- Update the JBoss OSGi Framework -->
+  <target name="update-framework" description="Update the JBoss OSGi Framework" depends="untar-osgitck">
+    <!-- Copy the OSGi Framework -->
+    <mkdir dir="${osgitck.dir}/licensed/repo/org.jboss.osgi.framework" />
+    <copy file="${jboss.osgi.framework.jar}" tofile="${osgitck.dir}/licensed/repo/org.jboss.osgi.framework/org.jboss.osgi.framework-1.0.0.jar" overwrite="true" />
+  </target>
+
   <!-- ================================================================== -->
   <!-- Hudson                                                             -->
   <!-- ================================================================== -->
@@ -121,15 +122,15 @@
   <target name="hudson-setup" description="Setup the TCK Hudson instance" depends="init">
     <ant dir="${basedir}/hudson" target="hudson-setup" />
   </target>
-  
+
   <target name="hudson-start" description="Start the TCK Hudson instance" depends="init">
     <ant dir="${basedir}/hudson" target="hudson-start" />
   </target>
-  
+
   <target name="hudson-stop" description="Stop the TCK Hudson instance" depends="init">
     <ant dir="${basedir}/hudson" target="hudson-stop" />
   </target>
-  
+
   <!-- ================================================================== -->
   <!-- TCK Tests                                                          -->
   <!-- ================================================================== -->
@@ -138,22 +139,22 @@
     <fail message="Cannot find: ${osgitck.dir}" unless="osgitck.dir.available" />
     <ant dir="${osgitck.dir}/osgi.ct" target="osgi.core.tests" />
   </target>
-  
+
   <target name="test-reports" description="Generate the TCK test reports" depends="init">
     <fail message="Cannot find: ${osgitck.dir}" unless="osgitck.dir.available" />
-    <mkdir dir="${reports.dir}"/>
+    <mkdir dir="${reports.dir}" />
     <junitreport todir="${reports.dir}">
       <fileset dir="${osgitck.dir}">
-        <include name="**/test-reports/TEST-*.xml"/>
+        <include name="**/test-reports/TEST-*.xml" />
       </fileset>
-      <report format="frames" todir="${reports.dir}/html"/>
+      <report format="frames" todir="${reports.dir}/html" />
     </junitreport>
-    
-    <echo/>
-    <echo message="Generated test reports: ${reports.dir}"/>
-    <echo/>
+
+    <echo />
+    <echo message="Generated test reports: ${reports.dir}" />
+    <echo />
   </target>
-  
+
   <!-- ================================================================== -->
   <!-- Clean                                                              -->
   <!-- ================================================================== -->

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java	2009-12-14 21:04:38 UTC (rev 97805)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java	2009-12-14 21:07:03 UTC (rev 97806)
@@ -43,6 +43,7 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 import java.util.jar.Attributes.Name;
@@ -117,54 +118,40 @@
 
    /** The bundle manager's bean name: OSGiBundleManager */
    public static final String BEAN_BUNDLE_MANAGER = "OSGiBundleManager";
-
    /** The framework version */
    private static String OSGi_FRAMEWORK_VERSION = "r4v42"; // [TODO] externalise
-
    /** The framework vendor */
    private static String OSGi_FRAMEWORK_VENDOR = "jboss.org"; // [TODO] externalise
-
    /** The framework language */
    private static String OSGi_FRAMEWORK_LANGUAGE = Locale.getDefault().getISO3Language(); // REVIEW correct?
-
    /** The os name */
    private static String OSGi_FRAMEWORK_OS_NAME;
-
    /** The os version */
    private static String OSGi_FRAMEWORK_OS_VERSION;
-
    /** The os version */
    private static String OSGi_FRAMEWORK_PROCESSOR;
-
    /** The bundles by id */
    private List<AbstractBundleState> bundles = new CopyOnWriteArrayList<AbstractBundleState>();
-
    /** The kernel */
    private Kernel kernel;
-
    /** The main deployer */
    private DeployerClient deployerClient;
-
    /** The deployment structure */
    private MainDeployerStructure deployerStructure;
-
    /** The deployment registry */
    private DeploymentRegistry registry;
-
    /** The instance metadata factory */
    private MetaDataRetrievalFactory factory;
-
    /** The executor */
    private Executor executor;
-
    /** The system bundle */
    private OSGiSystemState systemBundle;
-
    /** The registered manager plugins */
    private Map<Class<?>, Plugin> plugins = Collections.synchronizedMap(new LinkedHashMap<Class<?>, Plugin>());
-
    /** The frame work properties */
    private Map<String, Object> properties = new ConcurrentHashMap<String, Object>();
+   /** The framework stop monitor*/
+   private AtomicInteger stopMonitor = new AtomicInteger(0);
 
    static
    {
@@ -433,7 +420,7 @@
    public void setProperties(Map<String, Object> props)
    {
       properties.putAll(props);
-      
+
       // Init default framework properties
       if (getProperty(Constants.FRAMEWORK_VERSION) == null)
          setProperty(Constants.FRAMEWORK_VERSION, OSGi_FRAMEWORK_VERSION);
@@ -693,7 +680,7 @@
       BundleInfo info = BundleInfo.createBundleInfo(root, location);
       Deployment dep = DeploymentFactory.createDeployment(info);
       dep.setAutoStart(autoStart);
-      
+
       return installBundle(dep);
    }
 
@@ -1537,7 +1524,19 @@
    }
 
    /**
-    * Init the Framework
+    * Initialize this Framework. 
+    * 
+    * After calling this method, this Framework must:
+    * - Be in the Bundle.STARTING state.
+    * - Have a valid Bundle Context.
+    * - Be at start level 0.
+    * - Have event handling enabled.
+    * - Have reified Bundle objects for all installed bundles.
+    * - Have registered any framework services. For example, PackageAdmin, ConditionalPermissionAdmin, StartLevel.
+    * 
+    * This Framework will not actually be started until start is called.
+    * 
+    * This method does nothing if called when this Framework is in the Bundle.STARTING, Bundle.ACTIVE or Bundle.STOPPING states. 
     */
    public void initFramework()
    {
@@ -1555,10 +1554,25 @@
       // Put into the STARTING state
       systemBundle.changeState(Bundle.STARTING);
 
+      // Create the system bundle context
+      systemBundle.createBundleContext();
+
       // [TODO] Be at start level 0
 
-      // [TODO] Have event handling enabled
+      // Have event handling enabled
+      FrameworkEventsPlugin eventsPlugin = getPlugin(FrameworkEventsPlugin.class);
+      eventsPlugin.setActive(true);
 
+      // Have registered any framework services.
+      for (Plugin plugin : plugins.values())
+      {
+         if (plugin instanceof ServicePlugin)
+         {
+            ServicePlugin servicePlugin = (ServicePlugin)plugin;
+            servicePlugin.startService();
+         }
+      }
+
       // Cleanup the storage area
       String storageClean = getProperty(Constants.FRAMEWORK_STORAGE_CLEAN);
       BundleStoragePlugin storagePlugin = getOptionalPlugin(BundleStoragePlugin.class);
@@ -1577,19 +1591,6 @@
       if (systemBundle.getState() != Bundle.STARTING)
          initFramework();
 
-      // Create the system bundle context
-      systemBundle.createBundleContext();
-
-      // Start registered service plugins
-      for (Plugin plugin : plugins.values())
-      {
-         if (plugin instanceof ServicePlugin)
-         {
-            ServicePlugin servicePlugin = (ServicePlugin)plugin;
-            servicePlugin.startService();
-         }
-      }
-
       // All installed bundles must be started
       AutoInstallPlugin autoInstall = getOptionalPlugin(AutoInstallPlugin.class);
       if (autoInstall != null)
@@ -1612,44 +1613,132 @@
    }
 
    /**
-    * Stop the framework
+    * Stop this Framework.
+    * 
+    * The method returns immediately to the caller after initiating the following steps to be taken on another thread.
+    * 
+    * 1. This Framework's state is set to Bundle.STOPPING.
+    * 2. All installed bundles must be stopped without changing each bundle's persistent autostart setting. 
+    * 3. Unregister all services registered by this Framework.
+    * 4. Event handling is disabled.
+    * 5. This Framework's state is set to Bundle.RESOLVED.
+    * 6. All resources held by this Framework are released. This includes threads, bundle class loaders, open files, etc.
+    * 7. Notify all threads that are waiting at waitForStop that the stop operation has completed.
+    * 
+    * After being stopped, this Framework may be discarded, initialized or started. 
     */
    public void stopFramework()
    {
-      AbstractBundleState systemBundle = getSystemBundle();
-      if (systemBundle.getState() != Bundle.ACTIVE)
-         return;
-
-      systemBundle.changeState(Bundle.STOPPING);
-      for (AbstractBundleState bundleState : getBundles())
+      int beforeCount = stopMonitor.get();
+      Runnable stopcmd = new Runnable()
       {
-         if (bundleState != systemBundle)
+         public void run()
          {
-            try
+            synchronized (stopMonitor)
             {
-               // [TODO] don't change the  persistent state
-               bundleState.stop();
+               // Start the stop process
+               stopMonitor.addAndGet(1);
+
+               // This Framework's state is set to Bundle.STOPPING
+               systemBundle.changeState(Bundle.STOPPING);
+
+               // If this Framework implements the optional Start Level Service Specification, 
+               // then the start level of this Framework is moved to start level zero (0), as described in the Start Level Service Specification. 
+
+               // All installed bundles must be stopped without changing each bundle's persistent autostart setting
+               for (AbstractBundleState bundleState : getBundles())
+               {
+                  if (bundleState != systemBundle)
+                  {
+                     try
+                     {
+                        // [TODO] don't change the  persistent state
+                        bundleState.stop();
+                     }
+                     catch (Exception ex)
+                     {
+                        // Any exceptions that occur during bundle stopping must be wrapped in a BundleException and then 
+                        // published as a framework event of type FrameworkEvent.ERROR
+                        fireError(bundleState, "stopping bundle", ex);
+                     }
+                  }
+               }
+
+               // Stop registered service plugins
+               List<Plugin> reverseServicePlugins = new ArrayList<Plugin>(plugins.values());
+               Collections.reverse(reverseServicePlugins);
+               for (Plugin plugin : reverseServicePlugins)
+               {
+                  if (plugin instanceof ServicePlugin)
+                  {
+                     ServicePlugin servicePlugin = (ServicePlugin)plugin;
+                     servicePlugin.stopService();
+                  }
+               }
+
+               // Event handling is disabled
+               FrameworkEventsPlugin eventsPlugin = getPlugin(FrameworkEventsPlugin.class);
+               eventsPlugin.setActive(false);
+
+               // This Framework's state is set to Bundle.RESOLVED
+               systemBundle.changeState(Bundle.RESOLVED);
+
+               // All resources held by this Framework are released
+               systemBundle.destroyBundleContext();
+
+               // Notify all threads that are waiting at waitForStop that the stop operation has completed
+               stopMonitor.notifyAll();
             }
-            catch (Throwable t)
-            {
-               fireWarning(bundleState, "stopping bundle", t);
-            }
          }
+      };
+      executor.execute(stopcmd);
+
+      // Wait for the stop thread
+      while (stopMonitor.get() == beforeCount)
+      {
+         try
+         {
+            Thread.sleep(100);
+         }
+         catch (InterruptedException ex)
+         {
+            // ignore
+         }
       }
+   }
 
-      // Stop registered service plugins
-      List<Plugin> reverseServicePlugins = new ArrayList<Plugin>(plugins.values());
-      Collections.reverse(reverseServicePlugins);
-      for (Plugin plugin : reverseServicePlugins)
+   /**
+    * Wait until this Framework has completely stopped. 
+    * 
+    * The stop and update methods on a Framework performs an asynchronous stop of the Framework. 
+    * This method can be used to wait until the asynchronous stop of this Framework has completed. 
+    * This method will only wait if called when this Framework is in the Bundle.STARTING, Bundle.ACTIVE, or Bundle.STOPPING states. 
+    * Otherwise it will return immediately.
+    * 
+    * A Framework Event is returned to indicate why this Framework has stopped.
+    */
+   public FrameworkEvent waitForStop(long timeout) throws InterruptedException
+   {
+      int state = systemBundle.getState();
+
+      // Only wait when this Framework is in Bundle.STARTING, Bundle.ACTIVE, or Bundle.STOPPING state
+      if (state != Bundle.STARTING && state != Bundle.ACTIVE && state != Bundle.STOPPING)
+         return new FrameworkEvent(FrameworkEvent.STOPPED, systemBundle, null);
+
+      long timeoutTime = System.currentTimeMillis() + timeout;
+      synchronized (stopMonitor)
       {
-         if (plugin instanceof ServicePlugin)
+         while (state != Bundle.RESOLVED && System.currentTimeMillis() < timeoutTime)
          {
-            ServicePlugin servicePlugin = (ServicePlugin)plugin;
-            servicePlugin.stopService();
+            stopMonitor.wait(timeout);
+            state = systemBundle.getState();
          }
       }
 
-      systemBundle.changeState(Bundle.RESOLVED);
+      if (System.currentTimeMillis() > timeoutTime)
+         return new FrameworkEvent(FrameworkEvent.WAIT_TIMEDOUT, systemBundle, null);
+
+      return new FrameworkEvent(FrameworkEvent.STOPPED, systemBundle, null);
    }
 
    /**

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/launch/OSGiFramework.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/launch/OSGiFramework.java	2009-12-14 21:04:38 UTC (rev 97805)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/launch/OSGiFramework.java	2009-12-14 21:07:03 UTC (rev 97806)
@@ -79,16 +79,12 @@
    @Override
    public void stop() throws BundleException
    {
-      // [TODO] The method returns immediately to the caller after initiating the following steps
-
       bundleManager.stopFramework();
    }
 
    @Override
    public void stop(int options) throws BundleException
    {
-      // [TODO] The method returns immediately to the caller after initiating the following steps
-
       bundleManager.stopFramework();
    }
 
@@ -144,11 +140,11 @@
       throw new BundleException("The system bundle cannot be uninstalled");
    }
 
+   /**
+    * Wait until this Framework has completely stopped. 
+    */
    public FrameworkEvent waitForStop(long timeout) throws InterruptedException
    {
-      // [TODO] Wait until this Framework has completely stopped.
-
-      // [TODO] A Framework Event indicating the reason this method returned
-      return new FrameworkEvent(FrameworkEvent.STOPPED, this, null);
+      return bundleManager.waitForStop(timeout);
    }
 }
\ No newline at end of file

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/FrameworkEventsPlugin.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/FrameworkEventsPlugin.java	2009-12-14 21:04:38 UTC (rev 97805)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/FrameworkEventsPlugin.java	2009-12-14 21:07:03 UTC (rev 97806)
@@ -38,6 +38,10 @@
  */
 public interface FrameworkEventsPlugin extends Plugin
 {
+   boolean isActive();
+   
+   void setActive(boolean active);
+   
    void addBundleListener(Bundle bundle, BundleListener listener);
 
    void removeBundleListener(Bundle bundle, BundleListener listener);

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/internal/FrameworkEventsPluginImpl.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/internal/FrameworkEventsPluginImpl.java	2009-12-14 21:04:38 UTC (rev 97805)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/internal/FrameworkEventsPluginImpl.java	2009-12-14 21:07:03 UTC (rev 97806)
@@ -65,6 +65,8 @@
    // Provide logging
    final Logger log = Logger.getLogger(FrameworkEventsPluginImpl.class);
 
+   /** The active state of this plugin */
+   private boolean active;
    /** The bundle listeners */
    private final Map<Bundle, List<BundleListener>> bundleListeners = new ConcurrentHashMap<Bundle, List<BundleListener>>();
    /** The framework listeners */
@@ -94,6 +96,16 @@
       this.synchronous = synchronous;
    }
 
+   public boolean isActive()
+   {
+      return active;
+   }
+
+   public void setActive(boolean active)
+   {
+      this.active = active;
+   }
+
    public void addBundleListener(Bundle bundle, BundleListener listener)
    {
       if (listener == null)



More information about the jboss-osgi-commits mailing list