public static void indexTargetPlatform(
      OutputStream outputStream,
      List<File> additionalJarFiles,
      long stopWaitTimeout,
      String... dirNames)
      throws Exception {

    Framework framework = null;

    Path tempPath = Files.createTempDirectory(null);

    ClassLoader classLoader = TargetPlatformIndexerUtil.class.getClassLoader();

    try (InputStream inputStream =
        classLoader.getResourceAsStream("META-INF/system.packages.extra.mf")) {

      Map<String, String> properties = new HashMap<>();

      properties.put(Constants.FRAMEWORK_STORAGE, tempPath.toString());

      Manifest extraPackagesManifest = new Manifest(inputStream);

      Attributes attributes = extraPackagesManifest.getMainAttributes();

      properties.put(
          Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, attributes.getValue("Export-Package"));

      ServiceLoader<FrameworkFactory> serviceLoader = ServiceLoader.load(FrameworkFactory.class);

      FrameworkFactory frameworkFactory = serviceLoader.iterator().next();

      framework = frameworkFactory.newFramework(properties);

      framework.init();

      BundleContext bundleContext = framework.getBundleContext();

      Bundle systemBundle = bundleContext.getBundle(0);

      TargetPlatformIndexer targetPlatformIndexer =
          new TargetPlatformIndexer(systemBundle, additionalJarFiles, dirNames);

      targetPlatformIndexer.index(outputStream);
    } finally {
      framework.stop();

      FrameworkEvent frameworkEvent = framework.waitForStop(stopWaitTimeout);

      if (frameworkEvent.getType() == FrameworkEvent.WAIT_TIMEDOUT) {
        throw new Exception(
            "OSGi framework event "
                + frameworkEvent
                + " triggered after a "
                + stopWaitTimeout
                + "ms timeout");
      }

      PathUtil.deltree(tempPath);
    }
  }
    @Override
    public void frameworkEvent(FrameworkEvent frameworkEvent) {
      if (frameworkEvent.getType() != FrameworkEvent.PACKAGES_REFRESHED) {
        return;
      }

      for (Bundle bundle : _startBundles) {
        try {
          startBundle(bundle, 0, false);
        } catch (Exception e) {
          _log.error(e, e);
        }
      }

      for (Bundle bundle : _lazyActivationBundles) {
        try {
          startBundle(bundle, Bundle.START_ACTIVATION_POLICY, false);
        } catch (Exception e) {
          _log.error(e, e);
        }
      }

      try {
        Bundle bundle = frameworkEvent.getBundle();

        BundleContext bundleContext = bundle.getBundleContext();

        bundleContext.removeFrameworkListener(this);
      } catch (Exception e) {
        _log.error(e, e);
      }
    }
  @SuppressWarnings("rawtypes")
  private EventObject waitForEvent(List events, int type) throws InterruptedException {
    // Timeout for event delivery: 3 sec
    int timeout = 30;

    EventObject eventFound = null;
    while (eventFound == null && 0 < timeout) {
      synchronized (events) {
        events.wait(100);
        for (Object aux : events) {
          if (aux instanceof BundleEvent) {
            BundleEvent event = (BundleEvent) aux;
            if (type == event.getType()) {
              eventFound = event;
              break;
            }
          } else if (aux instanceof ServiceEvent) {
            ServiceEvent event = (ServiceEvent) aux;
            if (type == event.getType()) {
              eventFound = event;
              break;
            }
          } else if (aux instanceof FrameworkEvent) {
            FrameworkEvent event = (FrameworkEvent) aux;
            if (type == event.getType()) {
              eventFound = event;
              break;
            }
          }
        }
      }
      timeout--;
    }
    return eventFound;
  }
 /*
  * Do the work that should have happened init time. This also "turns on" the
  * filter so future calls pass directly through this class to the wrapped
  * filter.
  */
 public void frameworkEvent(FrameworkEvent event) {
   if (event.getType() != FrameworkEvent.STARTED) {
     return;
   }
   try {
     delayed.init(delayedConfig);
     ready = true;
   } catch (ServletException e) {
     log.error(e);
   }
 }
 @Override
 public void frameworkEvent(FrameworkEvent event) {
   synchronized (frameworkEvents) {
     log.debug(
         "FrameworkEvent type="
             + ConstantsHelper.frameworkEvent(event.getType())
             + " for "
             + event);
     frameworkEvents.add(event);
     frameworkEvents.notifyAll();
   }
 }
 protected void assertFrameworkEvent(
     int type, Bundle bundle, Class<? extends Throwable> expectedThrowable) throws Exception {
   FrameworkEvent event = (FrameworkEvent) waitForEvent(frameworkEvents, type);
   log.debug("frameworkEvents=" + frameworkEvents);
   assertNotNull("Event not null", event);
   frameworkEvents.remove(event);
   assertEquals(
       ConstantsHelper.frameworkEvent(type), ConstantsHelper.frameworkEvent(event.getType()));
   Throwable t = event.getThrowable();
   if (expectedThrowable == null) {
     if (t != null) {
       log.error("Unexpected error in Framework event: ", t);
       fail("Unexpected throwable: " + t);
     }
   } else {
     String message =
         expectedThrowable.getSimpleName() + " is assignable from " + t.getClass().getSimpleName();
     assertTrue(message, expectedThrowable.isAssignableFrom(t.getClass()));
   }
   assertEquals(bundle, event.getSource());
   assertEquals(bundle, event.getBundle());
 }
  public long[] getFrameworkEvents() {
    synchronized (frameworkEvents) {
      try {

        long[] r = new long[frameworkEvents.size() * 2];
        if (bDebug) {
          System.out.println("server: getFrameworkEvents size=" + r.length / 2);
        }
        int i = 0;

        for (Iterator it = frameworkEvents.iterator(); it.hasNext(); ) {
          FrameworkEvent ev = (FrameworkEvent) it.next();
          Bundle b = ev.getBundle();
          long bid = -1;
          if (b == null) {
            if (bDebug) {
              System.out.println("fw event: " + ev + " - no bundle");
            }
          } else {
            bid = b.getBundleId();
          }
          r[i * 2] = bid;
          r[i * 2 + 1] = ev.getType();
          i++;
        }

        frameworkEvents.clear();
        if (bDebug) {
          System.out.println("server: getFrameworkEvents -> " + r);
        }
        return r;
      } catch (Exception e) {
        if (bDebug) {
          e.printStackTrace();
        }
      }
    }
    return null;
  }
 @Override
 public void frameworkEvent(FrameworkEvent event) {
   if (event.getType() == FrameworkEvent.STARTED) {
     fireApplicationStarted();
   }
 }
  /**
   * Bottom level event dispatcher for the BundleContext.
   *
   * @param originalListener listener object registered under.
   * @param l listener to call (may be filtered).
   * @param action Event class type
   * @param object Event object
   */
  public void dispatchEvent(Object originalListener, Object l, int action, Object object) {
    // save the bundle ref to a local variable
    // to avoid interference from another thread closing this context
    AbstractBundle tmpBundle = bundle;
    Object previousTCCL = setContextFinder();
    try {
      if (isValid()) /* if context still valid */ {
        switch (action) {
          case Framework.BUNDLEEVENT:
          case Framework.BUNDLEEVENTSYNC:
            {
              BundleListener listener = (BundleListener) l;

              if (Debug.DEBUG_EVENTS) {
                String listenerName =
                    listener.getClass().getName()
                        + "@"
                        + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$
                Debug.println(
                    "dispatchBundleEvent["
                        + tmpBundle
                        + "]("
                        + listenerName
                        + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
              }

              BundleEvent event = (BundleEvent) object;
              switch (event.getType()) {
                case Framework.BATCHEVENT_BEGIN:
                  {
                    if (listener instanceof BatchBundleListener)
                      ((BatchBundleListener) listener).batchBegin();
                    break;
                  }
                case Framework.BATCHEVENT_END:
                  {
                    if (listener instanceof BatchBundleListener)
                      ((BatchBundleListener) listener).batchEnd();
                    break;
                  }
                default:
                  {
                    listener.bundleChanged((BundleEvent) object);
                  }
              }
              break;
            }

          case ServiceRegistry.SERVICEEVENT:
            {
              ServiceEvent event = (ServiceEvent) object;

              ServiceListener listener = (ServiceListener) l;
              if (Debug.DEBUG_EVENTS) {
                String listenerName =
                    listener.getClass().getName()
                        + "@"
                        + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$
                Debug.println(
                    "dispatchServiceEvent["
                        + tmpBundle
                        + "]("
                        + listenerName
                        + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
              }
              listener.serviceChanged(event);

              break;
            }

          case Framework.FRAMEWORKEVENT:
            {
              FrameworkListener listener = (FrameworkListener) l;

              if (Debug.DEBUG_EVENTS) {
                String listenerName =
                    listener.getClass().getName()
                        + "@"
                        + Integer.toHexString(System.identityHashCode(listener)); // $NON-NLS-1$
                Debug.println(
                    "dispatchFrameworkEvent["
                        + tmpBundle
                        + "]("
                        + listenerName
                        + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
              }

              listener.frameworkEvent((FrameworkEvent) object);
              break;
            }
          default:
            {
              throw new InternalError();
            }
        }
      }
    } catch (Throwable t) {
      if (Debug.DEBUG_GENERAL) {
        Debug.println(
            "Exception in bottom level event dispatcher: " + t.getMessage()); // $NON-NLS-1$
        Debug.printStackTrace(t);
      }
      // allow the adaptor to handle this unexpected error
      framework.adaptor.handleRuntimeError(t);
      publisherror:
      {
        if (action == Framework.FRAMEWORKEVENT) {
          FrameworkEvent event = (FrameworkEvent) object;
          if (event.getType() == FrameworkEvent.ERROR) {
            break publisherror; // avoid infinite loop
          }
        }

        framework.publishFrameworkEvent(FrameworkEvent.ERROR, tmpBundle, t);
      }
    } finally {
      if (previousTCCL != Boolean.FALSE)
        Thread.currentThread().setContextClassLoader((ClassLoader) previousTCCL);
    }
  }
Esempio n. 10
0
  /**
   * This method performs the main task of constructing an framework instance and starting its
   * execution. The following functions are performed when invoked:
   *
   * <ol>
   *   <li><i><b>Examine and verify command-line arguments.</b></i> The launcher accepts a
   *       "<tt>-b</tt>" command line switch to set the bundle auto-deploy directory and a single
   *       argument to set the bundle cache directory.
   *   <li><i><b>Read the system properties file.</b></i> This is a file containing properties to be
   *       pushed into <tt>System.setProperty()</tt> before starting the framework. This mechanism
   *       is mainly shorthand for people starting the framework from the command line to avoid
   *       having to specify a bunch of <tt>-D</tt> system property definitions. The only properties
   *       defined in this file that will impact the framework's behavior are the those concerning
   *       setting HTTP proxies, such as <tt>http.proxyHost</tt>, <tt>http.proxyPort</tt>, and
   *       <tt>http.proxyAuth</tt>. Generally speaking, the framework does not use system properties
   *       at all.
   *   <li><i><b>Read the framework's configuration property file.</b></i> This is a file containing
   *       properties used to configure the framework instance and to pass configuration information
   *       into bundles installed into the framework instance. The configuration property file is
   *       called <tt>config.properties</tt> by default and is located in the <tt>conf/</tt>
   *       directory of the Felix installation directory, which is the parent directory of the
   *       directory containing the <tt>felix.jar</tt> file. It is possible to use a different
   *       location for the property file by specifying the desired URL using the
   *       <tt>felix.config.properties</tt> system property; this should be set using the
   *       <tt>-D</tt> syntax when executing the JVM. If the <tt>config.properties</tt> file cannot
   *       be found, then default values are used for all configuration properties. Refer to the <a
   *       href="Felix.html#Felix(java.util.Map)"><tt>Felix</tt></a> constructor documentation for
   *       more information on framework configuration properties.
   *   <li><i><b>Copy configuration properties specified as system properties into the set of
   *       configuration properties.</b></i> Even though the Felix framework does not consult system
   *       properties for configuration information, sometimes it is convenient to specify them on
   *       the command line when launching Felix. To make this possible, the Felix launcher copies
   *       any configuration properties specified as system properties into the set of configuration
   *       properties passed into Felix.
   *   <li><i><b>Add shutdown hook.</b></i> To make sure the framework shutdowns cleanly, the
   *       launcher installs a shutdown hook; this can be disabled with the
   *       <tt>felix.shutdown.hook</tt> configuration property.
   *   <li><i><b>Create and initialize a framework instance.</b></i> The OSGi standard
   *       <tt>FrameworkFactory</tt> is retrieved from <tt>META-INF/services</tt> and used to create
   *       a framework instance with the configuration properties.
   *   <li><i><b>Auto-deploy bundles.</b></i> All bundles in the auto-deploy directory are deployed
   *       into the framework instance.
   *   <li><i><b>Start the framework.</b></i> The framework is started and the launcher thread waits
   *       for the framework to shutdown.
   * </ol>
   *
   * <p>It should be noted that simply starting an instance of the framework is not enough to create
   * an interactive session with it. It is necessary to install and start bundles that provide a
   * some means to interact with the framework; this is generally done by bundles in the auto-deploy
   * directory or specifying an "auto-start" property in the configuration property file. If no
   * bundles providing a means to interact with the framework are installed or if the configuration
   * property file cannot be found, the framework will appear to be hung or deadlocked. This is not
   * the case, it is executing correctly, there is just no way to interact with it.
   *
   * <p>The launcher provides two ways to deploy bundles into a framework at startup, which have
   * associated configuration properties:
   *
   * <ul>
   *   <li>Bundle auto-deploy - Automatically deploys all bundles from a specified directory,
   *       controlled by the following configuration properties:
   *       <ul>
   *         <li><tt>felix.auto.deploy.dir</tt> - Specifies the auto-deploy directory from which
   *             bundles are automatically deploy at framework startup. The default is the
   *             <tt>bundle/</tt> directory of the current directory.
   *         <li><tt>felix.auto.deploy.action</tt> - Specifies the auto-deploy actions to be found
   *             on bundle JAR files found in the auto-deploy directory. The possible actions are
   *             <tt>install</tt>, <tt>update</tt>, <tt>start</tt>, and <tt>uninstall</tt>. If no
   *             actions are specified, then the auto-deploy directory is not processed. There is no
   *             default value for this property.
   *       </ul>
   *   <li>Bundle auto-properties - Configuration properties which specify URLs to bundles to
   *       install/start:
   *       <ul>
   *         <li><tt>felix.auto.install.N</tt> - Space-delimited list of bundle URLs to
   *             automatically install when the framework is started, where <tt>N</tt> is the start
   *             level into which the bundle will be installed (e.g., felix.auto.install.2).
   *         <li><tt>felix.auto.start.N</tt> - Space-delimited list of bundle URLs to automatically
   *             install and start when the framework is started, where <tt>N</tt> is the start
   *             level into which the bundle will be installed (e.g., felix.auto.start.2).
   *       </ul>
   * </ul>
   *
   * <p>These properties should be specified in the <tt>config.properties</tt> so that they can be
   * processed by the launcher during the framework startup process.
   *
   * @param args Accepts arguments to set the auto-deploy directory and/or the bundle cache
   *     directory.
   * @throws Exception If an error occurs.
   */
  public static void main(String[] args) throws Exception {
    // Look for bundle directory and/or cache directory.
    // We support at most one argument, which is the bundle
    // cache directory.
    String bundleDir = null;
    String cacheDir = null;
    boolean expectBundleDir = false;
    for (int i = 0; i < args.length; i++) {
      if (args[i].equals(BUNDLE_DIR_SWITCH)) {
        expectBundleDir = true;
      } else if (expectBundleDir) {
        bundleDir = args[i];
        expectBundleDir = false;
      } else {
        cacheDir = args[i];
      }
    }

    if ((args.length > 3) || (expectBundleDir && bundleDir == null)) {
      System.out.println("Usage: [-b <bundle-deploy-dir>] [<bundle-cache-dir>]");
      System.exit(0);
    }

    // Load system properties.
    Main.loadSystemProperties();

    // Read configuration properties.
    Properties configProps = Main.loadConfigProperties();
    // If no configuration properties were found, then create
    // an empty properties object.
    if (configProps == null) {
      System.err.println("No " + CONFIG_PROPERTIES_FILE_VALUE + " found.");
      configProps = new Properties();
    }

    // Copy framework properties from the system properties.
    Main.copySystemProperties(configProps);

    // If there is a passed in bundle auto-deploy directory, then
    // that overwrites anything in the config file.
    if (bundleDir != null) {
      configProps.setProperty(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY, bundleDir);
    }

    // If there is a passed in bundle cache directory, then
    // that overwrites anything in the config file.
    if (cacheDir != null) {
      configProps.setProperty(Constants.FRAMEWORK_STORAGE, cacheDir);
    }

    // If enabled, register a shutdown hook to make sure the framework is
    // cleanly shutdown when the VM exits.
    String enableHook = configProps.getProperty(SHUTDOWN_HOOK_PROP);
    if ((enableHook == null) || !enableHook.equalsIgnoreCase("false")) {
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread("Felix Shutdown Hook") {
                public void run() {
                  try {
                    if (m_fwk != null) {
                      m_fwk.stop();
                      m_fwk.waitForStop(0);
                    }
                  } catch (Exception ex) {
                    System.err.println("Error stopping framework: " + ex);
                  }
                }
              });
    }

    try {
      // Create an instance of the framework.
      FrameworkFactory factory = getFrameworkFactory();
      m_fwk = factory.newFramework(configProps);
      // Initialize the framework, but don't start it yet.
      m_fwk.init();
      // Use the system bundle context to process the auto-deploy
      // and auto-install/auto-start properties.
      AutoProcessor.process(configProps, m_fwk.getBundleContext());
      FrameworkEvent event;
      do {
        // Start the framework.
        m_fwk.start();
        // Wait for framework to stop to exit the VM.
        event = m_fwk.waitForStop(0);
      }
      // If the framework was updated, then restart it.
      while (event.getType() == FrameworkEvent.STOPPED_UPDATE);
      // Otherwise, exit.
      System.exit(0);
    } catch (Exception ex) {
      System.err.println("Could not create framework: " + ex);
      ex.printStackTrace();
      System.exit(0);
    }
  }