To deploy a portlet WAR in a portal, you need to provide the basic portlet.xml descriptor specified in the Java Portlet standard. In addition, you may need to include possible portal vendor specific deployment descriptors. The ones required by Liferay are described below.

The portlet WAR must include a portlet descriptor located at WebContent/WEB-INF/portlet.xml. A portlet definition includes the portlet name, mapping to a servlet in web.xml, modes supported by the portlet, and other configuration. Below is an example of a simple portlet definition in portlet.xml descriptor.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<portlet-app
  xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="2.0"
  xsi:schemaLocation=
    "http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
     http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">

  <portlet>
    <portlet-name>Portlet Example portlet</portlet-name>
    <display-name>Vaadin Portlet Example</display-name>

    <!-- Map portlet to a servlet. -->
    <portlet-class>
      com.vaadin.terminal.gwt.server.ApplicationPortlet2
    </portlet-class>
    <init-param>
      <name>application</name>

      <!-- The application class with package name. -->
      <value>com.example.myportlet.MyportletApplication</value>
    </init-param>

    <!-- Supported portlet modes and content types. -->
    <supports>
      <mime-type>text/html</mime-type>
      <portlet-mode>view</portlet-mode>
      <portlet-mode>edit</portlet-mode>
      <portlet-mode>help</portlet-mode>
    </supports>

    <!-- Not always required but Liferay requires these. -->
    <portlet-info>
      <title>Vaadin Portlet Example</title>
      <short-title>Portlet Example</short-title>
    </portlet-info>
  </portlet>
</portlet-app>

Listing supported portlet modes in portlet.xml enables the corresponding portlet controls in the portal user interface that allow changing the mode, as described later.

The portlet deployment descriptor for Portlet 1.0 API is largely the same as for Portlet 2.0. The main differences are:

  1. XML namespace and schema names

  2. Portlet-class: ApplicationPortlet vs ApplicationPortlet2

  3. The application parameter is a name of the servlet (defined in web.xml in Portlet 1.0, but name of the application class in Portlet 2.0. There is no longer a separate web.xml file in Servlet 2.0.

  4. The portlet-name must not be same as the servlet name in Portlet 1.0; in Portlet 2.0 this does not matter.

Below is an example of a complete deployment descriptor for Portlet 1.0:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app
  version="1.0"
  xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation=
       "http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
        http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

  <portlet>
    <!-- Must not be the same as servlet name. -->
    <portlet-name>Portlet Example portlet</portlet-name>
    <display-name>Vaadin Portlet Example</display-name>

    <!-- Map portlet to a servlet. -->
    <portlet-class>
      com.vaadin.terminal.gwt.server.ApplicationPortlet
    </portlet-class>
    <init-param>
      <name>application</name>

      <!-- Must match the servlet URL mapping in web.xml. -->
      <value>portletexample</value>
    </init-param>

    <!-- Supported portlet modes and content types. -->
    <supports>
      <mime-type>text/html</mime-type>
      <portlet-mode>view</portlet-mode>
      <portlet-mode>edit</portlet-mode>
      <portlet-mode>help</portlet-mode>
    </supports>

    <!-- Not always required but Liferay requires these. -->
    <portlet-info>
      <title>Vaadin Portlet Example</title>
      <short-title>Portlet Example</short-title>
    </portlet-info>
  </portlet>
</portlet-app>

The value of the application parameter must match the context in the <url-pattern> element in the <servlet-mapping> in the web.xml deployment descriptor, without the path qualifiers in the pattern. The above example would match the following servlet mapping in web.xml:

  <servlet-mapping>
      <servlet-name>Portlet Example</servlet-name>
      <url-pattern>/portletexample/*</url-pattern>
  </servlet-mapping>

In fact, it would also match the /* mapping.

If you have just one Vaadin application that you ever need to run in your portal, you can just deploy the WAR as described above and that's it. However, if you have multiple applications, especially ones that use different custom widget sets, you run into problems, because a portal window can load only a single Vaadin widget set at a time. You can solve this problem by combining all the different widget sets in your different applications into a single widget set using inheritance or composition.

For example, the portal demos defined in the portlet.xml in the demo WAR have the following setting for all portlets so that they will all use the same widget set:

<portlet>
  ...
  <!-- Use the portal default widget set for all portal demos. -->
  <init-param>
    <name>widgetset</name>
    <value>com.vaadin.portal.gwt.PortalDefaultWidgetSet</value>
  </init-param>
  ...

The PortalDefaultWidgetSet extends SamplerWidgetSet, which extends the DefaultWidgetSet. The DefaultWidgetSet is therefore essentially a subset of PortalDefaultWidgetSet, which contains also the widgets required by the Sampler demo. Other applications that would otherwise require only the regular DefaultWidgetSet, and do not define their own widgets, can just as well use the larger set, making them compatible with the demos. The PortalDefaultWidgetSet will also be the default Vaadin widgetset bundled in Liferay 5.3 and later.

If your portlets are contained in multiple WARs, which can happen quite typically, you need to install the widget set and theme portal-wide so that all the portlets can use them. See Section 13.5, “Installing Vaadin in Liferay” on configuring the widget sets in the portal itself.