OSGi Portlets on Liferay 7

Lifeary 7 supports modular portlet development using OSGi, and enables e.g. using multiple different Vaadin versions in different portlets on a page.

For general OSGi considerations with Vaadin Framework such as packaging and bundle manifests, and how to publish static resources such as themes and widget sets, see "Vaadin OSGi Support".

Publishing a Portlet With OSGi

Publishing an OSGi portlet on Liferay 7+ can be done in two ways: using annotations or using properties.

Annotating a UI class with @VaadinLiferayPortletConfiguration (available in vaadin-liferay-integration) and making it an OSGi service of type UI is the easiest way to automatically publish the UI as a portlet and configure it to use the correct static resources.

@Theme(MyTheme.THEME_NAME)
@VaadinLiferayPortletConfiguration(name = "Vaadin.Tutorial.1", displayName = "Vaadin Tutorial App")
@Component(service = UI.class, scope = ServiceScope.PROTOTYPE)
public class MyUI extends UI {
  ...
}

When using this approach, it is not necessary to create all the portlet property files that plain JSR-362 portlets require.

Alternatively, the property com.vaadin.osgi.liferay.portlet-ui=true can be used when publishing a UI as an OSGi service to publish the UI as a portlet.

The scope of the service should be set to ServiceScope.PROTOTYPE, as new instances of the UI will be needed. When this scope set, declarative services annotations can be used to get references to other services within a UI instance.

This is not an absolute requirement if you are not using other declarative services annotations in your UI besides the @Component. If the scope is not set to prototype a warning will be logged and the constructor of the UI will be used when new instances are needed.

@Theme(MyTheme.THEME_NAME)
@Component(service = UI.class, property = {
        "com.liferay.portlet.display-category=category.vaadin",
        "javax.portlet.name=my.vaadin.app.app.1.0.0",
        "javax.portlet.display-name=Tutorial Portlet",
        "javax.portlet.security-role-ref=power-user,user",
        "com.vaadin.osgi.liferay.portlet-ui=true"},
        scope = ServiceScope.PROTOTYPE)
public class MyUI extends UI {
  ...
}

Deployment a Portlet With OSGi (Gradle)

Here is an example of a Liferay workspace with a portlet module and a short readme on how to deploy that to a Liferay portal. https://github.com/elmot/liferay-7-solid-portlet-example/

Deployment a Portlet With OSGi (Maven)

An OSGi portlet should be packaged as a JAR with a proper OSGi bundle manifest, and deployed to a portal that has its required bundles installed. The maven archetype com.vaadin:vaadin-archetype-liferay-portlet is a good starting point to build an OSGi portlet application. The required bundles (and the application as well) can be installed using blade client. The latest client binary can be downloaded from the link: https://releases.liferay.com/tools/blade-cli/latest/blade.jar

Here is an example script for doing that (be sure to check the versions required by your project using mvn dependency:list ):

java -jar blade.jar sh start https://repo1.maven.org/maven2/org/jsoup/jsoup/1.11.2/jsoup-1.11.2.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/external/gentyref/1.2.0.vaadin1/gentyref-1.2.0.vaadin1.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-shared/8.6.3/vaadin-shared-8.6.3.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-server/8.6.3/vaadin-server-8.6.3.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-osgi-integration/8.6.3/vaadin-osgi-integration-8.6.3.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-client-compiled/8.6.3/vaadin-client-compiled-8.6.3.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-themes/8.6.3/vaadin-themes-8.6.3.jar
java -jar blade.jar sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-liferay-integration/8.6.3/vaadin-liferay-integration-8.6.3.jar
java -jar blade.jar sh start file:<path_to_liferay_portlet.jar>

However if you are using Vaadin 8 with compatibility libraries, the list above does not work, since you need to load compatibility versions of the bundles in addition to base versions in right order, here is example of that

blade sh start https://repo1.maven.org/maven2/org/jsoup/jsoup/1.11.3/jsoup-1.11.3.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/external/gentyref/1.2.0.vaadin1/gentyref-1.2.0.vaadin1.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-shared/8.6.4/vaadin-shared-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-compatibility-shared/8.6.4/vaadin-compatibility-shared-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-server/8.6.4/vaadin-server-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-compatibility-server/8.6.4/vaadin-compatibility-server-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-osgi-integration/8.6.4/vaadin-osgi-integration-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-compatibility-client-compiled/8.6.4/vaadin-compatibility-client-compiled-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-compatibility-themes/8.6.4/vaadin-compatibility-themes-8.6.4.jar
blade sh start https://repo1.maven.org/maven2/com/vaadin/vaadin-liferay-integration/8.6.4/vaadin-liferay-integration-8.6.4.jar
java -jar blade.jar sh start file:<path_to_liferay_portlet.jar>