[jboss-cvs] JBossAS SVN: r98958 - in projects/jboss-osgi/projects/runtime/framework/trunk/src: main/java/org/jboss/osgi/framework/deployers and 8 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Dec 31 10:51:38 EST 2009


Author: thomas.diesler at jboss.com
Date: 2009-12-31 10:51:37 -0500 (Thu, 31 Dec 2009)
New Revision: 98958

Added:
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractDeployedBundleState.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiFragmentState.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/META-INF/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/META-INF/MANIFEST.MF
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/META-INF/
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/META-INF/MANIFEST.MF
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/OSGiBundleManager.java
   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/OSGiSystemState.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/deployers/OSGiBundleStateAddDeployer.java
   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/service/internal/PackageAdminImpl.java
   projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java
Log:
Work on bundle validation.
Initial fragment support.

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-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractBundleState.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -29,6 +29,7 @@
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashSet;
@@ -71,7 +72,7 @@
 import org.osgi.framework.Version;
 
 /**
- * BundleState.
+ * The abstract state of all bundles.
  * 
  * @author <a href="adrian at jboss.com">Adrian Brock</a>
  * @author Thomas.Diesler at jboss.com
@@ -153,6 +154,8 @@
       return state.get();
    }
 
+   public abstract boolean isFragment();
+   
    public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int signersType)
    {
       throw new NotImplementedException();
@@ -350,7 +353,10 @@
    }
 
    // Get the entry without checking permissions and bundle state. 
-   abstract URL getEntryInternal(String path);
+   protected URL getEntryInternal(String path)
+   {
+      return null;
+   }
 
    public String getProperty(String key)
    {
@@ -418,7 +424,10 @@
     *
     * @return the registered contexts
     */
