You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/01/08 20:35:09 UTC
svn commit: r732800 [3/4] - in
/felix/trunk/framework/src/main/java/org/apache/felix: framework/
framework/cache/ framework/searchpolicy/ framework/util/ moduleloader/
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=732800&r1=732799&r2=732800&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 Thu Jan 8 11:35:07 2009
@@ -24,6 +24,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
import org.apache.felix.framework.searchpolicy.Resolver;
import org.apache.felix.framework.searchpolicy.PackageSource;
import org.apache.felix.framework.util.Util;
@@ -32,7 +33,6 @@
import org.apache.felix.moduleloader.IModule;
import org.apache.felix.moduleloader.IRequirement;
import org.apache.felix.moduleloader.IWire;
-import org.apache.felix.moduleloader.ModuleImpl;
import org.osgi.framework.Constants;
import org.osgi.framework.PackagePermission;
import org.osgi.framework.Version;
@@ -66,7 +66,7 @@
// exports to simplify later processing when resolving bundles.
m_moduleList.add(module);
- ICapability[] caps = module.getDefinition().getCapabilities();
+ ICapability[] caps = module.getCapabilities();
// Add exports to unresolved package map.
for (int i = 0; (caps != null) && (i < caps.length); i++)
@@ -93,7 +93,7 @@
m_moduleList.remove(module);
// Remove exports from package maps.
- ICapability[] caps = module.getDefinition().getCapabilities();
+ ICapability[] caps = module.getCapabilities();
for (int i = 0; (caps != null) && (i < caps.length); i++)
{
if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
@@ -132,6 +132,9 @@
// Set wires to null, which will remove the module from all
// of its dependent modules.
((ModuleImpl) module).setWires(null);
+ // Close the module's content.
+ ((ModuleImpl) module).close();
+
// Remove the module from the "resolved" map.
// TODO: RB - Maybe this can be merged with ModuleData.
m_resolvedCapMap.remove(module);
@@ -139,6 +142,39 @@
m_moduleDataMap.remove(module);
}
+/* TODO: RESOLVER - We need to figure out what to do with this.
+ public void moduleRefreshed(ModuleEvent event)
+ {
+ synchronized (m_factory)
+ {
+ IModule module = event.getModule();
+ // Remove exports from package maps.
+ ICapability[] caps = event.getModule().getDefinition().getCapabilities();
+ // Add exports to unresolved package map.
+ for (int i = 0; (caps != null) && (i < caps.length); i++)
+ {
+ ICapability[] resolvedCaps = (ICapability[]) m_resolvedCapMap.get(module);
+ resolvedCaps = addCapabilityToArray(resolvedCaps, caps[i]);
+ m_resolvedCapMap.put(module, resolvedCaps);
+
+ // If the capability is a package, then add the exporter module
+ // of the wire to the "resolved" package index and remove it
+ // from the "unresolved" package index.
+ if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+ {
+ // Get package name.
+ String pkgName = (String)
+ caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
+ // Add to "resolved" package index.
+ indexPackageCapability(
+ m_resolvedPkgIndexMap,
+ module,
+ caps[i]);
+ }
+ }
+ }
+ }
+*/
private void dumpPackageIndexMap(Map pkgIndexMap)
{
for (Iterator i = pkgIndexMap.entrySet().iterator(); i.hasNext(); )
@@ -164,24 +200,10 @@
return (IModule[]) m_moduleList.toArray(new IModule[m_moduleList.size()]);
}
- public String getBundleSymbolicName(IModule module)
- {
- ICapability[] caps = module.getDefinition().getCapabilities();
- for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
- {
- if (caps[capIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
- {
- return (String)
- caps[capIdx].getProperties().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
- }
- }
- return null;
- }
-
// TODO: FRAGMENT - Not very efficient.
private static Version getBundleVersion(IModule module)
{
- ICapability[] caps = module.getDefinition().getCapabilities();
+ ICapability[] caps = module.getCapabilities();
for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
{
if (caps[capIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
@@ -193,27 +215,9 @@
return Version.emptyVersion;
}
- public synchronized boolean isResolved(IModule module)
+ public synchronized void moduleResolved(IModule module)
{
- ModuleData data = (ModuleData) m_moduleDataMap.get(module);
- if (data != null)
- {
- return data.m_resolved;
- }
- return false;
- }
-
- public synchronized void setResolved(IModule module, boolean b)
- {
- ModuleData data = (ModuleData) m_moduleDataMap.get(module);
- if (data == null)
- {
- data = new ModuleData(module);
- m_moduleDataMap.put(module, data);
- }
- data.m_resolved = b;
-
- if (data.m_resolved)
+ if (module.isResolved())
{
// At this point, we need to remove all of the resolved module's
// capabilities from the "unresolved" package map and put them in
@@ -223,7 +227,7 @@
// module and not another module. If it points to another module
// then the capability should be ignored, since the framework
// decided to honor the import and discard the export.
- ICapability[] caps = module.getDefinition().getCapabilities();
+ ICapability[] caps = module.getCapabilities();
// First remove all existing capabilities from the "unresolved" map.
for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
@@ -261,18 +265,15 @@
// satisfies any of the wire requirements.
for (int wireIdx = 0; (wires != null) && (wireIdx < wires.length); wireIdx++)
{
- // If the wire requirement is satisfied by the current capability,
- // then check to see if the wire is to the module itself. If it
- // is to another module, then null the current capability since
- // it was both providing and requiring the same capability and
- // the resolve process chose to import rather than provide that
- // capability, therefore we should ignore it.
+ // If one of the module's capabilities satifies the requirement
+ // for an existing wire, this means the capability was
+ // substituted with another provider by the resolver and
+ // the module's capability was not used. Therefore, we should
+ // null it here so it doesn't get added the list of resolved
+ // capabilities for this module.
if (wires[wireIdx].getRequirement().isSatisfied(capsCopy[capIdx]))
{
- if (!wires[wireIdx].getExporter().equals(module))
- {
- capsCopy[capIdx] = null;
- }
+ capsCopy[capIdx] = null;
break;
}
}
@@ -314,7 +315,7 @@
{
List hostList = new ArrayList();
- IRequirement[] reqs = fragment.getDefinition().getRequirements();
+ IRequirement[] reqs = fragment.getRequirements();
IRequirement hostReq = null;
for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++)
{
@@ -328,14 +329,14 @@
IModule[] modules = getModules();
for (int modIdx = 0; (hostReq != null) && (modIdx < modules.length); modIdx++)
{
- if (!fragment.equals(modules[modIdx]) && !isResolved(modules[modIdx]))
+ if (!fragment.equals(modules[modIdx]) && !modules[modIdx].isResolved())
{
- ICapability[] caps = modules[modIdx].getDefinition().getCapabilities();
+ ICapability[] caps = modules[modIdx].getCapabilities();
for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
{
if (caps[capIdx].getNamespace().equals(ICapability.HOST_NAMESPACE)
&& hostReq.isSatisfied(caps[capIdx])
- && !modules[modIdx].isStale())
+ && !((BundleImpl) modules[modIdx].getBundle()).isStale())
{
hostList.add(modules[modIdx]);
break;
@@ -353,7 +354,7 @@
// TODO: FRAGMENT - This should check to make sure that the host allows fragments.
Map fragmentMap = new HashMap();
- ICapability[] caps = host.getDefinition().getCapabilities();
+ ICapability[] caps = host.getCapabilities();
ICapability bundleCap = null;
for (int capIdx = 0; capIdx < caps.length; capIdx++)
{
@@ -369,12 +370,13 @@
{
if (!host.equals(modules[modIdx]))
{
- IRequirement[] reqs = modules[modIdx].getDefinition().getRequirements();
+ IRequirement[] reqs = modules[modIdx].getRequirements();
for (int reqIdx = 0; (reqs != null) && (reqIdx < reqs.length); reqIdx++)
{
if (reqs[reqIdx].getNamespace().equals(ICapability.HOST_NAMESPACE)
&& reqs[reqIdx].isSatisfied(bundleCap)
- && !modules[modIdx].isStale())
+ && !((BundleImpl) modules[modIdx].getBundle()).isStale()
+ && !((BundleImpl) modules[modIdx].getBundle()).isRemovalPending())
{
indexFragment(fragmentMap, modules[modIdx]);
break;
@@ -404,7 +406,7 @@
{
// TODO: RB - Is this permission check correct.
if ((System.getSecurityManager() != null) &&
- !((BundleProtectionDomain) modules[modIdx].getContentLoader().getSecurityContext()).impliesDirect(
+ !((BundleProtectionDomain) modules[modIdx].getSecurityContext()).impliesDirect(
new PackagePermission(pkgName,
PackagePermission.EXPORT)))
{
@@ -439,7 +441,7 @@
// TODO: RB - Is this permission check correct.
if (resolvedCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
(System.getSecurityManager() != null) &&
- !((BundleProtectionDomain) module.getContentLoader().getSecurityContext()).impliesDirect(
+ !((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
new PackagePermission(
(String) resolvedCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY),
PackagePermission.EXPORT)))
@@ -486,7 +488,7 @@
ICapability cap = Util.getSatisfyingCapability(modules[modIdx], req);
// If compatible and it is not currently resolved, then add
// the unresolved candidate to the list.
- if ((cap != null) && !isResolved(modules[modIdx]))
+ if ((cap != null) && !modules[modIdx].isResolved())
{
PackageSource[] tmp = new PackageSource[candidates.length + 1];
System.arraycopy(candidates, 0, tmp, 0, candidates.length);
@@ -574,8 +576,7 @@
private void indexFragment(Map map, IModule module)
{
- String symName = getBundleSymbolicName(module);
- IModule[] modules = (IModule[]) map.get(symName);
+ IModule[] modules = (IModule[]) map.get(module.getSymbolicName());
// We want to add the fragment into the list of matching
// fragments in sorted order (descending version and
@@ -631,7 +632,7 @@
}
}
- map.put(symName, modules);
+ map.put(module.getSymbolicName(), modules);
}
private static IModule[] removeModuleFromArray(IModule[] modules, IModule m)
@@ -682,7 +683,7 @@
public static ICapability getExportPackageCapability(IModule m, String pkgName)
{
- ICapability[] caps = m.getDefinition().getCapabilities();
+ ICapability[] caps = m.getCapabilities();
for (int i = 0; (caps != null) && (i < caps.length); i++)
{
if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
@@ -719,17 +720,4 @@
return caps;
}
- //
- // Simple utility classes.
- //
-
- private static class ModuleData
- {
- public IModule m_module = null;
- public boolean m_resolved = false;
- public ModuleData(IModule module)
- {
- m_module = module;
- }
- }
}
\ No newline at end of file
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java Thu Jan 8 11:35:07 2009
@@ -22,7 +22,7 @@
class FindEntriesEnumeration implements Enumeration
{
- private FelixBundle m_bundle = null;
+ private BundleImpl m_bundle = null;
private Enumeration m_enumeration = null;
private String m_path = null;
private String[] m_filePattern = null;
@@ -30,12 +30,12 @@
private Object m_next = null;
public FindEntriesEnumeration(
- FelixBundle bundle, String path, String filePattern, boolean recurse)
+ BundleImpl bundle, String path, String filePattern, boolean recurse)
{
m_bundle = bundle;
m_path = path;
- m_enumeration = (m_bundle.getInfo().getCurrentModule().getContentLoader().getContent() == null)
- ? null : m_bundle.getInfo().getCurrentModule().getContentLoader().getContent().getEntries();
+ m_enumeration = (m_bundle.getCurrentModule().getContent() == null)
+ ? null : m_bundle.getCurrentModule().getContent().getEntries();
m_recurse = recurse;
// Sanity check the parameters.
@@ -113,8 +113,8 @@
if (checkSubstring(m_filePattern, lastElement))
{
// Convert entry name into an entry URL.
- return m_bundle.getInfo().getCurrentModule()
- .getContentLoader().getResourceFromContent(entryName);
+ return m_bundle.getCurrentModule()
+ .getResourceFromContent(entryName);
}
}
}
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java Thu Jan 8 11:35:07 2009
@@ -23,17 +23,16 @@
class GetEntryPathsEnumeration implements Enumeration
{
- private FelixBundle m_bundle = null;
+ private BundleImpl m_bundle = null;
private Enumeration m_enumeration = null;
private String m_path = null;
private Object m_next = null;
- public GetEntryPathsEnumeration(FelixBundle bundle, String path)
+ public GetEntryPathsEnumeration(BundleImpl bundle, String path)
{
m_bundle = bundle;
m_path = path;
- m_enumeration = m_bundle.getInfo().getCurrentModule()
- .getContentLoader().getContent().getEntries();
+ m_enumeration = m_bundle.getCurrentModule().getContent().getEntries();
// Sanity check the parameters.
if (m_path == null)
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java Thu Jan 8 11:35:07 2009
@@ -20,10 +20,10 @@
import java.util.*;
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.VersionRange;
import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.ModuleImpl;
import org.osgi.framework.*;
import org.osgi.service.packageadmin.*;
@@ -111,8 +111,8 @@
String sym = bundles[i].getSymbolicName();
if ((sym != null) && sym.equals(symbolicName))
{
- String s = (String) ((FelixBundle) bundles[i])
- .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+ String s = (String) ((BundleImpl) bundles[i])
+ .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
Version v = (s == null) ? new Version("0.0.0") : new Version(s);
if ((vr == null) || vr.isInRange(v))
{
@@ -128,10 +128,10 @@
Arrays.sort(bundles,new Comparator() {
public int compare(Object o1, Object o2)
{
- String s1 = (String) ((FelixBundle) o1)
- .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
- String s2 = (String) ((FelixBundle) o2)
- .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+ String s1 = (String) ((BundleImpl) o1)
+ .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
+ String s2 = (String) ((BundleImpl) o2)
+ .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
Version v1 = (s1 == null) ? new Version("0.0.0") : new Version(s1);
Version v2 = (s2 == null) ? new Version("0.0.0") : new Version(s2);
// Compare in reverse order to get descending sort.
@@ -143,7 +143,7 @@
public int getBundleType(Bundle bundle)
{
- Map headerMap = ((FelixBundle) bundle).getInfo().getCurrentHeader();
+ Map headerMap = ((BundleImpl) bundle).getCurrentModule().getHeaders();
if (headerMap.containsKey(Constants.FRAGMENT_HOST))
{
return PackageAdmin.BUNDLE_TYPE_FRAGMENT;
@@ -201,13 +201,12 @@
// Get attached fragments.
IModule[] modules =
((ModuleImpl)
- ((FelixBundle) bundle).getInfo().getCurrentModule()).getFragments();
+ ((BundleImpl) bundle).getCurrentModule()).getFragments();
// Convert fragment modules to bundles.
List list = new ArrayList();
for (int i = 0; (modules != null) && (i < modules.length); i++)
{
- long id = Util.getBundleIdFromModuleId(modules[i].getId());
- Bundle b = m_felix.getBundle(id);
+ Bundle b = modules[i].getBundle();
if (b != null)
{
list.add(b);
@@ -225,7 +224,7 @@
{
if (getBundleType(bundle) == BUNDLE_TYPE_FRAGMENT)
{
- return m_felix.getDependentBundles((FelixBundle) bundle);
+ return m_felix.getDependentBundles((BundleImpl) bundle);
}
return null;
}
@@ -236,10 +235,11 @@
Bundle[] bundles = m_felix.getBundles();
for (int i = 0; i < bundles.length; i++)
{
- FelixBundle fb = (FelixBundle) bundles[i];
- if ((symbolicName == null) || (symbolicName.equals(fb.getInfo().getSymbolicName())))
+ BundleImpl impl = (BundleImpl) bundles[i];
+ if ((symbolicName == null)
+ || (symbolicName.equals(impl.getCurrentModule().getSymbolicName())))
{
- list.add(new RequiredBundleImpl(m_felix, fb));
+ list.add(new RequiredBundleImpl(m_felix, impl));
}
}
return (list.size() == 0)
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java Thu Jan 8 11:35:07 2009
@@ -22,10 +22,10 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
import org.apache.felix.framework.util.Util;
import org.apache.felix.moduleloader.ICapability;
import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.ModuleImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
@@ -34,9 +34,9 @@
class RequiredBundleImpl implements RequiredBundle
{
private final Felix m_felix;
- private final FelixBundle m_bundle;
+ private final BundleImpl m_bundle;
- public RequiredBundleImpl(Felix felix, FelixBundle bundle)
+ public RequiredBundleImpl(Felix felix, BundleImpl bundle)
{
m_felix = felix;
m_bundle = bundle;
@@ -55,7 +55,7 @@
public Bundle[] getRequiringBundles()
{
// Spec says to return null for stale bundles.
- if (m_bundle.getInfo().isStale())
+ if (m_bundle.isStale())
{
return null;
}
@@ -64,7 +64,7 @@
// associated with this bundle.
List moduleList = new ArrayList();
// Loop through all of this bundle's modules.
- IModule[] modules = m_bundle.getInfo().getModules();
+ IModule[] modules = m_bundle.getModules();
for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
{
// For each of this bundle's modules, loop through all of the
@@ -80,8 +80,7 @@
Set bundleSet = new HashSet();
for (int modIdx = 0; modIdx < moduleList.size(); modIdx++)
{
- long id = Util.getBundleIdFromModuleId(((IModule) moduleList.get(modIdx)).getId());
- Bundle bundle = m_felix.getBundle(id);
+ Bundle bundle = ((IModule) moduleList.get(modIdx)).getBundle();
if (bundle != null)
{
bundleSet.add(bundle);
@@ -94,7 +93,7 @@
{
ICapability[] caps =
Util.getCapabilityByNamespace(
- m_bundle.getInfo().getCurrentModule(), ICapability.MODULE_NAMESPACE);
+ m_bundle.getCurrentModule(), ICapability.MODULE_NAMESPACE);
if ((caps != null) && (caps.length > 0))
{
return (Version) caps[0].getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
@@ -104,6 +103,6 @@
public boolean isRemovalPending()
{
- return m_bundle.getInfo().isRemovalPending();
+ return m_bundle.isRemovalPending();
}
}
\ No newline at end of file
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java Thu Jan 8 11:35:07 2009
@@ -122,8 +122,7 @@
// Get the package.
String pkgName =
Util.getClassPackage(className);
- IModule requesterModule =
- ((FelixBundle) requester).getInfo().getCurrentModule();
+ IModule requesterModule = ((BundleImpl) requester).getCurrentModule();
// Get package wiring from service requester.
IWire requesterWire = Util.getWire(requesterModule, pkgName);
@@ -148,8 +147,7 @@
}
// Get package wiring from service provider.
- IModule providerModule =
- ((FelixBundle) m_bundle).getInfo().getCurrentModule();
+ IModule providerModule = ((BundleImpl) m_bundle).getCurrentModule();
IWire providerWire = Util.getWire(providerModule, pkgName);
// Case 2: Only include service reference if the service
@@ -159,12 +157,12 @@
// If the provider is not the exporter of the requester's package,
// then try to use the service registration to see if the requester's
// class is accessible.
- if (!((FelixBundle) m_bundle).getInfo().hasModule(requesterWire.getExporter()))
+ if (!((BundleImpl) m_bundle).hasModule(requesterWire.getExporter()))
{
try
{
// Load the class from the requesting bundle.
- Class requestClass = requesterModule.getClass(className);
+ Class requestClass = requesterModule.getClassByDelegation(className);
// Get the service registration and ask it to check
// if the service object is assignable to the requesting
// bundle's class.
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java Thu Jan 8 11:35:07 2009
@@ -38,16 +38,13 @@
private Logger m_logger = null;
private Felix m_felix = null;
- private List m_requestList = null;
- private Bundle m_systemBundle = null;
+ private final List m_requestList = new ArrayList();
private Thread m_thread = null;
public StartLevelImpl(Logger logger, Felix felix)
{
m_logger = logger;
m_felix = felix;
- m_requestList = new ArrayList();
- m_systemBundle = m_felix.getBundle(0);
// Start a thread to perform asynchronous package refreshes.
m_thread = new Thread(this, "FelixStartLevel");
m_thread.setDaemon(true);
@@ -85,7 +82,7 @@
**/
public int getStartLevel()
{
- return m_felix.getStartLevel();
+ return m_felix.getActiveStartLevel();
}
/* (non-Javadoc)
@@ -98,7 +95,7 @@
if (sm != null)
{
((SecurityManager) sm).checkPermission(
- new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+ new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
}
if (startlevel <= 0)
@@ -202,7 +199,7 @@
if (sm != null)
{
((SecurityManager) sm).checkPermission(
- new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+ new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
}
m_felix.setInitialBundleStartLevel(startlevel);
}
@@ -262,7 +259,7 @@
if (request instanceof Integer)
{
// Set the new framework start level.
- m_felix.setFrameworkStartLevel(((Integer) request).intValue());
+ m_felix.setActiveStartLevel(((Integer) request).intValue());
}
else
{
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java Thu Jan 8 11:35:07 2009
@@ -33,7 +33,7 @@
import java.util.Map;
import java.util.StringTokenizer;
-import org.apache.felix.framework.searchpolicy.ContentClassLoader;
+import org.apache.felix.framework.searchpolicy.ModuleClassLoader;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.SecureAction;
import org.apache.felix.framework.util.SecurityManagerEx;
@@ -611,7 +611,7 @@
for (int i = 0; i < stack.length; i++)
{
if ((stack[i].getClassLoader() != null) &&
- ContentClassLoader.class.getName().equals(
+ ModuleClassLoader.class.getName().equals(
stack[i].getClassLoader().getClass().getName()))
{
targetClass = stack[i];
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java Thu Jan 8 11:35:07 2009
@@ -69,7 +69,7 @@
// bundle://<module-id>:<bundle-classpath-index>/<resource-path>
// Where <module-id> = <bundle-id>.<revision>
long bundleId = Util.getBundleIdFromModuleId(url.getHost());
- FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
+ BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
if (bundle == null)
{
throw new IOException("No bundle associated with resource: " + url);
@@ -77,7 +77,7 @@
m_contentTime = bundle.getLastModified();
int revision = Util.getModuleRevisionFromModuleId(url.getHost());
- IModule[] modules = bundle.getInfo().getModules();
+ IModule[] modules = bundle.getModules();
if ((modules == null) || (revision >= modules.length))
{
throw new IOException("Resource does not exist: " + url);
@@ -102,9 +102,9 @@
{
m_classPathIdx = 0;
}
- if (!modules[revision].getContentLoader().hasInputStream(m_classPathIdx, url.getPath()))
+ if (!modules[revision].hasInputStream(m_classPathIdx, url.getPath()))
{
- URL newurl = modules[revision].getContentLoader().getResource(url.getPath());
+ URL newurl = modules[revision].getResourceByDelegation(url.getPath());
if (newurl == null)
{
throw new IOException("Resource does not exist: " + url);
@@ -121,8 +121,7 @@
{
throw new IOException("Resource does not exist: " + url);
}
- m_is = m_targetModule.getContentLoader()
- .getInputStream(m_classPathIdx, url.getPath());
+ m_is = m_targetModule.getInputStream(m_classPathIdx, url.getPath());
m_contentLength = (m_is == null) ? 0 : m_is.available();
m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
connected = true;
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java Thu Jan 8 11:35:07 2009
@@ -49,8 +49,7 @@
**/
public URLHandlersServiceTracker(Felix framework, String filter)
{
- m_context = ((FelixBundle)
- framework.getBundle(0)).getInfo().getBundleContext();
+ m_context = ((BundleImpl) framework).getBundleContext();
m_filter = filter;
synchronized (this)
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java Thu Jan 8 11:35:07 2009
@@ -22,10 +22,7 @@
import java.net.URLDecoder;
import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.util.ObjectInputStreamX;
-import org.apache.felix.moduleloader.IModule;
import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
/**
* <p>
@@ -77,7 +74,6 @@
private static final transient String BUNDLE_STATE_FILE = "bundle.state";
private static final transient String BUNDLE_START_LEVEL_FILE = "bundle.startlevel";
private static final transient String REFRESH_COUNTER_FILE = "refresh.counter";
- private static final transient String BUNDLE_ACTIVATOR_FILE = "bundle.activator";
private static final transient String BUNDLE_LASTMODIFIED_FILE = "bundle.lastmodified";
private static final transient String REVISION_DIRECTORY = "version";
private static final transient String DATA_DIRECTORY = "data";
@@ -572,90 +568,6 @@
/**
* <p>
- * Returns the serialized activator for this archive. This is an
- * extension to the OSGi specification.
- * </p>
- * @return the serialized activator for this archive.
- * @throws Exception if any error occurs.
- **/
- public synchronized BundleActivator getActivator(IModule module)
- throws Exception
- {
- // Get bundle activator file.
- File activatorFile = new File(m_archiveRootDir, BUNDLE_ACTIVATOR_FILE);
- // If the activator file doesn't exist, then
- // assume there isn't one.
- if (!BundleCache.getSecureAction().fileExists(activatorFile))
- {
- return null;
- }
-
- // Deserialize the activator object.
- InputStream is = null;
- ObjectInputStreamX ois = null;
- try
- {
- is = BundleCache.getSecureAction()
- .getFileInputStream(activatorFile);
- ois = new ObjectInputStreamX(is, module);
- Object o = ois.readObject();
- return (BundleActivator) o;
- }
- catch (Exception ex)
- {
- m_logger.log(
- Logger.LOG_ERROR,
- getClass().getName() + ": Trying to deserialize - " + ex);
- }
- finally
- {
- if (ois != null) ois.close();
- if (is != null) is.close();
- }
-
- return null;
- }
-
- /**
- * <p>
- * Serializes the activator for this archive.
- * </p>
- * @param obj the activator to serialize.
- * @throws Exception if any error occurs.
- **/
- public synchronized void setActivator(Object obj) throws Exception
- {
- if (!(obj instanceof Serializable))
- {
- return;
- }
-
- // Serialize the activator object.
- OutputStream os = null;
- ObjectOutputStream oos = null;
- try
- {
- os = BundleCache.getSecureAction()
- .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_ACTIVATOR_FILE));
- oos = new ObjectOutputStream(os);
- oos.writeObject(obj);
- }
- catch (IOException ex)
- {
- m_logger.log(
- Logger.LOG_ERROR,
- getClass().getName() + ": Unable to serialize activator - " + ex);
- throw ex;
- }
- finally
- {
- if (oos != null) oos.close();
- if (os != null) os.close();
- }
- }
-
- /**
- * <p>
* Returns the number of revisions available for this archive.
* </p>
* @return tthe number of revisions available for this archive.
@@ -733,7 +645,7 @@
* @return true if the undo was a success false if there is no previous revision
* @throws Exception if any error occurs.
*/
- public synchronized boolean undoRevise() throws Exception
+ public synchronized boolean rollbackRevise() throws Exception
{
// Can only undo the revision if there is more than one.
if (getRevisionCount() <= 1)
Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java Thu Jan 8 11:35:07 2009
@@ -31,7 +31,7 @@
private static final transient String LIBRARY_DIRECTORY = "lib";
private Logger m_logger;
- private Object m_revisionLock;
+ private final Object m_revisionLock;
private File m_rootDir;
private File m_dir;
@@ -168,7 +168,6 @@
}
}
}
- System.out.println("+++ EXTRACTED JAR DIR " + extractedDir);
return new JarContent(m_logger, m_revisionLock, extractedDir, file);
}
Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java?rev=732800&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java Thu Jan 8 11:35:07 2009
@@ -0,0 +1,653 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.searchpolicy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.cache.JarContent;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.util.manifestparser.Requirement;
+import org.apache.felix.moduleloader.ICapability;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IModule;
+import org.apache.felix.moduleloader.IRequirement;
+import org.apache.felix.moduleloader.IWire;
+import org.apache.felix.moduleloader.ResourceNotFoundException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class ModuleClassLoader extends SecureClassLoader
+{
+ private static final Constructor m_dexFileClassConstructor;
+ private static final Method m_dexFileClassLoadClass;
+ static
+ {
+ Constructor dexFileClassConstructor = null;
+ Method dexFileClassLoadClass = null;
+ try
+ {
+ Class dexFileClass;
+ try
+ {
+ dexFileClass = Class.forName("dalvik.system.DexFile");
+ }
+ catch (Exception ex)
+ {
+ dexFileClass = Class.forName("android.dalvik.DexFile");
+ }
+
+ dexFileClassConstructor = dexFileClass.getConstructor(
+ new Class[] { java.io.File.class });
+ dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
+ new Class[] { String.class, ClassLoader.class });
+ }
+ catch (Exception ex)
+ {
+ dexFileClassConstructor = null;
+ dexFileClassLoadClass = null;
+ }
+ m_dexFileClassConstructor = dexFileClassConstructor;
+ m_dexFileClassLoadClass = dexFileClassLoadClass;
+ }
+
+ private final ModuleImpl m_module;
+ private final ProtectionDomain m_protectionDomain;
+ private final Map m_jarContentToDexFile;
+
+ public ModuleClassLoader(ModuleImpl module, ProtectionDomain protectionDomain)
+ {
+ m_module = module;
+ m_protectionDomain = protectionDomain;
+ if (m_dexFileClassConstructor != null)
+ {
+ m_jarContentToDexFile = new HashMap();
+ }
+ else
+ {
+ m_jarContentToDexFile = null;
+ }
+ }
+
+ public IModule getModule()
+ {
+ return m_module;
+ }
+
+ protected Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ Class clazz = null;
+
+ // Make sure the class was not already loaded.
+ synchronized (this)
+ {
+ clazz = findLoadedClass(name);
+ }
+
+ if (clazz == null)
+ {
+ try
+ {
+ return (Class) m_module.findClassOrResourceByDelegation(name, true);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ // This should never happen since we are asking for a class,
+ // so just ignore it.
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ ClassNotFoundException ex = cnfe;
+ String msg = name;
+ if (m_module.getLogger().getLogLevel() >= Logger.LOG_DEBUG)
+ {
+ msg = diagnoseClassLoadError(m_module, name);
+ ex = new ClassNotFoundException(msg, cnfe);
+ }
+ throw ex;
+ }
+ }
+
+ // Resolve the class and return it.
+ if (resolve)
+ {
+ resolveClass(clazz);
+ }
+ return clazz;
+ }
+
+ protected Class findClass(String name) throws ClassNotFoundException
+ {
+ // Do a quick check here to see if we can short-circuit this
+ // entire process if the class was already loaded.
+ Class clazz = null;
+ synchronized (this)
+ {
+ clazz = findLoadedClass(name);
+ }
+
+ // Search for class in module.
+ if (clazz == null)
+ {
+ String actual = name.replace('.', '/') + ".class";
+
+ byte[] bytes = null;
+
+ IContent content = null;
+ // Check the module class path.
+ for (int i = 0;
+ (bytes == null) &&
+ (i < m_module.getClassPath().length); i++)
+ {
+ bytes = m_module.getClassPath()[i].getEntryAsBytes(actual);
+ content = m_module.getClassPath()[i];
+ }
+
+ if (bytes != null)
+ {
+ // Before we actually attempt to define the class, grab
+ // the lock for this class loader and make sure than no
+ // other thread has defined this class in the meantime.
+ synchronized (this)
+ {
+ clazz = findLoadedClass(name);
+
+ if (clazz == null)
+ {
+ // We need to try to define a Package object for the class
+ // before we call defineClass(). Get the package name and
+ // see if we have already created the package.
+ String pkgName = Util.getClassPackage(name);
+ if (pkgName.length() > 0)
+ {
+ if (getPackage(pkgName) == null)
+ {
+ Object[] params = definePackage(pkgName);
+ if (params != null)
+ {
+ definePackage(
+ pkgName,
+ (String) params[0],
+ (String) params[1],
+ (String) params[2],
+ (String) params[3],
+ (String) params[4],
+ (String) params[5],
+ null);
+ }
+ else
+ {
+ definePackage(pkgName, null, null,
+ null, null, null, null, null);
+ }
+ }
+ }
+
+ // If we can load the class from a dex file do so
+ if (content instanceof JarContent)
+ {
+ try
+ {
+ clazz = getDexFileClass((JarContent) content, name, this);
+ }
+ catch (Exception ex)
+ {
+ // Looks like we can't
+ }
+ }
+
+ if (clazz == null)
+ {
+ // If we have a security context, then use it to
+ // define the class with it for security purposes,
+ // otherwise define the class without a protection domain.
+ if (m_protectionDomain != null)
+ {
+ clazz = defineClass(name, bytes, 0, bytes.length,
+ m_protectionDomain);
+ }
+ else
+ {
+ clazz = defineClass(name, bytes, 0, bytes.length);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return clazz;
+ }
+
+ private Object[] definePackage(String pkgName)
+ {
+ Map headerMap = m_module.getHeaders();
+ String spectitle = (String) headerMap.get("Specification-Title");
+ String specversion = (String) headerMap.get("Specification-Version");
+ String specvendor = (String) headerMap.get("Specification-Vendor");
+ String impltitle = (String) headerMap.get("Implementation-Title");
+ String implversion = (String) headerMap.get("Implementation-Version");
+ String implvendor = (String) headerMap.get("Implementation-Vendor");
+ if ((spectitle != null)
+ || (specversion != null)
+ || (specvendor != null)
+ || (impltitle != null)
+ || (implversion != null)
+ || (implvendor != null))
+ {
+ return new Object[] {
+ spectitle, specversion, specvendor, impltitle, implversion, implvendor
+ };
+ }
+ return null;
+ }
+
+ private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
+ throws Exception
+ {
+ if (m_jarContentToDexFile == null)
+ {
+ return null;
+ }
+
+ Object dexFile = null;
+
+ if (!m_jarContentToDexFile.containsKey(content))
+ {
+ try
+ {
+ dexFile = m_dexFileClassConstructor.newInstance(
+ new Object[] { content.getFile() });
+ }
+ finally
+ {
+ m_jarContentToDexFile.put(content, dexFile);
+ }
+ }
+ else
+ {
+ dexFile = m_jarContentToDexFile.get(content);
+ }
+
+ if (dexFile != null)
+ {
+ return (Class) m_dexFileClassLoadClass.invoke(dexFile,
+ new Object[] { name.replace('.','/'), loader });
+ }
+ return null;
+ }
+
+ public URL getResource(String name)
+ {
+ try
+ {
+ return (URL) m_module.findClassOrResourceByDelegation(name, false);
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // This should never happen, so just ignore it.
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ // Not much we can do here since getResource() does not throw any
+ // exceptions, so just ignore it too.
+ }
+ return null;
+ }
+
+ protected URL findResource(String name)
+ {
+ return m_module.getResourceFromModule(name);
+ }
+
+ // This should actually be findResources(), but it can't be for the
+ // reason described below for the actual findResources() method.
+ Enumeration findResourcesFromModule(String name)
+ {
+ return m_module.getResourcesFromModule(name);
+ }
+
+ // The findResources() method should only look at the module itself, but
+ // instead it tries to delegate because in Java version prior to 1.5 the
+ // getResources() method was final and could not be overridden. We should
+ // override getResources() like getResource() to make it delegate, but we
+ // can't. As a workaround, we make findResources() delegate instead.
+ protected Enumeration findResources(String name)
+ {
+ return m_module.getResourcesByDelegation(name);
+ }
+
+ protected String findLibrary(String name)
+ {
+ // Remove leading slash, if present.
+ if (name.startsWith("/"))
+ {
+ name = name.substring(1);
+ }
+
+ R4Library[] libs = m_module.getNativeLibraries();
+ for (int i = 0; (libs != null) && (i < libs.length); i++)
+ {
+ if (libs[i].match(name))
+ {
+ return m_module.getContent()
+ .getEntryAsNativeLibrary(libs[i].getEntryName());
+ }
+ }
+
+ return null;
+ }
+
+ public String toString()
+ {
+ return m_module.toString();
+ }
+
+ private static String diagnoseClassLoadError(ModuleImpl module, String name)
+ {
+ // We will try to do some diagnostics here to help the developer
+ // deal with this exception.
+
+ // Get package name.
+ String pkgName = Util.getClassPackage(name);
+
+ // First, get the bundle ID of the module doing the class loader.
+ long impId = Util.getBundleIdFromModuleId(module.getId());
+
+ // Next, check to see if the module imports the package.
+ IWire[] wires = module.getWires();
+ for (int i = 0; (wires != null) && (i < wires.length); i++)
+ {
+ if (wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
+ wires[i].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
+ {
+ long expId = Util.getBundleIdFromModuleId(wires[i].getExporter().getId());
+
+ StringBuffer sb = new StringBuffer("*** Package '");
+ sb.append(pkgName);
+ sb.append("' is imported by bundle ");
+ sb.append(impId);
+ sb.append(" from bundle ");
+ sb.append(expId);
+ sb.append(", but the exported package from bundle ");
+ sb.append(expId);
+ sb.append(" does not contain the requested class '");
+ sb.append(name);
+ sb.append("'. Please verify that the class name is correct in the importing bundle ");
+ sb.append(impId);
+ sb.append(" and/or that the exported package is correctly bundled in ");
+ sb.append(expId);
+ sb.append(". ***");
+
+ return sb.toString();
+ }
+ }
+
+ // Next, check to see if the package was optionally imported and
+ // whether or not there is an exporter available.
+ IRequirement[] reqs = module.getRequirements();
+/*
+ * TODO: RB - Fix diagnostic message for optional imports.
+ for (int i = 0; (reqs != null) && (i < reqs.length); i++)
+ {
+ if (reqs[i].getName().equals(pkgName) && reqs[i].isOptional())
+ {
+ // Try to see if there is an exporter available.
+ IModule[] exporters = getResolvedExporters(reqs[i], true);
+ exporters = (exporters.length == 0)
+ ? getUnresolvedExporters(reqs[i], true) : exporters;
+
+ // An exporter might be available, but it may have attributes
+ // that do not match the importer's required attributes, so
+ // check that case by simply looking for an exporter of the
+ // desired package without any attributes.
+ if (exporters.length == 0)
+ {
+ IRequirement pkgReq = new Requirement(
+ ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+ exporters = getResolvedExporters(pkgReq, true);
+ exporters = (exporters.length == 0)
+ ? getUnresolvedExporters(pkgReq, true) : exporters;
+ }
+
+ long expId = (exporters.length == 0)
+ ? -1 : Util.getBundleIdFromModuleId(exporters[0].getId());
+
+ StringBuffer sb = new StringBuffer("*** Class '");
+ sb.append(name);
+ sb.append("' was not found, but this is likely normal since package '");
+ sb.append(pkgName);
+ sb.append("' is optionally imported by bundle ");
+ sb.append(impId);
+ sb.append(".");
+ if (exporters.length > 0)
+ {
+ sb.append(" However, bundle ");
+ sb.append(expId);
+ if (reqs[i].isSatisfied(
+ Util.getExportPackage(exporters[0], reqs[i].getName())))
+ {
+ sb.append(" does export this package. Bundle ");
+ sb.append(expId);
+ sb.append(" must be installed before bundle ");
+ sb.append(impId);
+ sb.append(" is resolved or else the optional import will be ignored.");
+ }
+ else
+ {
+ sb.append(" does export this package with attributes that do not match.");
+ }
+ }
+ sb.append(" ***");
+
+ return sb.toString();
+ }
+ }
+*/
+ // Next, check to see if the package is dynamically imported by the module.
+/* TODO: RESOLVER: Need to fix this too.
+ IRequirement[] dynamics = module.getDefinition().getDynamicRequirements();
+ for (int dynIdx = 0; dynIdx < dynamics.length; dynIdx++)
+ {
+ IRequirement target = createDynamicRequirement(dynamics[dynIdx], pkgName);
+ if (target != null)
+ {
+ // Try to see if there is an exporter available.
+ PackageSource[] exporters = getResolvedCandidates(target);
+ exporters = (exporters.length == 0)
+ ? getUnresolvedCandidates(target) : exporters;
+
+ // An exporter might be available, but it may have attributes
+ // that do not match the importer's required attributes, so
+ // check that case by simply looking for an exporter of the
+ // desired package without any attributes.
+ if (exporters.length == 0)
+ {
+ try
+ {
+ IRequirement pkgReq = new Requirement(
+ ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+ exporters = getResolvedCandidates(pkgReq);
+ exporters = (exporters.length == 0)
+ ? getUnresolvedCandidates(pkgReq) : exporters;
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // This should never happen.
+ }
+ }
+
+ long expId = (exporters.length == 0)
+ ? -1 : Util.getBundleIdFromModuleId(exporters[0].m_module.getId());
+
+ StringBuffer sb = new StringBuffer("*** Class '");
+ sb.append(name);
+ sb.append("' was not found, but this is likely normal since package '");
+ sb.append(pkgName);
+ sb.append("' is dynamically imported by bundle ");
+ sb.append(impId);
+ sb.append(".");
+ if (exporters.length > 0)
+ {
+ try
+ {
+ if (!target.isSatisfied(
+ Util.getSatisfyingCapability(exporters[0].m_module,
+ new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")"))))
+ {
+ sb.append(" However, bundle ");
+ sb.append(expId);
+ sb.append(" does export this package with attributes that do not match.");
+ }
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // This should never happen.
+ }
+ }
+ sb.append(" ***");
+
+ return sb.toString();
+ }
+ }
+*/
+ IRequirement pkgReq = null;
+ try
+ {
+ pkgReq = new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+ }
+ catch (InvalidSyntaxException ex)
+ {
+ // This should never happen.
+ }
+ PackageSource[] exporters =
+ module.getResolver().getResolvedCandidates(pkgReq);
+ exporters = (exporters.length == 0)
+ ? module.getResolver().getUnresolvedCandidates(pkgReq)
+ : exporters;
+ if (exporters.length > 0)
+ {
+ boolean classpath = false;
+ try
+ {
+ ModuleClassLoader.class.getClassLoader().loadClass(name);
+ classpath = true;
+ }
+ catch (NoClassDefFoundError err)
+ {
+ // Ignore
+ }
+ catch (Exception ex)
+ {
+ // Ignore
+ }
+
+ long expId = Util.getBundleIdFromModuleId(exporters[0].m_module.getId());
+
+ StringBuffer sb = new StringBuffer("*** Class '");
+ sb.append(name);
+ sb.append("' was not found because bundle ");
+ sb.append(impId);
+ sb.append(" does not import '");
+ sb.append(pkgName);
+ sb.append("' even though bundle ");
+ sb.append(expId);
+ sb.append(" does export it.");
+ if (classpath)
+ {
+ sb.append(" Additionally, the class is also available from the system class loader. There are two fixes: 1) Add an import for '");
+ sb.append(pkgName);
+ sb.append("' to bundle ");
+ sb.append(impId);
+ sb.append("; imports are necessary for each class directly touched by bundle code or indirectly touched, such as super classes if their methods are used. ");
+ sb.append("2) Add package '");
+ sb.append(pkgName);
+ sb.append("' to the '");
+ sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+ sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+ }
+ else
+ {
+ sb.append(" To resolve this issue, add an import for '");
+ sb.append(pkgName);
+ sb.append("' to bundle ");
+ sb.append(impId);
+ sb.append(".");
+ }
+ sb.append(" ***");
+
+ return sb.toString();
+ }
+
+ // Next, try to see if the class is available from the system
+ // class loader.
+ try
+ {
+ ModuleClassLoader.class.getClassLoader().loadClass(name);
+
+ StringBuffer sb = new StringBuffer("*** Package '");
+ sb.append(pkgName);
+ sb.append("' is not imported by bundle ");
+ sb.append(impId);
+ sb.append(", nor is there any bundle that exports package '");
+ sb.append(pkgName);
+ sb.append("'. However, the class '");
+ sb.append(name);
+ sb.append("' is available from the system class loader. There are two fixes: 1) Add package '");
+ sb.append(pkgName);
+ sb.append("' to the '");
+ sb.append(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+ sb.append("' property and modify bundle ");
+ sb.append(impId);
+ sb.append(" to import this package; this causes the system bundle to export class path packages. 2) Add package '");
+ sb.append(pkgName);
+ sb.append("' to the '");
+ sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+ sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+ sb.append(" ***");
+
+ return sb.toString();
+ }
+ catch (Exception ex2)
+ {
+ }
+
+ // Finally, if there are no imports or exports for the package
+ // and it is not available on the system class path, simply
+ // log a message saying so.
+ StringBuffer sb = new StringBuffer("*** Class '");
+ sb.append(name);
+ sb.append("' was not found. Bundle ");
+ sb.append(impId);
+ sb.append(" does not import package '");
+ sb.append(pkgName);
+ sb.append("', nor is the package exported by any other bundle or available from the system class loader.");
+ sb.append(" ***");
+
+ return sb.toString();
+ }
+}
\ No newline at end of file