karaf-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Jencks <david.a.jen...@gmail.com>
Subject Re: @Reference(service = MyApi.class) is not re-populated
Date Thu, 07 Mar 2019 05:30:04 GMT
This is expected and as per DS spec.
You can make your reference dynamic or greedy or both and it will work as you desire.

Your reference is static, so changing the bound services results in deactivating, recreating,
and reactivating the component: a dynamic reference will just add and remove services with
the original component instance.

Your reference is reluctant, so once created, a component instance will remain, with the same
references, as long as possible; thus, when a reference disappears the component instance
will be deactivated and reactivated with the reduced set of references, but when there is
at least one reference, so the component instance has been activated, nothing will happen
when a new reference appears.  A greedy reference will result in the component always having
an up to date set of references. If the reference is static, this means the component instance
will be deactivated, recreated, and activated with the new set of references.

David Jencks

> On Mar 6, 2019, at 7:48 PM, Xtra Coder <xtracoder@gmail.com> wrote:
> 
> I'm trying to use Declarative Services as outlined here
> https://blog.osgi.org/2018/03/osgi-r7-highlights-declarative-services.html 
> ... and I have the problem when referenced service does not re-appear after
> restart of its bundle.
> 
> In my scenario i need to dispatch invocation of a method call to number of
> implementations.
> To do this I create 3 implementation bundles, each of them has component
> like this
> 
> 	public interface MyApi {
> 		String sayHello(String why);
> 	}
> 
> 	@Component
> 	public class MyApiImpl1 implements MyApi {
> 
> 		public MyApiImpl1() {
> 			sayHello("startup");
> 		}
> 
> 		public String sayHello(String why) {
> 			System.out.println("Hello from Impl1: " + why);
> 			return "impl1";
> 		}
> 	}
> 
> And i also have dispatcher bundle #4, having following code
> 
> 	@Component
> 	public class MyApiDispatcher {
> 		@Reference(service = MyApi.class)
> 		List<MyApi> implementations;
> 
> 		boolean stopped;
> 		Thread ping = new Thread(() -> {
> 			while( !stopped ) {
> 				test("ping");
> 				try {
> 					Thread.sleep(2000);
> 				} catch (InterruptedException e) {
> 					e.printStackTrace();
> 				}
> 			}
> 		});
> 
> 		public MyApiDispatcher() {
> 			ping.start();
> 		}		
> 		
> 		@Deactivate
> 		public void deactivate() {
> 			stopped = true;
> 		}
> 
> 		public void test(String source) {
> 			if( implementations == null ) {
> 				System.out.println("implementations = <null>");
> 				return;
> 			}
> 
> 			List<String> calledImpls = new ArrayList<>();
> 
> 			for (MyApi impl : implementations) {
> 				calledImpls.add(impl.sayHello(source));
> 			}
> 
> 			System.out.println("calledImpls(" + source + ") = " + calledImpls);
> 		}
> 	}
> 
> Behaviour as I see it now is following:
> 
> 1. OK: initial startup - all 3 implementations are present in
> MyApiDispatcher
> 2. OK: after i stop bundle with Impl#1 - it disappears from
> MyApiDispatcher.implementations
> 3. BAD: after restart bundle with Impl#1 - it DOES NOT re-appear in
> MyApiDispatcher.implementations
> 4. WORKAROUND: after restart of bundle with dispatcher - it receives all 3
> implementations again
> 
> Behaviour #3 is very unexpected. 
> 
> Is it bug or OSGI spec defines such behaviour? 
> How can I make impl re-appear after restart of its bundle?
> 
> My current environment is following:
> 
>  Karaf version               4.2.3
>  OSGi Framework              org.apache.felix.framework-5.6.12
> 
> 
> 
> 
> 
> 
> 
> 
> 
> --
> Sent from: http://karaf.922171.n3.nabble.com/Karaf-User-f930749.html


Mime
View raw message