2014-01-21 2 views
0

Я пытаюсь научиться использовать Felix iPOJO API для динамического создания компонентов.IPOJO - Завод, связанный с типом компонента, недействителен (не запущены или отсутствуют обработчики)

У меня есть простой пакет со следующими файлами:

1- HelloService.java (содержит интерфейс Service).

/* 
* @author zaid almahmoud 
* 
*/ 
package helloipojo.service; 

public interface HelloService 
{ 

    public void sayHello(); 

} 

2- Его реализация HelloServiceImpl.java:

package helloipojo; 

import helloipojo.service.HelloService; 


public class HelloServiceImpl implements HelloService{ 

    @Override 
    public void sayHello() { 

     System.out.println("Hello iPojo!"); 

    } 


} 

3- Activator.java:

package helloipojo; 

import org.osgi.framework.BundleActivator; 
import org.osgi.framework.BundleContext; 


public class Activator implements BundleActivator { 


     public void start(BundleContext context) throws Exception { 


      System.out.println("Bundle Started!"); 


     } 
     public void stop(BundleContext context) throws Exception { 

      context = null; 
      System.out.println("Bundle Stopped!"); 


     } 

} 

4- MANIFEST.MF:

Manifest-Version: 1.0 
Bundle-ManifestVersion: 2 
Bundle-Name: HelloIPojo 
Bundle-SymbolicName: HelloIPojo 
Bundle-Version: 1.0.0.qualifier 
Bundle-Activator: helloipojo.Activator 
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 
Import-Package: org.osgi.framework 

В моем приложении , Я начала рамки Феликса и развернуть следующие пакеты:

iPOJO (core) 
iPOJO Composite 
iPOJO API 

В соответствии с this источника.

Далее, я устанавливаю свой пакет и создаю экземпляр компонента. Ниже мой класс:

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

import org.apache.felix.framework.Felix; 
import org.apache.felix.framework.util.FelixConstants; 
import org.osgi.framework.Bundle; 
import org.osgi.framework.BundleContext; 
import org.osgi.framework.BundleException; 
import org.osgi.framework.Constants; 
import org.osgi.framework.ServiceRegistration; 
import org.apache.felix.ipojo.ComponentInstance; 
import org.apache.felix.ipojo.ConfigurationException; 
import org.apache.felix.ipojo.MissingHandlerException; 
import org.apache.felix.ipojo.UnacceptableConfiguration; 
import org.apache.felix.ipojo.api.ComponentType; 
import org.apache.felix.ipojo.api.PrimitiveComponentType; 
import org.apache.felix.ipojo.api.Service; 

public class HostApplication 
{ 
    private HostActivator m_activator = null; 
    private Felix m_felix = null; 


    public HostApplication() 
    { 
     // Create a configuration property map. 
     Map config = new HashMap(); 
     config.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); 
     // Create host activator; 
     m_activator = new HostActivator(); 
     List list = new ArrayList(); 
     list.add(m_activator); 

