Пример #1
0
 public final synchronized BundleClassLoader createClassLoader() {
   if (classloader != null) return classloader;
   String[] classpath;
   try {
     classpath = bundle.getBundleData().getClassPath();
   } catch (BundleException e) {
     // no classpath
     classpath = new String[0];
     bundle.getFramework().publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
   }
   if (classpath == null) {
     // no classpath
     classpath = new String[0];
     bundle
         .getFramework()
         .publishFrameworkEvent(
             FrameworkEvent.ERROR,
             bundle,
             new BundleException(Msg.BUNDLE_NO_CLASSPATH_MATCH, BundleException.MANIFEST_ERROR));
   }
   BundleClassLoader bcl = createBCLPrevileged(bundle.getProtectionDomain(), classpath);
   parent = getParentPrivileged(bcl);
   classloader = bcl;
   return classloader;
 }
Пример #2
0
  final String findLocalLibrary(final String name) {
    String result = null;
    try {
      result = (String) searchHooks(name, PRE_LIBRARY);
    } catch (FileNotFoundException e) {
      return null;
    } catch (ClassNotFoundException e) {
      // will not happen
    }
    if (result != null) return result;
    result = bundle.getBundleData().findLibrary(name);
    if (result != null) return result;

    // look in fragments imports ...
    BundleFragment[] fragments = bundle.getFragments();
    if (fragments != null)
      for (int i = 0; i < fragments.length; i++) {
        result = fragments[i].getBundleData().findLibrary(name);
        if (result != null) return result;
      }
    try {
      return (String) searchHooks(name, POST_LIBRARY);
    } catch (FileNotFoundException e) {
      return null; // this is not necessary; but being consistent in case another step is added
      // below
    } catch (ClassNotFoundException e) {
      // will not happen
    }
    return null;
  }
Пример #3
0
 /*
  * get the loader proxy for a bundle description
  */
 public final BundleLoaderProxy getLoaderProxy(BundleDescription source) {
   BundleLoaderProxy sourceProxy = (BundleLoaderProxy) source.getUserObject();
   if (sourceProxy == null) {
     // may need to force the proxy to be created
     long exportingID = source.getBundleId();
     BundleHost exportingBundle = (BundleHost) bundle.getFramework().getBundle(exportingID);
     if (exportingBundle == null) return null;
     sourceProxy = exportingBundle.getLoaderProxy();
   }
   return sourceProxy;
 }
Пример #4
0
  BundleClassLoader createBCL(final BundleProtectionDomain pd, final String[] cp) {
    BundleClassLoader bcl = bundle.getBundleData().createClassLoader(BundleLoader.this, pd, cp);
    // attach existing fragments to classloader
    BundleFragment[] fragments = bundle.getFragments();
    if (fragments != null)
      for (int i = 0; i < fragments.length; i++) {
        try {
          bcl.attachFragment(
              fragments[i].getBundleData(),
              fragments[i].getProtectionDomain(),
              fragments[i].getBundleData().getClassPath());
        } catch (BundleException be) {
          bundle.getFramework().publishFrameworkEvent(FrameworkEvent.ERROR, bundle, be);
        }
      }

    // finish the initialization of the classloader.
    bcl.initialize();
    return bcl;
  }
Пример #5
0
 private boolean isRequestFromVM() {
   if (bundle.getFramework().isBootDelegationPackage("*")
       || !bundle.getFramework().contextBootDelegation) // $NON-NLS-1$
   return false;
   // works around VM bugs that require all classloaders to have access to parent packages
   Class[] context = CLASS_CONTEXT.getClassContext();
   if (context == null || context.length < 2) return false;
   // skip the first class; it is the ClassContext class
   for (int i = 1; i < context.length; i++)
     // find the first class in the context which is not BundleLoader or instanceof ClassLoader
     if (context[i] != BundleLoader.class && !ClassLoader.class.isAssignableFrom(context[i])) {
       // only find in parent if the class is not "Class" (Class#forName case) or if the class is
       // not loaded with a BundleClassLoader
       ClassLoader cl = getClassLoader(context[i]);
       if (cl
           != FW_CLASSLOADER) { // extra check incase an adaptor adds another class into the stack
         // besides an instance of ClassLoader
         if (Class.class != context[i] && !(cl instanceof BundleClassLoader)) return true;
         break;
       }
     }
   return false;
 }
