use of org.apache.felix.framework.cache.JarContent in project felix by apache.
the class ExtensionManager method resolveExtensionBundles.
public List<Bundle> resolveExtensionBundles(Felix felix) {
if (m_unresolvedExtensions.isEmpty()) {
return Collections.emptyList();
}
// Collect the highest version of unresolved that are not already resolved by bsn
List<BundleRevisionImpl> extensions = new ArrayList<BundleRevisionImpl>();
// Collect the unresolved that where filtered out as alternatives in case the highest version doesn't resolve
List<BundleRevisionImpl> alt = new ArrayList<BundleRevisionImpl>();
outer: for (BundleRevisionImpl revision : m_unresolvedExtensions) {
// Already resolved by bsn?
for (BundleRevisionImpl existing : m_resolvedExtensions) {
if (existing.getSymbolicName().equals(revision.getSymbolicName())) {
// Then ignore it
continue outer;
}
}
// Otherwise, does a higher version exist by bsn?
for (BundleRevisionImpl other : m_unresolvedExtensions) {
if ((revision != other) && (revision.getSymbolicName().equals(other.getSymbolicName())) && revision.getVersion().compareTo(other.getVersion()) < 0) {
// Add this one to alternatives and filter it
alt.add(revision);
continue outer;
}
}
// no higher version and not resolved yet by bsn - try to resolve it
extensions.add(revision);
}
// This will return all resolvable revisions with the wires they need
Map<BundleRevisionImpl, List<BundleWire>> wirings = findResolvableExtensions(extensions, alt);
List<Bundle> result = new ArrayList<Bundle>();
for (Map.Entry<BundleRevisionImpl, List<BundleWire>> entry : wirings.entrySet()) {
BundleRevisionImpl revision = entry.getKey();
// move this revision from unresolved to resolved
m_unresolvedExtensions.remove(revision);
m_resolvedExtensions.add(revision);
BundleWire wire = new BundleWireImpl(revision, revision.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE).get(0), m_systemBundleRevision, getCapabilities(BundleRevision.HOST_NAMESPACE).get(0));
try {
revision.resolve(new BundleWiringImpl(m_logger, m_configMap, null, revision, null, Collections.singletonList(wire), Collections.EMPTY_MAP, Collections.EMPTY_MAP));
} catch (Exception ex) {
m_logger.log(revision.getBundle(), Logger.LOG_ERROR, "Error resolving extension bundle : " + revision.getBundle(), ex);
}
felix.getDependencies().addDependent(wire);
appendCapabilities(entry.getKey().getDeclaredExtensionCapabilities(null));
for (BundleWire w : entry.getValue()) {
if (!w.getRequirement().getNamespace().equals(BundleRevision.HOST_NAMESPACE) && !w.getRequirement().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)) {
((BundleWiringImpl) w.getRequirer().getWiring()).addDynamicWire(w);
felix.getDependencies().addDependent(w);
}
}
final File f;
Content revisionContent = revision.getContent();
if (revisionContent instanceof JarContent) {
f = ((JarContent) revisionContent).getFile();
} else {
f = ((DirectoryContent) revisionContent).getFile();
}
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
m_extenderFramework.add(f);
return null;
}
});
} catch (Exception ex) {
m_logger.log(revision.getBundle(), Logger.LOG_ERROR, "Error adding extension bundle to framework classloader: " + revision.getBundle(), ex);
}
felix.setBundleStateAndNotify(revision.getBundle(), Bundle.RESOLVED);
result.add(revision.getBundle());
}
// at this point, all revisions left in unresolved are not resolvable
m_failedExtensions.addAll(m_unresolvedExtensions);
m_unresolvedExtensions.clear();
if (!wirings.isEmpty()) {
felix.getResolver().addRevision(getRevision());
}
return result;
}
use of org.apache.felix.framework.cache.JarContent in project felix by apache.
the class ExtensionManager method addExtensionBundle.
/**
* Add an extension bundle. The bundle will be added to the parent classloader
* and it's exported packages will be added to the module definition
* exports of this instance. Subsequently, they are available form the
* instance in it's role as content loader.
*
* @param felix the framework instance the given extension bundle comes from.
* @param bundle the extension bundle to add.
* @throws BundleException if extension bundles are not supported or this is
* not a framework extension.
* @throws SecurityException if the caller does not have the needed
* AdminPermission.EXTENSIONLIFECYCLE and security is enabled.
* @throws Exception in case something goes wrong.
*/
synchronized void addExtensionBundle(Felix felix, BundleImpl bundle) throws Exception {
Object sm = System.getSecurityManager();
if (sm != null) {
((SecurityManager) sm).checkPermission(new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
if (!((BundleProtectionDomain) bundle.getProtectionDomain()).impliesDirect(new AllPermission())) {
throw new SecurityException("Extension Bundles must have AllPermission");
}
}
String directive = ManifestParser.parseExtensionBundleHeader((String) ((BundleRevisionImpl) bundle.adapt(BundleRevision.class)).getHeaders().get(Constants.FRAGMENT_HOST));
final ClassPathExtenderFactory.ClassPathExtender extender;
if (!Constants.EXTENSION_FRAMEWORK.equals(directive)) {
throw new BundleException("Unsupported Extension Bundle type: " + directive, new UnsupportedOperationException("Unsupported Extension Bundle type!"));
} else if (m_extenderFramework == null) {
// We don't support extensions
m_logger.log(bundle, Logger.LOG_WARNING, "Unable to add extension bundle - Maybe ClassLoader is not supported (on java9, try --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED)?");
throw new UnsupportedOperationException("Unable to add extension bundle.");
}
Content content = bundle.adapt(BundleRevisionImpl.class).getContent();
final File file;
if (content instanceof JarContent) {
file = ((JarContent) content).getFile();
} else if (content instanceof DirectoryContent) {
file = ((DirectoryContent) content).getFile();
} else {
file = null;
}
if (file == null) {
// We don't support revision type for extension
m_logger.log(bundle, Logger.LOG_WARNING, "Unable to add extension bundle - wrong revision type?");
throw new UnsupportedOperationException("Unable to add extension bundle.");
}
BundleRevisionImpl bri = bundle.adapt(BundleRevisionImpl.class);
bri.resolve(null);
// we have to try again for all previously failed extensions because maybe they can now resolve.
m_unresolvedExtensions.addAll(m_failedExtensions);
m_failedExtensions.clear();
m_unresolvedExtensions.add(bri);
}
Aggregations