In my Maven project, I've created a simple OSGi service that does nothing but accepts one reference:
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@Component
public class MyFoo {
@Reference
private ResourceResolverFactory factory;
}
Then, using osgi-mock tutorial, I've created the following test class:
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
public class MyFooTest {
@Rule
public OsgiContext mockContext = new OsgiContext();
@Test
public void test() {
ResourceResolverFactory mockFactory = Mockito.mock(ResourceResolverFactory.class);
mockContext.registerService(ResourceResolverFactory.class, mockFactory);
mockContext.registerInjectActivateService(new MyFoo());
}
}
The test crashes on the last line with the following exception:
org.apache.sling.testing.mock.osgi.NoScrMetadataException: No OSGi SCR metadata found for class MyFoo
at org.apache.sling.testing.mock.osgi.OsgiServiceUtil.injectServices(OsgiServiceUtil.java:381)
at org.apache.sling.testing.mock.osgi.MockOsgi.injectServices(MockOsgi.java:148)
at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:153)
at org.apache.sling.testing.mock.osgi.context.OsgiContextImpl.registerInjectActivateService(OsgiContextImpl.java:141)
at MyFooTest.testGetResolver(MyFooTest.java:22)
//snippet
Following the advice on the internet, I've reached this configuration guide and ensured that my pom.xml
has exactly this configuration for maven-bundle-plugin
- this however did not resolve the issue.
Any idea where am I making a mistake?
I tried replicating your issue, ran into the same exception initially and got it working now. Issue is probably due to spoiled classpath because of transitive dependencies between maven-scr-plugin
and maven-bundle-plugin
.
Ensure you have the following in place:
Use osgi-mock 2.x mock dependency which is OSGI R6 compatible. This is what I used.
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.osgi-mock</artifactId>
<version>2.3.6</version>
<scope>test</scope>
</dependency>
Remove scr
maven plugins and dependencies (maven-scr-plugin
and org.apache.felix.scr
) as this leads to classpath conflicts when used in conjunction with OSGi R6 annotations. This is the version of maven-bundle-plugin
I've used. I picked up all the required dependencies from here.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.2.0</version>
</plugin>
Ensure your plugin build section contains the required configurations to generate the required DS metadata. You can refer to the felix docs that you've linked for more info on this.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>scr-metadata</id>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<exportScr>true</exportScr>
<instructions>
<Bundle-SymbolicName>com.aem.chula.chula</Bundle-SymbolicName>
<Sling-Model-Packages>
com.aem.models
</Sling-Model-Packages>
<_dsannotations>*</_dsannotations>
<_metatypeannotations>*</_metatypeannotations>
</instructions>
</configuration>
</plugin>
Do a mvn clean install
which will generate the DS output in /OSG-INF
.
Run your tests. I've used MockitoJunitRunner
, should work fine with PowerMock
as well.