Пример #6
0
 private Object searchHooks(String name, int type)
     throws ClassNotFoundException, FileNotFoundException {
   ClassLoaderDelegateHook[] delegateHooks = bundle.getFramework().getDelegateHooks();
   if (delegateHooks == null) return null;
   Object result = null;
   for (int i = 0; i < delegateHooks.length && result == null; i++) {
     switch (type) {
       case PRE_CLASS:
         result = delegateHooks[i].preFindClass(name, createClassLoader(), bundle.getBundleData());
         break;
       case POST_CLASS:
         result =
             delegateHooks[i].postFindClass(name, createClassLoader(), bundle.getBundleData());
         break;
       case PRE_RESOURCE:
         result =
             delegateHooks[i].preFindResource(name, createClassLoader(), bundle.getBundleData());
         break;
       case POST_RESOURCE:
         result =
             delegateHooks[i].postFindResource(name, createClassLoader(), bundle.getBundleData());
         break;
       case PRE_RESOURCES:
         result =
             delegateHooks[i].preFindResources(name, createClassLoader(), bundle.getBundleData());
         break;
       case POST_RESOURCES:
         result =
             delegateHooks[i].postFindResources(name, createClassLoader(), bundle.getBundleData());
         break;
       case PRE_LIBRARY:
         result =
             delegateHooks[i].preFindLibrary(name, createClassLoader(), bundle.getBundleData());
         break;
       case POST_LIBRARY:
         result =
             delegateHooks[i].postFindLibrary(name, createClassLoader(), bundle.getBundleData());
         break;
     }
   }
   return result;
 }
Пример #7
0
 /*
  * This method is used by Bundle.getResources to do proper parent delegation.
  */
 public Enumeration getResources(String name) throws IOException {
   if ((name.length() > 1) && (name.charAt(0) == '/')) /* if name has a leading slash */
     name = name.substring(1); /* remove leading slash before search */
   String pkgName = getResourcePackageName(name);
   // follow the OSGi delegation model
   // First check the parent classloader for system resources, if it is a java resource.
   Enumeration result = null;
   if (pkgName.startsWith(JAVA_PACKAGE)
       || bundle.getFramework().isBootDelegationPackage(pkgName)) {
     // 1) if startsWith "java." delegate to parent and terminate search
     // 2) if part of the bootdelegation list then delegate to parent and continue of failure
     ClassLoader parentCL = getParentClassLoader();
     result = parentCL == null ? null : parentCL.getResources(name);
     if (pkgName.startsWith(JAVA_PACKAGE)) return result;
   }
   return compoundEnumerations(result, findResources(name));
 }
Пример #8
0
 private PackageSource findDynamicSource(String pkgName) {
   if (isDynamicallyImported(pkgName)) {
     ExportPackageDescription exportPackage =
         bundle
             .getFramework()
             .getAdaptor()
             .getState()
             .linkDynamicImport(proxy.getBundleDescription(), pkgName);
     if (exportPackage != null) {
       PackageSource source = createExportPackageSource(exportPackage, null);
       synchronized (this) {
         if (importedSources == null) importedSources = new KeyedHashSet(false);
       }
       synchronized (importedSources) {
         importedSources.add(source);
       }
       return source;
     }
   }
   return null;
 }
Пример #9
0
 /**
  * Return a string representation of this loader.
  *
  * @return String
  */
 public final String toString() {
   BundleData result = bundle.getBundleData();
   return result == null ? "BundleLoader.bundledata == null!" : result.toString(); // $NON-NLS-1$
 }
