Robin Brouns created SLING-12104:
------------------------------------
Summary: OSGi Mock - Service Registration Designate OCD default
empty property is ignored, which leads to NPE
Key: SLING-12104
URL: https://issues.apache.org/jira/browse/SLING-12104
Project: Sling
Issue Type: Bug
Components: Testing
Affects Versions: Testing OSGi Mock 3.3.10
Reporter: Robin Brouns
Considering the following sample Class:
{code:java}
package com.sample.website.job;
import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.oak.commons.PathUtils;
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.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
@Component(service = Runnable.class)
@Designate(ocd = SampleJob.Config.class)
public class SampleJob implements Runnable {
private String sampleStringProperty;
@Activate
@Modified
public void update(final Config configuration) {
this.sampleStringProperty = configuration.sampleStringProperty();
}
@Override
public void run() {
if (PathUtils.isAbsolute(this.sampleStringProperty)) {
// do something
}
}
@ObjectClassDefinition(
name = "Sample Configuration",
description = "Sample Configuration Description"
)
@interface Config {
@AttributeDefinition(
name = "Sample String Property",
description = "Sample String Property"
)
String sampleStringProperty() default StringUtils.EMPTY;
}
} {code}
When I try to test this class with the default OSGi configuration via AEM Mocks:
{code:java}
final Runnable underTest =
aemContext.registerInjectActivateService(SampleJob.class); {code}
building this class leads to the following SCR definition:
{code:java}
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0"
name="com.sample.website.job.SampleJob" activate="update" modified="update">
<property name="updateImportPath" type="String" value=""/>
<service>
<provide interface="java.lang.Runnable"/>
</service>
<implementation class="com.sample.website.job.SampleJob"/>
</scr:component>{code}
the *default* value of *updateImportPath* (an empty String) is *not* injected
in the Configuration, but null is being used, which could lead to NPE.
AEM Mocks uses OSGi Mocks and the following method is used to retrieve the
*default* properties and values
[https://github.com/apache/sling-org-apache-sling-testing-osgi-mock/blob/c55d97ba266e0630200fcbb378b3f102d2dfba90/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java#L292C24-L292C46]
But as you can see the XPath Query doesn't match with the SCR definition: the
property exists with a *name* and there is a {*}value{*}, but it is empty, so:
{code:java}
String query = getComponentXPathQuery(clazz) + "/property[@name!='' and
@value!='']"; {code}
doesn't return the property and it default value and the result is a
Configuration returning *null*
The simple fix would be to check if the *value* attribute exists via the XPath
Query in the SCR definition, instead of checking for a non empty value.
A more robust fix would probably be to parse the OCD MetaType (if it is a OCD
config) and use the *default* attribute which is present over there, see:
{code:java}
<?xml version="1.0" encoding="UTF-8"?>
<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.2.0"
localization="OSGI-INF/l10n/com.sample.website.job.SampleJob$Config">
<OCD id="com.sample.website.job.SampleJob$Config" name="Sample Configuration"
description="Sample Configuration Description">
<AD id="updateImportPath" type="String" name="Sample String Property"
description="Sample String Property" default=""/>
</OCD>
<Designate pid="com.sample.website.job.SampleJob">
<Object ocdref="com.sample.website.job.SampleJob$Config"/>
</Designate>
</metatype:MetaData>
{code}
What do you think about this?
--
This message was sent by Atlassian Jira
(v8.20.10#820010)