> Markdown version of [Creating Vaadin Portlets](https://vaadin.com/docs/v14/flow/integrations/portlet/creating-vaadin-portlets). Section index: [llms.txt](https://vaadin.com/docs/v14/flow/llms.txt)

# Creating Vaadin Portlets

In this chapter, we will learn how to create Vaadin Portlets and deploy them to the [Liferay 7 Digital Experience Platform](https://liferay.com/products/dxp) or the [Pluto 3.1 Portal](https://portals.apache.org/pluto/index.html).

Pluto is a reference implementation for the Portlet specification and, although it is good for testing, it should not be used in a production environment.

## <a id="creating-a-vaadin-portlet"></a>Creating a Vaadin Portlet

We have two ways to start creating our Vaadin Portlet: from scratch or from the [base-starter-flow-portlet](https://github.com/vaadin/base-starter-flow-portlet) project. The starter project contains everything needed to quickly create your own Vaadin Portlet, with the code laid out in advance.

In order to become familiar with setting up a Vaadin Portlet project manually, we will start with a simple Vaadin project and then convert it to a Vaadin Portlet project.

### <a id="setting-up-portlet-project"></a>Setting Up Portlet Project

First, download the [Vaadin base starter](https://github.com/vaadin/skeleton-starter-flow/tree/v14/)

Next, update your `pom.xml`:

1. Add the following dependencies:

   pom.xml additions

   ```xml
   <dependency>
       <groupId>com.vaadin</groupId>
       <artifactId>vaadin-portlet</artifactId>
       <version>1.0.0</version>
   </dependency>
   ```

   ```xml
   <dependency>
       <groupId>javax.portlet</groupId>
       <artifactId>portlet-api</artifactId>
       <version>3.0.1</version>
       <scope>provided</scope>
   </dependency>
   ```

2. Add the `build-frontend` goal to `vaadin-maven-plugin`, as Vaadin Portlet does not work in development mode running `webpack-dev-server`.

### <a id="creating-the-portlet"></a>Creating the Portlet

In the most basic setup, Vaadin Portlets consist of two classes:

- A **portlet class**, which extends `VaadinPortlet` or `VaadinLiferayPortlet` (when running in Liferay)

The portlet class acts as the entry point for our Vaadin Portlet application. It serves a similar function to a Servlet, but in a portlet context.

- A portlet **view class**, which extends `Component`

The view class, which can be any normal Vaadin component, holds the contents of our Vaadin Portlet. You could use an existing component – through extension, composition, or as is – or just create an entirely new component for your Vaadin Portlet. `VaadinPortlet` and `VaadinLiferayPortlet` are generic classes and take the selected view class as a type parameter.

#### <a id="preparing-the-classes"></a>Preparing the Classes

Find the `MainView.java` provided with the project and create `MyPortlet.java` in the same folder. Inside the file, add the following code:

MyLiferayPortlet.java for Liferay Portals

```java
@PortletConfiguration(
    portletName = "MyLiferayPortlet",
    dependencies = @Dependency(name = "PortletHub", scope = "javax.portlet", version = "3.0.0")
)
public class MyLiferayPortlet extends VaadinLiferayPortlet<MainView> {

}
```

MyPortlet.java for non-Liferay Portals

```java
public class MyPortlet extends VaadinPortlet<MainView> {

}
```

Next, open `MainView.java`. Remove both the `@Route` and `@PWA` annotations. These do not make sense for our portlet.

The final code should look something like this:

MainView\.java

```java
public class MainView extends VerticalLayout {

    public MainView() {
        Button button = new Button("Click me",
                event -> Notification.show("Clicked!"));
        add(button);
    }
}
```

When a user clicks on the button, a notification with the text "Clicked!" should appear in the lower-left corner of the browser window. Your Vaadin Portlet is almost ready to go. We just need to get it ready for deployment.

### <a id="setting-a-portlet-deployment-descriptor"></a>Setting a Portlet Deployment Descriptor

In the Portlet 3.0 specification, a portlet deployment descriptor can be configured in two ways:

- `portlet.xml` (backwards compatible)

- annotations (only 3.0)

We will use the `portlet.xml` to configure our portlet deployment. `portlet.xml` serves the same purpose as `web.xml` does for servlets.

Create `portlet.xml` under `{project directory}/src/main/webapp/WEB-INF` and add the following contents:

portlet.xml

```xml
<?xml version="1.0"?>
<portlet-app xmlns="http://xmlns.jcp.org/xml/ns/portlet"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet http://xmlns.jcp.org/xml/ns/portlet/portlet-app_3_0.xsd"
             version="3.0">
    <portlet>
        <portlet-name>MyLiferayPortlet</portlet-name>
        <display-name>MyLiferayPortlet</display-name>
        <portlet-class>org.vaadin.example.MyPortlet</portlet-class>
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>view</portlet-mode>
        </supports>
        <portlet-info>
            <title>My Test Portlet - MyPortlet</title>
            <short-title>My Test Portlet</short-title>
            <keywords></keywords>
        </portlet-info>
    </portlet>
</portlet-app>
```

The `<portlet-class>` points to your class extending `VaadinPortlet`/`VaadinLiferayPortlet` with a fully qualified name. The `<supports>` section contains the portlet modes (`<portlet-mode>` tag) that the portlet supports. You can learn more about portlet modes for Vaadin Portlet in [the next chapter](https://vaadin.com/docs/v14/flow/integrations/portlet/handling-portlet-phases.md)

### <a id="setting-portlet-descriptors-specific-to-liferay"></a>Setting Portlet Descriptors Specific to Liferay

To run Vaadin Portlets in Liferay Portal, the following descriptors are also needed:

- `liferay-display.xml` - describes the category the portlet appears under in the `Add` menu of Liferay’s Widgets bar.

- `liferay-portlet.xml` - describes Liferay-specific enhancements for JSR-286 portlets installed on a Liferay Portal server.

Create `liferay-display.xml` and `liferay-portlet.xml` under `{project directory}/src/main/webapp/WEB-INF` and add the following contents:

<!-- vale Vale.Terms = NO -->

<!-- vale Vale.Spelling = NO -->

liferay-display.xml

```xml
<?xml version="1.0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 6.2.0//EN" "http://www.liferay.com/dtd/liferay-display_6_2_0.dtd">

<display>
    <category name="Vaadin Liferay Portlets">
        <portlet id="MyLiferayPortlet" />
    </category>
</display>
```

liferay-portlet.xml

```xml
<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 7.1.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_7_1_0.dtd">

<liferay-portlet-app>
    <portlet>
        <portlet-name>MyLiferayPortlet</portlet-name>
        <!-- Instanceable parameter means whether we can add the Portlet more than once on same page.-->
        <instanceable>false</instanceable>
    </portlet>
</liferay-portlet-app>
```

<!-- vale Vale.Terms = YES -->

<!-- vale Vale.Spelling = YES -->

> **Note:** The `instanceable` parameter specifies whether the Portlet can be added more than once on the same page. If it is `false`, then the Portlet can be added only once on a page.

### <a id="setting-an-external-stats-url-for-liferay"></a>Setting an External Stats URL for Liferay

If your portlet runs in the **Liferay Portal**, add the following `flow-build-info.json` resource file into `{project directory}/src/main/resources/META-INF/VAADIN/config` with the contents:

flow-build-info.json

```json
{
    "externalStatsUrl": "/o/vaadin-portlet-static/VAADIN/config/stats.json"
}
```

## <a id="deploying-your-vaadin-portlet"></a>Deploying Your Vaadin Portlet

### <a id="building-a-vaadin-portlet"></a>Building a Vaadin Portlet

In order to build the portlet we just created, we need to add some more configuration to the `pom.xml`. Vaadin Portlet deployments are packaged into two `WAR` files. One `WAR` file contains all the static resources shared by the Vaadin Portlets, and the other `WAR` file contains the actual portlets. This allows for more complex scenarios where multiple portlets come from separate `WAR` files. See [Creating a Multi-Module Portlet Project](https://vaadin.com/docs/v14/flow/integrations/portlet/creating-multi-module-portlet-project.md).

Add the following plugin configuration to the `pom.xml`:

```xml
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.2.3</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Implementation-Title>${project.name}</Implementation-Title>
                <Implementation-Version>${project.version}</Implementation-Version>
            </manifestEntries>
        </archive>
    </configuration>
    <!-- Generate 2 war archives for portlet. One for the portlet(s) and another for the static files -->
    <executions>
        <!-- Generate a static war 'vaadin-portlet-static.war' with all static files -->
        <execution>
            <id>static-files</id>
            <goals>
                <goal>war</goal>
            </goals>
            <configuration>
                <warName>vaadin-portlet-static</warName>
                <!-- static files should contain flow-client and all build files generated in VAADIN/ -->
                <packagingIncludes>WEB-INF/lib/flow-client*.jar,WEB-INF/lib/vaadin-portlet*.jar,VAADIN/</packagingIncludes>

                <webResources>
                    <resource>
                        <!-- this is relative to the pom.xml directory -->
                        <directory>target/classes/META-INF/</directory>
                        <!-- Include all files and folders below <directory> -->
                        <includes>
                            <include>**</include>
                        </includes>
                        <!-- do not include configuration files -->
                        <excludes>
                            <exclude>VAADIN/config/**</exclude>
                        </excludes>
                    </resource>
                </webResources>
            </configuration>
        </execution>
        <!-- Generate the portlet war excluding any static build files -->
        <execution>
            <id>portlet-war</id>
            <goals>
                <goal>war</goal>
            </goals>
            <configuration>
                <primaryArtifact>true</primaryArtifact>
                <packagingExcludes>WEB-INF/classes/META-INF/VAADIN/build/**,VAADIN/</packagingExcludes>
            </configuration>
        </execution>
    </executions>
</plugin>
```

Here we build two `WAR` files – one for the application (all portlets in this project) and one for the static files needed by the portlets (which contains the frontend bundle and client engine).

The static `WAR` is built as a portal window and can load only a single Vaadin bundle and client engine at a time. This provides a simple way for all the portlets on the page to use the same static bundle.

#### <a id="configuring-static-resources"></a>Configuring Static Resources

If you need to change the name of the static assets `WAR` (`vaadin-portlet-static` as default), you can do that via the `vaadin.portlet.static.resources.mapping` application property. For example, if you would like to serve static resources from `vaadin-static-resources.war`, you will need to

- rename the static `WAR` to `vaadin-static-resources` in the `pom.xml`

- rename the static portlet name in `flow-build-info.json` (if Liferay is used)

- pass the value `/vaadin-static-resources/` (for the **Liferay Portal**, it would be `/o/vaadin-portlet-resources/`) via the application property to the Vaadin application; that is, on a Tomcat web server, you would:

  - on \*nix-based operating systems, create or edit the file `$CATALINA_BASE/bin/setenv.sh` with the line\
    `JAVA_OPTS="$JAVA_OPTS -Dvaadin.portlet.static.resources.mapping=/vaadin-static-resources/"`

  - on Windows operating systems, create or edit the file `%CATALINA_BASE%\bin\setenv.bat` with the line\
    `set "JAVA_OPTS=%JAVA_OPTS% -Dvaadin.portlet.static.resources.mapping=/vaadin-static-resources/"`

### <a id="deploying-a-vaadin-portlet-to-liferay-7"></a>Deploying a Vaadin Portlet to Liferay 7

<!-- vale Vale.Spelling = NO -->

1. Run `mvn install` in your project directory.

2. Download the [Liferay Bundle](https://github.com/liferay/liferay-portal/releases) and extract it to a location of your choice.

3. Add the following parameter to Liferay Tomcat’s `setenv.sh` (`{liferay home}/tomcat-<version>/bin`): `-Dvaadin.portlet.static.resources.mapping=/o/vaadin-portlet-static/`

4. Download and copy the JNA dependency `JARs` of a specific version into `{liferay home}/tomcat-<version>/webapps/ROOT/WEB-INF/lib` (or `shielded-container-lib` depending on the version): [net.java.dev.jna:jna:5.7.0](https://mvnrepository.com/artifact/net.java.dev.jna/jna/5.7.0), [net.java.dev.jna:jna-platform:5.7.0](https://mvnrepository.com/artifact/net.java.dev.jna/jna-platform/5.7.0). This is needed because Vaadin Portlet uses a newer version of the JNA library, which can cause conflicts with the version that Liferay uses.

5. Create a `portal-ext.properties` file in Liferay’s home directory and place the following property there: `javascript.single.page.application.enabled=false`.

6. Copy both `*.war` files from `{project directory}/target` into `{liferay home}/deploy`.

7. Start the web server by

   - opening a command prompt in the `{bundle extract directory}` folder

   - running the command `./{tomcat-version}/bin/startup.sh` or `./{tomcat-version}/bin/startup.bat` (Unix/Windows)

8. Once the web server has started, navigate to <http://localhost:8080/>

9. Follow the instructions of the Liferay Wizard to set up a new user and sign in to the Portal.

10. Click on the "Menu" button at the top-left corner to open the menu console.

11. Find and click on the "Page tree" link and click on the "+" button to add a new page.

12. Select "Widget Page", give it a name and select an appropriate layout.

13. In the "Look and Feel" tab, select "Define a specific look and feel for this page" and enable "Show Maximize/Minimize".

14. Click "Save" and navigate to the home page, then to the layout you just created.

15. Click the "Add" button, which is usually at the top-right corner, find category "Vaadin Liferay Portlets", open it and drag and drop the portlet item from the panel to the page.

16. You should see the portlet with the title "MY TEST PORTLET - MYPORTLET", and a "Click me" button in the content area.

<!-- vale Vale.Spelling = YES -->

### <a id="deploying-a-vaadin-portlet-to-apache-pluto"></a>Deploying a Vaadin Portlet to Apache Pluto

1. Run `mvn install` in your project directory.

2. Download the [Tomcat 8.0 + Pluto 3.1 bundle](https://www.apache.org/dist/portals/pluto/pluto-bundle-3.1.0.zip) and extract it to a location of your choice.

3. Copy both `*.war` files from `{project directory}/target` into `{bundle extract location}/webapps`.

4. Start the web server by

   - opening a command prompt in the `{bundle extract directory}` folder

   - running the command `./bin/startup.sh` or `./bin/startup.bat` (Unix/Windows)

5. Once the web server has started, navigate to <http://localhost:8080/pluto/portal>

6. Sign in to the Portal

   - Username: `pluto`

   - Password: `pluto`

7. Select "Pluto Admin" from the sidebar

   - Under "Portal Pages", create a new page for your portlet, or select one of the existing pages

   - Under "Portlet Application", select your package and portlet and click "Add Portlet".

`47D3315C-11D5-4395-A60D-4EC6EA1ECF32`
