0

I wrote a module that contains this implementation of the com.liferay.portal.security.audit.AuditMessageProcessor service:

@Component(
    configurationPid = "my.MyAuditMessageProcessorConfiguration",
    immediate = true,
    property = {
            "eventTypes=*",
            "service.ranking:Integer=100000"
    },
    service = AuditMessageProcessor.class
)
public class MyElasticsearchAuditMessageProcessor
        implements AuditMessageProcessor {

    @Override
    public void process(AuditMessage auditMessage) {
        _log.info("This never appears even after login/logout");
        elasticsearch.send(auditMessage);
    }

    @Activate
    @Modified
    protected void activate(Map<String, Object> properties) {
        _myAuditMessageProcessorConfiguration = ConfigurableUtil
            .createConfigurable(
                MyAuditMessageProcessorConfiguration.class, properties);
    }

    @Reference(unbind = "-")
    protected my.Elasticsearch elasticsearch;

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

    private volatile MyAuditMessageProcessorConfiguration
        _myAuditMessageProcessorConfiguration;
}

Elasticsearch.java:

@Component(
        immediate = true
    )
public class Elasticsearch {
    [...]
}

After deploying, my module is seen by Gogo Shell as not implementing that service, as seen below. The other two services that my module implements are visible though.

g! inspect capability service 548
myaudit_1.0.0 [548] provides:
---------------------------------
service; javax.servlet.Filter with properties:
   servlet-filter-name = Audit Download Filter
   url-pattern = /documents/*
   servlet-context-name = 
   component.name = my.DownloadFilter
   component.id = 2573
   service.id = 7181
   service.bundleid = 548
   service.scope = bundle
   Used by:
      org.eclipse.osgi_3.10.200.v20150831-0856 [0]
service; com.liferay.portal.kernel.portlet.bridges.mvc.MVCRenderCommand with properties:
   service.ranking = 100
   mvc.command.name = /document_library/view_file_entry
   javax.portlet.name = com_liferay_document_library_web_portlet_DLPortlet, com_liferay_document_library_web_portlet_DLAdminPortlet, com_liferay_document_library_web_portlet_IGDisplayPortlet
   component.name = my.MyViewFileEntryMVCRenderCommand
   component.id = 2576
   service.id = 7182
   service.bundleid = 548
   service.scope = bundle
   Used by:
      org.eclipse.osgi_3.10.200.v20150831-0856 [0]

What am I doing wrong?

For info, inside my module's jar this OSGI-INF/my.MyAuditMessageProcessor.xml exists:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="my.MyAuditMessageProcessor" immediate="true" activate="activate" modified="activate" configuration-pid="my.MyAuditMessageProcessorConfiguration">
  <implementation class="my.MyAuditMessageProcessor"/>
  <service>
    <provide interface="com.liferay.portal.security.audit.AuditMessageProcessor"/>
  </service>
  <property name="eventTypes" type="String" value="*"/>
  <property name="service.ranking" type="Integer" value="100000"/>
</scr:component>
Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373

1 Answers1

3

As tipped by Christian, the problem is that my component had unsatisfied requirements. Please note that it is different from a bundle missing requirements, it is a level below.

My bundle has all requirements satisfied, but my module was missing a requirement. Here is how I found it out:

  1. Start Gogo Shell
  2. Type scr:list
  3. Luckily, your components should be towards the end of the long list
  4. That gives you your component's id, for instance 2587
  5. Type scr:info 2587
  6. That will display UnsatisfiedReference and Target: null for the missing dependency

In my case, I was trying to @Reference a @Component directly rather than a service. I solved the problem by creating an ElasticsearchService interface and making the Elasticsearch component implement it.

Nicolas Raoul
  • 58,567
  • 58
  • 222
  • 373