public void stop(boolean now) throws Exception {
    log.info("Stopping Gravity (now=%s)...", now);
    synchronized (this) {
      if (adapterFactory != null) {
        try {
          adapterFactory.stopAll();
        } catch (Exception e) {
          log.error(e, "Error while stopping adapter factory");
        }
        adapterFactory = null;
      }

      if (serverChannel != null) {
        try {
          removeChannel(serverChannel.getId(), false);
        } catch (Exception e) {
          log.error(e, "Error while removing server channel: %s", serverChannel);
        }
        serverChannel = null;
      }

      if (channelsTimer != null) {
        try {
          channelsTimer.cancel();
        } catch (Exception e) {
          log.error(e, "Error while cancelling channels timer");
        }
        channelsTimer = null;
      }

      if (gravityPool != null) {
        try {
          if (now) gravityPool.shutdownNow();
          else gravityPool.shutdown();
        } catch (Exception e) {
          log.error(e, "Error while stopping thread pool");
        }
        gravityPool = null;
      }

      if (udpReceiverFactory != null) {
        try {
          udpReceiverFactory.stop();
        } catch (Exception e) {
          log.error(e, "Error while stopping udp receiver factory");
        }
        udpReceiverFactory = null;
      }

      started = false;
    }
    log.info("Gravity sucessfully stopped.");
  }
  protected void createUdpReceiver(UdpReceiverFactory factory, AsyncHttpContext asyncHttpContext) {
    OutputStream os = null;
    try {
      Message connectMessage = asyncHttpContext.getConnectMessage();

      if (udpReceiver == null || udpReceiver.isClosed())
        udpReceiver = factory.newReceiver(this, asyncHttpContext.getRequest(), connectMessage);

      AsyncMessage reply = udpReceiver.acknowledge(connectMessage);

      HttpServletRequest request = asyncHttpContext.getRequest();
      HttpServletResponse response = asyncHttpContext.getResponse();

      GraniteContext context =
          HttpGraniteContext.createThreadIntance(
              gravity.getGraniteConfig(), gravity.getServicesConfig(), null, request, response);
      ((AMFContextImpl) context.getAMFContext())
          .setCurrentAmf3Message(asyncHttpContext.getConnectMessage());

      GravityServletUtil.serialize(
          gravity,
          response,
          new AsyncMessage[] {reply},
          ContentType.forMimeType(request.getContentType()));
    } catch (ServletException e) {
      log.error(e, "Could not send UDP connect acknowledgement to channel: %s", this);
    } catch (IOException e) {
      log.error(e, "Could not send UDP connect acknowledgement to channel: %s", this);
    } finally {
      try {
        GraniteContext.release();
      } catch (Exception e) {
        // should never happen...
      }

      // Close output stream.
      try {
        if (os != null) {
          try {
            os.close();
          } catch (IOException e) {
            log.warn(e, "Could not close output stream (ignored)");
          }
        }
      } finally {
        releaseAsyncHttpContext(asyncHttpContext);
      }
    }
  }
  private Message handleSecurityMessage(CommandMessage message) {
    GraniteConfig config = GraniteContext.getCurrentInstance().getGraniteConfig();

    Message response = null;

    if (!config.hasSecurityService())
      log.warn(
          "Ignored security operation (no security settings in granite-config.xml): %s", message);
    else if (!config.getSecurityService().acceptsContext())
      log.info(
          "Ignored security operation (security service does not handle this kind of granite context)",
          message);
    else {
      SecurityService securityService = config.getSecurityService();
      try {
        if (message.isLoginOperation())
          securityService.login(
              message.getBody(), (String) message.getHeader(Message.CREDENTIALS_CHARSET_HEADER));
        else securityService.logout();
      } catch (Exception e) {
        if (e instanceof SecurityServiceException)
          log.debug(e, "Could not process security operation: %s", message);
        else log.error(e, "Could not process security operation: %s", message);
        response = new ErrorMessage(message, e, true);
      }
    }

    if (response == null) {
      response = new AcknowledgeMessage(message, true);
      // For SDK 2.0.1_Hotfix2.
      if (message.isSecurityOperation()) response.setBody("success");
    }

    return response;
  }
  public void receive(AsyncMessage message) throws MessageReceivingException {
    if (message == null) throw new NullPointerException("message cannot be null");

    GravityInternal gravity = getGravity();

    if (udpReceiver != null) {
      if (udpReceiver.isClosed()) return;

      try {
        udpReceiver.receive(message);
      } catch (MessageReceivingException e) {
        if (e.getCause() instanceof SocketException) {
          log.debug(e, "Closing unreachable UDP channel %s", getId());
          udpReceiver.close(false);
        } else log.error(e, "Cannot access UDP channel %s", getId());
      }
      return;
    }

    receivedQueueLock.lock();
    try {
      if (receivedQueue.size() + 1 > gravity.getGravityConfig().getMaxMessagesQueuedPerChannel())
        throw new MessageReceivingException(
            message, "Could not queue message (channel's queue is full) for channel: " + this);

      log.debug(
          "Channel %s queue message %s for client %s",
          getId(), message.getMessageId(), message.getClientId());
      receivedQueue.add(message);
    } finally {
      receivedQueueLock.unlock();
    }

    if (hasAsyncHttpContext()) receiver.queue(gravity);
  }
  /*
   * (non-Javadoc)
   * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    if (log.isInfoEnabled())
      try {
        GraniteContext context =
            HttpGraniteContext.createThreadIntance(
                graniteConfig, servicesConfig, getServletContext(), request, response);
        if (context == null) throw new ServletException("GraniteContext not Initialized!!");

        // AMFContextImpl amf = (AMFContextImpl) context.getAMFContext();
        // Phase1 Deserializing AMF0 request
        if (log.isInfoEnabled())
          log.info(">>>>> Deserializing AMF0 request from..." + request.getRequestURI());
        AMF0Deserializer deserializer =
            new AMF0Deserializer(new DataInputStream(request.getInputStream()));
        AMF0Message amf0Request = deserializer.getAMFMessage();

        // Phase2 Processing AMF0 request
        if (log.isInfoEnabled()) log.info(">>>>> Processing AMF0 request: " + amf0Request);
        AMF0Message amf0Response = AMF0MessageProcessor.process(amf0Request);
        if (log.isInfoEnabled()) log.info("<<<<< Returning AMF0 response: " + amf0Response);

        // Phase3 Send back response to the client
        response.setContentType(AMF0Message.CONTENT_TYPE);
        AMF0Serializer serializer =
            new AMF0Serializer(new DataOutputStream(response.getOutputStream()));
        serializer.serializeMessage(amf0Response);
        if (log.isInfoEnabled()) log.info("...End of Processing AMF Request......");
      } catch (Exception e) {
        log.error(e, "Could not handle AMF request");
        throw new ServletException(e);
      }
  }
Beispiel #6
0
 public boolean handleMarkerItem(ScannedItem item) {
   try {
     return handleProperties(item.loadAsProperties());
   } catch (Exception e) {
     log.error(e, "Could not load properties: %s", item);
   }
   return true;
 }
  public Channel removeChannel(String channelId, boolean timeout) {
    if (channelId == null) return null;

    // Remove existing channel id/subscriptions in distributed data (clustering).
    try {
      DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
      if (gdd != null) {
        log.debug("Removing channel id from distributed data: %s", channelId);
        gdd.removeChannelId(channelId);
      }
    } catch (Exception e) {
      log.error(e, "Could not remove channel id from distributed data: %s", channelId);
    }

    TimeChannel<?> timeChannel = channels.get(channelId);
    Channel channel = null;
    if (timeChannel != null) {
      try {
        if (timeChannel.getTimerTask() != null) timeChannel.getTimerTask().cancel();
      } catch (Exception e) {
        // Should never happen...
      }

      channel = timeChannel.getChannel();

      try {
        for (Subscription subscription : channel.getSubscriptions()) {
          try {
            Message message = subscription.getUnsubscribeMessage();
            handleMessage(channel.getFactory(), message, true);
          } catch (Exception e) {
            log.error(
                e,
                "Error while unsubscribing channel: %s from subscription: %s",
                channel,
                subscription);
          }
        }
      } finally {
        channels.remove(channelId);
        channel.destroy(timeout);
      }
    }
    return channel;
  }
Beispiel #8
0
  private boolean handleProperties(Properties properties) {
    if (properties.getProperty("dependsOn") != null) {
      String dependsOn = properties.getProperty("dependsOn");
      try {
        TypeUtil.forName(dependsOn);
      } catch (ClassNotFoundException e) {
        // Class not found, skip scan for this package
        return true;
      }
    }

    String classGetterName = properties.getProperty("classGetter");
    if (!classGetterSet && classGetterName != null) {
      try {
        classGetter = TypeUtil.newInstance(classGetterName, ClassGetter.class);
      } catch (Throwable t) {
        log.error(t, "Could not create instance of: %s", classGetterName);
      }
    }

    String amf3MessageInterceptorName = properties.getProperty("amf3MessageInterceptor");
    if (amf3MessageInterceptor == null && amf3MessageInterceptorName != null) {
      try {
        amf3MessageInterceptor =
            TypeUtil.newInstance(amf3MessageInterceptorName, AMF3MessageInterceptor.class);
      } catch (Throwable t) {
        log.error(t, "Could not create instance of: %s", amf3MessageInterceptorName);
      }
    }

    for (Map.Entry<?, ?> me : properties.entrySet()) {
      if (me.getKey().toString().startsWith("converter.")) {
        String converterName = me.getValue().toString();
        try {
          converterClasses.add(TypeUtil.forName(converterName, Converter.class));
        } catch (Exception e) {
          throw new GraniteConfigException(
              "Could not get converter class for: " + converterName, e);
        }
      }
    }

    return false;
  }
Beispiel #9
0
 private void scanConfig(String graniteConfigProperties) {
   // if config overriding exists
   Scanner scanner =
       ScannerFactory.createScanner(
           this,
           graniteConfigProperties != null ? graniteConfigProperties : GRANITE_CONFIG_PROPERTIES);
   try {
     scanner.scan();
   } catch (Exception e) {
     log.error(e, "Could not scan classpath for configuration");
   }
 }
Beispiel #10
0
  private void handleClass(Class<?> clazz) {
    if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) return;

    if (Externalizer.class.isAssignableFrom(clazz)) {
      try {
        scannedExternalizers.add(TypeUtil.newInstance(clazz, Externalizer.class));
      } catch (Exception e) {
        log.error(e, "Could not create new instance of: %s", clazz);
      }
    }

    if (ExceptionConverter.class.isAssignableFrom(clazz)) {
      try {
        exceptionConverters.add(TypeUtil.newInstance(clazz, ExceptionConverter.class));
      } catch (Exception e) {
        if (!clazz
            .getName()
            .equals("org.granite.tide.hibernate.HibernateValidatorExceptionConverter")) // GDS-582
        log.error(e, "Could not create new instance of: %s", clazz);
      }
    }
  }
Beispiel #11
0
 public void handleScannedItem(ScannedItem item) {
   if ("class".equals(item.getExtension()) && item.getName().indexOf('$') == -1) {
     try {
       handleClass(item.loadAsClass());
     } catch (NoClassDefFoundError e) {
       // Ignore errors with Tide classes depending on Gravity
     } catch (LinkageError e) {
       // Ignore errors with GraniteDS/Hibernate classes depending on Hibernate 3 when using
       // Hibernate 4
     } catch (Throwable t) {
       log.error(t, "Could not load class: %s", item);
     }
   }
 }
  @Override
  public Set<Class<?>> scan(Set<String> packageNames) {
    Set<Class<?>> classes = new HashSet<Class<?>>();

    Scanner scanner =
        ScannerFactory.createScanner(new MessagingScannedItemHandler(packageNames, classes), null);
    try {
      scanner.scan();
    } catch (Exception e) {
      log.error(e, "Could not scan classpath for @RemoteAlias");
    }

    return classes;
  }
  @Validate
  public void start() {
    log.debug("Start OSGiServiceSimple: " + toString());

    if (servicesConfig.findServiceById(id) == null) {
      // Clear destinations
      destinations.clear();

      servicesConfig.addService(this);
      started = true;
    } else {
      log.error("Service \"" + id + "\" already registered");
    }
  }
Beispiel #14
0
 public void registerExceptionConverter(
     Class<? extends ExceptionConverter> exceptionConverterClass, boolean first) {
   for (ExceptionConverter ec : exceptionConverters) {
     if (ec.getClass() == exceptionConverterClass) return;
   }
   try {
     ExceptionConverter exceptionConverter =
         TypeUtil.newInstance(exceptionConverterClass, ExceptionConverter.class);
     if (first) exceptionConverters.add(0, exceptionConverter);
     else exceptionConverters.add(exceptionConverter);
   } catch (Exception e) {
     log.error(e, "Could not instantiate exception converter: %s", exceptionConverterClass);
   }
 }
  @Override
  protected ServiceException getServiceException(
      Message request, Destination destination, String method, Throwable t) {
    if (t == null) throw new NullPointerException("Parameter t cannot be null");

    Map<String, Object> extendedData = new HashMap<String, Object>();

    if (t instanceof ServiceException) {
      ((ServiceException) t).getExtendedData().putAll(extendedData);
      return (ServiceException) t;
    }

    List<Throwable> causes = new ArrayList<Throwable>();
    for (Throwable cause = t; cause != null; cause = getCause(cause)) causes.add(cause);

    String detail =
        "\n"
            + "- destination: "
            + (destination != null ? destination.getId() : "")
            + "\n"
            + "- method: "
            + method
            + "\n"
            + "- exception: "
            + t.toString()
            + "\n";

    for (int i = causes.size() - 1; i >= 0; i--) {
      Throwable cause = causes.get(i);
      for (ExceptionConverter ec :
          GraniteContext.getCurrentInstance().getGraniteConfig().getExceptionConverters()) {
        if (ec.accepts(cause, t)) return ec.convert(cause, detail, extendedData);
      }
    }

    if (getLogException()) log.error(t, "Could not process remoting message: %s", request);

    // Default exception handler
    ServiceException se =
        new ServiceException(
            t.getClass().getSimpleName() + ".Call.Failed", t.getMessage(), detail, t);
    se.getExtendedData().putAll(extendedData);
    return se;
  }
  private void dumpBytes(String label, byte[] bytes) {
    StringBuilder hexSb = new StringBuilder();
    StringBuilder charSb = new StringBuilder();

    for (int i = 0; i < bytes.length; i++) {
      int b = bytes[i] & 0xFF;
      if (hexSb.length() > 0) {
        hexSb.append(' ');
        charSb.append(' ');
      }
      hexSb.append(HEXS.charAt(b >> 4)).append(HEXS.charAt(b & 0x0F));
      if (b >= 0x20 && b <= 0x7e) charSb.append(' ').append((char) b);
      else charSb.append("##");
    }

    log.info("[RAW %s] {\n%s\n%s\n}", label.toUpperCase(), hexSb.toString(), charSb.toString());

    if (dumpDir != null) {
      File file =
          new File(
              dumpDir.getPath()
                  + File.separator
                  + label
                  + "_"
                  + System.currentTimeMillis()
                  + ".amf");
      for (int i = 1; i < 100 && file.exists(); i++)
        file = new File(file.getAbsolutePath() + "." + i);

      OutputStream os = null;
      try {
        os = new FileOutputStream(file);
        os.write(bytes);
      } catch (Exception e) {
        log.error(e, "Could not write dump file: %s", file);
      } finally {
        if (os != null)
          try {
            os.close();
          } catch (Exception e) {
          }
      }
    }
  }
  protected void internalStart() {
    gravityPool = new GravityPool(gravityConfig);
    channelsTimer = new Timer();

    if (graniteConfig.isRegisterMBeans()) {
      try {
        ObjectName name =
            new ObjectName(
                "org.graniteds:type=Gravity,context=" + graniteConfig.getMBeanContextName());
        log.info("Registering MBean: %s", name);
        OpenMBean mBean = OpenMBean.createMBean(this);
        MBeanServerLocator.getInstance().register(mBean, name, true);
      } catch (Exception e) {
        log.error(
            e,
            "Could not register Gravity MBean for context: %s",
            graniteConfig.getMBeanContextName());
      }
    }
  }
  private Message handleUnsubscribeMessage(
      final ChannelFactory<?> channelFactory, CommandMessage message) {
    Channel channel = getChannel(channelFactory, (String) message.getClientId());
    if (channel == null) return handleUnknownClientMessage(message);

    AsyncMessage reply = null;

    ServiceAdapter adapter = adapterFactory.getServiceAdapter(message);

    reply = (AcknowledgeMessage) adapter.manage(channel, message);

    postManage(channel);

    if (!(reply instanceof ErrorMessage)) {
      // Remove subscription message in distributed data (clustering).
      try {
        DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
        if (gdd != null) {
          String subscriptionId =
              (String) message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER);
          log.debug(
              "Removing subscription message from channel info: %s - %s",
              channel.getId(), subscriptionId);
          gdd.removeSubcription(channel.getId(), subscriptionId);
        }
      } catch (Exception e) {
        log.error(
            e,
            "Could not remove subscription from distributed data: %s - %s",
            channel.getId(),
            message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER));
      }
    }

    reply.setDestination(message.getDestination());
    reply.setClientId(channel.getId());
    reply.getHeaders().putAll(message.getHeaders());

    return reply;
  }
  public boolean runPublish() {
    LinkedList<AsyncPublishedMessage> publishedCopy = null;

    publishedQueueLock.lock();
    try {
      if (publishedQueue.isEmpty()) return false;
      publishedCopy = publishedQueue;
      publishedQueue = new LinkedList<AsyncPublishedMessage>();
    } finally {
      publishedQueueLock.unlock();
    }

    for (AsyncPublishedMessage message : publishedCopy) {
      try {
        message.publish(this);
      } catch (Exception e) {
        log.error(e, "Error while trying to publish message: %s", message);
      }
    }

    return true;
  }
  /*
   * (non-Javadoc)
   * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
   */
  @Override
  public void init(ServletConfig config) {
    try {
      super.init(config);
      Configuration configuration = Activator.getConfigurationService();
      getServletContext()
          .setAttribute(ServletGraniteConfig.GRANITE_CONFIG_CONFIGURATION_KEY, configuration);
      graniteConfig = ServletGraniteConfig.loadConfig(getServletContext());
      servicesConfig = ServletServicesConfig.loadConfig(getServletContext());

      // register EventHandler ServicesConfig handle Add or Remove dataservice
      Dictionary<String, Object> properties = new Hashtable<String, Object>();
      String[] topics =
          new String[] {
            OSGIConstants.TOPIC_GDS_ADD_SERVICE, OSGIConstants.TOPIC_GDS_REMOVE_SERVICE
          };
      properties.put(EventConstants.EVENT_TOPIC, topics);
      context.registerService(
          EventHandler.class.getName(), new ServiceEventHandler(servicesConfig), properties);

    } catch (ServletException e) {
      log.error(e, "Could initialize OSGi service adaptor");
    }
  }
  @SuppressWarnings("unchecked")
  public <C extends Channel> C getChannel(ChannelFactory<C> channelFactory, String clientId) {
    if (clientId == null) return null;

    TimeChannel<C> timeChannel = (TimeChannel<C>) channels.get(clientId);
    if (timeChannel == null) {
      // Look for existing channel id/subscriptions in distributed data (clustering).
      log.debug("Lookup channel %s in distributed data", clientId);
      try {
        DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
        if (gdd != null && gdd.hasChannelId(clientId)) {
          log.debug("Found channel id in distributed data: %s", clientId);
          String channelFactoryClassName = gdd.getChannelFactoryClassName(clientId);
          String clientType = gdd.getChannelClientType(clientId);
          channelFactory =
              (ChannelFactory<C>)
                  TypeUtil.newInstance(
                      channelFactoryClassName, new Class<?>[] {Gravity.class}, new Object[] {this});
          C channel = channelFactory.newChannel(clientId, clientType);
          timeChannel = new TimeChannel<C>(channel);
          if (channels.putIfAbsent(clientId, timeChannel) == null) {
            for (CommandMessage subscription : gdd.getSubscriptions(clientId)) {
              log.debug("Resubscribing channel: %s - %s", clientId, subscription);
              handleSubscribeMessage(channelFactory, subscription, false);
            }
            access(clientId);
          }
        }
      } catch (Exception e) {
        log.error(
            e, "Could not recreate channel/subscriptions from distributed data: %s", clientId);
      }
    }

    return (timeChannel != null ? timeChannel.getChannel() : null);
  }
  protected <C extends Channel> C createChannel(ChannelFactory<C> channelFactory, String clientId) {
    C channel = null;
    if (clientId != null) {
      channel = getChannel(channelFactory, clientId);
      if (channel != null) return channel;
    }

    String clientType = GraniteContext.getCurrentInstance().getClientType();
    channel = channelFactory.newChannel(UUIDUtil.randomUUID(), clientType);
    TimeChannel<C> timeChannel = new TimeChannel<C>(channel);
    for (int i = 0; channels.putIfAbsent(channel.getId(), timeChannel) != null; i++) {
      if (i >= 10)
        throw new RuntimeException("Could not find random new clientId after 10 iterations");
      channel.destroy(false);
      channel = channelFactory.newChannel(UUIDUtil.randomUUID(), clientType);
      timeChannel = new TimeChannel<C>(channel);
    }

    String channelId = channel.getId();

    // Save channel id in distributed data (clustering).
    try {
      DistributedData gdd = graniteConfig.getDistributedDataFactory().getInstance();
      if (gdd != null) {
        log.debug("Saving channel id in distributed data: %s", channelId);
        gdd.addChannelId(channelId, channelFactory.getClass().getName(), clientType);
      }
    } catch (Exception e) {
      log.error(e, "Could not add channel id in distributed data: %s", channelId);
    }

    // Initialize timer task.
    access(channelId);

    return channel;
  }
  /* (non-Javadoc)
   * @see org.granite.tide.ejb.EJBServiceContextIntf#findComponent(java.lang.String)
   */
  @Override
  public Object findComponent(String componentName, Class<?> componentClass) {
    if ("identity".equals(componentName)) return identity;

    EjbComponent component = ejbLookupCache.get(componentName);
    if (component != null) return component.ejbInstance;

    // Compute EJB JNDI binding.
    String name = componentName;
    if (lookup != null) {
      name = lookup;
      if (lookup.contains(CAPITALIZED_DESTINATION_ID))
        name = lookup.replace(CAPITALIZED_DESTINATION_ID, capitalize(componentName));
      if (lookup.contains(DESTINATION_ID)) name = lookup.replace(DESTINATION_ID, componentName);
    }

    InitialContext ic = null;
    try {
      ic = new InitialContext();
    } catch (Exception e) {
      throw new ServiceException("Could not get InitialContext", e);
    }

    log.debug(">> New EjbServiceInvoker looking up: %s", name);

    try {
      component = new EjbComponent();
      component.ejbInstance = ic.lookup(name);
      component.ejbClasses = new HashSet<Class<?>>();
      Class<?> scannedClass = null;
      EjbScannedItemHandler itemHandler = EjbScannedItemHandler.instance();
      for (Class<?> i : component.ejbInstance.getClass().getInterfaces()) {
        if (itemHandler.getScannedClasses().containsKey(i)) {
          scannedClass = itemHandler.getScannedClasses().get(i);
          break;
        }
      }
      if (scannedClass == null)
        scannedClass = itemHandler.getScannedClasses().get(component.ejbInstance.getClass());
      // GDS-768: handle of proxied no-interface EJBs in GlassFish v3
      if (scannedClass == null && component.ejbInstance.getClass().getSuperclass() != null)
        scannedClass =
            itemHandler.getScannedClasses().get(component.ejbInstance.getClass().getSuperclass());

      if (scannedClass != null) {
        component.ejbClasses.add(scannedClass);
        for (Map.Entry<Class<?>, Class<?>> me : itemHandler.getScannedClasses().entrySet()) {
          if (me.getValue().equals(scannedClass)) component.ejbClasses.add(me.getKey());
        }
        component.ejbMetadata =
            new EjbServiceMetadata(scannedClass, component.ejbInstance.getClass());
      } else
        log.warn(
            "Ejb "
                + componentName
                + " was not scanned: remove method will not be called if it is a Stateful bean. Add META-INF/services-config.properties if needed.");

      ejbLookupCache.put(componentName, component);

      return component.ejbInstance;
    } catch (NamingException e) {
      log.error("EJB not found " + name + ": " + e.getMessage());
      throw new ServiceException("Could not lookup for: " + name, e);
    }
  }
  public boolean runReceived(AsyncHttpContext asyncHttpContext) {

    GravityInternal gravity = getGravity();

    if (asyncHttpContext != null && gravity.hasUdpReceiverFactory()) {
      UdpReceiverFactory factory = gravity.getUdpReceiverFactory();

      if (factory.isUdpConnectRequest(asyncHttpContext.getConnectMessage())) {
        createUdpReceiver(factory, asyncHttpContext);
        return true;
      }

      if (udpReceiver != null) {
        if (!udpReceiver.isClosed()) udpReceiver.close(false);
        udpReceiver = null;
      }
    }

    boolean httpAsParam = (asyncHttpContext != null);
    LinkedList<AsyncMessage> messages = null;
    OutputStream os = null;

    try {
      receivedQueueLock.lock();
      try {
        // Do we have any pending messages?
        if (receivedQueue.isEmpty()) return false;

        // Do we have a valid http context?
        if (asyncHttpContext == null) {
          asyncHttpContext = acquireAsyncHttpContext();
          if (asyncHttpContext == null) return false;
        }

        // Both conditions are ok, get all pending messages.
        messages = receivedQueue;
        receivedQueue = new LinkedList<AsyncMessage>();
      } finally {
        receivedQueueLock.unlock();
      }

      HttpServletRequest request = asyncHttpContext.getRequest();
      HttpServletResponse response = asyncHttpContext.getResponse();

      // Set response messages correlation ids to connect request message id.
      String correlationId = asyncHttpContext.getConnectMessage().getMessageId();
      AsyncMessage[] messagesArray = new AsyncMessage[messages.size()];
      int i = 0;
      for (AsyncMessage message : messages) {
        message.setCorrelationId(correlationId);
        messagesArray[i++] = message;
      }

      // Setup serialization context (thread local)
      GraniteContext context =
          HttpGraniteContext.createThreadIntance(
              gravity.getGraniteConfig(), gravity.getServicesConfig(), null, request, response);
      ((AMFContextImpl) context.getAMFContext())
          .setCurrentAmf3Message(asyncHttpContext.getConnectMessage());

      // Write messages to response output stream.
      GravityServletUtil.serialize(
          gravity, response, messagesArray, ContentType.forMimeType(request.getContentType()));

      return true; // Messages were delivered, http context isn't valid anymore.
    } catch (ServletException e) {
      log.error(e, "Configuration error for channel: %s", getId());

      return true;
    } catch (IOException e) {
      log.warn(e, "Could not send messages to channel: %s (retrying later)", getId());

      GravityConfig gravityConfig = getGravity().getGravityConfig();
      if (gravityConfig.isRetryOnError()) {
        receivedQueueLock.lock();
        try {
          if (receivedQueue.size() + messages.size()
              > gravityConfig.getMaxMessagesQueuedPerChannel()) {
            log.warn(
                "Channel %s has reached its maximum queue capacity %s (throwing %s messages)",
                getId(), gravityConfig.getMaxMessagesQueuedPerChannel(), messages.size());
          } else receivedQueue.addAll(0, messages);
        } finally {
          receivedQueueLock.unlock();
        }
      }

      return true; // Messages weren't delivered, but http context isn't valid anymore.
    } finally {
      // Cleanup serialization context (thread local)
      try {
        GraniteContext.release();
      } catch (Exception e) {
        // should never happen...
      }

      // Close output stream.
      try {
        if (os != null) {
          try {
            os.close();
          } catch (IOException e) {
            log.warn(e, "Could not close output stream (ignored)");
          }
        }
      } finally {
        // Cleanup http context (only if this method wasn't explicitly called with a non null
        // AsyncHttpContext from the servlet).
        if (!httpAsParam) releaseAsyncHttpContext(asyncHttpContext);
      }
    }
  }