java - Apache Felix @Reference 注解问题

标签 java servlets osgi apache-felix sling

我目前正在开发一个 Sling servlet,它通过 Apache Felix 使用 OSGi 框架。据我了解,如果您想获取并使用其他服务,您有两种选择: 1. 编写一个服务监听器,确保在获取和使用您的服务之前注册您想要的服务。 2. 使用 Apache Felix 的 @Reference 注解获取服务。

我想做选项 2,因为选项 1 需要大量我不需要编写的代码。

所以,这就是我的做法。只是免责声明:以下是我的代码片段,并不构成我的整个项目。不要指望能够编译这个或任何东西。我已经包含了我认为相关的部分。

首先,我有我的 sling servlet:

package mypackage;
import /*necessary imports*/

@Component( name = "My Sling Servlet", immediate = false, metatype = true)
@Properties({
    @Property(name = "sling.servlet.paths", value = "/bin/mytest"),
    @Property(name = "sling.servlet.methods", value = "GET")
})

@Service(Servlet.class)
public class MyServlet extends SlingSafeMethodsServlet {
    @Reference
    private MyService service;

    // Do stuff with service
}

据我了解,@Component注释让OSGi知道这个类文件定义了一个组件。 @Properties 注释定义了组件的一些基本属性(在本例中,对我们来说重要的是现在我们可以通过转到 [hostname]/bin/mytest 来运行此 servlet)。 @Service 注释让 OSGi 知道该类是一个服务(特别是实现 Servlet 类的服务),并注册该服务。最后,@Reference 注释告诉 OSGi 我们要声明的字段是该 bundle 中已注册的 OSGi 服务,我们应该捕获它。

现在,这是另一个相关文件,它定义了服务 MyService:

package mypackage;
import /*necessary imports*/

@Component(name="MyService", immediate=false,metatype=true)

@Service(value = MyServiceInterface.class)
public class MyService implements MyServiceInterface {
    // Implementation of MyServiceInterface
}

在这里,我们使用 @Component 注释声明 MyService 是一个 OSGi 组件。这里重要的一点是,我们使用了 @Service 注释,它显然完成了一项基本任务:@Service 注释注册服务。

请假设有一个文件 MyServiceInterface.java 看起来像这样:

package mypackage;
import /*necessary imports*/

public interface MyServiceInterface {
    //stuff
}

完成所有这些预备工作后,这是我的问题。当我通过在 Web 浏览器中访问 [hostname]/bin/mytest 来运行 servlet 时,出现 404 页面未找到错误。这表明我的浏览器找不到该 servlet。

您现在可能会问自己,为什么我认为这与 @Reference 注释有某种关系。嗯,我认为这在某种程度上是负责任的,因为当我将其注释掉并以老式方式获取服务(即上面的方法 1)时,servlet 运行没有任何问题。

另一个可能相关的信息是我正在使用 Maven 来构建这个项目。如果您认为相关的 pom.xml 文件包含有用的信息,我很乐意提供它们。

请帮我弄清楚为什么当我使用@Reference注释时找不到我的servlet!如果您需要我在帮助我之前提供更多信息,我很乐意这样做。如果我没有提供足够的信息,请在评论中指出。

提前致谢!

最佳答案

我总是做的第一件事就是检查我的包和 servlet 是否在 Apache Felix 控制台 http://localhost:8080/system/console/bundles 中处于 Activity 状态。和 http://localhost:8080/system/console/components 。您是否缺少任何依赖项,导致您的 bundle 或组件无法激活?

根据您的问题,我的第一个猜测是您可能没有使用 Apache Felix Maven SCR Plugin 。正如您所说,您不想手动创建 ServiceListeners(您指定的选项 1),而是希望使用声明式服务(您指定的选项 2),并且为此您需要 SCR 插件。 @Reference 等注释不是运行时的,SCR 插件使用它们来生成您的服务在具有声明性服务的 OSGi 环境中工作所需的代码和元数据。上面提供的文档链接详细介绍了该插件的功能。只需将插件添加到您的 pom.xml 文件中,如文档中所示:

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-scr-plugin</artifactId>
        <version>1.20.0</version>
        <executions>
          <execution>
            <id>generate-scr-scrdescriptor</id>
            <goals>
              <goal>scr</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

参见Using the Apache Felix Maven SCR Plugin to generate Declarative Services and Metatype Service descriptors during a Maven Build .

关于java - Apache Felix @Reference 注解问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37952560/

相关文章:

java - 从一个来源安装多个包

osgi - 将参数传递给 OSGi 应用程序

java - 什么是NullPointerException,我该如何解决?

java - 带有线条和区域的程序地形纹理

java - 如何从常规 servlet 过滤器访问 JAX RS 方法?

java - 在 Jetty 9.4.2 中禁用默认错误响应主体

java - 在 OSGi 中,传递服务引用是一种好的做法还是应该由 bundle 自行查找?

java - 如何单独启动JUnit测试?

java - ChooserActivity 泄露了 IntentReceiver

java - 如果类不在 servlet-context 的基础包中,则为 "No message found under code"。为什么?