Пример #10
0
  URL findResource(String name, boolean checkParent) {
    if ((name.length() > 1) && (name.charAt(0) == '/')) /* if name has a leading slash */
      name = name.substring(1); /* remove leading slash before search */
    String pkgName = getResourcePackageName(name);
    boolean bootDelegation = false;
    ClassLoader parentCL = getParentClassLoader();
    // follow the OSGi delegation model
    // First check the parent classloader for system resources, if it is a java resource.
    if (checkParent && parentCL != null) {
      if (pkgName.startsWith(JAVA_PACKAGE))
        // 1) if startsWith "java." delegate to parent and terminate search
        // we never delegate java resource requests past the parent
        return parentCL.getResource(name);
      else if (bundle.getFramework().isBootDelegationPackage(pkgName)) {
        // 2) if part of the bootdelegation list then delegate to parent and continue of failure
        URL result = parentCL.getResource(name);
        if (result != null) return result;
        bootDelegation = true;
      }
    }

    URL result = null;
    try {
      result = (URL) searchHooks(name, PRE_RESOURCE);
    } catch (FileNotFoundException e) {
      return null;
    } catch (ClassNotFoundException e) {
      // will not happen
    }
    if (result != null) return result;
    // 3) search the imported packages
    PackageSource source = findImportedSource(pkgName, null);
    if (source != null)
      // 3) found import source terminate search at the source
      return source.getResource(name);
    // 4) search the required bundles
    source = findRequiredSource(pkgName, null);
    if (source != null)
      // 4) attempt to load from source but continue on failure
      result = source.getResource(name);
    // 5) search the local bundle
    if (result == null) result = findLocalResource(name);
    if (result != null) return result;
    // 6) attempt to find a dynamic import source; only do this if a required source was not found
    if (source == null) {
      source = findDynamicSource(pkgName);
      if (source != null)
        // must return the result of the dynamic import and do not continue
        return source.getResource(name);
    }

    if (result == null)
      try {
        result = (URL) searchHooks(name, POST_RESOURCE);
      } catch (FileNotFoundException e) {
        return null;
      } catch (ClassNotFoundException e) {
        // will not happen
      }
    // do buddy policy loading
    if (result == null && policy != null) result = policy.doBuddyResourceLoading(name);
    if (result != null) return result;
    // hack to support backwards compatibiility for bootdelegation
    // or last resort; do class context trick to work around VM bugs
    if (parentCL != null
        && !bootDelegation
        && ((checkParent && bundle.getFramework().compatibiltyBootDelegation) || isRequestFromVM()))
      // we don't need to continue if the resource is not found here
      return parentCL.getResource(name);
    return result;
  }
