2016-06-21 2 views
0

В настоящее время я работаю над сервлетом Sling, который использует инфраструктуру OSGi через Apache Felix. Из того, что я понимаю, если вы хотите получить и использовать другую услугу, у вас есть два варианта: 1. Напишите слушателя службы, который гарантирует, что служба, которую вы хотите, зарегистрирована до приобретения и использования вашего сервиса. 2. Используйте @Reference аннотацию от Apache Felix, чтобы приобрести услугу.Apache Felix @ Проблемы с аннотацией речи

Я хочу сделать вариант 2, поскольку для варианта 1 требуется много кода, который мне не нужно писать.

Итак, вот как я это сделал. Просто отказ от ответственности: что следует за фрагментами моего кода и не составляют весь мой проект. Не ожидайте, что сможете скомпилировать это или что-нибудь еще. Я включил то, что, как я считаю, является соответствующими частями.

Во-первых, у меня есть слинг сервлет:

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). Аннотации @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 является компонентом OSGi с помощью @Component аннотацию. Важное замечание здесь состоит в том, что мы использовали аннотацию @Service, которая, по-видимому, выполняет важную задачу: @Service аннотация REGISTERS сервис.

Пожалуйста, просто предположим, что есть файл MyServiceInterface.java, который выглядит примерно так:

package mypackage; 
import /*necessary imports*/ 

public interface MyServiceInterface { 
    //stuff 
} 

Со всеми этими отборочные из пути, вот мой вопрос. Когда я запускаю свой сервлет, посетив [hostname]/bin/mytest в веб-браузере, я получаю ошибку на 404 странице. Это означает, что мой браузер не может найти сервлет.

Теперь вы можете спросить себя, почему я так думаю, что это связано с аннотацией @Reference. Ну, я думаю, что это так ответственно, потому что, комментируя это и приобретая услугу старомодным способом (т. Е. Метод 1 выше), сервлет работает без проблем.

Другая потенциально важная информация заключается в том, что я использую Maven для создания этого проекта. Я рад предоставить соответствующие файлы pom.xml, если вы считаете, что они содержат полезную информацию.

Пожалуйста, помогите мне выяснить, почему мой сервлет не может быть найден, когда я использую аннотацию @Reference! Если вам нужно, чтобы я предоставил больше информации, прежде чем помогать мне, я буду рад сделать это. Пожалуйста, укажите в комментариях, если я не предоставил достаточную информацию.

Спасибо заранее!

+0

Вы подключили отладчик? Вы реализовали метод #doGet и достигли? – nateyolles

+0

Да, у меня есть отладчик, и я переопределил метод doGet. Метод 'doGet' не достигается, когда присутствует аннотация' @ Reference'. Тем не менее, это определенно достигается, когда я удаляю аннотацию. – Pr4isethesun

+0

Что произойдет, если вы установите значение true? – nateyolles

ответ

0

Первое, что я всегда делаю, это проверить, активны ли мои пакеты и сервлеты в консоли Apache Felix по адресу http://localhost:8080/system/console/bundles и http://localhost:8080/system/console/components. У вас есть какие-либо недостающие зависимости, которые препятствуют тому, чтобы ваш пакет или компонент стали активными?

Основываясь на вашем вопросе, я предполагаю, что вы, возможно, не используете Apache Felix Maven SCR Plugin. Как вы заявили, вы не хотите вручную создавать ServiceListeners (заявленный вариант 1), но скорее будете использовать Declarative Services (ваш заявленный вариант 2), и для этого вам нужен плагин SCR. Аннотации, такие как @Reference, не являются исполняемыми, они используются плагином SCR для генерации кода и метаданных, необходимых для работы вашей службы в среде OSGi с Declarative Services. Ссылка на документацию, приведенная выше, дает подробный отчет о функции плагина. Просто добавьте плагин в файл 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 См.

+0

Спасибо за ваш ответ! Это и хорошие вещи для проверки. Что касается компонента, я уже проверил, что он активен через консоль. Что касается плагина SCR, я убедился, что он включен в мой файл 'pom.xml'. Тем не менее, у меня все еще такая проблема. Спасибо за вашу помощь. – Pr4isethesun

0

Если ваш сервлет работает без ссылки и он перестает работать, как только вы добавляете ссылку, то сама проблема должна быть проблемой.

Наиболее очевидным решением является то, что ссылка недоступна (по какой-либо причине, может быть, класс интерфейса службы не экспортируется, но он находится в другом комплекте?), Поэтому он имеет статус «неудовлетворен». В этом случае сервлет не запустится.

Вы действительно проверили свой сервлет в/system/console/components или вы только проверили соответствующий компонент?

Кстати, ваш сервлет не нуждается во всех этих аннотациях. Просто используйте @SlingServlet (paths = {"/ bin/mytest"}, metatype = false, generateService = true) Затем вы можете удалить @Component и @Service.

Смежные вопросы