Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Servlet is being initialized more than once?

I have a servlet that is called MyServlet. This servlet is bound in my web.xml file. This servlet is iterating over my Grails Services and looks after Services that ends with ListenerService. If so, it initializes a new Servlet for this Service.

I have the following Listener Services:

ChatListenerService
NotificationListenerService
ThirdListenerService

This means that I should get three Servlets generated by MyServlet. When you look at the output you see that the first Servlet is being generated three times, the second is generated twice and the third Service is generated once.

Here is the output I get:

2013-10-25 13:05:50,460 [localhost-startStop-1] INFO  cpr.AtmosphereServlet  - AtmosphereServlet with native support for Tomcat 6/7 and JBossWeb Installed.
>>>>>>>>>>>>>>> been: test.ChatListenerService@41028653
2013-10-25 13:05:50,577 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.ChatListenerService
2013-10-25 13:05:50,577 [localhost-startStop-1] INFO  test.MyServlet  - registered chatListener as handler for /atmosphere/chat/*
>>>>>>>>>>>>>>> been: test.NotificationListenerService@70b005e0
2013-10-25 13:05:50,582 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.NotificationListenerService
2013-10-25 13:05:50,582 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.ChatListenerService
2013-10-25 13:05:50,582 [localhost-startStop-1] INFO  test.MyServlet  - registered notificationListener as handler for /atmosphere/notification/*
>>>>>>>>>>>>>>> been: test.ThirdListenerService@4cba9be9
2013-10-25 13:05:50,587 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.NotificationListenerService
2013-10-25 13:05:50,587 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.ChatListenerService
2013-10-25 13:05:50,587 [localhost-startStop-1] INFO  handler.ReflectorServletProcessor  - Installing Servlet test.ThirdListenerService
2013-10-25 13:05:50,587 [localhost-startStop-1] INFO  test.MyServlet  - registered pedigreeListener as handler for /atmosphere/third/*
2013-10-25 13:05:50,587 [localhost-startStop-1] INFO  test.MyServlet  - Initialized MyServlet

What went wrong here? Since I iterate over each Service only once I do not see why the services are generated more than once. What do I have to fix?

my web.xml:

<servlet>
    <description>MyServlet</description>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>test.MyServlet</servlet-class>
    <load-on-startup>0</load-on-startup>

    <!-- If you want to use Servlet 3.0 -->
    <async-supported>true</async-supported>

    <init-param>
        <param-name>org.atmosphere.useNative</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.AtmosphereInterceptor</param-name>
        <param-value>org.atmosphere.interceptor.AtmosphereResourceLifecycleInterceptor,org.atmosphere.interceptor.HeartbeatInterceptor,org.atmosphere.client.TrackMessageSizeInterceptor</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.broadcaster.shareableThreadPool</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
           <param-name>org.atmosphere.useWebSocketAndServlet3</param-name>
           <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.Broadcaster.writeTimeout</param-name>
        <param-value>30000</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.sessionSupport</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
        <param-value>org.atmosphere.cache.UUIDBroadcasterCache</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/atmosphere/*</url-pattern>
</servlet-mapping>

my MyService class:

class MyServlet extends MeteorServlet {

    @Override
     void init(ServletConfig sc) throws ServletException {
         super.init(sc)

        def webApplicationContext = WebApplicationContextUtils.getWebApplicationContext sc.servletContext

        def grailsApplication = webApplicationContext.getBean("grailsApplication")

        def services = grailsApplication.getArtefacts "Service"

        def suffix = "Listener"

        services.each { serviceClass ->
            def serviceName = serviceClass.logicalPropertyName
            if(serviceName.endsWith(suffix)) {
                def prefix = serviceName - suffix

                def bean = webApplicationContext.getBean(serviceClass.clazz)

                def servlet = serviceClass.clazz

                String servletClass = bean.class.getName()
                ReflectorServletProcessor rsp = new ReflectorServletProcessor(bean)
                rsp.setServletClassName(servletClass)

                framework.addAtmosphereHandler("/atmosphere/${prefix}/*", rsp).initAtmosphereHandler(sc)        

                log.info "registered $serviceName as handler for /atmosphere/${prefix}/*"
            }
        }

        log.info "Initialized MyServlet"

     }  

My ChatListenerService (the other look similar):

class ChatListenerService extends HttpServlet {


    static transactional = false

        @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
          Meteor meteor = Meteor.build(request)
          ...
        }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
          Meteor meteor = Meteor.build(request)
          ...
        }
...
}

1 Answers

You're calling initAtmosphereHandler every time

framework.addAtmosphereHandler("/atmosphere/${prefix}/*", rsp).initAtmosphereHandler(sc)        

The addAtmosphereHandler() method simply registers the services. The call to initAtmosphereHandler actually instantiates them. The javadoc simply says

Initialize AtmosphereServletProcessor.

So first loop iteration, you have one registered service. In the second iteration, you have two registered services. In the third iteration, you have three registered services. In each iteration, all the services are instantiated.

Get rid of the initAtmosphereHandler call and do it outside the each loop.

like image 82
Sotirios Delimanolis Avatar answered Feb 02 '26 01:02

Sotirios Delimanolis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!