Expand my Community achievements bar.

Circular reference detected trying to get service

Avatar

Level 2

Hello everyone.

We have the following problem:

When the server starts the following message appears in the log.error.

15.03.2024 12:07:36.743 *ERROR* [FelixLogListener] ROOT bundle org.apache.felix.scr:2.2.4 (15) Circular reference detected trying to get service [com.myproject.catalog.core.services.googleMaps.GoogleMapsService]_ stack of references: ServiceReference: [com.myproyect.catalog.core.services.googleMaps.GoogleMapsService]_ (java.lang.Exception: stack trace)
java.lang.Exception: stack trace
at org.apache.felix.scr.impl.ComponentRegistry.enterCreate(ComponentRegistry.java:493) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.BundleComponentActivator.enterCreate(BundleComponentActivator.java:722) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:901) [org.apache.felix.scr:2.2.4]
at org.apache.felix.framework.ServiceRegistrationImpl.getFactoryUnchecked(ServiceRegistrationImpl.java:349)
at org.apache.felix.framework.ServiceRegistrationImpl.getService(ServiceRegistrationImpl.java:249)
at org.apache.felix.framework.ServiceRegistry.getService(ServiceRegistry.java:362)
at org.apache.felix.framework.Felix.getService(Felix.java:3984)
at org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:450)
at org.apache.felix.scr.impl.manager.SingleRefPair.getServiceObject(SingleRefPair.java:88) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.inject.methods.BindMethod.getServiceObject(BindMethod.java:675) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.DependencyManager.getServiceObject(DependencyManager.java:2612) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.DependencyManager$MultipleDynamicCustomizer.prebind(DependencyManager.java:434) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.DependencyManager.prebind(DependencyManager.java:1830) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.collectDependencies(AbstractComponentManager.java:1060) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:955) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:776) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:674) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:437) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:671) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:310) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:593) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.Activator.access$200(Activator.java:74) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:460) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169) [org.apache.felix.scr:2.2.4]
at org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:49) [org.apache.felix.scr:2.2.4]
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:488)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:420)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450)
at org.apache.felix.framework.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:915)
at org.apache.felix.framework.EventDispatcher.fireEventImmediately(EventDispatcher.java:834)
at org.apache.felix.framework.EventDispatcher.fireBundleEvent(EventDispatcher.java:516)
at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4847)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2363)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1566)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:297)
at java.base/java.lang.Thread.run(Thread.java:834)

 

It is an OSGI factory service that we have created.

We have a OCD config, Interface and implement class with interface.

 

INTERFACE:

public interface GoogleMapsService
{
String getSiteNameId();
String getGoogleUrlApiMaps();
GoogleMapsService getConfig(String siteName);
String getGoogleStyleMaps();

}
 
*********************************************************

IMPLEMENTATION CLASS

