8
votes

OSGI: Utiliser ServiceFactories?

Je cherche actuellement à obtenir un simple paquet contenant une usine de service en cours d'exécution.

Ceci est ma classe d'usine: p> xxx pré>

C'est mon service qui devrait être créé par l'usine: p> xxx pré>

et enfin l'OSGI-INF / Component.xml p> xxx pré>

si je cours mon test Bundles (A, B et C) dans Equinox, je reçois l'erreur suivante: P>

org.osgi.framework.ServiceException: org.eclipse.equinox.internal.ds.FactoryReg.getService() returned a service object that is not an instance of the service class bundleb.ServiceB


2 commentaires

Le paquet contenant votre service ne doit pas avoir le fichier ServiceB.class. Si c'est le cas, il utiliserait un service de service différent pour différents paquets - c'est faux.


Je pense que vous avez mal compris. Si vous spécifiez l'attribut ServiceFactory, DS créera une nouvelle instance pour chaque paquet. Vous pouvez obtenir le paquet que vous avez été attribué à partir du composantContext.


3 Réponses :


0
votes

ServiceFactory permet à votre code de fournir un objet de service personnalisé pour différents faisceaux. Notez que, avec ServiceFactory , les clients de votre service ne contrôlent toujours pas quand une nouvelle instance est créée, le service de recherche par son interface ( Serviceb ) comme d'habitude. Donc, pour eux, il n'y a pas de différence si votre service est enregistré en tant que ServiceFactory ou non.

Avec des services déclaratifs, vous ne devez pas implémenter ServiceFactory vous-même. Il suffit d'ajouter ServiceFactory = "true" attribut au (vous avez déjà fait) et différentes instances de votre classe de composants seront créées automatiquement (activées) pour une demande différente. liasses. Vous devez spécifier ServiceBIMPL comme classe de mise en œuvre du composant.


3 commentaires

Et comment la plate-forme OSGI sait-elle quelle classe d'usine à utiliser?


Je tiens à fournir ma propre mise en œuvre de l'usine pour faciliter une meilleure vérification de votre code. Voir cette discussion: Stackoverflow.com/Questtions/7004165/ ... j'ai trouvé à Knopflerfish.org/osgi_service_Tutorial.html Un exemple comment faire Cela, mais je dois enregistrer l'usine de service dans l'activateur. N'y a-t-il aucun moyen de le faire dans la déclaration des composants, de sorte que DS le fera pour moi?


Il créera sa propre usine qui fera fondamentalement quelque chose de similaire à getService () {objet comp = clazz.newinstance (); ActivateComponent (Comp); Retour Comp; }



12
votes

Voici un exemple en utilisant un composantFactory qui doit correspondre à vos besoins (et contient un test d'intégration simple pour aider avec votre Autre question ). Clause de non-responsabilité; Le code n'est pas bien écrit, juste par exemple, par exemple.

Certaines interfaces de service: p> xxx pré>

et: p> xxx pré> Puis les implémentations: p> xxx pré>

} p>

et: p> xxx pré>

Un test d'intégration qui Donne le tout (note; il y a une méthode principale afin de l'exécuter tout en démarrant / arrêter les paquets, etc.). p> xxx pré>

et voici le Maven POM: P>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.earcam</groupId>
    <artifactId>net.earcam.example.servicecomponent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <version.java.source>1.6</version.java.source>
        <version.java.target>1.6</version.java.target>

        <version.osgi>4.2.0</version.osgi>
        <version.paxexam>2.1.0</version.paxexam>
        <version.paxrunner>1.7.4</version.paxrunner>
        <version.cometd>2.3.1</version.cometd>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.core</artifactId>
            <version>${version.osgi}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.osgi</groupId>
            <artifactId>org.osgi.compendium</artifactId>
            <version>${version.osgi}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
            <version>1.4.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
            <version>1.3.RC2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jmock</groupId>
            <artifactId>jmock-junit4</artifactId>
            <version>2.5.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-junit4</artifactId>
            <version>${version.paxexam}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-container-paxrunner</artifactId>
            <version>${version.paxexam}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-link-assembly</artifactId>
            <version>${version.paxexam}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-testforge</artifactId>
            <version>${version.paxexam}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.ops4j.pax.runner</groupId>
            <artifactId>pax-runner-no-jcl</artifactId>
            <version>${version.paxrunner}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr</artifactId>
            <version>1.6.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${version.java.source}</source>
                    <target>${version.java.target}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>

            <plugin>
                <!-- Unit Tests -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.8.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <excludes>
                        <exclude>**/*IntegrationTest.java</exclude>
                    </excludes>
                </configuration>
            </plugin>

            <plugin>
                <!-- Integration Tests -->
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>failsafe-maven-plugin</artifactId>
                <version>2.4.3-alpha-1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                        <phase>integration-test</phase>
                    </execution>
                </executions>
                <configuration>
                    <includes>
                        <include>**/*IntegrationTest.java</include>
                    </includes>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.ops4j.pax.exam</groupId>
                <artifactId>maven-paxexam-plugin</artifactId>
                <version>1.2.3</version>
                <executions>
                    <execution>
                        <id>generate-config</id>
                        <goals>
                            <goal>generate-depends-file</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!-- Process the DS annotations -->
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-scr-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <execution>
                        <id>generate-scr-descriptor</id>
                        <goals>
                            <goal>scr</goal>
                        </goals>
                        <phase>process-classes</phase>
                        <configuration>
                            <strictMode>true</strictMode>
                            <outputDirectory>${project.build.outputDirectory}/</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


            <plugin>
                <!-- Generate OSGi bundle MAINFEST.MF entries -->
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>2.3.4</version>
                <extensions>true</extensions>
                <configuration>
                    <supportedProjectTypes>
                        <supportedProjectType>jar</supportedProjectType>
                    </supportedProjectTypes>
                    <instructions>
                        <Bundle-Vendor>earcam</Bundle-Vendor>
                        <Service-Component>OSGI-INF/serviceComponents.xml</Service-Component>
                        <!-- PAX mangles this, it uses the name of the project for the symbolicname 
                            of test bundle? <Bundle-SymbolicName>${project.name}</Bundle-SymbolicName> -->
                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Bundle-Version>${project.version}</Bundle-Version>
                        <Export-Package>!${project.artifactId}.internal,${project.artifactId}.*</Export-Package>
                        <Import-Package>*</Import-Package>
                    </instructions>
                </configuration>
                <executions>
                    <execution>
                        <id>bundle-manifest</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>manifest</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <archive>
                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                    </archive>
                </configuration>
            </plugin>

        </plugins>
    </build>
</project>


2 commentaires

C'est génial! Merci beaucoup pour votre réponse détaillée et votre patience.


Merci @arcam pour la réponse très détaillée, bien meilleure que les docs Pax-Exam, cela m'a beaucoup aidé. Mais avoir une certaine confusion, cela fonctionne avec Java 6 mais pas sur le Java 8, j'ai essayé beaucoup avec une version de dépendance de PAX différente mais qui ne pouvait pas comprendre le conflit avec Java 8, pouvez-vous fournir le flux de dépendance de la version si possible?



1
votes

Il est en fait assez simple ... DS crée une instance pour chaque paquet, donc avec DS, vous ne mettez pas en œuvre usine de service, DS fait tout le travail difficile. Par exemple: xxx

Chaque fois qu'un autre paquet obtient ce XYZservice, DS créera une nouvelle instance. Vous pouvez utiliser le composantContext (éventuellement transmis dans la méthode d'activation) pour obtenir le paquet qui vous utilise.


1 commentaires

Le lien GitHub est maintenant cassé