Creating Vaadin Portlets
In this chapter, you learn how to create Vaadin Portlets and how to deploy these portlets to the Liferay 7 Digital Experience Platform.
Creating a Vaadin Portlet
You have two ways to start the creation of a Vaadin Portlet: starting from the beginning or from 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.
To become familiar with setting up a Vaadin Portlet project manually, you start with a simple Vaadin project and then convert it into a Vaadin Portlet project.
Setting Up Portlet Project
First, download the Vaadin base starter
Next, update your pom.xml
:
-
Add the following dependencies:
<dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-portlet</artifactId> <version>1.0.0</version> </dependency>
<dependency> <groupId>javax.portlet</groupId> <artifactId>portlet-api</artifactId> <version>3.0.1</version> <scope>provided</scope> </dependency>
-
Add a
build-frontend
goal tovaadin-maven-plugin
, as Vaadin Portlet doesn’t work in development mode runningvaadin-dev-server
.
Creating the Portlet
In the most basic setup, Vaadin Portlets consist of two classes:
-
A portlet class, which extends
VaadinLiferayPortlet
orVaadinPortlet
(when running in non-Liferay Portal)
The portlet class acts as the entry point for your 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, contains the contents of your Vaadin Portlet.
You could use an existing component through extension, composition, or as is.
Or 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.
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
@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
public class MyPortlet extends VaadinPortlet<MainView> {
}
Next, open the MainView.java
.
Remove both the @Route
and @PWA
annotations, which don’t make sense for your portlet.
The final code should look something like this:
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; you only need to make it ready for deployment.
Setting Portlet Deployment Descriptor
In the Portlet 3.0 specification, the portlet deployment descriptor can be configured in two ways:
-
portlet.xml
(backwards-compatible) -
annotations (only 3.0)
You use the portlet.xml
to configure your portlet deployment.
The 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:
<?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) the portlet supports.
You can learn more about portlet modes for Vaadin Portlet in the next chapter
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 theAdd
menu of Liferay’s Widgets bar. -
liferay-portlet.xml
- describes Liferay-specific enhancements for Java Specification Requests (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:
<?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>
<?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>
Note
|
The parameter instanceable specifies whether the Portlet can be added more than once on same page.
If it’s false , it can be added only once on a page.
|
Setting External Stats URL in Liferay
If your portlet runs in Liferay Portal, add the following resource file flow-build-info.json
into {project directory}/src/main/resources/META-INF/VAADIN/config
with the contents:
{
"externalStatsUrl": "/o/vaadin-portlet-static/VAADIN/config/stats.json"
}
Enable webpack for Front-End Builds
Starting with Vaadin 23.2, Vite is the default tool for front-end builds.
However, Vaadin Portlet requires webpack to be used.
To use webpack, you must enable it with the webpackForFrontendBuild
feature flag.
com.vaadin.experimental.webpackForFrontendBuild=true
See Feature Flags for more information.
Deploying Your Vaadin Portlet
Building Vaadin Portlet
To build the portlet you created, you must 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 Multi-Module Portlet Project.
Add the following plugin configuration to the pom.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/VAADIN/webapp/</directory>
<!-- Include all files and folders below <directory> -->
<includes>
<include>**</include>
</includes>
</resource>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>target/classes/META-INF/</directory>
<!--
Include all config files to root except flow-build-info
that is not needed at runtime when running fronted builds
-->
<includes>
<include>VAADIN/config/**</include>
</includes>
<!-- do not include file as it contains portlet configuration -->
<excludes>
<exclude>VAADIN/config/flow-build-info.json</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/webapp/VAADIN/build/**,VAADIN/</packagingExcludes>
<webResources>
<resource>
<directory>${project.basedir}/src/main/resources/</directory>
<!--
Include original flow-build-info.json, not the one produced by vaadin plugin
and included in the static portlet
-->
<includes>
<include>META-INF/VAADIN/config/flow-build-info.json</include>
</includes>
<targetPath>WEB-INF/classes/</targetPath>
</resource>
</webResources>
</configuration>
</execution>
</executions>
</plugin>
Here you 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 front-end bundle and client engine).
The static WAR
is built as a portal window that 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.
Configuring Static Resources
If you need to change the name of the static assets WAR
(by default, vaadin-portlet-static
), you can do this via the vaadin.portlet.static.resources.mapping
application property.
For example, if you want to serve static resources from vaadin-static-resources.war
, you need to
-
rename the static
WAR
tovaadin-static-resources
in thepom.xml
; -
change the static portlet name in
flow-build-info.json
(if Liferay is used); -
pass the value
/vaadin-static-resources/
(for Liferay Portal, it would be/o/vaadin-portlet-resources/
) via the application property to the Vaadin application; that is, on the 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/"
.
-
Deploying Vaadin Portlet to Liferay 7
-
Run
mvn install
in your project directory. -
Download Liferay Bundle and extract it to a location you prefer.
-
Add the following parameter to Liferay Tomcat’s
setenv.sh
({liferay home}/tomcat-<version>/bin
):-Dvaadin.portlet.static.resources.mapping=/o/vaadin-portlet-static/
-
Download and copy the JNA dependency
JARs
of the specific version into{liferay home}/tomcat-<version>/webapps/ROOT/WEB-INF/lib
(orshielded-container-lib
depending on the version): net.java.dev.jna:jna:5.7.0, net.java.dev.jna:jna-platform:5.7.0. This is needed because Vaadin Portlet uses a newer version of the Java Native Access (JNA) library which can cause conflicts with the version that Liferay uses. -
Create a
portal-ext.properties
file in Liferay’s home directory and place the following property there:javascript.single.page.application.enabled=false
. -
Copy both
WAR
files from{project directory}/target
into{liferay home}/deploy
. -
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).
-
-
Once the web server has started, navigate to http://localhost:8080/
-
Follow the instructions of the Liferay wizard to set up a new user and sign in to the Portal.
-
Click on the "Menu" button at the top-left corner to open the menu console.
-
Find and click on the "Page tree" link and click on the "+" button to add a new page.
-
Select "Widget Page", give it a name and select the appropriate layout.
-
In the "Look and Feel" tab, select "Define a specific look and feel for this page" and enable "Show Maximize/Minimize".
-
Click "Save" and navigate to the home page, then to the layout you created.
-
Click the "Add" button, which is usually placed at the top-right corner, find the category "Vaadin Liferay Portlets", open it and drag the portlet item from the panel to the page.
-
You should see the portlet with the title MY TEST PORTLET - MYPORTLET and a Click me button in the content area.
DBCCB99A-428F-4A13-AA7E-BDD0AFB0531B