简体   繁体   中英

Cometd Oort Cluster - Spring Integration

Getting null pointer exception on trying to integrate spring with cometd oort cluster:

<servlet>
        <servlet-name>cometd</servlet-name>
        <servlet-class>org.cometd.server.CometdServlet</servlet-class>
         <init-param>
            <param-name>transports</param-name>
           <param-value>org.cometd.websocket.server.WebSocketTransport</param-value>
        </init-param>
        <async-supported>true</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>cometd</servlet-name>
        <url-pattern>/cometd/*</url-pattern>
    </servlet-mapping>

Found this information on internet :If you use Spring to configure CometD objects, then you must not use configuration servlets such as OortMulticastConfigServlet. All your configuration belongs to Spring and you do everything in the initializer.

 <!-- 
    <servlet>
        <servlet-name>oort</servlet-name>
          <servlet-class>org.cometd.oort.OortStaticConfigServlet</servlet-class>
         <init-param>
             <param-name>oort.url</param-name>
            <param-value>http://10.30.3.106:9080/project/cometd</param-value>
        </init-param>
         <init-param>
            <param-name>oort.cloud</param-name>
            <param-value>http://10.30.1.112:8080/project/cometd</param-value>
        </init-param>
    </servlet>    -->

Does seti need to be configured in web.xml when using Spring ?

<servlet>
        <servlet-name>seti</servlet-name>
        <servlet-class>org.cometd.oort.SetiServlet</servlet-class>
    </servlet>

Cometd Integration with Spring :

package com.efacec.oms.powr.cometd;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletContext;

import org.apache.log4j.Logger;
import org.cometd.annotation.ServerAnnotationProcessor;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.oort.Oort;
import org.cometd.oort.Seti;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.ext.TimesyncExtension;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;

@Component
@Singleton
public class Configurer  implements DestructionAwareBeanPostProcessor, ServletContextAware
{
    private BayeuxServer bayeuxServer;
    private ServerAnnotationProcessor processor;
    private Oort oort;
    private Seti seti;
    private Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    BayeuxAuthenticator bayeuxAuthenticator;


    @Inject
    private void setBayeuxServer(BayeuxServer bayeuxServer)
    {
        this.bayeuxServer = bayeuxServer;
        this.bayeuxServer.addExtension(new TimesyncExtension());
       // BayeuxAuthenticator authenticator = new BayeuxAuthenticator();
        this.bayeuxServer.setSecurityPolicy(bayeuxAuthenticator);

    } 

    @PostConstruct
    public void init()
    {

         this.processor = new ServerAnnotationProcessor(bayeuxServer);

    }

    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
    {
        processor.processDependencies(bean);
        processor.processConfigurations(bean);
        processor.processCallbacks(bean);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException
    {
        return bean;
    }

    public void postProcessBeforeDestruction(Object bean, String name) throws BeansException
    {
        processor.deprocessCallbacks(bean);
    }


    @Bean(initMethod = "start", destroyMethod = "stop")
    public BayeuxServer bayeuxServer()
    {
        BayeuxServerImpl bean = new BayeuxServerImpl();
        bean.setOption(BayeuxServerImpl.LOG_LEVEL, "3");
       // bean.setOption(BayeuxServerImpl., "3");
        return bean;
    }


    @Bean(name="oort", initMethod = "start", destroyMethod="stop")
    public Oort oort()
    {
        oort = new Oort(this.bayeuxServer,"oortion");
                              //Using bayeuxServer(), throw null pointer exception
        return oort;
    }

Is it really required to set Attribute Seti and oort on servlet Context?

    @Bean(name="seti", initMethod = "start", destroyMethod="stop")
    public Seti seti(){
    Seti seti = new Seti(oort);
        return seti;
    }

    public void setServletContext(ServletContext servletContext)
    {
        servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
    //  servletContext.setAttribute(Seti.SETI_ATTRIBUTE, seti);
    //  servletContext.setAttribute(Oort.OORT_ATTRIBUTE, oort);

    }

}

Cannot associate userId with session. seti.associate(loginUserId, serverSession); Cannot Inject Seti and OOrt in Security policy.

package com.efacec.oms.powr.cometd;

import java.util.HashMap;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletContext;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerMessage;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.oort.Oort;
import org.cometd.oort.OortComet;
import org.cometd.oort.Seti;
import org.cometd.server.DefaultSecurityPolicy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;



@Component
@Singleton
public class BayeuxAuthenticator extends DefaultSecurityPolicy implements ServerSession.RemoveListener     // (1)
{
    private Seti seti;
    private Oort oort;
    private Logger logger = Logger.getLogger(this.getClass());


    @Autowired
    public void setSeti(Seti seti) {
        this.seti = seti;
    }

    @Autowired
    public void setOort(Oort oort) {
        this.oort = oort;
    }


    @Override
    public boolean canHandshake(BayeuxServer server, ServerSession serverSession, ServerMessage message)          //(2)
    {

        if (serverSession.isLocalSession())                                                                       //(3)
            return true;

        // Remote Oort comets are allowed to handshake
      /*  if (oort.isOortHandshake(message))
            return true;
        */

        Map<String, Object> ext = message.getExt();
        if (ext == null)
            return false;

        @SuppressWarnings("unchecked")
        Map<String, Object> authentication = (Map<String, Object>)ext.get("authentication");
        if (authentication == null)
            return false;



        Object user=authentication.get("user");


        String loginUserId=user.toString();
        boolean user_is_number=StringUtils.isNumeric(loginUserId) ? true:false;

        seti.associate(loginUserId, serverSession);
            serverSession.addListener(this);                                                                         // (6)
             return true;
        }

        else
        {
            logger.debug("Authentication Failure !! ::"+serverSession.getId());
            serverSession.addListener(this);                                                                         // (6)
            return false;

        }


    }

    public void removed(ServerSession remote, boolean expired)                                           //  (7)
    {



    }



}

