RE: Issues with overriding OSGi module

Vishnu S Kumar, modified 6 Years ago. Regular Member Posts: 131 Join Date: 7/28/17 Recent Posts
I am trying to override the JournalContentPortlet componet to fit with a business requirement. I followed the Liferay documents and implemented as following. It builds fine and deployed to Liferay .  The OSGi failed to activate the component with this statement.
 Unresolved requirement: Import-Package: com.liferay.journal.content.web.internal.display.context
This is my Custom OSGi component:


package th.osgi.extension.journalcontentportlet;

import com.liferay.journal.content.web.internal.constants.JournalContentWebKeys;
import com.liferay.journal.content.web.internal.display.context.JournalContentDisplayContext;
import com.liferay.journal.content.web.internal.portlet.JournalContentPortlet;
import com.liferay.journal.model.JournalArticle;
import com.liferay.journal.model.JournalArticleDisplay;
import com.liferay.journal.service.JournalArticleLocalService;
import com.liferay.journal.util.JournalContent;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.language.LanguageUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.PortletRequestModel;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PrefsParamUtil;
import com.liferay.portal.kernel.util.ReflectionUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;

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

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.component.runtime.ServiceComponentRuntime;
import org.osgi.service.component.runtime.dto.ComponentDescriptionDTO;

@Component(immediate = true, service = Portlet.class)

public class JournalContentPortletExtender extends JournalContentPortlet {

	JournalArticleLocalService _journalArticleLocalService;
	JournalContent _journalContent;
	ServiceComponentRuntime _serviceComponentRuntime;

	@Reference(unbind = "unsetServiceComponentRuntime")
	protected void setServiceComponentRuntime(ServiceComponentRuntime j) throws Exception {
		_serviceComponentRuntime = j;
		_setSuperClassField("_serviceComponentRuntime", j);
	}

	protected void unsetServiceComponentRuntime() throws Exception {
		_serviceComponentRuntime = null;
		_setSuperClassField("_serviceComponentRuntime", null);

	}

	@Reference(unbind = "unsetJournalContent")
	protected void setJournalContent(JournalContent j) throws Exception {
		_journalContent = j;
		_setSuperClassField("_journalContent", j);
	}

	protected void unsetJournalContent() throws Exception {
		_journalContent = null;
		_setSuperClassField("_journalContent", null);

	}

	@Reference(unbind = "unsetJournalArticleLocalService")
	protected void setJournalArticleLocalService(JournalArticleLocalService j) throws Exception {
		_journalArticleLocalService = j;
		_setSuperClassField("_journalArticleLocalService", j);
	}

	protected void unsetJournalArticleLocalService() throws Exception {
		_journalArticleLocalService = null;
		_setSuperClassField("_journalArticleLocalService", null);

	}

	private void _setSuperClassField(String name, Object value) throws Exception {

		Field field = ReflectionUtil.getDeclaredField(JournalContentPortlet.class, name);

		field.set(this, value);
	}

	@Override
	public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
			throws IOException, PortletException {
		PortletPreferences portletPreferences = renderRequest.getPreferences();

		ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);

		long articleGroupId = PrefsParamUtil.getLong(portletPreferences, renderRequest, "groupId",
				themeDisplay.getScopeGroupId());

		String articleId = PrefsParamUtil.getString(portletPreferences, renderRequest, "articleId");

		JournalArticle article = null;
		JournalArticleDisplay articleDisplay = null;

		JournalContentDisplayContext journalContentDisplayContext = (JournalContentDisplayContext) renderRequest
				.getAttribute(JournalContentWebKeys.JOURNAL_CONTENT_DISPLAY_CONTEXT);

		if (journalContentDisplayContext != null) {
			try {
				article = journalContentDisplayContext.getArticle();
				articleDisplay = journalContentDisplayContext.getArticleDisplay();
			} catch (PortalException pe) {
				_log.error("Unable to get journal article", pe);
			}
		} else if ((articleGroupId > 0) && Validator.isNotNull(articleId)) {
			String viewMode = ParamUtil.getString(renderRequest, "viewMode");
			String languageId = LanguageUtil.getLanguageId(renderRequest);
			int page = ParamUtil.getInteger(renderRequest, "page", 1);

			article = _journalArticleLocalService.fetchLatestArticle(articleGroupId, articleId,
					WorkflowConstants.STATUS_APPROVED);

			try {
				if (article == null) {
					article = _journalArticleLocalService.getLatestArticle(articleGroupId, articleId,
							WorkflowConstants.STATUS_ANY);
				}

				String ddmTemplateKey = PrefsParamUtil.getString(portletPreferences, renderRequest, "ddmTemplateKey");

				if (Validator.isNull(ddmTemplateKey)) {
					ddmTemplateKey = article.getDDMTemplateKey();
				}

				articleDisplay = _journalContent.getDisplay(article, ddmTemplateKey, viewMode, languageId, page,
						new PortletRequestModel(renderRequest, renderResponse), themeDisplay);
			} catch (Exception e) {
				renderRequest.removeAttribute(WebKeys.JOURNAL_ARTICLE);
			}
		}

