Add non-OSGI jar dependencies into maven based MVC portlet in Liferay 7 CE

1.6k views Asked by At

I have created a MVC Portlet for Liferay 7 CE with corresponding maven archetype (as described here). I have added some additional non-OSGI jar files as the project dependencies in to the POM file of the project. When I deploy the project on liferay portal server, the OSGI container can not resolve the dependencies of the created module and the bundle remains in install phase. I want to add non-OSGI jar files and their transitive dependencies to the to bundle in an automatic manner. What should I do? The contents of the module as the following:

project structure:

enter image description here

pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>

    <project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    >
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.ranginkaman</groupId>
        <artifactId>second-maven-portlet</artifactId>
        <version>1.0.0</version>
        <packaging>jar</packaging>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <dependencies>
            <dependency>
                <groupId>com.liferay.portal</groupId>
                <artifactId>com.liferay.portal.kernel</artifactId>
                <version>2.0.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.liferay.portal</groupId>
                <artifactId>com.liferay.util.taglib</artifactId>
                <version>2.0.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.portlet</groupId>
                <artifactId>portlet-api</artifactId>
                <version>2.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.osgi</groupId>
                <artifactId>org.osgi.compendium</artifactId>
                <version>5.0.0</version>
                <scope>provided</scope>
            </dependency>

            <!-- https://mvnrepository.com/artifact/com.vividsolutions/jts -->
            <dependency>
                <groupId>com.vividsolutions</groupId>
                <artifactId>jts</artifactId>
                <version>1.13</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>2.6</version>
                    <configuration>
                        <archive>
                            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                        </archive>
                        <excludes>
                            <exclude>**/META-INF/resources/**/.sass-cache/</exclude>
                        </excludes>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>biz.aQute.bnd</groupId>
                    <artifactId>bnd-maven-plugin</artifactId>
                    <version>3.2.0</version>
                    <executions>
                        <execution>
                            <id>default-bnd-process</id>
                            <goals>
                                <goal>bnd-process</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>biz.aQute.bnd</groupId>
                            <artifactId>biz.aQute.bndlib</artifactId>
                            <version>3.2.0</version>
                        </dependency>
                        <dependency>
                            <groupId>com.liferay</groupId>
                            <artifactId>com.liferay.ant.bnd</artifactId>
                            <version>2.0.28</version>
                        </dependency>
                    </dependencies>
                </plugin>
                <plugin>
                    <groupId>com.liferay</groupId>
                    <artifactId>com.liferay.css.builder</artifactId>
                    <version>1.0.20</version>
                    <executions>
                        <execution>
                            <id>default-build-css</id>
                            <phase>generate-sources</phase>
                            <goals>
                                <goal>build-css</goal>
                            </goals>
                        </execution>
                    </executions>
                    <configuration>
                        <portalCommonPath>/</portalCommonPath>
                        <docrootDirName>src/main/resources</docrootDirName>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </project>

bnd.bnd:

    Bundle-Name: second-maven-portlet
    Bundle-SymbolicName: org.ranginkaman
    Bundle-Version: 1.0.0
    -jsp: *.jsp,*.jspf
    -plugin.jsp: com.liferay.ant.bnd.jsp.JspAnalyzerPlugin
    -plugin.resourcebundle: com.liferay.ant.bnd.resource.bundle.ResourceBundleLoaderAnalyzerPlugin
    -plugin.sass: com.liferay.ant.bnd.sass.SassAnalyzerPlugin
    -sass: *

build.gradle:

    buildscript {
        dependencies {
            classpath group: "com.liferay", name: "com.liferay.gradle.plugins", version: "3.0.23"
        }

        repositories {
            mavenLocal()

            maven {
                url "https://cdn.lfrs.sl/repository.liferay.com/nexus/content/groups/public"
            }
        }
    }

    apply plugin: "com.liferay.plugin"

    dependencies {
        compileOnly group: "com.liferay.portal", name: "com.liferay.portal.kernel", version: "2.0.0"
        compileOnly group: "com.liferay.portal", name: "com.liferay.util.taglib", version: "2.0.0"
        compileOnly group: "javax.portlet", name: "portlet-api", version: "2.0"
        compileOnly group: "javax.servlet", name: "javax.servlet-api", version: "3.0.1"
        compileOnly group: "jstl", name: "jstl", version: "1.2"
        compileOnly group: "org.osgi", name: "org.osgi.compendium", version: "5.0.0"
    }

    repositories {
        mavenLocal()

        maven {
            url "https://cdn.lfrs.sl/repository.liferay.com/nexus/content/groups/public"
        }
    }

SecondMavenPortletPortlet.java:

    package org.ranginkaman.portlet;

    import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
    import com.vividsolutions.jts.geom.Coordinate;
    import com.vividsolutions.jts.geom.GeometryFactory;
    import com.vividsolutions.jts.geom.Point;

    import java.io.IOException;

    import javax.portlet.Portlet;
    import javax.portlet.PortletException;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;

    import org.osgi.service.component.annotations.Component;

    @Component(
        immediate = true,
        property = {
            "com.liferay.portlet.display-category=category.sample",
            "com.liferay.portlet.instanceable=true",
            "javax.portlet.display-name=second-maven-portlet Portlet",
            "javax.portlet.init-param.template-path=/",
            "javax.portlet.init-param.view-template=/view.jsp",
            "javax.portlet.resource-bundle=content.Language",
            "javax.portlet.security-role-ref=power-user,user"
        },
        service = Portlet.class
    )
    public class SecondMavenPortletPortlet extends MVCPortlet {
        @Override
        public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
                throws IOException, PortletException {


            GeometryFactory geometryFactory = new GeometryFactory();

            Point point = geometryFactory.createPoint(new Coordinate(1.0, 2.0));

            System.out.println(point);

            super.doView(renderRequest, renderResponse);
        }
    }
3

There are 3 answers

0
Tom On

If com.vividsolutions.jts is not OSGi ready you can wrap it via bnd or SpringRoo

2
Vishal Rangras On

Here is a Liferay community blog for adding dependencies on OSGi module: https://web.liferay.com/web/user.26526/blog/-/blogs/osgi-module-dependencies

See if these options suits your requirement. You should go for option 3rd or 4th mentioned in this blog. It has worked in my case.

0
JohnL On

We've been running into similar issues on a project of ours as well. I noticed that the last answer was from January 15 and thought it might be good to include a useful reply to the Liferay blog entry that had been referenced. This is what led us to the realization that we have to pick Option 3 or 4 from the blog as mentioned in the previous answer.

So this is actually a common misconception - there is a difference between building in gradle using the dependency manager and the OSGi runtime environment that does not have a similar dependency manager.

OSGi purposely does not download dependencies, especially transitive dependencies, as this would lead to an unstable environment.

The build process will include transitive dependencies when compiling your code, but BND is not a compiler it's just building the jar file and including what you tell it to.

So yes, under normal circumstances, you must include all dependencies and transitive dependencies yourself. That said, some projects don't use "optional" markers in their transitive dependencies so OSGi sees them as must-haves. You have to add the classpath declaration in the BND file to forcibly exclude those packages that you really don't want.

This is definitely a PITA, but it's that way for a reason. The OSGi environment is your runtime environment and it is one that you want to actively manage and be aware of. As an administrator you want to know what your modules are using and manage deployments appropriately. From an administrative perspective, you wouldn't want the environment just downloading things on it's own (and often times this is not not possible in production environments anyway).