New example of osgi config files not working with Aem cloud SDK.
I tried and failed to get osgi config files to work in my own code as discussed here.
I found one example on the web of someone else who has created an OSGI config the same as mine, but unfortunately, they also don't include a config file.
I took their source code, added it to my project, added a config file, and get same result - AEM is ignoring the config file.
I suspect this is a problem with either
- my env (M1 Mac running Java 11),
- a bug in the latest AEM cloud SDK,
- a problem with the wknd sample project.
Here is the example I took:
https://github.com/nateyolles/aem-osgi-annotation-demo
As this project wont build (AnnotationProcessor is not an ImageIO SPI class), I simply copied the following files to the same place in the wknd projectv (see below for exact source code)
- SampleOsgiService.java
- /impl/Configuration.java
- /impl/SampleOsgiServiceImpl.java
- SampleOsgiServlet.java
package com.adobe.aem.guides.wknd.core.services;
public interface SampleOsgiService {
String getSettings();
}package com.adobe.aem.guides.wknd.core.services.impl;
import org.apache.commons.lang3.StringUtils;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.osgi.service.metatype.annotations.Option;
@ObjectClassDefinition(name = "Annotation Demo Service - OSGi")
public Configuration {
@AttributeDefinition(
name = "Boolean Property",
description = "Sample boolean value",
type = AttributeType.BOOLEAN
)
boolean servicename_propertyname_boolean() default true;
@AttributeDefinition(
name = "String Property",
description = "Sample String property",
type = AttributeType.STRING
)
String servicename_propertyname_string() default "foo";
@AttributeDefinition(
name = "Dropdown property",
description = "Sample dropdown property",
options = {
(label = "DAYS", value = "DAYS"),
(label = "HOURS", value = "HOURS"),
(label = "MILLISECONDS", value = "MILLISECONDS"),
(label = "MINUTES", value = "MINUTES"),
(label = "SECONDS", value = "SECONDS")
}
)
String servicename_propertyname_dropdown() default StringUtils.EMPTY;
@AttributeDefinition(
name = "String Array Property",
description = "Sample String array property",
type = AttributeType.STRING
)
String[] servicename_propertyname_string_array() default {"foo", "bar"};
/*
* To create password field, either set the AttributeType or have the
* property name end with "*.password" (or both).
*/
@AttributeDefinition(
name = "Password Property",
description = "Sample password property",
type = AttributeType.PASSWORD
)
String servicename_propertyname_password() default StringUtils.EMPTY;
@AttributeDefinition(
name = "Long Property",
description = "Sample long property",
type = AttributeType.LONG
)
long servicename_propertyname_long() default 0L;
}
package com.adobe.aem.guides.wknd.core.services.impl;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.Designate;
import com.adobe.aem.guides.wknd.core.services.SampleOsgiService;
@Component(
immediate = true,
service = SampleOsgiService.class,
configurationPid = "com.adobe.aem.guides.wknd.core.services.impl.SampleOsgiServiceImpl"
)
@Designate(
ocd = Configuration.class
)
public class SampleOsgiServiceImpl implements SampleOsgiService {
private ResourceResolverFactory resolverFactory;
boolean booleanProp;
String stringProp;
String dropdownProp;
String[] stringArrayProp;
char[] passwordProp;
long longProp;
public String getSettings() {
StringBuilder sb = new StringBuilder();
sb.append("Sample OSGi Service:\n");
sb.append("booleanProp: " + booleanProp + "\n");
sb.append("stringProp: " + stringProp + "\n");
sb.append("dropdownProp: " + dropdownProp + "\n");
sb.append("stringArrayProp: " + ArrayUtils.toString(stringArrayProp) + "\n");
sb.append("passwordProp: " + String.valueOf(passwordProp) + "\n");
sb.append("longProp: " + longProp + "\n");
return sb.toString();
}
protected final void activate(Configuration config) {
booleanProp = config.servicename_propertyname_boolean();
stringProp = config.servicename_propertyname_string();
dropdownProp = config.servicename_propertyname_dropdown();
stringArrayProp = config.servicename_propertyname_string_array();
passwordProp = config.servicename_propertyname_password().toCharArray();
longProp = config.servicename_propertyname_long();
}
protected void deactivate() {
}
}
package com.adobe.aem.guides.wknd.core.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import com.adobe.aem.guides.wknd.core.services.SampleOsgiService;
@Component(
immediate = true,
service = Servlet.class,
property = {
"sling.servlet.extensions=txt",
"sling.servlet.paths=/bin/osgi",
"sling.servlet.paths=/bin/foo",
"sling.servlet.methods=get"
},
configurationPid = "com.adobe.aem.guides.wknd.core.servlets.SampleOsgiServlet"
)
@Designate(ocd=SampleOsgiServlet.Configuration.class)
public class SampleOsgiServlet extends SlingSafeMethodsServlet {
private static final long serialVersionUID = 1L;
private SampleOsgiService sampleOsgiService;
private boolean enabled;
protected void doGet(final SlingHttpServletRequest req,
final SlingHttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
resp.setContentType("text/plain");
out.write("Annotation Demo Servlet - OSGi - enabled: " + enabled + "\n");
out.write(sampleOsgiService.getSettings());
}
protected void Activate(Configuration config) {
enabled = config.enabled();
}
@ObjectClassDefinition(name = "Annotation Demo Servlet - OSGi")
public Configuration {
@AttributeDefinition(
name = "Enable",
description = "Sample boolean property"
)
boolean enabled() default false;
}
}
/aem-guides-wknd/ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config/com.adobe.aem.guides.wknd.core.services.impl.SampleOsgiServiceImpl.cfg.json
With the following content:
{
"servicename_propertyname_string":"bar",
"servicename_propertyname_dropdown":"SECONDS"
}
Then I deleted the crx dir, restarted the server, and did
mvn clean install -PautoInstallSinglePackage.
However, when I run http://localhost:4502/bin/osgi I get:
Annotation Demo Servlet - OSGi - enabled: false
Sample OSGi Service:
booleanProp: true
stringProp: foo
dropdownProp:
stringArrayProp: {foo,bar}
passwordProp:
longProp: 0
stringProp should be "bar" and dropdownProp should be "SECONDS"
Just like in my code, the ConfigMngr ends up with two copies of the config:

The first one is created from the service, not from the .cfg.json file:

The second one, which I expected to contain my two values, only has "enable". Looking at the servlet, it also defines a configuration param, in addition to those created on the configuration class. This seems bizarre.

Below we see the config file is correct in crxde:

However, this config doesnt seem to exist in the configmgr. I would expect it to be called the same as the pid: com.adobe.aem.guides.wknd.core.services.impl.SampleOsgiServiceImpl.cfg.json but its not there.