RE: Unresolved requirement error when overriding an OSGi component.

txapeldot ., modified 7 Months ago. Junior Member Posts: 91 Join Date: 1/15/15 Recent Posts

I’m working on a task consisting of creating a plain Liferay module to override an OSGi component of the module ‘com.liferay.document.library.web’ (specifically, the component ‘com.liferay.document.library.web.internal.portlet.toolbar.contributorDefaultDLPortletToolbarContributor’). The overriding component has a reference to a component that resides in the module ‘com.liferay.document.library.web’:

@Reference
private DLPortletToolbarContributorHelper _dlPortletToolbarContributorHelper;

As a consequence, I’ve included the following dependency in my ‘pom.xml’ file:

<dependency>
    <groupId>com.liferay</groupId>
    <artifactId>com.liferay.document.library.web</artifactId>
    <scope>compile</scope>
</dependency>

Everything is ok during compiling and building stages, but when deploying the module’s jar file, I’m getting this error:

ERROR [fileinstall-F:/liferay/osgi/modules][LogService:93] Error while starting bundle: file:/F:/liferay/osgi/modules/my-module.jar

org.osgi.framework.BundleException: Could not resolve module: my-module [1070]_  Unresolved requirement: Import-Package: com.liferay.document.library.web.internal.portlet.toolbar.contributor.helper_ [Sanitized]

I’ve tried including the following directive in the my-module’s ‘bnd.bnd’ file, but I didn’t get rid of the previous error:

Import-Package: com.liferay.document.library.web.internal.portlet.toolbar.contributor.helper

Yet, I’ve tried the proposals suggested in this post, but it didn’t succeed.

I might be wrong, but my reasoning is that ‘my-module’ requires a package (the one stated in the ‘Import-Package’ directive), and thus, the target module should export that package. However, the target package resides in the module ‘com.liferay.document.library.web’, which is a Liferay module whose ‘bnd.bnd’ file I can't handle.

I’d really appreciate if someone could clarify what’s going on, and how I should proceed to get rid of the problem that is making the overriding module not be deployed successfully.

Thanks.

 

thumbnail
Olaf Kock, modified 7 Months ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts

A module can't depend on another module's non-exported code. And the package com.liferay.document.library.web. internal .portlet.toolbar.contributor.helper is a good hint that it's not exported.

You'll either need to bring in the whole implementation with your overridden service, or go for a "marketplace override". The documentation that I found for that is quite old though, I'm not sure it's 100% accurate still, but chances are that it is.

Be aware though that this is quite a low-level technique, paid for by technical debt and dependence on internal code with absolutely zero guarantee of any kind of stability. This code will have to be checked meticulously on every future upgrade - so the maintenance cost might be higher than you like.

If you go this route, don't complain that future upgrades are painful: If you depend on implementation level code, not on public APIs, that's the price you'll have to pay.

txapeldot ., modified 7 Months ago. Junior Member Posts: 91 Join Date: 1/15/15 Recent Posts

Thank you very much for your clarification.

Never heard about "marketplace override". Could you provide to me with reliable documentation so that I give it a try?

thumbnail
Olaf Kock, modified 7 Months ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts

https://liferay.dev/blogs/-/blogs/extending-liferay-osgi-modules-revisited

thumbnail
David H Nebinger, modified 7 Months ago. Liferay Legend Posts: 14933 Join Date: 9/2/06 Recent Posts

You can't import it because the other module doesn't export the package. Since it is in an internal package, it is not available outside of the module and is not meant to be used externally.

txapeldot ., modified 7 Months ago. Junior Member Posts: 91 Join Date: 1/15/15 Recent Posts

Thank you very much for your clarification.

Is there any way of making an internal package available outside its module? Do you think it could be accomplished under the prespective of OSGi Fragment Bundles? It seems to me that if I were able to create a 'bnd' file and that file exported the internal package, then the overriding module could import it.