		if (article != null) {
			renderRequest.setAttribute(WebKeys.JOURNAL_ARTICLE, article);
		}

		if (articleDisplay != null) {
			renderRequest.setAttribute(WebKeys.JOURNAL_ARTICLE_DISPLAY, articleDisplay);
		} else {
			renderRequest.removeAttribute(WebKeys.JOURNAL_ARTICLE_DISPLAY);
		}

		super.doView(renderRequest, renderResponse);
	}

	private static final Log _log = LogFactoryUtil.getLog(JournalContentPortlet.class);

	private BundleContext _bundleContext;

	@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC, policyOption = ReferencePolicyOption.GREEDY, target = "(component.name=com.liferay.site.util.JournalContentPortlet)", unbind = "unsetJournalContentPortlet")
	protected void setJournalContentPortlet(JournalContentPortlet jcp) throws Exception {

		_deactivateExistingComponent();
	}

	protected void unsetJournalContentPortlet(JournalContentPortlet jcp) {
	}

	@Activate
	public void activate(ComponentContext componentContext, BundleContext bundleContext, Map<string, object> config)
			throws Exception {

		_bundleContext = bundleContext;

		_deactivateExistingComponent();
	}

	private void _deactivateExistingComponent() throws Exception {

		if (_bundleContext == null) {
			return;
		}

		String componentName = JournalContentPortlet.class.getName();

		Collection<servicereference<journalcontentportlet>&gt; serviceReferences = _bundleContext
				.getServiceReferences(JournalContentPortlet.class, "(component.name=" + componentName + ")");

		for (ServiceReference<!--?--> serviceReference : serviceReferences) {
			Bundle bundle = serviceReference.getBundle();

			ComponentDescriptionDTO description = _serviceComponentRuntime.getComponentDescriptionDTO(bundle,
					componentName);
			_serviceComponentRuntime.disableComponent(description);
		}
	}

	@Deactivate
	public void deactivate() throws Exception {

		_activateExistingComponent();

		_bundleContext = null;
	}

	private void _activateExistingComponent() throws Exception {

		if (_bundleContext == null) {
			return;
		}

		String componentName = JournalContentPortlet.class.getName();

		Collection<servicereference<journalcontentportlet>&gt; serviceReferences = _bundleContext
				.getServiceReferences(JournalContentPortlet.class, "(component.name=" + componentName + ")");

		for (ServiceReference<!--?--> serviceReference : serviceReferences) {
			Bundle bundle = serviceReference.getBundle();

			ComponentDescriptionDTO description = _serviceComponentRuntime.getComponentDescriptionDTO(bundle,
					componentName);

			_serviceComponentRuntime.enableComponent(description);
		}
	}
}
</servicereference<journalcontentportlet></servicereference<journalcontentportlet></string,>
thumbnail
Olaf Kock, modified 6 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts
Vishnu S Kumar:

I am trying to override the JournalContentPortlet componet to fit with a business requirement. I followed the Liferay documents and implemented as following. It builds fine and deployed to Liferay .  The OSGi failed to activate the component with this statement.
 Unresolved requirement: Import-Package: com.liferay.journal.content.web.internal.display.context
com.liferay.journal.content.web.internal.display.context
I've emphasized the root cause of your problem: This package can't be reached from another OSGi bundle, it's not exported, by design. You'll either have to modify the bundle itself with your code, modify the bundle to export that class, duplicate the required class, or change your approach altogether.
What is your business requirement?
Vishnu S Kumar, modified 6 Years ago. Regular Member Posts: 131 Join Date: 7/28/17 Recent Posts
Thanks Olaf.
Our requirement is to allow the business users to see the latest web content instead of the latest approved web content.
You'll either have to modify the bundle itself with your code, modify the bundle to export that class, duplicate the required class, or change your approach
I think I'll go with one of these approaches.