-   protected abstract Set<ControllerContext> getRegisteredContexts();
+   protected Set<ControllerContext> getRegisteredContexts()
+   {
+      return Collections.emptySet();
+   }
 
    public ServiceReference[] getRegisteredServices()
    {

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractDeployedBundleState.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractDeployedBundleState.java	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/AbstractDeployedBundleState.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -0,0 +1,158 @@
+/*
+* 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.osgi.framework.bundle;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
+import org.jboss.osgi.deployment.deployer.Deployment;
+import org.jboss.osgi.framework.metadata.OSGiMetaData;
+import org.jboss.virtual.VirtualFile;
+import org.osgi.framework.Bundle;
+
+/**
+ * The abstract state of a deployed bundle or fragment.
+ * 
+ * @author Thomas.Diesler at jboss.com
+ * @since 25-Dec-2009
+ */
+public abstract class AbstractDeployedBundleState extends AbstractBundleState
+{
+   /** Used to generate a unique id */
+   private static final AtomicLong bundleIDGenerator = new AtomicLong();
+
+   /** The bundle id */
+   private long bundleId;
+
+   /** The bundle location */
+   private String location;
+
+   /** The bundle root file */
+   private VirtualFile rootFile;
+
+   /** The list of deployment units */
+   private List<DeploymentUnit> units = new ArrayList<DeploymentUnit>();
+
+   /** The headers localized with the default locale */
+   Dictionary<String, String> headersOnUninstall;
+
+   /**
+    * Create a new BundleState.
+    * 
+    * @param unit the deployment unit
+    * @throws IllegalArgumentException for a null parameter
+    */
+   public AbstractDeployedBundleState(DeploymentUnit unit)
+   {
+      if (unit == null)
+         throw new IllegalArgumentException("Null deployment unit");
+
+      // The bundle location is not necessarily the bundle root url
+      // The framework is expected to preserve the location passed into installBundle(String)
+      Deployment dep = unit.getAttachment(Deployment.class);
+      location = (dep != null ? dep.getLocation() : unit.getName());
+      rootFile = (dep != null ? dep.getRoot() : ((VFSDeploymentUnit)unit).getRoot());
+
+      bundleId = bundleIDGenerator.incrementAndGet();
+
+      addDeploymentUnit(unit);
+   }
+
+   /**
+    * Get the root file for this bundle 
+    */
+   public VirtualFile getRoot()
+   {
+      return rootFile;
+   }
+
+   @Override
+   public OSGiMetaData getOSGiMetaData()
+   {
+      DeploymentUnit unit = getDeploymentUnit();
+      OSGiMetaData osgiMetaData = unit.getAttachment(OSGiMetaData.class);
+      return osgiMetaData;
+   }
+
+   public long getBundleId()
+   {
+      return bundleId;
+   }
+
+   /**
+    * Get the DeploymentUnit that was added last.
+    * 
+    * Initially, an OSGiBundleState is associated with just one DeploymentUnit.
+    * A sucessful call to {@link #update()} or its variants pushes an additional
+    * DeploymentUnit to the stack.   
+    * 
+    * @return the unit that corresponds to the last sucessful update.
+    */
+   public DeploymentUnit getDeploymentUnit()
+   {
+      int index = (units.size() - 1);
+      return units.get(index);
+   }
+
+   /**
+    * Add a DeploymentUnit to the list.
+    * 
+    * @see {@link OSGiBundleManager#updateBundle(DeployedBundleState, InputStream)}
+    */
+   void addDeploymentUnit(DeploymentUnit unit)
+   {
+      unit.getMutableMetaData().addMetaData(unit, DeploymentUnit.class);
+      units.add(unit);
+   }
+
+   /**
+    * Get the list of DeploymentUnits.
+    * 
+    * @see {@link OSGiBundleManager#uninstallBundle(DeployedBundleState)}
+    */
+   List<DeploymentUnit> getDeploymentUnits()
+   {
+      return Collections.unmodifiableList(units);
+   }
+
+   public String getLocation()
+   {
+      return location;
+   }
+
+   @Override
+   public Dictionary<String, String> getHeaders(String locale)
+   {
+      // This method must continue to return Manifest header information while this bundle is in the UNINSTALLED state, 
+      // however the header values must only be available in the raw and default locale values
+      if (getState() == Bundle.UNINSTALLED)
+         return headersOnUninstall;
+
+      return super.getHeaders(locale);
+   }
+}

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-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleManager.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -91,8 +91,8 @@
 import org.jboss.osgi.framework.plugins.ServicePlugin;
 import org.jboss.osgi.framework.util.NoFilter;
 import org.jboss.osgi.framework.util.URLHelper;
-import org.jboss.osgi.spi.NotImplementedException;
 import org.jboss.osgi.spi.util.BundleInfo;
+import org.jboss.util.platform.Java;
 import org.jboss.virtual.VFS;
 import org.jboss.virtual.VFSUtils;
 import org.jboss.virtual.VirtualFile;
@@ -126,10 +126,8 @@
 
    /** 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";
-   /** The framework vendor */
-   private static String OSGi_FRAMEWORK_VENDOR = "jboss.org";
+   /** The framework execution environment */
+   private static String OSGi_FRAMEWORK_EXECUTIONENVIRONMENT;
    /** The framework language */
    private static String OSGi_FRAMEWORK_LANGUAGE = Locale.getDefault().getISO3Language(); // REVIEW correct?
    /** The os name */
@@ -138,8 +136,12 @@
    private static String OSGi_FRAMEWORK_OS_VERSION;
    /** The os version */
    private static String OSGi_FRAMEWORK_PROCESSOR;
+   /** The framework vendor */
+   private static String OSGi_FRAMEWORK_VENDOR = "jboss.org";
+   /** The framework version */
+   private static String OSGi_FRAMEWORK_VERSION = "r4v42";
    /** The bundles by id */
-   private List<AbstractBundleState> bundles = new CopyOnWriteArrayList<AbstractBundleState>();
+   private List<AbstractBundleState> allBundles = new CopyOnWriteArrayList<AbstractBundleState>();
    /** The kernel */
    private Kernel kernel;
    /** The main deployer */
@@ -167,6 +169,16 @@
       {
          public Object run()
          {
+            List<String> execEnvironments = new ArrayList<String>();
+            if (Java.isCompatible(Java.VERSION_1_5))
+               execEnvironments.add("J2SE-1.5");
+            if (Java.isCompatible(Java.VERSION_1_6))
+               execEnvironments.add("JavaSE-1.6");
+
+            String envlist = execEnvironments.toString();
+            envlist = envlist.substring(1, envlist.length() - 1);
+            OSGi_FRAMEWORK_EXECUTIONENVIRONMENT = envlist;
+
             OSGi_FRAMEWORK_OS_NAME = System.getProperty("os.name");
             OSGi_FRAMEWORK_OS_VERSION = System.getProperty("os.version");
             OSGi_FRAMEWORK_PROCESSOR = System.getProperty("os.arch");
@@ -359,9 +371,24 @@
             OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
             if (bundleState == null)
             {
+               OSGiMetaData osgiMetaData = unit.getAttachment(OSGiMetaData.class);
+               if (osgiMetaData == null)
+               {
+                  Manifest manifest = unit.getAttachment(Manifest.class);
+                  // [TODO] we need a mechanism to construct an OSGiMetaData from an easier factory
+                  if (manifest == null)
+                     manifest = new Manifest();
+                  // [TODO] populate some bundle information
+                  Attributes attributes = manifest.getMainAttributes();
+                  attributes.put(new Name(Constants.BUNDLE_NAME), unit.getName());
+                  attributes.put(new Name(Constants.BUNDLE_SYMBOLICNAME), unit.getName());
+                  osgiMetaData = new AbstractOSGiMetaData(manifest);
+                  unit.addAttachment(OSGiMetaData.class, osgiMetaData);
+               }
+
                try
                {
-                  bundleState = addDeployment(unit);
+                  bundleState = (OSGiBundleState)addDeployment(unit);
                   bundleState.startInternal();
                   unit.addAttachment(OSGiBundleState.class, bundleState);
                }
@@ -425,10 +452,8 @@
       properties.putAll(props);
 
       // Init default framework properties
-      if (getProperty(Constants.FRAMEWORK_VERSION) == null)
-         setProperty(Constants.FRAMEWORK_VERSION, OSGi_FRAMEWORK_VERSION);
-      if (getProperty(Constants.FRAMEWORK_VENDOR) == null)
-         setProperty(Constants.FRAMEWORK_VENDOR, OSGi_FRAMEWORK_VENDOR);
+      if (getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT) == null)
+         setProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT, OSGi_FRAMEWORK_EXECUTIONENVIRONMENT);
       if (getProperty(Constants.FRAMEWORK_LANGUAGE) == null)
          setProperty(Constants.FRAMEWORK_LANGUAGE, OSGi_FRAMEWORK_LANGUAGE);
       if (getProperty(Constants.FRAMEWORK_OS_NAME) == null)
@@ -437,6 +462,10 @@
          setProperty(Constants.FRAMEWORK_OS_VERSION, OSGi_FRAMEWORK_OS_VERSION);
       if (getProperty(Constants.FRAMEWORK_PROCESSOR) == null)
          setProperty(Constants.FRAMEWORK_PROCESSOR, OSGi_FRAMEWORK_PROCESSOR);
+      if (getProperty(Constants.FRAMEWORK_VENDOR) == null)
+         setProperty(Constants.FRAMEWORK_VENDOR, OSGi_FRAMEWORK_VENDOR);
+      if (getProperty(Constants.FRAMEWORK_VERSION) == null)
+         setProperty(Constants.FRAMEWORK_VERSION, OSGi_FRAMEWORK_VERSION);
    }
 
    /**
@@ -686,9 +715,17 @@
       if (location == null)
          throw new IllegalArgumentException("Null location");
 
-      BundleInfo info = BundleInfo.createBundleInfo(root, location);
-      Deployment dep = DeploymentFactory.createDeployment(info);
-      dep.setAutoStart(autoStart);
+      Deployment dep;
+      try
+      {
+         BundleInfo info = BundleInfo.createBundleInfo(root, location);
+         dep = DeploymentFactory.createDeployment(info);
+         dep.setAutoStart(autoStart);
+      }
+      catch (RuntimeException ex)
+      {
+         throw new BundleException("Cannot install bundle: " + root, ex);
+      }
 
       return installBundle(dep);
    }
@@ -710,11 +747,16 @@
          MutableAttachments att = (MutableAttachments)deployment.getPredeterminedManagedObjects();
          att.addAttachment(Deployment.class, dep);
 
+         // In case of update the OSGiBundleState is attached
+         OSGiBundleState bundleState = dep.getAttachment(OSGiBundleState.class);
+         if (bundleState != null)
+            att.addAttachment(OSGiBundleState.class, bundleState);
+
          deployerClient.deploy(deployment);
          try
          {
             DeploymentUnit unit = deployerStructure.getDeploymentUnit(deployment.getName());
-            OSGiBundleState bundleState = unit.getAttachment(OSGiBundleState.class);
+            bundleState = unit.getAttachment(OSGiBundleState.class);
             if (bundleState == null)
                throw new IllegalStateException("Unable to determine bundle state for " + deployment.getName());
 
@@ -740,11 +782,11 @@
    private String getIncompleteDeploymentInfo(Deployment dep, IncompleteDeploymentException ex)
    {
       IncompleteDeployments deployments = ex.getIncompleteDeployments();
-      
+
       StringWriter stringWriter = new StringWriter();
       PrintWriter printWriter = new PrintWriter(stringWriter);
       printWriter.println("Error installing bundle from: " + dep);
-      
+
       // Contexts in error 
       Collection<Throwable> contextsError = deployments.getContextsInError().values();
       if (contextsError.size() > 0)
@@ -905,12 +947,27 @@
    public void uninstallBundle(OSGiBundleState bundleState) throws BundleException
    {
       long id = bundleState.getBundleId();
-      if (id == 0)
-         throw new IllegalArgumentException("Cannot uninstall system bundle");
-
       if (getBundleById(id) == null)
          throw new BundleException(bundleState + " not installed");
 
+      // If this bundle's state is ACTIVE, STARTING or STOPPING, this bundle is stopped 
+      // as described in the Bundle.stop method.
+      int state = bundleState.getState();
+      if (state == Bundle.ACTIVE || state == Bundle.STARTING || state == Bundle.STOPPING)
+      {
+         try
+         {
+            stopBundle(bundleState);
+         }
+         catch (Exception ex)
+         {
+            // If Bundle.stop throws an exception, a Framework event of type FrameworkEvent.ERROR is
+            // fired containing the exception
+            fireError(bundleState, "Error stopping bundle: " + bundleState, ex);
+         }
+      }
+
+      DeploymentException depEx = null;
       for (DeploymentUnit unit : bundleState.getDeploymentUnits())
       {
          try
@@ -918,11 +975,21 @@
             deployerClient.undeploy(unit.getName());
             bundleState.updateLastModified();
          }
-         catch (DeploymentException e)
+         catch (DeploymentException ex)
          {
-            throw new BundleException("Unable to uninstall " + bundleState, e);
+            log.error("Cannot undeploy: " + unit.getName(), depEx = ex);
          }
       }
+
+      // Rethrow deployment exception 
+      if (depEx != null)
+      {
+         Throwable cause = depEx.getCause();
+         if (cause instanceof BundleException)
+            throw (BundleException)cause;
+
+         throw new BundleException("Unable to uninstall " + bundleState, cause);
+      }
    }
 
    /**
@@ -932,39 +999,41 @@
     * @return the bundle state
     * @throws IllegalArgumentException for a null parameter
     */
-   public OSGiBundleState addDeployment(DeploymentUnit unit)
+   public AbstractDeployedBundleState addDeployment(DeploymentUnit unit)
    {
       if (unit == null)
          throw new IllegalArgumentException("Null unit");
 
-      OSGiMetaData osgiMetaData = unit.getAttachment(OSGiMetaData.class);
-      if (osgiMetaData == null)
+      // In case of Bundle.update() the OSGiBundleState is attached
+      AbstractDeployedBundleState absBundle = unit.getAttachment(OSGiBundleState.class);
+      if (absBundle != null)
       {
-         Manifest manifest = unit.getAttachment(Manifest.class);
-         // [TODO] we need a mechanism to construct an OSGiMetaData from an easier factory
-         if (manifest == null)
-            manifest = new Manifest();
-         // [TODO] populate some bundle information
-         Attributes attributes = manifest.getMainAttributes();
-         attributes.put(new Name(Constants.BUNDLE_NAME), unit.getName());
-         attributes.put(new Name(Constants.BUNDLE_SYMBOLICNAME), unit.getName());
-         osgiMetaData = new AbstractOSGiMetaData(manifest);
-         unit.addAttachment(OSGiMetaData.class, osgiMetaData);
+         // Add the DeploymentUnit to the OSGiBundleState 
+         absBundle.addDeploymentUnit(unit);
       }
-
-      // In case of Bundle.update() the OSGiBundleState should be attached. We add the DeploymentUnit 
-      Deployment dep = unit.getAttachment(Deployment.class);
-      OSGiBundleState bundleState = (dep != null ? dep.getAttachment(OSGiBundleState.class) : null);
-      if (bundleState != null)
-         bundleState.addDeploymentUnit(unit);
-
-      // Create a new OSGiBundleState and add it to the manager
-      if (bundleState == null)
+      else
       {
-         bundleState = new OSGiBundleState(unit);
-         addBundle(bundleState);
+         OSGiMetaData osgiMetaData = unit.getAttachment(OSGiMetaData.class);
+         ParameterizedAttribute fragmentHost = osgiMetaData.getFragmentHost();
+         if (fragmentHost != null)
+         {
+            // Create a new OSGiFragmentState
+            OSGiFragmentState fragmentBundle = new OSGiFragmentState(unit);
+            unit.addAttachment(OSGiFragmentState.class, fragmentBundle);
+            absBundle = fragmentBundle;
+            addBundle(fragmentBundle);
+         }
+         else
+         {
+            // Create a new OSGiBundleState
+            OSGiBundleState bundleState = new OSGiBundleState(unit);
+            unit.addAttachment(OSGiBundleState.class, bundleState);
+            absBundle = bundleState;
+            addBundle(bundleState);
+         }
       }
-      return bundleState;
+
+      return absBundle;
    }
 
    /**
@@ -1004,7 +1073,7 @@
       validateBundle(bundleState);
 
       bundleState.setBundleManager(this);
-      bundles.add(bundleState);
+      allBundles.add(bundleState);
 
       // Only fire the INSTALLED event if this is not an update
       boolean fireEvent = true;
@@ -1037,13 +1106,9 @@
       if (osgiMetaData == null)
          return;
 
-      ParameterizedAttribute fragmentHost = osgiMetaData.getFragmentHost();
-      if (fragmentHost != null)
-         throw new NotImplementedException("Fragments not implemented: " + fragmentHost);
-      
       // Delegate to the validator for the appropriate revision
       OSGiBundleValidator validator = new OSGiBundleValidatorR3(this);
-      if(osgiMetaData.getBundleManifestVersion() > 1)
+      if (osgiMetaData.getBundleManifestVersion() > 1)
          validator = new OSGiBundleValidatorR4(this);
 
       validator.validateBundle(bundleState);
@@ -1068,7 +1133,7 @@
       if (bundleResolver != null)
          bundleResolver.removeBundle(bundleState);
 
-      bundles.remove(bundleState);
+      allBundles.remove(bundleState);
       log.debug("Removed " + bundleState.getCanonicalName());
    }
 
@@ -1119,7 +1184,7 @@
    public AbstractBundleState getBundleById(long id)
    {
       AbstractBundleState result = null;
-      for (AbstractBundleState aux : bundles)
+      for (AbstractBundleState aux : allBundles)
       {
          if (id == aux.getBundleId())
          {
@@ -1140,7 +1205,7 @@
    public AbstractBundleState getBundle(String symbolicName, Version version)
    {
       AbstractBundleState result = null;
-      for (AbstractBundleState aux : bundles)
+      for (AbstractBundleState aux : allBundles)
       {
          String auxName = aux.getSymbolicName();
          Version auxVersion = aux.getVersion();
@@ -1184,7 +1249,7 @@
 
       AbstractBundleState result = null;
 
-      for (AbstractBundleState aux : bundles)
+      for (AbstractBundleState aux : allBundles)
       {
          String auxLocation = aux.getLocation();
          if (location.equals(auxLocation))
@@ -1214,6 +1279,12 @@
     */
    public Collection<AbstractBundleState> getBundles()
    {
+      List<AbstractBundleState> bundles = new ArrayList<AbstractBundleState>();
+      for (AbstractBundleState aux : allBundles)
+      {
+         if (aux.isFragment() == false)
+            bundles.add(aux);
+      }
       return Collections.unmodifiableList(bundles);
    }
 
@@ -1226,12 +1297,12 @@
    public Collection<AbstractBundleState> getBundles(int state)
    {
       List<AbstractBundleState> bundles = new ArrayList<AbstractBundleState>();
-      for (AbstractBundleState aux : getBundles())
+      for (AbstractBundleState aux : allBundles)
       {
-         if (aux.getState() == state)
+         if (aux.isFragment() == false && aux.getState() == state)
             bundles.add(aux);
       }
-      return bundles;
+      return Collections.unmodifiableList(bundles);
    }
 
    /**
@@ -1241,12 +1312,39 @@
     * @param errorOnFail whether to throw an error if it cannot be resolved
     * @return true when resolved
     */
-   public boolean resolveBundle(OSGiBundleState bundleState, boolean errorOnFail)
+   public boolean resolveBundle(OSGiBundleState bundleState, boolean errorOnFail) throws BundleException
    {
       int state = bundleState.getState();
       if (state != Bundle.INSTALLED)
          return true;
 
+      // A bundle can only resolve if the framework is running on a VM which
+      // implements one of the listed required execution environments. 
+      List<String> reqExecEnvironments = bundleState.getOSGiMetaData().getRequiredExecutionEnvironment();
+      if (reqExecEnvironments != null)
+      {
+         boolean foundExecEnv = false;
+         String fwExecEnvs = getProperty(Constants.FRAMEWORK_EXECUTIONENVIRONMENT);
+         for (String aux : reqExecEnvironments)
+         {
+            if (fwExecEnvs.contains(aux))
+            {
+               foundExecEnv = true;
+               break;
+            }
+         }
+
+         if (foundExecEnv == false)
+         {
+            String msg = "Cannot find any of the required execution environments " + reqExecEnvironments + ", we have: " + fwExecEnvs;
+            if (errorOnFail == true)
+               throw new BundleException(msg);
+
+            log.error(msg);
+            return false;
+         }
+      }
+
       DeploymentUnit unit = bundleState.getDeploymentUnit();
       ControllerContext context = unit.getAttachment(ControllerContext.class);
 
@@ -1267,7 +1365,7 @@
          context.setRequiredState(requiredState);
 
          if (errorOnFail)
-            throw new IllegalStateException("Error resolving bundle: " + bundleState, ex);
+            throw new BundleException("Error resolving bundle: " + bundleState, ex);
 
          return false;
       }
@@ -1333,6 +1431,7 @@
             deployerClient.change(unit.getName(), DeploymentStages.CLASSLOADER);
             deployerClient.checkComplete(unit.getName());
 
+            // Rethrow the attached BundleException
             throw startEx;
          }
       }
