我目前正在开发一个Sling servlet,它通过Apache使用OSGi框架。据我所知,如果您想获得和使用另一个服务,您有两个选项: 1.编写一个服务侦听器,确保在获取和使用您的服务之前注册您想要的服务。2.使用Apache的@Reference注释获取服务。
我想做选项2,因为选项1需要大量我不需要编写的代码。
我就是这么做的。只是一个免责声明:下面是我的代码片段,并不构成我的整个项目。不要期望能够编译这个或任何东西。我已经包括了我认为是相关的部分。
首先,我有了吊索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
}在这里,我们已经声明MyService是一个使用@Component注释的OSGi组件。这里要注意的是,我们使用了@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!如果你需要我在帮助我之前提供更多的信息,那么我很乐意这样做。如果我没有提供足够的资料,请在评论中注明。
提前谢谢!
发布于 2016-06-23 02:08:18
我总是做的第一件事是检查我的包和servlet是否在http://localhost:8080/system/console/bundles和http://localhost:8080/system/console/components的Apache控制台中活动。您是否有任何缺失的依赖关系来阻止您的包或组件变得活跃?
根据您的问题,我的第一个猜测是您可能没有使用Apache Felix Maven SCR插件。正如您所述,您不希望手动创建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>见使用Apache插件在Maven构建期间生成声明性服务和元类型服务描述符。
发布于 2016-06-28 10:06:39
如果您的servlet在没有引用的情况下工作,并且在添加引用之后它就停止工作,那么引用本身就是问题所在。
最明显的解决方案是,引用是不可访问的(无论出于什么原因,服务接口类可能不是导出的,而是在另一个包中?)因此,它具有“不满意”的地位。在这种情况下,servlet将不会启动。
您真的在/system/控制台/组件中签入了servlet,还是只检查了相应的组件?
顺便说一下,servlet不需要所有这些注释。只需使用@SlingServlet(path={ "/bin/mytest“}、metatype = false、generateService = true),就可以删除@组件和@Service。
发布于 2019-07-14 05:36:28
首先,您需要知道造成这种情况的原因:有时您对一个对象使用多个依赖项(特别是在大型项目中),这会导致IDE无法识别您指的是哪个对象。
就我而言:
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-api</artifactId>
<version>${onos.version}</version>
</dependency>以及:
<dependency>
<groupId>org.onosproject</groupId>
<artifactId>onos-providers-openflow-meter</artifactId>
<version>1.8.9</version>
</dependency>两者都指向同一个对象,因此使用@Reference注释会导致IDE无法注入该对象的问题。错误的文本可能如下:
Annotation @reference is disallowed for this location.现在您已经知道了问题所在,如何解决这个问题:不要比项目需要更多地使用依赖关系。在上面的例子中,删除第二个依赖解决了这个问题。
另一种方法是设置确切的依赖关系:如您所知,在OSGi注释中使用@Reference注释有多种方法。而不是使用:
@Reference
MyService myService;用这个:
private MyService myService;
@Reference
public void bindMyService(MyService myService) {
this.myService = myService;
}
public void unbindMyService(MyService myService) {
this.myService = myService;
}第二种选择解决了问题。
https://stackoverflow.com/questions/37952560
复制相似问题