Пример #11
0
  private Class findClassInternal(String name, boolean checkParent, ClassLoader parentCL)
      throws ClassNotFoundException {
    if (Debug.DEBUG && Debug.DEBUG_LOADER)
      Debug.println(
          "BundleLoader["
              + this
              + "].loadBundleClass("
              + name
              + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    String pkgName = getPackageName(name);
    boolean bootDelegation = false;
    // follow the OSGi delegation model
    if (checkParent && parentCL != null && bundle.getFramework().isBootDelegationPackage(pkgName))
      // 2) if part of the bootdelegation list then delegate to parent and continue of failure
      try {
        return parentCL.loadClass(name);
      } catch (ClassNotFoundException cnfe) {
        // we want to continue
        bootDelegation = true;
      }
    Class result = null;
    try {
      result = (Class) searchHooks(name, PRE_CLASS);
    } catch (ClassNotFoundException e) {
      throw e;
    } catch (FileNotFoundException e) {
      // will not happen
    }
    if (result != null) return result;
    // 3) search the imported packages
    PackageSource source = findImportedSource(pkgName, null);
    if (source != null) {
      // 3) found import source terminate search at the source
      result = source.loadClass(name);
      if (result != null) return result;
      throw new ClassNotFoundException(name);
    }
    // 4) search the required bundles
    source = findRequiredSource(pkgName, null);
    if (source != null)
      // 4) attempt to load from source but continue on failure
      result = source.loadClass(name);
    // 5) search the local bundle
    if (result == null) result = findLocalClass(name);
    if (result != null) return result;
    // 6) attempt to find a dynamic import source; only do this if a required source was not found
    if (source == null) {
      source = findDynamicSource(pkgName);
      if (source != null) {
        result = source.loadClass(name);
        if (result != null) return result;
        // must throw CNFE if dynamic import source does not have the class
        throw new ClassNotFoundException(name);
      }
    }

    if (result == null)
      try {
        result = (Class) searchHooks(name, POST_CLASS);
      } catch (ClassNotFoundException e) {
        throw e;
      } catch (FileNotFoundException e) {
        // will not happen
      }
    // do buddy policy loading
    if (result == null && policy != null) result = policy.doBuddyClassLoading(name);
    if (result != null) return result;
    // hack to support backwards compatibiility for bootdelegation
    // or last resort; do class context trick to work around VM bugs
    if (parentCL != null
        && !bootDelegation
        && ((checkParent && bundle.getFramework().compatibiltyBootDelegation) || isRequestFromVM()))
      // we don't need to continue if a CNFE is thrown here.
      try {
        return parentCL.loadClass(name);
      } catch (ClassNotFoundException e) {
        // we want to generate our own exception below
      }
    throw new ClassNotFoundException(name);
  }
Пример #12
0
 /*
  * Close the the BundleLoader.
  *
  */
 synchronized void close() {
   if ((loaderFlags & FLAG_CLOSED) != 0) return;
   if (classloader != null) classloader.close();
   if (policy != null) policy.close(bundle.getFramework().getSystemBundleContext());
   loaderFlags |= FLAG_CLOSED; /* This indicates the BundleLoader is destroyed */
 }
Пример #13
0
  /**
   * BundleLoader runtime constructor. This object is created lazily when the first request for a
   * resource is made to this bundle.
   *
   * @param bundle Bundle object for this loader.
   * @param proxy the BundleLoaderProxy for this loader.
   * @exception org.osgi.framework.BundleException
   */
  protected BundleLoader(BundleHost bundle, BundleLoaderProxy proxy) throws BundleException {
    this.bundle = bundle;
    this.proxy = proxy;
    try {
      bundle.getBundleData().open(); /* make sure the BundleData is open */
    } catch (IOException e) {
      throw new BundleException(Msg.BUNDLE_READ_EXCEPTION, e);
    }
    BundleDescription description = proxy.getBundleDescription();
    // init the require bundles list.
    BundleDescription[] required = description.getResolvedRequires();
    if (required.length > 0) {
      // get a list of re-exported symbolic names
      HashSet reExportSet = new HashSet(required.length);
      BundleSpecification[] requiredSpecs = description.getRequiredBundles();
      if (requiredSpecs != null && requiredSpecs.length > 0)
        for (int i = 0; i < requiredSpecs.length; i++)
          if (requiredSpecs[i].isExported()) reExportSet.add(requiredSpecs[i].getName());

      requiredBundles = new BundleLoaderProxy[required.length];
      int[] reexported = new int[required.length];
      int reexportIndex = 0;
      for (int i = 0; i < required.length; i++) {
        requiredBundles[i] = getLoaderProxy(required[i]);
        if (reExportSet.contains(required[i].getSymbolicName())) reexported[reexportIndex++] = i;
      }
      if (reexportIndex > 0) {
        reexportTable = new int[reexportIndex];
        System.arraycopy(reexported, 0, reexportTable, 0, reexportIndex);
      } else {
        reexportTable = null;
      }
      requiredSources = new KeyedHashSet(10, false);
    } else {
      requiredBundles = null;
      reexportTable = null;
      requiredSources = null;
    }

    // init the provided packages set
    ExportPackageDescription[] exports = description.getSelectedExports();
    if (exports != null && exports.length > 0) {
      exportedPackages =
          Collections.synchronizedCollection(
              exports.length > 10
                  ? (Collection) new HashSet(exports.length)
                  : new ArrayList(exports.length));
      initializeExports(exports, exportedPackages);
    } else {
      exportedPackages = Collections.synchronizedCollection(new ArrayList(0));
    }

    ExportPackageDescription substituted[] = description.getSubstitutedExports();
    if (substituted.length > 0) {
      substitutedPackages =
          substituted.length > 10
              ? (Collection) new HashSet(substituted.length)
              : new ArrayList(substituted.length);
      for (int i = 0; i < substituted.length; i++)
        substitutedPackages.add(substituted[i].getName());
    } else {
      substitutedPackages = null;
    }

    // This is the fastest way to access to the description for fragments since the
    // hostdescription.getFragments() is slow
    BundleFragment[] fragmentObjects = bundle.getFragments();
    BundleDescription[] fragments =
        new BundleDescription[fragmentObjects == null ? 0 : fragmentObjects.length];
    for (int i = 0; i < fragments.length; i++)
      fragments[i] = fragmentObjects[i].getBundleDescription();
    // init the dynamic imports tables
    if (description.hasDynamicImports()) addDynamicImportPackage(description.getImportPackages());
    // ...and its fragments
    for (int i = 0; i < fragments.length; i++)
      if (fragments[i].isResolved() && fragments[i].hasDynamicImports())
        addDynamicImportPackage(fragments[i].getImportPackages());

    // Initialize the policy handler
    String buddyList = null;
    try {
      buddyList = (String) bundle.getBundleData().getManifest().get(Constants.BUDDY_LOADER);
    } catch (BundleException e) {
      // do nothing; buddyList == null
    }
    policy =
        buddyList != null
            ? new PolicyHandler(this, buddyList, bundle.getFramework().getPackageAdmin())
            : null;
    if (policy != null) policy.open(bundle.getFramework().getSystemBundleContext());
  }