Using Navigator Addon with other Custom Add-on using differents Servlets

Hi John,

I have tried to use Navigator Servlet with an other Servlet I should use extending Vaadin servlet too.
I neeeded that especially for IcePush Addon here
IcePush

As you can see Ice Push need also a custom servlet and I had to merge navigator servlet and icepush Servlet as there is only one decendant from VaadinApplication.

To achieve that, I used the sources provided in each Add-on and have tried to customize Servlet class.

I endeed up with that :

package org.company.core.ui;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.icepush.servlet.MainServlet;
import org.vaadin.artur.icepush.ICEPush;
import org.vaadin.artur.icepush.JavascriptProvider;
import org.vaadin.navigator7.WebApplication;

import com.vaadin.terminal.gwt.server.ApplicationServlet;

/** Extends Vaadin Servlet to instantiate the WebApplication class (or descendant) 
 * and attach it to the ServletContext. 
 * 
 * @author John Rizzo - BlackBeltFactory.com
 * 
 * */
public class NavigatorIcePushServlet extends ApplicationServlet {

	private static final long serialVersionUID = 8507549113847241656L;
    private MainServlet NavigatorIcePushServlet;

    private JavascriptProvider javascriptProvider;
	/**
     * Called by the servlet container to indicate to a servlet that the servlet
     * is being placed into service.
     * 
     * @param servletConfig
     *            the object containing the servlet's configuration and
     *            initialization parameters
     * @throws javax.servlet.ServletException
     *             if an exception has occurred that interferes with the
     *             servlet's normal operation.
     */
    @SuppressWarnings("unchecked")
    @Override
    public void init(javax.servlet.ServletConfig servletConfig)
            throws javax.servlet.ServletException {
        super.init(servletConfig);
        
        WebApplication.init(servletConfig, getServletContext(), getClassLoader());
        
        NavigatorIcePushServlet = new MainServlet(servletConfig.getServletContext());

        try {
            javascriptProvider = new JavascriptProvider(getServletContext()
                    .getContextPath());

            ICEPush.setCodeJavascriptLocation(javascriptProvider
                    .getCodeLocation());
        } catch (IOException e) {
            throw new ServletException("Error initializing JavascriptProvider",
                    e);
        }
    }
    
    /** I'd prefer to do that in a Filter, but it would be against the Vaadin current architecture 
     * Note that Vaadin TransactionListeners have no access to the ServletContext => we cannot use TransactionListeners. */
    @SuppressWarnings("unchecked")
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        WebApplication.beforeService(request, response, getServletContext());
        //Beggining icePush insertion
       String pathInfo = request.getPathInfo();
        if (pathInfo != null
                && pathInfo.equals("/" + javascriptProvider.getCodeName())) {
            // Serve icepush.js
            serveIcePushCode(request, response);
            return;
        }
        if (request.getRequestURI().endsWith(".icepush")) {
            // Push request
            try {
            	NavigatorIcePushServlet.service(request, response);
            } catch (ServletException e) {
                throw e;
            } catch (IOException e) {
                throw e;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            // Vaadin request
            super.service(request, response);
        }
        //End icePush insertion
        WebApplication.afterService(request, response, getServletContext());
        
 


    }
    
    private void serveIcePushCode(HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        String icepushJavscript = javascriptProvider.getJavaScript();

        response.setHeader("Content-Type", "text/javascript");
        response.getOutputStream().write(icepushJavscript.getBytes());
    }
    
    @Override
    public void destroy() {
        super.destroy();
        NavigatorIcePushServlet.shutdown();
    }
}

But when i use the push method, it seems there is a nullpointer inside the push method.

Maybe icePush Servlet isn’t compatible with navigator Servlet, I don’t really know…

This post shouldn’t be there but maybe you have also used icePush add-on and could send me some advice on how to mixt theses 2 Servlet.

Thanks :slight_smile:

Ok mates,

I could fix it by configuring web.xml rightly :wink:

Now i get a message " Adapting to Thread Blocking environment" when i try to use IcePush.
it seems push notification can be called only once… i don’t know why.

if I can fix it, I will post the whole Servlet Code maybe it could help vaadin developpers using both Icepush and navigator Servlet.

As a related note, there are now several add-ons which require their own servlet classes. It would be nice to make the servlets easier to extend and to compose of multiple parts, but it is very hard to see all the possible combinations nor all the “extension points” one might want to use.

I did not test this, but I guess you could directly extend IcePushServlet and simply add the three calls in a small subclass where init() and service() also call the corresponding superclass methods.

A possible bug: in the code you gave, WebApplication.beforeService() might not always be matched by a WebApplication.afterService().