@component(service = {GoogleMapsService.class}, immediate = true,configurationPolicy = ConfigurationPolicy.REQUIRE)
@Designate(ocd= GoogleMapsServiceConfig.class, factory=true)
public class GoogleMapsServiceImpl implements GoogleMapsService {

private String siteNameId;
private String googleUrlApiMaps;
private String getGoogleStyleMaps;
private Map<String,GoogleMapsService> configMap;
private Logger logger = LoggerFactory.getLogger(GoogleMapsServiceImpl.class);
@activate
@MODIFIED
public void activate (final GoogleMapsServiceConfig config) {

siteNameId=config.getSiteNameId();
googleUrlApiMaps=config.getGoogleUrlApiMaps();
getGoogleStyleMaps=config.getGoogleStyleMaps();
}
@reference(name = "GoogleMapsService", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected synchronized void bindOSGIFactoryConfig(final GoogleMapsService config) {
if (configMap == null) {
configMap = new HashMap<String,GoogleMapsService>();
}


if (config!=null) {configMap.put(config.getSiteNameId(), config);}
}

protected synchronized void unbindOSGIFactoryConfig(final GoogleMapsService config) {

if (config!=null){ configMap.remove(config.getSiteNameId());}
}
@Override
public synchronized GoogleMapsService getConfig(String siteName) {
logger.debug("ConfigMapValues for {} {}", siteName ,configMap.get(siteName));
return configMap.get(siteName);
}
@Override
public String getSiteNameId() {
return siteNameId;
}
@Override
public String getGoogleUrlApiMaps() {
return googleUrlApiMaps;
}
@Override
public String getGoogleStyleMaps() {
return getGoogleStyleMaps;
}
}

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

OCD CONFIG

@ObjectClassDefinition(name = "Google Maps config")
public @interface GoogleMapsServiceConfig {
@AttributeDefinition(
name = "Site name Identifier",
description = "Identifier the site must be unique id",
type = AttributeType.STRING
)
String getSiteNameId() default StringUtils.EMPTY;
@AttributeDefinition(
name = "Url google Api Maps",
description = "Url google, api key and method init",
type = AttributeType.STRING
)
String getGoogleUrlApiMaps() default StringUtils.EMPTY;
@AttributeDefinition(
name = "Style Maps google",
description = "Json format style map",
type = AttributeType.STRING
)
String getGoogleStyleMaps() default StringUtils.EMPTY;
}

**********************************************************

The service works well even though it gives the error.

Any idea what is happend?

 

thank you very much.

 

 

 

 

 

2 Replies

Avatar

Community Advisor

Circular reference detected trying to get service [com.myproject.catalog.core.services.googleMaps.GoogleMapsService]_ stack of references: ServiceReference: [com.myproyect.catalog.core.services.googleMaps.GoogleMapsService]_ (java.lang.Exception: stack trace)

 

Circular reference means - OSGi service depends on itself either directly or indirectly.

 

as per your implementation class GoogleMapsServiceImpl - 

 

GoogleMapsServiceImpl service is referencing itself. This is happening because of the @reference annotation on the bindOSGIFactoryConfig method. This method is called when a GoogleMapsService is registered, and since GoogleMapsServiceImpl is a GoogleMapsService, it's causing a circular reference.

 

Create interface for and separate the reference.

  1. Create an interface for the configuration, separate from the service interface. This could be something like GoogleMapsConfig.

public interface GoogleMapsConfig {
String getSiteNameId();
String getGoogleUrlApiMaps();
String getGoogleStyleMaps();
}

2.Update your GoogleMapsServiceConfig interface to implement this new interface.

@ObjectClassDefinition(name = "Google Maps config")
public @interface GoogleMapsServiceConfig extends GoogleMapsConfig {
// ...
}

 

3.Change the @reference annotation in GoogleMapsServiceImpl to reference GoogleMapsConfig instead of GoogleMapsService.

 

@component(service = {GoogleMapsService.class}, immediate = true, configurationPolicy = ConfigurationPolicy.REQUIRE)
@Designate(ocd= GoogleMapsServiceConfig.class, factory=true)
public class GoogleMapsServiceImpl implements GoogleMapsService {
/* */

@reference(name = "GoogleMapsConfig", cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected synchronized void bindOSGIFactoryConfig(final GoogleMapsConfig config) {
/* */
}

protected synchronized void unbindOSGIFactoryConfig(final GoogleMapsConfig config) {
/* */
}


}

Avatar

Level 2

Thank you very much SureshDhulipudi.

I have tried what you were talking about.

The bind event does not work, when I create new Osgi configuration.

I think it does not work because of the pid

Persistent Identity (PID) com.mycompany.mysite.core.services.googleMaps.impl.GoogleMapsServiceImpl.3fb73689-95f9-42cb-b92f-44aa1b4ab186
Factory Persistent Identifier (Factory PID) com.mycompany.mysite.core.services.googleMaps.impl.GoogleMapsServiceImpl

Best regards.