模拟 OSGi 上下文中的服务激活异常

Exception on service activation in mock OSGi context

在我的 Maven 项目中,我创建了一个简单的 OSGi 服务,它只接受一个引用:

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;
}

然后,使用 osgi-mock 教程,我创建了以下测试 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());
    }

}

测试在最后一行崩溃,出现以下异常:

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

按照互联网上的建议,我已经达到了 this configuration guide 并确保我的 pom.xml 具有 maven-bundle-plugin 的正确配置 - 但是这并没有解决问题。

知道我哪里出错了吗?

我尝试将您的问题 运行 复制到最初的同一个异常中,现在它开始工作了。问题可能是由于 maven-scr-pluginmaven-bundle-plugin.

之间的 t运行sitive 依赖关系导致类路径损坏

确保您具备以下条件:

  • 使用 osgi-mock 2.x 兼容 OSGI R6 的模拟依赖项。这是我用的。

        <dependency>
            <groupId>org.apache.sling</groupId>
            <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
            <version>2.3.6</version>
            <scope>test</scope>
        </dependency>
    
  • 删除 scr Maven 插件和依赖项(maven-scr-pluginorg.apache.felix.scr),因为这会在与 OSGi R6 注释结合使用时导致类路径冲突。这是我用过的 maven-bundle-plugin 版本。我从 here.

    中获取了所有必需的依赖项
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
    
  • 确保您的插件构建部分包含生成所需 DS 元数据所需的配置。您可以参考您链接的 felix 文档以获取更多信息。

        <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>
    
  • 执行 mvn clean install 将在 /OSG-INF 中生成 DS 输出。

  • 运行 你的测试。我用过 MockitoJunitRunner,用 PowerMock 应该也能正常工作。

在我的例子中,我必须添加 ds-annotations 依赖项

<dependency>
    <groupId>org.apache.felix</groupId>
    <artifactId>org.apache.felix.scr.ds-annotations</artifactId>
    <version>1.2.10</version>
    <scope>provided</scope>
</dependency>

http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/apache-felix-maven-scr-plugin-use.html

所述