Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6338567
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T19:28:18+00:00 2026-05-24T19:28:18+00:00

I’m currently trying to get a simple bundle containing a Service Factory running. This

  • 0

I’m currently trying to get a simple bundle containing a Service Factory running.

This is my factory class:

public class SvcFactory implements ServiceFactory<ServiceB> {

    @Override
    public ServiceB getService(Bundle bundle,
            ServiceRegistration<ServiceB> registration) {

        return new ServiceBImpl();
    }

    @Override
    public void ungetService(Bundle bundle, ServiceRegistration<ServiceB> registration,
            ServiceB service) {

    }

}

This is my service that should be created by the factory:

public class ServiceBImpl implements ServiceB {

    private ServiceA svcA;

    public void setA(ServiceA a) {
        svcA = a;
    }

}

And finally the OSGI-INF/component.xml

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="bundleb.internal.SvcFactory">

   <implementation class="bundleb.internal.SvcFactory"/>

  <reference bind="setA" cardinality="1..1" interface="bundlea.ServiceA" name="ServiceA" policy="static"/>

   <service servicefactory="true">
      <provide interface="bundleb.ServiceB"/>
   </service>
</scr:component>

If I run my test bundles (A, B and C) within equinox I’m getting the following error:

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

I can’t find much information about using ServiceFeactories declared in a component definition on the internet. Even the book “OSGi and Equinox” didn’t tell me much about using them.
Could anyone please explain to me what I’m doing wrong?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T19:28:19+00:00Added an answer on May 24, 2026 at 7:28 pm

    Here’s an example using ComponentFactory which should fit your needs (and contains a simple integration test to aid with your other question). Disclaimer; the code isn’t well written, just for example’s sake.

    Some service interfaces:

    package net.earcam.example.servicecomponent;
    
    public interface EchoService {
    
        String REPEAT_PARAMETER = "repeat";
        String FACTORY_DS = "echo.factory";
        String NAME_DS = "echo";
    
        String echo(String message);
    }
    

    And:

    package net.earcam.example.servicecomponent;
    
    public interface SequenceService {
        long next();
    }
    

    Then the implementations:

    import static net.earcam.example.servicecomponent.EchoService.FACTORY_DS;
    import static net.earcam.example.servicecomponent.EchoService.NAME_DS;
    import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY;
    import static org.apache.felix.scr.annotations.ReferencePolicy.DYNAMIC;
    import net.earcam.example.servicecomponent.EchoService;
    import net.earcam.example.servicecomponent.SequenceService;
    
    import org.apache.felix.scr.annotations.Activate;
    import org.apache.felix.scr.annotations.Component;
    import org.apache.felix.scr.annotations.Reference;
    import org.osgi.service.component.ComponentContext;
    
    @Component(factory = FACTORY_DS, name = NAME_DS)
    public class EchoServiceImp implements EchoService {
    
        @Reference(cardinality = MANDATORY_UNARY, policy = DYNAMIC)
        private SequenceService sequencer = null;
        private transient int repeat = 1;
    
        @Activate
    protected void activate(final ComponentContext componentContext)
    {
        repeat = Integer.parseInt(componentContext.getProperties().get(REPEAT_PARAMETER).toString());
    }
    
    
    @Override
    public String echo(final String message)
    {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i = 0; i < repeat; i++) {
            addEchoElement(stringBuilder, message);
        }
        return stringBuilder.toString();
    }
    
    
    private void addEchoElement(final StringBuilder stringBuilder, final String message) {
        stringBuilder.append(sequencer.next()).append(' ').append(message).append("\n");        
    }
    
    
    protected void unbindSequencer()
    {
        sequencer = null;
    }
    
    
    protected void bindSequencer(final SequenceService sequencer)
    {
        this.sequencer = sequencer;
    }
    

    }

    And:

    package net.earcam.example.servicecomponent.internal;
    
    import java.util.concurrent.atomic.AtomicLong;
    
    import net.earcam.example.servicecomponent.SequenceService;
    
    import org.apache.felix.scr.annotations.Activate;
    import org.apache.felix.scr.annotations.Component;
    import org.apache.felix.scr.annotations.Deactivate;
    import org.apache.felix.scr.annotations.Service;
    
    /**
     * @author caspar
     */
    @Component
    @Service
    public class SequenceServiceImp implements SequenceService {
    
        private AtomicLong sequence;
    
    
        @Override
        public long next()
        {
            return sequence.incrementAndGet();
        }
    
    
        @Activate
        protected void activate()
        {
            sequence = new AtomicLong();
        }
    
    
        @Deactivate
        protected void deactivate()
        {
            sequence = null;
        }
    }
    

    An integration test that drives the whole thing (note; there’s a main method so you run it while start/stopping bundles etc).

    package net.earcam.example.servicecomponent.test;
    
    import static org.ops4j.pax.exam.CoreOptions.*;
    import static org.ops4j.pax.exam.OptionUtils.combine;
    import static org.ops4j.pax.exam.spi.container.PaxExamRuntime.createContainer;
    import static org.ops4j.pax.exam.spi.container.PaxExamRuntime.createTestSystem;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FileNotFoundException;
    import java.util.Dictionary;
    import java.util.Hashtable;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import net.earcam.example.servicecomponent.EchoService;
    import net.earcam.example.servicecomponent.SequenceService;
    
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.ops4j.pax.exam.Option;
    import org.ops4j.pax.exam.junit.Configuration;
    import org.ops4j.pax.exam.junit.ExamReactorStrategy;
    import org.ops4j.pax.exam.junit.JUnit4TestRunner;
    import org.ops4j.pax.exam.spi.reactors.EagerSingleStagedReactorFactory;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceReference;
    import org.osgi.service.component.ComponentFactory;
    import org.osgi.service.component.ComponentInstance;
    
    
    @ExamReactorStrategy(EagerSingleStagedReactorFactory.class)
    @RunWith(JUnit4TestRunner.class)
    public class EchoServiceIntegrationTest {
    
    
        public static void main(String[] args) {
            try {
                createContainer(
                        createTestSystem(
                                combine(
                                        new EchoServiceIntegrationTest().config(), 
                                        profile("gogo"))
                        )).start();
            } catch(Throwable t) {
                t.printStackTrace();
            }
        }
    
    
    
        @Configuration
        public Option[] config()
        {
            return options(
                    felix(),
                    equinox(),
                    junitBundles(),
                    systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("TRACE"),
                    mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.scr").versionAsInProject(),
                    bundle("file:" + findFileInCurrentDirectoryAndBelow(
                            Pattern.compile("net\\.earcam\\.example\\.servicecomponent\\-[\\.\\d]+(\\-SNAPSHOT)?\\.[wj]ar")))
            );
        }
    
    
        @Test
        public void bundleContextIsAvailable(BundleContext context)
        {
            Assert.assertNotNull("PAX Exam BundleContext available", context);
        }
    
    
        @Test
        public void sequenceServiceIsAvailable(BundleContext context)
        {
            Assert.assertNotNull("SequenceService available", fetchService(context, SequenceService.class));
        }
    
    
        @Test
        public void serviceResponseContainsThreeEchos(BundleContext context) throws Exception
        {
            final String message = "message";
            final String expected = "1 " + message + "\n2 " + message + "\n3 " + message + "\n";
    
            ComponentFactory factory = fetchComponentFactory(context, EchoService.FACTORY_DS);
    
            Dictionary<String, String> properties = new Hashtable<String, String>();
            properties.put(EchoService.REPEAT_PARAMETER, "3");
            ComponentInstance instance = factory.newInstance(properties);
            EchoService service = (EchoService) instance.getInstance();
            String actual = service.echo(message);
            Assert.assertEquals("Expected response", expected, actual);
        }
    
    
        private ComponentFactory fetchComponentFactory(BundleContext context, String componentFactoryId) throws Exception
        {
            String filter = "(component.factory=" + componentFactoryId + ")";
            ServiceReference[] references = context.getServiceReferences(ComponentFactory.class.getCanonicalName(), filter);
            return (references.length) == 0 ?  null : (ComponentFactory) context.getService(references[0]);
        }
    
    
        private <T> T fetchService(BundleContext context, Class<T> clazz)
        {
            ServiceReference reference = context.getServiceReference(clazz.getCanonicalName());
            @SuppressWarnings("unchecked")
            T service = (T) context.getService(reference);
            return service;
        }
    
    
        private String findFileInCurrentDirectoryAndBelow(final Pattern filePattern) {
            FileFilter filter = new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    Matcher matcher = filePattern.matcher(pathname.getName());
                    return (matcher.matches());
                }
            };
            return findFile(new File("."), filter, filePattern);
        }
    
    
        private String findFile(File directory, FileFilter filter, Pattern filePattern) {
            File[] matches = directory.listFiles(filter);
            if(matches != null && matches.length > 0) {
                return matches[0].getAbsolutePath();
            }
            File[] subdirs = directory.listFiles(new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                    return pathname.isDirectory();
                }
            });
            for(final File subdir : subdirs) {
                String found = findFile(subdir, filter, filePattern);
                if(!"".equals(found)) {
                    return found;
                }
            }
            throw new RuntimeException(new FileNotFoundException("No match for pattern: " + filePattern.pattern()));
        }
    }
    

    And here’s the maven pom:

    <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>
    

    A couple of things to note; I like my integration tests inside the module they test, that way mvn clean install deploy fails if my integration test does – but it’s common to see projects with a single integration module for all integration tests. This explains the ugly method findFileInCurrentDirectoryAndBelow(Pattern pattern) which is used to locate the current module’s bundle in the target directory, and also explains the non-standard setup of the maven-bundle-plugin and maven-scr-plugin plugins.

    Also the way Pax-Exam picks up the dependencies requires you run the maven build for every change in dependencies and config (e.g. bundle imports/exports, DS changes). But once this is done you can run/debug the tests from Eclipse.

    I’ve put the project in a tarball here

    HTH =)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am currently running into a problem where an element is coming back from
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I am doing a simple coin flipping experiment for class that involves flipping a
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
For some reason, after submitting a string like this Jack’s Spindle from a text
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
this is what i have right now Drawing an RSS feed into the php,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.