Component Activation Problems

Hi,
I cannot get my component to activate. I’ve tried locating the problem in wrong Service-Declarations, package import/exports, .bnd configurations and I reinstalled Eclipse to make sure it’s not Eclipse related but I still have no idea what I’m doing wrong and I always get
WARN [nentmanager.OsgiValidateWorker] [_componentManager] Component(s) configured but not active: loadForecast0.

I cut my component down to a minimum of only one class plus Config and Channels:

`import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import io.openems.edge.common.component.AbstractOpenemsComponent;
import io.openems.edge.common.component.ComponentManager;
import io.openems.edge.common.component.OpenemsComponent;

@Designate(ocd = Config.class, factory = true)
@Component(
	name = "Predictor.Load.LoadForecast", //
	immediate = true, //
	configurationPolicy = ConfigurationPolicy.REQUIRE)
public class LoadForecast extends AbstractOpenemsComponent
		implements OpenemsComponent {

	@Reference
	protected ComponentManager componentManager;
	
	public LoadForecast() {
		super(OpenemsComponent.ChannelId.values(), //
				ForecastChannelId.values());
	}

	@Activate
	void activate(ComponentContext context, Config config) {
		super.activate(context, config.alias(), config.id(), config.enabled());
	}
	
	@Deactivate
	protected void deactivate() {
		super.deactivate();
	}
}`

bnd.bnd and .classpath are:

`Bundle-Name: OpenEMS Edge Predictor Load
Bundle-Vendor: OpenEMS Association 
Bundle-License: https://opensource.org/licenses/EPL-2.0
Bundle-Version:	1.0.0.${tstamp}
Bundle-Description: \
	Load Forecast

Export-Package: \
	
Private-Package:  \
	io.openems.edge.predictor.load

-buildpath: \
	${buildpath},\
	io.openems.common;version=latest,\
	io.openems.edge.common;version=latest,\
	org.ops4j.pax.logging.pax-logging-api

-testpath: ${testpath}

javac.source: 1.8
javac.target: 1.8`

and

`<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
	<classpathentry kind="src" output="bin" path="src"/>
	<classpathentry kind="output" path="bin"/>
</classpath>

`

But still the same problem… Strangely, when I added implements Controller, it would get activated correctly and stay activated but that’s obviously no help. I’m a little lost at this point, maybe someone can draw some conclusions out of this or had similar problems?
I appreciate every help,
Erik

Hello erik40021, your activate() method calls super.activate(..., config.enabled()). Does the OsgiValidateWorker warning always appear or only if your component is disabled?
What happens if you switch the enabled state of your OSGI configuration?
Because I think the OsgiValidateWorker will show this warning when a component is configured but not enabled.
What I do not understand is, why it should work if you implement Controller.

This topic may be relevant: Cannot get bundle to activate

Yes it always appears. Like in most configurations, the enabled() entry is set true on default. From what I can see through the logs is that it does get activated initially, there are no exceptions or anything visible that happens whilst activation. It also doesn’t get visibly deactivated, so it either doesn’t stay activated or wasn’t actually ever activated properly.

Hi eric40021,
I don’t get the details of OSGI, but there is a little difference between your module declaration and my declaration. Can you please try to change your @Component declaration to

@Component(
	name = "Predictor.Load.LoadForecast", //
	immediate = true, //
	configurationPolicy = ConfigurationPolicy.REQUIRE),
	property = { "type=PRODUCTION" })

Because if you add that property, the enabledComponents list in the ComponentManagerImpl
is build up correctly and the warning disappears. But to be honest I don’t know why.

Update: This post is useless. The property declaration does not influence the activation mechanism!

Thanks for your help first! Did you manage to get what I sent or something similar to activate or what exactly do you mean by

the enabledComponents list in the ComponentManagerImpl is build up correctly and the warning disappears

I couldn’t reproduce it by adding that to property in @Component, also (if this is relevant) I’m not sure what the type of my Component would be.

Hello Eric, I didn’t run your code. I just played around with mine. Sorry for pointing you in the wrong direction.
I had a closer look at your code and found a little problem. The call in the activate() method is wrong. Please try to change it to

super.activate(context, config.id(), config.alias(), config.enabled());

The AbstractOpenemsCanComponent expects the id first and the alias as next parameter.

1 Like

Hi Erik,

I tested your code and it works for me. @c.lehne’s correction is important and it might have caused an exception at activate.

I created a branch that works for me: https://github.com/sfeilmeier/openems/tree/demo/161

Did you put a breakpoint in the constructor and activate method? This will help finding out if the Component really is not activated or if it throws an exception on activate. Unfortunately exception stacktraces often do to appear in the logs.

Please also have a look at https://github.com/OpenEMS/openems/tree/develop/io.openems.edge.predictor.persistencemodel/src/io/openems/edge/predictor/persistencemodel/consumption, as it might be similar to what you are planning to implement.

@c.lehne: the ‘type=PRODUCTION’ property is only used for meter implementations. This information is used in the UI to categorize energy measurements.

Regards,
Stefan

@stefan.feilmeier
Hi Stefan, sorry I should have been more clear in my post. I debugged the code from Erik. I saw that the
OsgiValidateWorker calls isComponentActivated(). That method checks if a given componentId is part of the list of enabled components (in my case erics module was part of the list).
Note here that AbstractOpenemsComponent sets the id to “_componentX” if id==null. The code from eric has switched alias and id. I assume here that the configuration sets alias==null. So because of the switched id and alias the componentId will be set to “_componentX” and not to the real componentId. And that will lead to the “Component(s) configured but not active” warning, because the OsgiValidateWorker could not find the component.

Thanks for the “type=Production” hint. At some time I need to get a better understanding of OSGI.

1 Like

Thank you @c.lehne for finding the error and you two for your help, it works now! but what a dumb mistake… :confused:

Yes that was part of the problem I guess. Anyway, thanks again, regards, Erik

1 Like

I realize that it is always difficult to get started creating OpenEMS Components from scratch. I took some time today to create templates for bndtools.

Could you please try and see if this works better for you?

This may be why I’m currently struggling myself - is there a way to allow these outputs? I’m finding myself struggling to understand the OSGi Logging mechanism

I agree with Kyle, no exceptions slows down debugging a lot, without the eclipse debugger it would be impossible. Something like a developer logging mode could be a helpful future feature.

This was a big help - I was putting breakpoints in the activate method instead of the constructor, but I was also expecting exceptions to come up in the console. Perhaps something for a future FAQ?