Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

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.