     config.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list); 

     try 
     { 
      // Now create an instance of the framework with 
      // our configuration properties. 
      m_felix = new Felix(config); 
      // Now start Felix instance. 
      m_felix.start(); 
     } 
     catch (Exception ex) 
     { 
      System.err.println("Could not create framework: " + ex); 
      ex.printStackTrace(); 
     } 


     // Register the application's context as an OSGi service! 
     BundleContext bundleContext1 = m_felix.getBundleContext(); 


       System.out.println("6"); 

       try { 

        //starting ipojo required bundles 
        Bundle coreBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo-1.6.2.jar"); 
        coreBundle.start(); 
        if(coreBundle.getState()== coreBundle.ACTIVE) 
         System.out.println("Core Bundle is Active!"); 

        Bundle apiBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo.api-1.6.0.jar"); 
        apiBundle.start(); 
        if(apiBundle.getState()== apiBundle.ACTIVE) 
         System.out.println("API Bundle is Active!"); 


        Bundle compositeBundle = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Dropbox\\EBTIC\\ADERE\\feasibility-codes\\ipojo\\ipojo-distribution-1.11.0\\bundle\\org.apache.felix.ipojo.composite-1.6.0.jar"); 
        compositeBundle.start(); 
        if(compositeBundle.getState()== compositeBundle.ACTIVE) 
         System.out.println("Composite Bundle is Active!"); 


//HERE INSTALLING AND STARTING MY BUNDLE!! 
Bundle b = bundleContext1.installBundle("file:C:\\Users\\zaid.almahmoud\\Desktop\\plugins\\HelloIPojo_1.0.0.201401211340.jar"); 
       b.start(); 

        try { 

         ComponentType type = new PrimitiveComponentType() 
           .setBundleContext(b.getBundleContext()) 
           .setComponentTypeName("hello.type") 
           .setClassName("helloipojo.HelloServiceImpl") 
           .setImmediate(true); 
         type.start(); 

         ComponentInstance instance = type.createInstance(); 



        } 

        catch (UnacceptableConfiguration 
          | MissingHandlerException | ConfigurationException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } // Create the instance 







        System.out.println("done starting bundles!"); 


       } catch (BundleException e) { 

        e.printStackTrace(); 

        System.out.println("Not done!"); 
       } 



       //shutdownApplication(); 

    } 

    public Bundle[] getInstalledBundles() 
    { 
     // Use the system bundle activator to gain external 
     // access to the set of installed bundles. 
     return m_activator.getBundles(); 
    } 

    public void shutdownApplication() 
    { 
     // Shut down the felix framework when stopping the 
     // host application. 
     try { 
      m_felix.stop(); 
     } catch (BundleException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     try { 
      m_felix.waitForStop(0); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

Когда я запускаю мое приложение, оно показывает следующий вывод (с ошибкой в ​​конце):

6 
Core Bundle is Active! 
API Bundle is Active! 
Composite Bundle is Active! 
Bundle Started! 
Exception in thread "main" java.lang.IllegalStateException: The factory associated with the component type is invalid (not started or missing handlers) 
    at org.apache.felix.ipojo.api.ComponentType.ensureFactory(ComponentType.java:189) 
    at org.apache.felix.ipojo.api.ComponentType.ensureAndGetFactory(ComponentType.java:177) 
    at org.apache.felix.ipojo.api.ComponentType.createInstance(ComponentType.java:79) 
    at HostApplication.<init>(HostApplication.java:109) 
    at Embedder.main(Embedder.java:11) 

Где я ошибся? Благодарю.

Update 1

Я мог видеть, что мне не хватает 2 обработчиков. Я знал, что, добавив следующие две строки:

System.out.println(type.getFactory().getRequiredHandlers()); 
System.out.println(type.getFactory().getMissingHandlers()); 

Выход из вышеуказанных двух линий:

[org.apache.felix.ipojo:architecture, org.apache.felix.ipojo:callback] 
[org.apache.felix.ipojo:architecture, org.apache.felix.ipojo:callback] 

Я также попытался:

type.getFactory().createComponentInstance(new Properties());

тогда я получил:

org.apache.felix.ipojo.MissingHandlerException: Missing handlers : org.apache.felix.ipojo:architecture org.apache.felix.ipojo:callback 

Я не знаю, почему эти обработчики отсутствуют. Я попытался добавить их, но не смог понять правильный синтаксис. Любая помощь? Благодарю.

Update 2

Согласно Клименту в his ответ, мой пучок должен импортировать: org.apache.felix.ipojo и org.apache.felix.ipojo.architecture

Я сделал это, и теперь я получаю следующее сообщение об ошибке:

java.lang.ClassCastException: org.apache.felix.ipojo.HandlerManagerFactory cannot be cast to org.apache.felix.ipojo.HandlerFactory 

Я получаю сообщение об ошибке: type.start();

Пожалуйста, помогите. Благодаря!

ответ

1

Проблема исходит от асинхронного запуска iPOJO. Когда вы создаете свой экземпляр, не все доступно.

У меня есть несколько вопросов: Почему вы используете API iPOJO для объявления своего типа и экземпляра? Вы не можете использовать аннотации? В этом случае он будет просто создавать все гладко.

Если вам действительно нужно/нужно использовать API, не создавайте экземпляр, как вы, а выставляйте объявление экземпляра: http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/ipojo-advanced-topics/ipojo-factory-service.html#deleting-instances. Объявление ждет, пока завод не будет действительным для создания экземпляра.

+0

Спасибо. Моя цель номер 1 состоит в том, чтобы динамически создавать, запускать и останавливать компоненты. Я не думаю, что это возможно с аннотациями, не так ли? Я пробовал: \t Объявление об объявлении экземпляра = новое DefaultInstanceDeclaration (b.getBundleContext(), «my-factory»); В нем нет ошибок, но автор ссылки, которую вы опубликовали, говорит, что вы можете запустить и остановить экземпляр объявления. Хотя, я не нашел метод start или stop (declaration.start() показал синтаксическую ошибку). Что происходит? –

+0

Я был бы очень признателен, если вы сможете обновить свой ответ фрагментом кода, чтобы показать правильный синтаксис. –

+0

Наконец, у меня есть полный доступ к моим службам пакетов, ссылкам, свойствам с помощью экземпляра объявления? Могу ли я ими манипулировать динамически с помощью этого экземпляра? Большое спасибо. –