Return-Path: Delivered-To: apmail-felix-commits-archive@www.apache.org Received: (qmail 75410 invoked from network); 29 Jan 2010 21:31:30 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 29 Jan 2010 21:31:30 -0000 Received: (qmail 2437 invoked by uid 500); 29 Jan 2010 21:31:30 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 2380 invoked by uid 500); 29 Jan 2010 21:31:30 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 2371 invoked by uid 99); 29 Jan 2010 21:31:30 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 29 Jan 2010 21:31:30 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 29 Jan 2010 21:31:29 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id A51DD23889E3; Fri, 29 Jan 2010 21:31:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r904631 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: BundleImpl.java Felix.java FelixResolverState.java Date: Fri, 29 Jan 2010 21:31:09 -0000 To: commits@felix.apache.org From: rickhall@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100129213109.A51DD23889E3@eris.apache.org> Author: rickhall Date: Fri Jan 29 21:31:09 2010 New Revision: 904631 URL: http://svn.apache.org/viewvc?rev=904631&view=rev Log: If a fragment bundle is uninstalled, it must be unmerged from any unresolved hosts to avoid causing an exception. Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java?rev=904631&r1=904630&r2=904631&view=diff ============================================================================== --- felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java (original) +++ felix/trunk/framework/src/main/java/org/apache/felix/framework/BundleImpl.java Fri Jan 29 21:31:09 2010 @@ -134,6 +134,21 @@ } } + /** + * This is sort of a hacky method called after uninstalling a bundle. + * If the bundle is a fragment, this will unmerge it from any unresolved + * hosts. This is necessary since fragments are pre-merged into unresolved + * hosts. If uninstalled fragments are not unmerged from unresolved hosts, + * any attempts to subsequently resolve the host will result in an exception. + */ + synchronized void cleanAfterUninstall() + { + for (int i = 0; i < m_modules.length; i++) + { + getFramework().getResolverState().unmergeFragment(m_modules[i]); + } + } + synchronized void refresh() throws Exception { if (isExtension() && (getFramework().getState() != Bundle.STOPPING)) Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=904631&r1=904630&r2=904631&view=diff ============================================================================== --- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original) +++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Fri Jan 29 21:31:09 2010 @@ -2261,6 +2261,10 @@ // Set state to uninstalled. setBundleStateAndNotify(bundle, Bundle.UNINSTALLED); bundle.setLastModified(System.currentTimeMillis()); + + // If this bundle is a fragment, unmerge it from any + // unresolved hosts. + bundle.cleanAfterUninstall(); } finally { Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java?rev=904631&r1=904630&r2=904631&view=diff ============================================================================== --- felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java (original) +++ felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java Fri Jan 29 21:31:09 2010 @@ -288,6 +288,101 @@ } } + public void unmergeFragment(IModule module) + { + if (!Util.isFragment(module)) + { + return; + } + + // Get fragment list, which may be null for system bundle fragments. + List fragList = (List) m_fragmentMap.get(module.getSymbolicName()); + if (fragList != null) + { + // Remove from fragment map. + fragList.remove(module); + if (fragList.size() == 0) + { + m_fragmentMap.remove(module.getSymbolicName()); + } + + // If we have any matching hosts, then remove fragment while + // removing any older version of the new fragment. Also remove host's + // existing capabilities from the package index and reindex its new + // ones after attaching the fragment. + List matchingHosts = getMatchingHosts(module); + for (int hostIdx = 0; hostIdx < matchingHosts.size(); hostIdx++) + { + IModule host = ((ICapability) matchingHosts.get(hostIdx)).getModule(); + // Find any unresolved hosts into which the fragment is merged + // and unmerge it. + IModule[] fragments = ((ModuleImpl) host).getFragments(); + for (int fragIdx = 0; + !host.isResolved() && (fragments != null) && (fragIdx < fragments.length); + fragIdx++) + { + if (!fragments[fragIdx].equals(module)) + { + List fragmentList = getMatchingFragments(host); + + // Remove host's existing exported packages from index. + ICapability[] caps = host.getCapabilities(); + for (int i = 0; (caps != null) && (i < caps.length); i++) + { + if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)) + { + // Get package name. + String pkgName = (String) + caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY); + // Remove from "unresolved" package map. + List capList = (List) m_unresolvedPkgIndex.get(pkgName); + if (capList != null) + { + capList.remove(caps[i]); + } + } + } + + // Check if fragment conflicts with existing metadata. + checkForConflicts(host, fragmentList); + + // Attach the fragments to the host. + fragments = (fragmentList.size() == 0) + ? null + : (IModule[]) fragmentList.toArray(new IModule[fragmentList.size()]); + try + { + ((ModuleImpl) host).attachFragments(fragments); + } + catch (Exception ex) + { + // Try to clean up by removing all fragments. + try + { + ((ModuleImpl) host).attachFragments(null); + } + catch (Exception ex2) + { + } + m_logger.log(Logger.LOG_ERROR, + "Serious error attaching fragments.", ex); + } + + // Reindex the host's exported packages. + caps = host.getCapabilities(); + for (int i = 0; (caps != null) && (i < caps.length); i++) + { + if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE)) + { + indexPackageCapability(m_unresolvedPkgIndex, caps[i]); + } + } + } + } + } + } + } + private List getMatchingHosts(IModule fragment) { // Find the fragment's host requirement.