@@ -1381,6 +1480,7 @@
          BundleException stopEx = unit.removeAttachment(BundleException.class);
          if (stopEx != null)
          {
+            // Rethrow the attached BundleException
             throw stopEx;
          }
       }

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-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiBundleState.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -24,18 +24,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.List;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
 
 import org.jboss.dependency.spi.ControllerContext;
 import org.jboss.deployers.structure.spi.DeploymentUnit;
 import org.jboss.deployers.vfs.spi.structure.VFSDeploymentUnit;
-import org.jboss.osgi.deployment.deployer.Deployment;
 import org.jboss.osgi.framework.metadata.OSGiMetaData;
 import org.jboss.osgi.framework.plugins.PackageAdminPlugin;
 import org.jboss.virtual.VirtualFile;
@@ -53,26 +48,8 @@
  * @author <a href="ales.justin at jboss.org">Ales Justin</a>
  * @version $Revision: 1.1 $
  */
-public class OSGiBundleState extends AbstractBundleState
+public class OSGiBundleState extends AbstractDeployedBundleState
 {
-   /** Used to generate a unique id */
-   private static final AtomicLong bundleIDGenerator = new AtomicLong();
-
-   /** The bundle id */
-   private long bundleId;
-
-   /** The bundle location */
-   private String location;
-   
-   /** The bundle root file */
-   private VirtualFile rootFile;
-
-   /** The list of deployment units */
-   private List<DeploymentUnit> units = new ArrayList<DeploymentUnit>();
-   
-   /** The headers localized with the default locale */
-   Dictionary<String, String> headersOnUninstall;
-   
    /**
     * Create a new BundleState.
     * 
@@ -81,18 +58,7 @@
     */
    public OSGiBundleState(DeploymentUnit unit)
    {
-      if (unit == null)
-         throw new IllegalArgumentException("Null deployment unit");
-      
-      // The bundle location is not necessarily the bundle root url
-      // The framework is expected to preserve the location passed into installBundle(String)
-      Deployment dep = unit.getAttachment(Deployment.class);
-      location = (dep != null ? dep.getLocation() : unit.getName());
-      rootFile = (dep != null ? dep.getRoot() : ((VFSDeploymentUnit)unit).getRoot());
-
-      bundleId = bundleIDGenerator.incrementAndGet();
-      
-      addDeploymentUnit(unit);
+      super(unit);
    }
 
    /**
@@ -108,73 +74,16 @@
       return (OSGiBundleState)bundle;
    }
    
-   /**
-    * Get the root file for this bundle 
-    */
-   public VirtualFile getRoot()
+   public boolean isFragment()
    {
-      return rootFile;
+      return false;
    }
-
-   @Override
-   public OSGiMetaData getOSGiMetaData()
-   {
-      DeploymentUnit unit = getDeploymentUnit();
-      OSGiMetaData osgiMetaData = unit.getAttachment(OSGiMetaData.class);
-      return osgiMetaData;
-   }
-
+   
    protected Set<ControllerContext> getRegisteredContexts()
    {
       return getBundleManager().getRegisteredContext(this);
    }
 
-   public long getBundleId()
-   {
-      return bundleId;
-   }
-
-   /**
-    * Get the DeploymentUnit that was added last.
-    * 
-    * Initially, an OSGiBundleState is associated with just one DeploymentUnit.
-    * A sucessful call to {@link #update()} or its variants pushes an additional
-    * DeploymentUnit to the stack.   
-    * 
-    * @return the unit that corresponds to the last sucessful update.
-    */
-   public DeploymentUnit getDeploymentUnit()
-   {
-      int index = (units.size() - 1);
-      return units.get(index);
-   }
-
-   /**
-    * Add a DeploymentUnit to the list.
-    * 
-    * @see {@link OSGiBundleManager#updateBundle(OSGiBundleState, InputStream)}
-    */
-   void addDeploymentUnit(DeploymentUnit unit)
-   {
-      unit.getMutableMetaData().addMetaData(unit, DeploymentUnit.class);
-      units.add(unit);
-   }
-
-   /**
-    * Get the list of DeploymentUnits.
-    * 
-    * @see {@link OSGiBundleManager#uninstallBundle(OSGiBundleState)}
-    */
-   List<DeploymentUnit> getDeploymentUnits()
-   {
-      return Collections.unmodifiableList(units);
-   }
-
-   public String getLocation()
-   {
-      return location;
-   }
-
    public URL getEntry(String path)
    {
       checkInstalled();
@@ -184,9 +93,8 @@
       return getEntryInternal(path);
    }
 
-   // Get the entry without checking permissions and bundle state. 
    @Override
-   URL getEntryInternal(String path)
+   protected URL getEntryInternal(String path)
    {
       DeploymentUnit unit = getDeploymentUnit();
       if (unit instanceof VFSDeploymentUnit)
@@ -523,6 +431,10 @@
    public void uninstall() throws BundleException
    {
       checkAdminPermission(AdminPermission.LIFECYCLE); // [TODO] extension bundles
+
+      // If this bundle's state is UNINSTALLED then an IllegalStateException is thrown
+      if (getState() == Bundle.UNINSTALLED)
+         throw new IllegalStateException("Bundle already uninstalled: " + this);
       
       // Cache the headers in the default locale 
       headersOnUninstall = getHeaders(null);

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiFragmentState.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiFragmentState.java	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiFragmentState.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -0,0 +1,113 @@
+/*
+* 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.osgi.framework.bundle;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.jboss.deployers.structure.spi.DeploymentUnit;
+import org.jboss.osgi.spi.NotImplementedException;
+import org.osgi.framework.BundleException;
+
+/**
+ * OSGiSystemBundle.
+ * 
+ * @author Thomas.Diesler at jboss.com
+ * @since 25-Dec-2009
+ */
+public class OSGiFragmentState extends AbstractDeployedBundleState
+{
+   /**
+    * Create a new OSGiFragmentState
+    */
+   public OSGiFragmentState(DeploymentUnit unit)
+   {
+      super(unit);
+   }
+
+   public boolean isFragment()
+   {
+      return true;
+   }
+   
+   @SuppressWarnings("rawtypes")
+   public Enumeration findEntries(String path, String filePattern, boolean recurse)
+   {
+      throw new NotImplementedException();
+   }
+
+   public URL getEntry(String path)
+   {
+      throw new NotImplementedException();
+   }
+
+   @SuppressWarnings("rawtypes")
+   public Enumeration getEntryPaths(String path)
+   {
+      throw new NotImplementedException();
+   }
+
+   public URL getResource(String name)
+   {
+      throw new NotImplementedException();
+   }
+
+   @SuppressWarnings("rawtypes")
+   public Enumeration getResources(String name) throws IOException
+   {
+      throw new NotImplementedException();
+   }
+
+   @SuppressWarnings("rawtypes")
+   public Class loadClass(String name) throws ClassNotFoundException
+   {
+      throw new NotImplementedException();
+   }
+
+   public void start(int options) throws BundleException
+   {
+      throw new NotImplementedException();
+   }
+
+   public void stop(int options) throws BundleException
+   {
+      throw new NotImplementedException();
+   }
+
+   public void update() throws BundleException
+   {
+      throw new NotImplementedException();
+   }
+
+   public void update(InputStream input) throws BundleException
+   {
+      throw new NotImplementedException();
+   }
+
+   @Override
+   public void uninstall() throws BundleException
+   {
+      throw new NotImplementedException();
+   }
+}

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiSystemState.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiSystemState.java	2009-12-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/bundle/OSGiSystemState.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -70,6 +70,11 @@
       return osgiMetaData;
    }
 
+   public boolean isFragment()
+   {
+      return false;
+   }
+   
    protected Set<ControllerContext> getRegisteredContexts()
    {
       return registered;
@@ -133,13 +138,6 @@
 
    public URL getEntry(String path)
    {
-      return getEntryInternal(path);
-   }
-
-   // Get the entry without checking permissions and bundle state. 
-   @Override
-   URL getEntryInternal(String path)
-   {
       log.warn("[JBOSGI-138] getEntry(" + path + ")");
       return null;
    }

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/deployers/OSGiBundleStateAddDeployer.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/deployers/OSGiBundleStateAddDeployer.java	2009-12-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/deployers/OSGiBundleStateAddDeployer.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -22,11 +22,9 @@
 package org.jboss.osgi.framework.deployers;
 
 import org.jboss.deployers.spi.DeploymentException;
-import org.jboss.deployers.spi.deployer.DeploymentStage;
 import org.jboss.deployers.spi.deployer.DeploymentStages;
 import org.jboss.deployers.structure.spi.DeploymentUnit;
 import org.jboss.osgi.framework.bundle.OSGiBundleManager;
-import org.jboss.osgi.framework.bundle.OSGiBundleState;
 import org.jboss.osgi.framework.metadata.OSGiMetaData;
 
 /**
@@ -43,9 +41,6 @@
  */
 public class OSGiBundleStateAddDeployer extends AbstractOSGiBundleStateDeployer
 {
-   /** The required stage */
-   private DeploymentStage requiredStage;
-   
    /**
     * Create a new BundleStateDeployer.
     * 
@@ -56,26 +51,14 @@
    {
       super(bundleManager);
       setInput(OSGiMetaData.class);
-      this.requiredStage = DeploymentStages.DESCRIBE;
    }
 
    @Override
    protected void internalDeploy(DeploymentUnit unit) throws DeploymentException
    {
       // [TODO] look at manifest headers and persistent state for this
-      unit.setRequiredStage(requiredStage);
+      unit.setRequiredStage(DeploymentStages.DESCRIBE);
       
-      OSGiBundleState bundleState = bundleManager.addDeployment(unit);
-      unit.addAttachment(OSGiBundleState.class, bundleState);
+      bundleManager.addDeployment(unit);
    }
-
-   /**
-    * Set required stage.
-    *
-    * @param stage the required stage
-    */
-   public void setRequiredStage(String stage)
-   {
-      requiredStage = new DeploymentStage(stage);
-   }
 }

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-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/plugins/internal/FrameworkEventsPluginImpl.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -376,6 +376,18 @@
                {
                   listener.frameworkEvent(event);
                }
+               catch (RuntimeException ex)
+               {
+                  log.warn("Error while firing " + typeName + " for framework", ex);
+                  
+                  // The Framework must publish a FrameworkEvent.ERROR if a callback to an
+                  // event listener generates an unchecked exception - except when the callback
+                  // happens while delivering a FrameworkEvent.ERROR
+                  if (type != FrameworkEvent.ERROR)
+                  {
+                     fireFrameworkEvent(bundle, FrameworkEvent.ERROR, ex);
+                  }
+               }
                catch (Throwable t)
                {
                   log.warn("Error while firing " + typeName + " for framework", t);

Modified: projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/service/internal/PackageAdminImpl.java
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/service/internal/PackageAdminImpl.java	2009-12-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/main/java/org/jboss/osgi/framework/service/internal/PackageAdminImpl.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -47,6 +47,7 @@
 import org.jboss.osgi.spi.NotImplementedException;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.Version;
 import org.osgi.service.packageadmin.ExportedPackage;
@@ -229,11 +230,19 @@
          while (it.hasNext())
          {
             OSGiBundleState bundleState = it.next();
-            if (bundleManager.resolveBundle(bundleState, false))
+            try
             {
-               it.remove();
-               resolved++;
+               boolean bundleResolved = bundleManager.resolveBundle(bundleState, false);
+               if (bundleResolved)
+               {
+                  it.remove();
+                  resolved++;
+               }
             }
+            catch (BundleException ex)
+            {
+               // ignore
+            }
          }
       }
 

Modified: 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	2009-12-30 22:48:50 UTC (rev 98957)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/java/org/jboss/test/osgi/bundle/BundleLifecycleTestCase.java	2009-12-31 15:51:37 UTC (rev 98958)
@@ -27,8 +27,10 @@
 import org.jboss.test.osgi.bundle.support.a.FailOnStartActivator;
 import org.jboss.test.osgi.bundle.support.b.LifecycleService;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
 
 /**
  * BundleLifecycleTestCase.
@@ -51,16 +53,16 @@
    /**
     * Verifies that the service bundle can get started
     */
-   public void testServiceBundle() throws Exception
+   public void testSimpleStart() throws Exception
    {
       Bundle bundleA = installBundle(assembleBundle("lifecycle-service", "/bundles/lifecycle/simple-service", LifecycleService.class));
       try
       {
          assertBundleState(Bundle.INSTALLED, bundleA.getState());
-         
+
          bundleA.start();
          assertBundleState(Bundle.ACTIVE, bundleA.getState());
-         
+
          ServiceReference sref = bundleA.getBundleContext().getServiceReference(LifecycleService.class.getName());
          assertNotNull("Service available", sref);
       }
@@ -70,17 +72,17 @@
          assertBundleState(Bundle.UNINSTALLED, bundleA.getState());
       }
    }
-   
+
    /**
     * Verifies that the bundle state is RESOLVED after a failure in BundleActivator.start()
     */
-   public void testServiceNotAvailable() throws Exception
+   public void testDependencyNotAvailable() throws Exception
    {
       Bundle bundleA = installBundle(assembleBundle("lifecycle-service", "/bundles/lifecycle/simple-service", LifecycleService.class));
       try
       {
          assertBundleState(Bundle.INSTALLED, bundleA.getState());
-         
+
          // BundleA not started - service not available  
          ServiceReference sref = getSystemBundle().getBundleContext().getServiceReference(LifecycleService.class.getName());
          assertNull("Service not available", sref);
@@ -89,7 +91,7 @@
          try
          {
             assertBundleState(Bundle.INSTALLED, bundleB.getState());
-            
+
             bundleB.start();
             fail("BundleException expected");
          }
@@ -113,7 +115,7 @@
    /**
     * Verifies that BundleB can get started when the service is available
     */
-   public void testServiceAvailable() throws Exception
+   public void testDependencyAvailable() throws Exception
    {
       Bundle bundleA = installBundle(assembleBundle("lifecycle-service", "/bundles/lifecycle/simple-service", LifecycleService.class));
       try
@@ -143,18 +145,18 @@
    /**
     * Verifies that BundleB can get started when the service is made available 
     */
-   public void testServiceMakeAvailable() throws Exception
+   public void testStartRetry() throws Exception
    {
       Bundle bundleA = installBundle(assembleBundle("lifecycle-service", "/bundles/lifecycle/simple-service", LifecycleService.class));
       try
       {
          assertBundleState(Bundle.INSTALLED, bundleA.getState());
-         
+
          Bundle bundleB = installBundle(assembleBundle("lifecycle-failstart", "/bundles/lifecycle/fail-on-start", FailOnStartActivator.class));
          try
          {
             assertBundleState(Bundle.INSTALLED, bundleB.getState());
-            
+
             try
             {
                bundleB.start();
@@ -163,12 +165,12 @@
             catch (BundleException ex)
             {
                assertBundleState(Bundle.RESOLVED, bundleB.getState());
-               
+
                // Now, make the service available
                bundleA.start();
                assertBundleState(Bundle.ACTIVE, bundleA.getState());
             }
-            
+
             // BundleB can now be started
             bundleB.start();
             assertBundleState(Bundle.ACTIVE, bundleB.getState());
@@ -185,4 +187,59 @@
          assertBundleState(Bundle.UNINSTALLED, bundleA.getState());
       }
    }
+
+   /**
+    * Verifies that BundleB is still INSTALLED after a failure in PackageAdmin.resolve()
+    */
+   public void testFailToResolve() throws Exception
+   {
+      Bundle bundleB = installBundle(assembleBundle("lifecycle-failstart", "/bundles/lifecycle/fail-on-start", FailOnStartActivator.class));
+      try
+      {
+         assertBundleState(Bundle.INSTALLED, bundleB.getState());
+
+         // Get the PackageAdmin service
+         BundleContext sysContext = getSystemBundle().getBundleContext();
+         ServiceReference sref = sysContext.getServiceReference(PackageAdmin.class.getName());
+         PackageAdmin packageAdmin = (PackageAdmin)sysContext.getService(sref);
+         
+         // Attempt to explicitly resolve a bundle with missing dependency 
+         boolean allResolved = packageAdmin.resolveBundles(new Bundle[] { bundleB });
+         assertFalse("Resolve fails", allResolved);
+         
+         // Verify that the bundkle is still in state INSTALLED
+         assertBundleState(Bundle.INSTALLED, bundleB.getState());
+      }
+      finally
+      {
+         bundleB.uninstall();
+         assertBundleState(Bundle.UNINSTALLED, bundleB.getState());
+      }
+   }
+
+   /**
+    * Verifies that we get a BundleException when an invalid bundle is installed
+    */
+   public void testInstallInvalid() throws Exception
+   {
+      try
+      {
+         installBundle(assembleBundle("missing-symbolic-name", "/bundles/lifecycle/invalid01"));
+         fail("BundleException expected");
+      }
+      catch (BundleException ex)
+      {
+         // expected
+      }
+      
+      try
+      {
+         installBundle(assembleBundle("invalid-export", "/bundles/lifecycle/invalid02"));
+         fail("BundleException expected");
+      }
+      catch (BundleException ex)
+      {
+         // expected
+      }
+   }
 }

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/META-INF/MANIFEST.MF
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/META-INF/MANIFEST.MF	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid01/META-INF/MANIFEST.MF	2009-12-31 15:51:37 UTC (rev 98958)
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+

Added: projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/META-INF/MANIFEST.MF
===================================================================
--- projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/META-INF/MANIFEST.MF	                        (rev 0)
+++ projects/jboss-osgi/projects/runtime/framework/trunk/src/test/resources/bundles/lifecycle/invalid02/META-INF/MANIFEST.MF	2009-12-31 15:51:37 UTC (rev 98958)
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: invalid-export
+Export-Package: java.lang
+
+




More information about the jboss-cvs-commits mailing list