IPOJO - фабрика, связанная с типом компонента, недопустима (не запущены или отсутствуют обработчики)

Я пытаюсь научиться использовать API Felix iPOJO для динамического создания компонентов.

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

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

/*
 * @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

В моем приложении я запускаю инфраструктуру Felix и внедряю следующие пакеты:

iPOJO (core)
iPOJO Composite
iPOJO API 

По данным этого источника.

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

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)

Где я неправ? Благодарю.

Обновление 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 

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

Обновление 2

Согласно Клименту в его ответе, моя пачка должна импортировать: 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. Когда вы создаете свой экземпляр, не все доступно.

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

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

Другие вопросы по тегам