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.

 

 

 

 

 

4 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.

 

Avatar

Level 1

Hi @JoseManuel121 ,

 

Were you able to resolve this? 

Facing the same issue.

 

@SureshDhulipudi 

Avatar

Level 2

Hello VishalGu5

Sorry to say no.
We found an alternative, we ruled it out for performance.
In the Current service it loads the OSGI configurations in the service, just after starting the environment and only updates them if you change data(Add, delete or modify) in system/console/ConfigMgr.

In the solution we found, every time you instantiate the service from the component, it performs the bind of all the configurations, so we discard this option.

Since the error only gives us on AEM startup and at runtime we don't see that it is affecting performance we haven't kept looking at it officially.

In my spare time I keep looking around the internet.

I have recently found this article, but I have not been able to test it.
https://medium.com/@amitnath/multi-site-factory-configurations-in-aem-with-osgi-3dce1a424d44
Good luck.