OSGI HttpService не может быть правильно инициализирован / введен

1

Я хотел бы использовать функцию декларативных услуг в моем проекте OSGI для своих сервлетов. Подробнее: пользователь может установить модуль вручную в главном приложении, выбрав некоторый файл *.jar, основное приложение имеет встроенный сервер OSGI, а когда модуль OSGI активирован, он должен быть зарегистрирован для некоторых запросов. Например, следующим образом:

protected void startup() {
  MyServlet servlet = new MyServlet();
  if (httpService != null)  {
    httpService.registerServlet("/req", servlet, null, null); **//OK!**
  }
}

К сожалению, я не могу инициализировать экземпляр httpService и проблему. Здесь приведен код ошибки модуля сервлета:

@Component(name="app", immediate=true)
@Service(value=App.class)
public class App {                
        @Reference(name = "httpService", referenceInterface = HttpService.class, bind = "bindHttpService", unbind = "unbindHttpService")
        private HttpService httpService;

        @Activate
        protected void startup() {                    
            MyServlet servlet = new MyServlet();
            if (httpService != null)    {
                httpService.registerServlet("/req", servlet, null, null);
                //OK!
            } else {
                //Not OK! 
            }
        }

        protected void bindHttpService(HttpService httpService) {               
            this.httpService = httpService;
        }

        protected void unbindHttpService(HttpService httpService) {         
            this.httpService = null;
        }
        // some more code.........              
}

Настройки плагина Maven pom.xml

<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <extensions>true</extensions>
    <configuration>
        <instructions>
            <Bundle-SymbolicName>app</Bundle-SymbolicName>
            <Embed-Dependency>!org.osgi.core</Embed-Dependency>
            <Embed-Transitive>true</Embed-Transitive>                                               
            <Import-Package>                        
             <![CDATA[ 
               org.osgi*,
               com.mynamespace                        
            ]]>                     
            </Import-Package>                       
        </instructions>
    </configuration>
</plugin>

И вот упрощенный код для встроенного OSGI-сервера в основном приложении:

public static void main(String[] args) 
{
    FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
    Map<String, String> config = new HashMap<String, String>();
    config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "onFirstInit");
    config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "javax.microedition.io");
    Framework framework = frameworkFactory.newFramework(config);
    framework.start();
    BundleContext context = framework.getBundleContext();
    List<Bundle> installedBundles = new LinkedList<Bundle>();
    // install prerequisites
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.util_1.0.500.v20130404-1337.jar"));
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.osgi.services_3.4.0.v20131120-1328.jar"));
    installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar"));
    //install servlet module
    installedBundles.add(context.installBundle("file:///MY_PATH\\app.jar"));
    for (Bundle bundle : installedBundles) {
        bundle.start();
    }
}

