OSGi

Hi,

Looking at various sources on the internet, I’m a little confused as to what the current practice is of using Vaadin 7 in an OSGi environment, more specifically, using Vaadin in an embedded Jetty server which to is embedded in an OSGi environment.

A few months back I got the current code to work:

== WEB SERVER ==
[font=Courier New]
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(9080);
connector.setMaxIdleTime(30000);

    WebAppContext context = new WebAppContext("webapps/processes", "/");
    context.setDefaultsDescriptor(null);
    context.addServlet(new ServletHolder(new MyApplication.Servlet()), "/*");

    ContextHandlerCollection handlerCollection = new ContextHandlerCollection();
    handlerCollection.addHandler(context);

    server.addConnector(connector);
    server.setHandler(handlerCollection);
    server.start();
    server.join();

[/font]

== VAADIN APPLICATION ==
[font=Courier New]
public class MyApplication extends Application {

@Override
protected Root getRoot(WrappedRequest request) throws RootRequiresMoreInformationException {
return new ProcessAdminRoot();
}

@WebServlet(urlPatterns = “/*”)
public static class Servlet extends AbstractApplicationServlet {

@Override
protected Application getNewApplication(HttpServletRequest request) throws ServletException {
  return new MyApplication();
}

@Override
protected Class<? extends Application> getApplicationClass() throws ClassNotFoundException {
  return MyApplication.class;
}

}
}
[/font]

== ROOT ==
[font=Courier New]
public final class MyRoot extends Root {

@Override
protected void init(final WrappedRequest request) {
final VerticalLayout view = new VerticalLayout();
Label label = new Label(“Hello World”);
view.addComponent(label);
setContent(view);
}
}

[/font]

Does the above approach still apply to the released version of Vaadin 7?

Thanks,
Jorge

Hi,

I’m assuming that somthing that used to be fairly simple, has become terribly complicated in Vaadin 7

Hi Jorge,
yes it seems to be difficult to solve the topic easily.
Maybe my last post https://vaadin.com/forum/-/message_boards/view_message/2487315 can give you some hints.

Cheers, Mario

Hi Mario,

Thanks for taking the time to respond to my post.

I’ve kinda looked at the link provided and the package at github before. My first impression of the github package looked overly complicated - I’ll try looking at it again in the future if that is the only source of information for using Vaadin 7 in an OSGi environment, unfortunately I don’t have time to look at it for the current project so Vaadin 7 wiil have to sit out for this one.

Thanks again,
Jorge

Hi,

As a proof of concept I got the following “Hello World” application to work.

I have not done extensive testing but constructive criticisms and suggestions are more than welcome.

[b]

Create a class that extends VaadinServlet

[/b]

    public final class VaadinOSGiServlet extends VaadinServlet {
      private static final long serialVersionUID = -6803764941423184854L;
      @Override
      protected VaadinServletService createServletService(final DeploymentConfiguration deploymentConfiguration) {
        VaadinOSGiServletService servletService = new VaadinOSGiServletService(this, deploymentConfiguration);
        return servletService;
      }
    }

[b]

Create a class that extends VaadinServletService

[/b]

    public final class VaadinOSGiServletService extends VaadinServletService {
      private static final long serialVersionUID = -6452889839000802542L;
      public VaadinOSGiServletService(final VaadinServlet servlet, final DeploymentConfiguration deploymentConfiguration) {
        super(servlet, deploymentConfiguration);
      }
      @Override
      protected VaadinSession createVaadinSession(final VaadinRequest request) throws ServiceException {
        VaadinOSGiSession session = new VaadinOSGiSession(this);
        return session;
      }
    }

[b]

Create a class that extends VaadinSession

[/b]

    public final class VaadinOSGiSession extends VaadinSession {
      private static final long serialVersionUID = -7624953346675752761L;
      private final List<UIProvider> uiProviders;
      public VaadinOSGiSession(VaadinService service) {
        super(service);
        uiProviders = new ArrayList<UIProvider>() {
          private static final long serialVersionUID = -9193410632996461485L;
          {
            add(OSGiUIProvider.instance());
          }
        };
      }
      @Override
      public List<UIProvider> getUIProviders() {
        return uiProviders;
      }
    }

[b]

Create a class that extends UIProvider

[/b]

    public final class OSGiUIProvider extends UIProvider {
      private static final long serialVersionUID = 1451931523729856181L;
      private static final OSGiUIProvider INSTANCE = new OSGiUIProvider();
      private OSGiUIProvider() {}
      public static OSGiUIProvider instance() {
        return INSTANCE;
      }
      @Override
      public Class<? extends UI> getUIClass(final UIClassSelectionEvent event) {
        return Greeter.class;
      }
      @Override
      public UI createInstance(final UICreateEvent e) {
        UI ui = new Greeter();
        return ui;
      }
    }

[b]

Create a class that extends UI

[/b]

  public final class Greeter extends UI {
    private static final long serialVersionUID = -7333618595654346783L;
    @Override
    protected void init(final VaadinRequest request) {
      final VerticalLayout view = new VerticalLayout();
      final Label label = new Label("Hello World");
      view.addComponent(label);
      setContent(view);
    }
  }

[b]

Register the VaadinOSGiServlet (usging jetty web server)

[/b]

    final WebAppContext context = new WebAppContext("webapps/greeter", "/");
    context.setDefaultsDescriptor(null);
    context.addServlet(new ServletHolder(VaadinOSGiServlet.class),"/*");

[b]

Under the directory that was registered in the WebAppContext class create the following structure:

[/b]

     webapps
      |__greeter
          |__VAADIN  
          |   |__themes               (extracted from vaadin-themes-7.0.0.jar)
          |   |__widgetsets           (extracted from vaadin-client-compiled-7.0.0.jar)
          |   |__vaadinBootstrap.js   (extracted from vaadin-server-7.0.0.jar)
          |__WEB-INF   
              |__web.xml

[b]

Deploy the following OSGi bundles:

[/b]

    com.vaadin.client-compiled-7.0.0.jar
    com.vaadin.server-7.0.0.jar
    com.vaadin.shared-7.0.0.jar
    com.vaadin.themes-7.0.0.jar
    com.vaadin.shared.deps-1.0.2.jar
    org.jsoup-1.6.3.jar

I’m not certain if this would work, but it might be possible to simplify this so that you don’t need custom VaadinOSGiServletService and VaadinOSGiSession classes.

Instead, you could register a SessionInitListener in VaadinOSGiServlet.init(…), and do event.getSession().addUIProvider(OSGiUIProvider.instance()) in sessionInit(SessionInitEvent) of the listener.

If you need to eliminate other UIProviders, it gets a little more complicated.

Not sure if I’m on the right track here but I’ve tried the following:


in VaadinOSGiServlet

  @Override
  public void init() throws ServletException {
    super.init();
    getService().addSessionInitListener(new SessionInitListener() {
      private static final long serialVersionUID = -3430847247361456116L;
      @Override
      public void sessionInit(SessionInitEvent e) throws ServiceException {
        e.getSession().addUIProvider(OSGiUIProvider.instance());
      }
    });
  }

but getService() returns null at this point which probably makes sense. Should I be registering the SessionInitListener elsewhere?

Thanks,
Jorge

Hi Henri,

You gave me another idea…

Instead of overriding the createServletService method in VaadinOSGiServlet the way I originally did, do the following:

  @Override
  protected VaadinServletService createServletService(DeploymentConfiguration deploymentConfiguration) {
    VaadinServletService service = super.createServletService(deploymentConfiguration);
    service.addSessionInitListener(new SessionInitListener() {
      private static final long serialVersionUID = -3430847247361456116L;

      @Override
      public void sessionInit(SessionInitEvent e) throws ServiceException {
        e.getSession().addUIProvider(OSGiUIProvider.instance());
      }
    });
    return service;
  }

Adding listeners always comes with a question - WHEN AND WHERE DO WE REMOVE THE LISTENER WHEN WE’RE DONE WITH IT?

Jorge

With respect to removing the SessionInitListener, I think the following would probably be best:

public final class VaadinOSGiServlet extends VaadinServlet {
  private static final long serialVersionUID = -6803764941423184854L;

  @Override
  protected VaadinServletService createServletService(DeploymentConfiguration deploymentConfiguration) {
    final VaadinServletService service = super.createServletService(deploymentConfiguration);
    service.addSessionInitListener(new SessionInitListener() {
      private static final long serialVersionUID = -3430847247361456116L;
      @Override
      public void sessionInit(SessionInitEvent e) throws ServiceException {
        e.getSession().addUIProvider(OSGiUIProvider.instance());
        service.removeSessionInitListener(this);
      }
    });
    return service;
  }
}

Jorge