Error Message :

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configurer': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.efacec.oms.powr.cometd.BayeuxAuthenticator com.efacec.oms.powr.cometd.Configurer.bayeuxAuthenticator; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bayeuxAuthenticator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.efacec.oms.powr.cometd.BayeuxAuthenticator.setSeti(org.cometd.oort.Seti); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seti' defined in class path resource [com/efacec/oms/powr/cometd/Configurer.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:232)
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:618)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:467)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4992)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5490)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.efacec.oms.powr.cometd.BayeuxAuthenticator com.efacec.oms.powr.cometd.Configurer.bayeuxAuthenticator; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bayeuxAuthenticator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.efacec.oms.powr.cometd.BayeuxAuthenticator.setSeti(org.cometd.oort.Seti); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seti' defined in class path resource [com/efacec/oms/powr/cometd/Configurer.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 23 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bayeuxAuthenticator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.efacec.oms.powr.cometd.BayeuxAuthenticator.setSeti(org.cometd.oort.Seti); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seti' defined in class path resource [com/efacec/oms/powr/cometd/Configurer.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 25 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.efacec.oms.powr.cometd.BayeuxAuthenticator.setSeti(org.cometd.oort.Seti); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seti' defined in class path resource [com/efacec/oms/powr/cometd/Configurer.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 36 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'seti' defined in class path resource [com/efacec/oms/powr/cometd/Configurer.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:989)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1017)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:960)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:553)
    ... 38 more
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.cometd.oort.Seti com.efacec.oms.powr.cometd.Configurer.seti()] threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
    ... 50 more
**Caused by: java.lang.NullPointerException
    at org.cometd.oort.Seti.<init>(Seti.java:82)
    at com.efacec.oms.powr.cometd.Configurer.seti(Configurer.java:100)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at** org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
    ... 51 more

I have added an example on how to configure Oort and Seti using Spring annotations.

As for your questions:

  1. The NullPointerException is due to the fact that methods on your Configurer class are called in an order that you don't expect. By the way, Configurer should be annotated with Spring's @Configuration rather than @Component ( COMETD-547 ).

  2. SetiServlet is the configuration Servlet for Seti , so if you configure CometD using Spring, you should configure Seti in Spring, not in web.xml .

  3. Setting Oort and Seti as ServletContext attribute is strongly recommended. It's a simple one liner in the Spring configuration, and allows you for full compatibility with code that uses those attributes.

Follow the example I linked above, and everything should be good.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM