Question

I am trying to use the @Reference Felix SCR annotation in Scala

This is how it can be used in Java:

public class Foo {

    @Reference
    MyServiceInterface service;
    // some code here
}

Here, MyService is ideally a Java Interface and not a concrete class (dependency injection)

I am using the same annotation in Scala, trying to depend on the same MyService (a Java Interface), like:

class Foo {
    @Reference
    val service = MyServiceInterface // ??
    // some code here
}

How can I use this annotation in Scala, to refer to a Java Interface?

example:

@Reference
val MyServiceInterface service

or

@Reference
val service = MyServiceInterface

is not valid Scala code

Thank you

Was it helpful?

Solution 3

I was able to solve this problem by specifying the type of the variable correctly like:

@Reference
var service: MyServiceInterface = null

@Neil is right, we must use a var instead of a val as the service binding happens at runtime.

Secondly, I had to add the following configuration to the maven-scr-plugin:

<configuration>
    <scanClasses>true</scanClasses>
</configuration>

Then, I had to specifically instruct the Maven Bundle plugin to NOT import the org.apache.felix.scr.annotations package as follows:

<Import-Package>!org.apache.felix.scr.annotations, *</Import-Package>

because the manifest would otherwise include an entry for this package as something that the bundle depends on.

Once this was done, the mvn-scr-plugin would generate the XML file correctly and the mvn-bundle-plugin would generate the bundle, manifest correctly.

OTHER TIPS

I know very little about Scala but I believe "val" means an immutable value, and thus it makes very little sense to bind it to a (mutable) service reference.

Shouldn't this member field be declared with "def" or "var" instead? In which case maybe the annotation will be allowed.

The reference annotation has a interfaceReference attribute. This attribute can be used to specify the java interface.

I assume in scala it would look like (never used Felix Annotation in scala):

@Reference(interfaceReference = MyServiceInterface)
val MyServiceInterface service

It might be that you also have to specify the bind and unbind method in this case. Please see also Felix Annotations documentation

Since 1.9.0 Felix Annotation are runtime annotations. The Annotation Felix Processor has an option scanClasses to use classes instead of source code to process the annotations. This works perfectly fine with groovy. I see no reason why that should not work with Scala.

If you use Intellij then please have a look at the Felix Annotation Plugin. The plugin uses by default scan classes

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top