Beispiel #1
0
 /** Create the web context for the application of specified name */
 WebAppContext createWebAppContext(Builder b) {
   WebAppContext ctx = new WebAppContext();
   setContextAttributes(ctx.getServletContext(), b.contextAttrs);
   ctx.setDisplayName(b.name);
   ctx.setContextPath("/");
   ctx.setWar(appDir + "/" + b.name);
   return ctx;
 }
 public EmbeddedWebServer(BimServer bimServer, boolean localDev) {
   server = new Server();
   //		Disabled 26-04-2015, I am pretty sure we don't use session anymore at all
   //		HashSessionIdManager hashSessionIdManager = new HashSessionIdManager(new Random()); //
   // Should be SecureRandom, but this makes startup slow on certain systems
   //		server.setSessionIdManager(hashSessionIdManager);
   ServerConnector socketConnector = new ServerConnector(server);
   socketConnector.setPort(bimServer.getConfig().getPort());
   server.addConnector(socketConnector);
   context = new WebAppContext(server, "", "/");
   context.setTempDirectory(bimServer.getHomeDir().resolve("jettytmp").toFile());
   if (localDev) {
     // TODO document why
     context.setDefaultsDescriptor("www/WEB-INF/webdefault.xml");
   }
   context.getServletContext().setAttribute("bimserver", bimServer);
   if (context.getResourceBase() == null) {
     context.setResourceBase("../BimServer/www");
   }
 }
  /**
   * @see
   *     org.eclipse.jetty.webapp.AbstractConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
   */
  @Override
  public void configure(WebAppContext context) throws Exception {
    context.addDecorator(new AnnotationDecorator(context));

    // Even if metadata is complete, we still need to scan for ServletContainerInitializers - if
    // there are any

    if (!context.getMetaData().isMetaDataComplete()) {
      // If metadata isn't complete, if this is a servlet 3 webapp or isConfigDiscovered is true, we
      // need to search for annotations
      if (context.getServletContext().getEffectiveMajorVersion() >= 3
          || context.isConfigurationDiscovered()) {
        _discoverableAnnotationHandlers.add(new WebServletAnnotationHandler(context));
        _discoverableAnnotationHandlers.add(new WebFilterAnnotationHandler(context));
        _discoverableAnnotationHandlers.add(new WebListenerAnnotationHandler(context));
      }
    }

    // Regardless of metadata, if there are any ServletContainerInitializers with @HandlesTypes,
    // then we need to scan all the
    // classes so we can call their onStartup() methods correctly
    createServletContainerInitializerAnnotationHandlers(
        context, getNonExcludedInitializers(context));

    if (!_discoverableAnnotationHandlers.isEmpty()
        || _classInheritanceHandler != null
        || !_containerInitializerAnnotationHandlers.isEmpty()) scanForAnnotations(context);

    // Resolve container initializers
    List<ContainerInitializer> initializers =
        (List<ContainerInitializer>)
            context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
    if (initializers != null && initializers.size() > 0) {
      Map<String, Set<String>> map =
          (Map<String, Set<String>>)
              context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
      if (map == null) LOG.warn("ServletContainerInitializers: detected. Class hierarchy: empty");
      for (ContainerInitializer i : initializers) i.resolveClasses(context, map);
    }
  }
  @SuppressWarnings({"unchecked", "rawtypes"})
  public Task<Void> start() {

    // Ensuring that jersey will use singletons from the orbit container.
    ServiceLocator locator = Injections.createLocator();
    DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
    DynamicConfiguration dc = dcs.createDynamicConfiguration();

    final List<Class<?>> classes = new ArrayList<>(providers);
    if (container != null) {
      classes.addAll(container.getClasses());
      for (final Class<?> c : container.getClasses()) {
        if (c.isAnnotationPresent(Singleton.class)) {
          Injections.addBinding(
              Injections.newFactoryBinder(
                      new Factory() {
                        @Override
                        public Object provide() {
                          return container.get(c);
                        }

                        @Override
                        public void dispose(final Object instance) {}
                      })
                  .to(c),
              dc);
        }
      }
    }
    dc.commit();

    final ResourceConfig resourceConfig = new ResourceConfig();

    // installing jax-rs classes known by the orbit container.
    for (final Class c : classes) {
      if (c.isAnnotationPresent(javax.ws.rs.Path.class)
          || c.isAnnotationPresent(javax.ws.rs.ext.Provider.class)) {
        resourceConfig.register(c);
      }
    }

    final WebAppContext webAppContext = new WebAppContext();
    final ProtectionDomain protectionDomain = EmbeddedHttpServer.class.getProtectionDomain();
    final URL location = protectionDomain.getCodeSource().getLocation();
    logger.info(location.toExternalForm());
    webAppContext.setInitParameter("useFileMappedBuffer", "false");
    webAppContext.setWar(location.toExternalForm());
    // this sets the default service locator to one that bridges to the orbit container.
    webAppContext.getServletContext().setAttribute(ServletProperties.SERVICE_LOCATOR, locator);
    webAppContext.setContextPath("/*");
    webAppContext.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*");

    final ContextHandler resourceContext = new ContextHandler();
    ResourceHandler resourceHandler = new ResourceHandler();
    resourceHandler.setDirectoriesListed(true);
    resourceHandler.setWelcomeFiles(new String[] {"index.html"});
    resourceHandler.setBaseResource(Resource.newClassPathResource("/web"));

    resourceContext.setHandler(resourceHandler);
    resourceContext.setInitParameter("useFileMappedBuffer", "false");
    final ContextHandlerCollection contexts = new ContextHandlerCollection();

    contexts.setHandlers(
        new Handler[] {
          wrapHandlerWithMetrics(resourceContext, "resourceContext"),
          wrapHandlerWithMetrics(webAppContext, "webAppContext")
        });

    server = new Server(port);
    server.setHandler(contexts);
    try {
      /// Initialize javax.websocket layer
      final ServerContainer serverContainer =
          WebSocketServerContainerInitializer.configureContext(webAppContext);

      for (Class c : classes) {
        if (c.isAnnotationPresent(ServerEndpoint.class)) {
          final ServerEndpoint annotation = (ServerEndpoint) c.getAnnotation(ServerEndpoint.class);

          final ServerEndpointConfig serverEndpointConfig =
              ServerEndpointConfig.Builder.create(c, annotation.value())
                  .configurator(
                      new ServerEndpointConfig.Configurator() {
                        @Override
                        public <T> T getEndpointInstance(final Class<T> endpointClass)
                            throws InstantiationException {
                          return container.get(endpointClass);
                        }
                      })
                  .build();

          serverContainer.addEndpoint(serverEndpointConfig);
        }
      }
    } catch (Exception e) {
      logger.error("Error starting jetty", e);
      throw new UncheckedException(e);
    }

    try {
      server.start();
    } catch (Exception e) {
      logger.error("Error starting jetty", e);
      throw new UncheckedException(e);
    }
    return Task.done();
  }
  /**
   * Perform scanning of classes for annotations
   *
   * @param context
   * @throws Exception
   */
  protected void scanForAnnotations(WebAppContext context) throws Exception {
    AnnotationParser parser = createAnnotationParser();
    _parserTasks = new ArrayList<ParserTask>();

    long start = 0;

    if (LOG.isDebugEnabled())
      LOG.debug(
          "Annotation scanning commencing: webxml={}, metadatacomplete={}, configurationDiscovered={}, multiThreaded={}, maxScanWait={}",
          context.getServletContext().getEffectiveMajorVersion(),
          context.getMetaData().isMetaDataComplete(),
          context.isConfigurationDiscovered(),
          isUseMultiThreading(context),
          getMaxScanWait(context));

    parseContainerPath(context, parser);
    // email from Rajiv Mordani jsrs 315 7 April 2010
    //    If there is a <others/> then the ordering should be
    //          WEB-INF/classes the order of the declared elements + others.
    //    In case there is no others then it is
    //          WEB-INF/classes + order of the elements.
    parseWebInfClasses(context, parser);
    parseWebInfLib(context, parser);

    start = System.nanoTime();

    // execute scan, either effectively synchronously (1 thread only), or asynchronously (limited by
    // number of processors available)
    final Semaphore task_limit =
        (isUseMultiThreading(context)
            ? new Semaphore(Runtime.getRuntime().availableProcessors())
            : new Semaphore(1));
    final CountDownLatch latch = new CountDownLatch(_parserTasks.size());
    final MultiException me = new MultiException();

    for (final ParserTask p : _parserTasks) {
      task_limit.acquire();
      context
          .getServer()
          .getThreadPool()
          .execute(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    p.call();
                  } catch (Exception e) {
                    me.add(e);
                  } finally {
                    task_limit.release();
                    latch.countDown();
                  }
                }
              });
    }

    boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS);

    if (LOG.isDebugEnabled()) {
      for (ParserTask p : _parserTasks)
        LOG.debug(
            "Scanned {} in {}ms",
            p.getResource(),
            TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS));

      LOG.debug(
          "Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}",
          _containerPathStats.getTotal(),
          _webInfLibStats.getTotal(),
          _webInfClassesStats.getTotal(),
          (TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS)),
          context);
    }

    if (timeout) me.add(new Exception("Timeout scanning annotations"));
    me.ifExceptionThrow();
  }