Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ApacheFelix@Reference注释问题_Java_Servlets_Osgi_Apache Felix_Sling - Fatal编程技术网

Java ApacheFelix@Reference注释问题

Java ApacheFelix@Reference注释问题,java,servlets,osgi,apache-felix,sling,Java,Servlets,Osgi,Apache Felix,Sling,我目前正在开发一个Slingservlet,它通过ApacheFelix使用OSGi框架。据我所知,如果您想获得并使用其他服务,您有两种选择: 1.编写一个服务侦听器,确保在获取和使用您的服务之前注册了您想要的服务。 2.使用ApacheFelix的@Reference注释来获取服务 我想做选项2,因为选项1需要很多我不需要编写的代码 所以,我是这样做的。免责声明:下面是我的代码片段,并不构成我的整个项目。不要期望能够编译这个或任何东西。我已经包括了我认为相关的部分 首先,我有我的sling s

我目前正在开发一个Slingservlet,它通过ApacheFelix使用OSGi框架。据我所知,如果您想获得并使用其他服务,您有两种选择: 1.编写一个服务侦听器,确保在获取和使用您的服务之前注册了您想要的服务。 2.使用ApacheFelix的
@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,我们要声明的字段是这个捆绑包中已经注册的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
}
Annotation @reference is disallowed for this location.
所有这些预备赛都已经结束了,这是我的问题。当我在web浏览器中访问
[hostname]/bin/mytest
来运行servlet时,我得到一个404页面未找到错误。这表示我的浏览器找不到servlet

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

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

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


提前谢谢

我经常做的第一件事是检查我的bundle和servlet是否在和的Apache Felix控制台中处于活动状态。您是否缺少阻止捆绑包或组件激活的依赖项

根据你的问题,我的第一个猜测是你可能没有使用。正如您所说的,您不想手动创建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>

...
...
...
org.apache.felix

.

我经常做的第一件事是检查我的bundle和servlet是否在和的Apache Felix控制台中处于活动状态。您是否缺少阻止捆绑包或组件激活的依赖项

根据你的问题,我的第一个猜测是你可能没有使用。正如您所说的,您不想手动创建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>

...
...
...
org.apache.felix

.

如果您的servlet在没有引用的情况下工作,并且在添加引用后立即停止工作,那么引用本身就是问题所在

最明显的解决方案是引用不可访问(无论出于何种原因,可能服务接口类没有导出,但它在另一个包中?),因此它的状态为“未满足”。在这种情况下,servlet将不会启动

您是真的在/system/console/components中检查了servlet,还是只检查了相应的组件

顺便说一句,servlet不需要所有这些注释。简单使用 @SlingServlet(路径={“/bin/mytest”},元类型=false,generateService=true)
然后您可以删除@Component和@Service。

如果您的servlet在没有引用的情况下工作,并且在添加引用后它就停止工作,那么引用本身就是问题所在

最明显的解决方案是引用不是access
Annotation @reference is disallowed for this location.
@Reference
MyService myService;
private MyService myService;
@Reference
public void bindMyService(MyService myService) {
     this.myService = myService;
}
public void unbindMyService(MyService myService) {
     this.myService = myService;
}