Я был вдохновлен примером из блога Питера Фриса (http://www.peterfriese.de/osgi-servlets-flexibility-by-simplicity/), но я не могу инициализировать экземпляр httpService. Модуль App даже можно запустить, только если аннотация @Reference удалена или закрыта комментарием, в другом случае модуль не будет активирован.

Я подозреваю, что мой встроенный OSGI не имеет какого-то обязательного модуля, но не может получить информацию об этом - консоль журнала ничего не говорит.

ОБНОВИТЬ

Спасибо за подсказку Балаш!
Есть мои ошибки:
0. Когда <Embed-Dependency>!org.osgi.core</Embed-Dependency> httpService не может быть автоматически привязана через @Reference annotatoin, поэтому bind = "bindHttpService", unbind = "unbindHttpService" бесполезен. Я удалил объявление <Embed-Dependency> и он помогает связать httpService, как будто я хочу его (через bindHttpService).

  1. Прежде чем устанавливать пакеты на OSGI, необходимо указать параметры причала сервера:

    System.setProperty( "jetty.port", "8080");
    System.setProperty("jetty.home.bundle", "org.eclipse.jetty.osgi.boot");

  2. На встроенный сервер OSGI должно быть установлено слишком много банок, в моем случае

    //Установлены обязательные связкиBundles.add(context.installBundle("file:///MY_PATH\org.eclipse.equinox.util_1.0.500.v20130404-1337.jar")); installedBundles.add(( "Файл:///my_path\org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar" context.installBundle)); installedBundles.add(( "Файл:///my_path\org.eclipse.osgi.services_3.4.0.v20131120-1328.jar" context.installBundle)); installedBundles.add(( "Файл:///my_path\javax.servlet-апи-3.0.1.jar" context.installBundle));

            // Container bundles
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.security_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.servlet_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.continuation_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.server_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.util_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.io_8.1.12.v20130726.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.jetty.http_8.1.12.v20130726.jar"));
    
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.servlet_1.1.400.v20130418-1354.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.jetty_3.0.200.v20131021-1843.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.servletbridge_1.0.300.v20130327-1442.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.servletbridge_1.3.0.v20130927-1541.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.common_3.6.200.v20130402-1505.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.registry_3.5.400.v20130717-1325.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.eclipse.equinox.http.registry_1.1.300.v20130402-1529.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\org.osgi.service.obr-1.0.2.jar"));
    
            // Service bundles
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-httpservice-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\ow2-httpservice-1.2-spec-1.0.0.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-osgi-boot-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-deploy-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-webapp-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-security-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-http-8.0.4.v20111024.jar"));
            installedBundles.add(context.installBundle("file:///MY_PATH\\jetty-xml-8.0.4.v20111024.jar"));
    
            // Finally, required OSGI bundle
            installedBundles.add(context.installBundle("file:///MY_PATH\\app.jar"));
    

Поэтому с этими изменениями у меня есть инициализированный объект httpService, и теперь я хочу зарегистрировать свой экземпляр сервлета

@Activate
protected void startup() {                    
   MyServlet servlet = new MyServlet();
   if (httpService != null) {
        System.out.println("Greetings! I just want to be sure that service isn't null!")
        //httpService.registerServlet("/req", servlet, null, null); // BAD PLACE
   } else {
        System.out.println("Something goes wrong")
   }
}

В приведенном выше фрагменте кода будет отображаться сообщение "Приветствия", но если я попытаюсь зарегистрировать сервлет и раскомментировать "ПЛОХОЕ МЕСТО", сообщение не будет показано, ничего не происходит. Исключение также не может быть уловлено; похоже, что метод "запуска" игнорируется. Какие-нибудь идеи, что неправильно?

  • 0
    Связки, которые вы собрали, кажутся мне немного странными. Вы получаете пакеты от Jetty версии 8.0.4, а также от Jetty версии 8.1.12. Вы также получаете некоторые связки от равноденствия. Возможно ли, что у вас есть пакет org.osgi.service.http дважды в вашем контейнере OSGi? В этом случае может случиться так, что ваш Bundle подключится к одному из них, в то время как объект HttpService будет создан на основе другого. Я рекомендую вам проверить транзитные зависимости по ссылке, которую я отправил, так как она работает точно (с Jetty 9.1.0).
  • 0
    Спасибо @BalazsZsoldos. На самом деле нужно установить много ненужных пакетов, поэтому я изменил свой пример [ответ ниже]. В вашем примере вы используете Jetty 9.1.0, который зависит от версии javax.servlet 3.1.0. к сожалению, в комплекте org.eclipse.equinox.http.servlet_1.1.400.v20130418-1354 есть ограничение: javax.servlet; version = "[2.3.0,3.1.0)" ', и этот пакет является ограничением для org.eclipse.jetty.osgi.httpservice_9.1.0.v20131115 с реализацией HttpService. Вот почему я должен использовать версию javax.servlet 3.0.1 и Jetty 8.0.4 - у этого набора зависимостей нет никаких проблем.
Теги:
servlets
osgi
apache-felix
osgi-bundle

2 ответа

1
Лучший ответ

Я не вижу, что вы добавляете пакет, содержащий любой контейнер сервлетов (причал или кошка). Я также не вижу в списке список, содержащий реализацию HttpService.

Если вам нужен рабочий пример, см. Зависимости здесь в разделе "Jetty with HTTP service". Если вы импортируете эти зависимости с их зависимостями транзитивно, у вас будет сервер Jetty с HttpService. В примере зависимости закомментированы, поскольку они используются только во время разработки. Обратите внимание, что вы должны запустить встроенный контейнер сервлета таким образом, чтобы были определены следующие системные свойства:

jetty.port=8080
jetty.home.bundle=org.eclipse.jetty.osgi.boot

Если вы google, вы можете найти другие комплекты комплектов для Tomcat или Jetty.

  • 0
    Спасибо, Балаш, теперь я могу инициализировать httpService. Однако регистрация сервлета не работает. Я обновил свой пост с последними изменениями
0

Таким образом, список установленных пакетов следующий:

// without these bundles http service won't be initialized
context.installBundle(libsDirectoryURL + "org.eclipse.equinox.util_1.0.500.v20130404-1337.jar");
context.installBundle(libsDirectoryURL + "org.eclipse.equinox.ds_1.4.200.v20131126-2331.jar");          
context.installBundle(libsDirectoryURL + "org.eclipse.osgi.services_3.4.0.v20131120-1328.jar");
context.installBundle(libsDirectoryURL + "org.eclipse.equinox.http.servlet_1.1.400.v20130418-1354.jar");

context.installBundle(libsDirectoryURL + "javax.servlet-api-3.0.1.jar");                                
context.installBundle(libsDirectoryURL + "jetty-httpservice-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-server-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-osgi-boot-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-deploy-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-continuation-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-servlet-8.0.4.v20111024.jar"));
context.installBundle(libsDirectoryURL + "jetty-webapp-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-server-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-security-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-http-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-io-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-util-8.0.4.v20111024.jar");
context.installBundle(libsDirectoryURL + "jetty-xml-8.0.4.v20111024.jar");

Я хотел бы использовать javax.servlet 3.1.0 с jetty 9.1.0, но не смог решить проблему с jetty-httpservice, которая зависит от org.eclipse.equinox.http.servlet (возможно, есть версия этого банку, которая отлично работает с javax.servlet 3.1.0, но я не нашел его)

Я разместил небольшой пример кода встроенного сервера OSGI с HttpService на bitbucket, может быть, кто-то найдет его полезным: https://bitbucket.org/vbashur/diff/src/

  • 0
    ПРИМЕЧАНИЕ. Выполнение кода в Eclipse IDE с Java 6 не влияет на службу OSGI, поэтому убедитесь, что путь сборки настроен для jdk1.7

Ещё вопросы

Сообщество Overcoder
Наверх
Меню