5 Replies Latest reply on Apr 13, 2007 8:18 AM by rolmovel

    Servlet as a topic listener

      Hi, I,m trying to subscribe a servlet to a topic for event notifying to clients (with lazy loading technology) but when i instance the servlet from the IExplorer i get next exception:

      12:25:58,989 ERROR [STDERR] javax.jms.IllegalStateException: This method is not applicable inside the application server. See the J2EE spec, e.g. J2EE1.4 Section 6.6
      12:25:58,989 ERROR [STDERR] at org.jboss.resource.adapter.jms.JmsSession.checkStrict(JmsSession.java:542)
      12:25:58,989 ERROR [STDERR] at org.jboss.resource.adapter.jms.JmsMessageConsumer.setMessageListener(JmsMessageConsumer.java:136)
      12:25:58,989 ERROR [STDERR] at elimina.ServletPrueba.service(ServletPrueba.java:79)
      12:25:58,989 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
      12:25:58,989 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
      12:25:58,989 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
      12:25:58,989 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
      12:25:58,989 ERROR [STDERR] at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
      12:25:58,989 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
      12:25:58,989 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
      12:25:58,989 ERROR [STDERR] at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
      12:25:58,989 ERROR [STDERR] at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
      12:25:58,989 ERROR [STDERR] at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
      12:25:58,989 ERROR [STDERR] at java.lang.Thread.run(Unknown Source)
      12:25:59,005 INFO [CachedConnectionManager] Closing a connection for you. Please close them yourself: org.jboss.resource.adapter.jms.JmsSession@ed7f5c
      java.lang.Throwable: STACKTRACE
       at org.jboss.resource.connectionmanager.CachedConnectionManager.registerConnection(CachedConnectionManager.java:290)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:417)
       at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:842)
       at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.allocateConnection(JmsSessionFactoryImpl.java:389)
       at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.createTopicSession(JmsSessionFactoryImpl.java:166)
       at elimina.ServletPrueba.service(ServletPrueba.java:75)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:175)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.jboss.web.tomcat.tc5.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:156)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Unknown Source)
      
      


      Here is the code ...
      
      package elimina;
      
      import javax.jms.Message;
      import javax.jms.Session;
      import javax.jms.TextMessage;
      import javax.jms.Topic;
      import javax.jms.TopicConnection;
      import javax.jms.TopicConnectionFactory;
      import javax.jms.TopicSession;
      import javax.jms.TopicSubscriber;
      import javax.management.ObjectName;
      import javax.naming.Context;
      import javax.naming.InitialContext;
      import javax.servlet.http.HttpServlet;
      
      import java.io.IOException;
      import java.util.Hashtable;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      /**
       * Servlet Class
       *
       * @web.servlet name="ServletPrueba"
       * display-name="Name for ServletPrueba"
       * description="Description for ServletPrueba"
       * @web.servlet-mapping url-pattern="/ServletPrueba"
       * @web.servlet-init-param name="A parameter"
       * value="A value"
       */
      public class ServletPrueba extends HttpServlet implements javax.jms.MessageListener {
      
       public ServletPrueba() {
       // TODO Auto-generated constructor stub
       }
      
       public void onMessage (Message message) {
       try {
       TextMessage textMessage = (TextMessage) message;
       System.out.println("Mensaje recibido");
       } catch (Exception e) {
       // Ver excepciones y tratamiento
       System.out.println(e);
       }
       }
      
       protected void service(HttpServletRequest req, HttpServletResponse resp)
       throws ServletException,
       IOException {
       // TODO Auto-generated method stub
       Topic topic = null;
       TopicConnectionFactory topicConnectionFactory = null;
       TopicConnection topicConnection = null;
      
       super.service(req, resp);
       try {
       Hashtable props = new Hashtable();
       props.put(
       Context.INITIAL_CONTEXT_FACTORY,
       "org.jnp.interfaces.NamingContextFactory");
       props.put(
       Context.URL_PKG_PREFIXES,
       "org.jboss.naming:org.jnp.interfaces");
       props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
       Context ctx = new InitialContext(props);
      
       topicConnectionFactory = (TopicConnectionFactory)ctx.lookup("TopicConnectionFactory");
       topic = (Topic)ctx.lookup("topic/testTopic");
       ctx.close();
      
       // conectamos
       topicConnection = topicConnectionFactory.createTopicConnection();
       TopicSession topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
      
      
       TopicSubscriber topicSubscriber = topicSession.createSubscriber(topic);
       topicSubscriber.setMessageListener(this);
      
       topicConnection.start();
       for (;;) {
       java.io.OutputStream out = resp.getOutputStream();
       out.write("1".getBytes());
       out.write(new byte[450]);
       out.flush();
       Thread.sleep(100);
       }
      
       } catch (Exception e) {
       // Ver que excepciones lanza y el trataimento
       e.printStackTrace();
       }
      
      
       }
      
      }


      Thanks in advanced

        • 1. Re: Servlet as a topic listener
          genman

          Not sure why you'd receive messages inside a servlet. This seems like an awful hack.

          I would recommend creating an MBean service to receive traffic instead.

          http://wiki.jboss.org/wiki/Wiki.jsp?page=ExampleHelloWorldService

          • 2. Re: Servlet as a topic listener

            do you mean to create an mbean subscribing the queue and a servlet accessing the Mbean?

            thanks in advance...

            • 3. Re: Servlet as a topic listener

              Finally I had to deploy the web application in a standalone tomcat. It seems to work... But, what´s happening with jboss? Why can´t do that in the embeded tomcat? Perhaps a bug?

              • 4. Re: Servlet as a topic listener
                timfox

                Firstly I agree with genman that what you're trying to do sounds like an awful hack.

                I also notice from your stack trace that you're using the JMS JCA resource adapter which is normally available at java:JmsXA when inside the app server. The resource adapter is correctly noticing that you're not closing connections in your code (i.e. a bug).

                Also, when using the JCA adapter you can't use methods like setMessageListener, as per the spec.

                What's probably happening is that when running "standalone" you are not using the JCA resource adapter - just the straight jms connection factory - which will not report you not closing connections, and will allow you to use the full JMS API.

                If you want this to work inside the app server make sure you don't use the JMS resource adapter.

                But I would first advise you to rethink your architecture - since this all seems quite hackish to me, and looking up a connection factory, creating s connection, creating a subscriber, getting message and closing connection every time, is not going to be fast.

                • 5. Re: Servlet as a topic listener

                  thanks for your comments, but do you know a better way to push data from server to browsers?

                  Tahnks in advance...