Letzte Blogger

Sandeep Sapra

3 Nachrichten
24. November 2017

John Feeney

Staff
2 Nachrichten
24. November 2017

Zeno Rocha

Staff
17 Nachrichten
7. November 2017

Yasuyuki Takeo

Staff
3 Nachrichten
5. November 2017

Gregory Amerson

Staff
30 Nachrichten
3. November 2017

Minhchau Dang

Staff
13 Nachrichten
3. November 2017

Petteri Karttunen

Staff
5 Nachrichten
30. Oktober 2017

Alex Swain

2 Nachrichten
27. Oktober 2017

Jamie Sammons

Staff
10 Nachrichten
23. Oktober 2017

Jan Verweij

Staff
2 Nachrichten
23. Oktober 2017

Resolve NullPointerException when calling service that has not yet been loaded

Technical Blogs 4. September 2017 Von Dániel Jávorszky Staff

Sometimes, when creating a module, we may run into a situation where the service we're trying to use has not been properly loaded and tracked by OSGi yet. In such cases, the result of our service call will be a NullPointerException coming from the *ServiceUtil class, for example:

java.lang.NullPointerException
    at com.liferay.dynamic.data.mapping.service.DDMStructureLocalServiceUtil.getStructures(DDMStructureLocalServiceUtil.java:910)

Checking the line from where its thrown, we see that the only way for a NullPointerException to occur is if getService() returns null.

getService() calls the serviceTracker, which, according to its javadoc, returns null if its not tracking any service objects for that service.

Such a situation can arise if we're trying to call the service during the global.startup.events phase for example - Where OSGi is still working on registering all the services that are being loaded.

Thankfully, there's a way to resolve this issue - add a ServiceDependencyListener.

A ServiceDependencyListener, once added with one or more services, will be called once all of the services have been properly loaded and tracked.

To register a ServiceDependencyListener, just add the below:

ServiceDependencyManager serviceDependencyManager = new ServiceDependencyManager();

serviceDependencyManager.addServiceDependencyListener(new ServiceDependencyListener() {

    @Override
    public void dependenciesFulfilled() {
        _log.info("Dependencies fulfilled.");
        doWhatNeedsToBeDone();
    }

    @Override
    public void destroy() {
        // ignore
    }

});

Registry registry = RegistryUtil.getRegistry();

Filter ddmFilter = registry.getFilter("(&(objectClass=" + DDMStructureService.class.getName() + "))");

serviceDependencyManager.registerDependencies(ddmFilter);

The above is quite straightforward: Create a ServiceDependencyManager, add a new Listener with its two required methods that will be called once the dependencies are fulfilled and once the listener is no longer needed, then get the registry, construct a filter and register it as a dependency.

Hope this helps,

Daniel

Zeige 1 Ergebnisse.