Java ApacheFelix@Reference注释问题
我目前正在开发一个Slingservlet,它通过ApacheFelix使用OSGi框架。据我所知,如果您想获得并使用其他服务,您有两种选择: 1.编写一个服务侦听器,确保在获取和使用您的服务之前注册了您想要的服务。 2.使用ApacheFelix的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
@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;
}