Hi David,

By looking in Felix SCR source code I found the lines causing the exception:

// field value type
if ( !m_isMultiple )
{
    // value type must not be specified for unary references
    if ( m_field_collection_type != null )
    {
throw componentMetadata.validationFailure( "Field value type must not be set for unary field references." );
    }
}

It seems Felix SCR is not happy because the attribute m_field_collection_type is set to "service" in the component XML (i.e. not null), while no cardinality is specified...

I thus changed my annotation like this:

@Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE)
private List<FileReaderService> availableServices;

I also added a factory service consumer in order to test the application and it works!

For those interested, the fixed source code is available here:
https://github.com/neopium/FileReader

Kind regards,
Ben

Le 13.01.2016 08:26, David Jencks a écrit :
Yes, this is a better place to ask :-)

I don’t see what’s wrong by just looking, I’m hoping to have enough
time shortly to try your code, unless someone else gets there first.

thanks
david jencks

On Jan 12, 2016, at 11:02 PM, b...@petinou.fr wrote:

Hi everyone,

I have a ComponentException in Felix SCR that I don't understand.

Here is my use case:

1) I have a file reader service that reads a file:

public interface FileReaderService {
   /**
    * Reads the given file.
    * @param filePath Path of the file to read
    * @return the data object built from the file
    * @throws IOException if there is an error while reading the file
    */
   String readFile(Path filePath) throws IOException;

   /**
    * Detects if the format of the provided file is supported.
    * @param filePath the file to check
* @return true if the format of the file is supported, false otherwise
    * @throws IOException if there is an error while reading the file
    */
   boolean isFormatSupported(Path filePath) throws IOException;
}

2) I then have several implementations such as:

@Component
public class TxtFileReader implements FileReaderService {

   @Override
   public String readFile(Path filePath) throws IOException {
       // Do something smart with the file
       return "";
   }

   @Override
public boolean isFormatSupported(Path filePath) throws IOException { PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.txt");
       return matcher.matches(filePath);
   }
}

3) I want a "factory" that would use the appropriate service depending on the file format:

@Component
public class FileReaderFactory implements ReaderFactoryService {

   @Reference
   private List<FileReaderService> availableServices;

   @Override
   public String readFile(Path filePath) throws IOException {

       for (FileReaderService reader : availableServices) {
           if (reader.isFormatSupported(filePath)) {
               return reader.readFile(filePath);
           }
       }

       return null;
   }

   @Override
public boolean isFormatSupported(Path filePath) throws IOException {
       for (FileReaderService reader : availableServices) {
           if (reader.isFormatSupported(filePath)) {
               return true;
           }
       }
       return false;
   }
}

The source code can be found on GitHub: https://github.com/neopium/FileReader

You can get it from here and build it. I configured it so that it generates a Karaf assembly with the required features. When you start karaf and type scr:list, you see the two readers with null status. The factory is not there at all.

Here is the generated component xml file:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0"; name="org.test.reader.service.factory.FileReaderFactory"> <implementation class="org.test.reader.service.factory.FileReaderFactory"/>
 <service>
   <provide interface="org.test.reader.service.ReaderFactoryService"/>
 </service>
<reference name="availableServices" interface="org.test.reader.service.FileReaderService" field="availableServices" field-collection-type="service"/>
</scr:component>

Here is the full stacktrace (can be found in Assembly/target/assembly/data/log/karaf.log):

2016-01-12 11:12:36,961 | ERROR | pool-8-thread-1 | file-reader-service-impl | 9 - file-reader-service-impl - 1.0.0.SNAPSHOT | [org.test.reader.service.factory.FileReaderFactory] Cannot register Component org.osgi.service.component.ComponentException: Component org.test.reader.service.factory.FileReaderFactory validation failed: Field value type must not be set for unary field references. at org.apache.felix.scr.impl.metadata.ComponentMetadata.validationFailure(ComponentMetadata.java:953)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.metadata.ReferenceMetadata.validate(ReferenceMetadata.java:710)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.metadata.ComponentMetadata.validate(ComponentMetadata.java:873)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.BundleComponentActivator.loadDescriptor(BundleComponentActivator.java:454)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:309)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:270)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:358)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.Activator.access$000(Activator.java:53)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:260)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259)[24:org.apache.felix.scr:2.0.2] at org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232)[24:org.apache.felix.scr:2.0.2] at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:482)[org.osgi.core-6.0.0.jar:] at org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:415)[org.osgi.core-6.0.0.jar:] at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)[org.osgi.core-6.0.0.jar:] at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444)[org.osgi.core-6.0.0.jar:] at org.apache.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:916)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:835)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:517)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.Felix.fireBundleEvent(Felix.java:4541)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.Felix.startBundle(Felix.java:2172)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998)[org.apache.felix.framework-5.4.0.jar:] at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984)[org.apache.felix.framework-5.4.0.jar:] at org.apache.karaf.features.internal.service.FeaturesServiceImpl.startBundle(FeaturesServiceImpl.java:1189)[7:org.apache.karaf.features.core:4.0.3] at org.apache.karaf.features.internal.service.Deployer.deploy(Deployer.java:836)[7:org.apache.karaf.features.core:4.0.3] at org.apache.karaf.features.internal.service.FeaturesServiceImpl.doProvision(FeaturesServiceImpl.java:1079)[7:org.apache.karaf.features.core:4.0.3] at org.apache.karaf.features.internal.service.FeaturesServiceImpl$1.call(FeaturesServiceImpl.java:975)[7:org.apache.karaf.features.core:4.0.3] at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_65] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)[:1.8.0_65] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)[:1.8.0_65]
       at java.lang.Thread.run(Thread.java:745)[:1.8.0_65]

Any idea how to solve this?

Kind regards,
Ben

P.S. : I already posted my question on Stackoverflow http://stackoverflow.com/questions/34706041/how-to-manage-several-service-instances-with-declarative-services and on Karaf mailing list http://mail-archives.apache.org/mod_mbox/karaf-dev/201601.mbox/%3C86ce97d48759d7f266072e86986f0cf3%40petinou.fr%3E

I know cross-posting is bad (sorry about that), but I think I didn't choose wisely where to post before. My problem seems to be more Felix SCR-related, so here I am. I will of course update all posts when I find an answer to my problem.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@felix.apache.org
For additional commands, e-mail: users-h...@felix.apache.org

Reply via email to