felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fabio Fonseca <fabio.l.fons...@gmail.com>
Subject Re: Dynamically change the bound service
Date Tue, 20 Dec 2011 02:53:29 GMT

Hello!

Yes, that you are right! I'm starting a thread in my run() method. I have
just modified my simple consumer + two providers test to remove the thread
and everything worked! Thanks! I only had to create a "super" consumer (that
consumes my consumer) to make it run my consumer's run() method without
having to stop and start it again. I did that because my objective was to
see the bound provider being changed automatically without the need to
restart the consumer.

However, I would like to see it working in a second example that uses a
Thread. I'm still doing some tests with it. I'll post my results here as
soon as possible.

Thanks!
Fabio


Richard S. Hall wrote:
> 
> Overall, it looks not unreasonable.
> 
> Are you starting a thread? If so, that could be an issue.
> 
> iPOJO does some sophisticated service reference management to simplify 
> concurrency issues for you. My guess is that iPOJO cannot tell that the 
> thread you've created ever exits the component, so it keeps a cached 
> reference for the lifetime of the thread.
> 
> Try to modify your thread so that it performs it functionality via a 
> method on the component itself invoked form its run() method...i.e., 
> your thread should explicitly enter and exit a method block to use a 
> service so that iPOJO can properly keep track of it for you, because 
> iPOJO is likely caching the service reference while your thread runs in 
> its run() method.
> 
> To provide a little more detail, when a thread enters a component 
> method, if that method accesses a service field, then iPOJO will 
> automatically cache the service reference for that thread for the entire 
> time that it executes inside that method. This way the thread doesn't 
> have to worry about its service changing in the middle of using it. (Of 
> course, it could still get errors if the service goes away, but that is 
> normal for OSGi.) In this case, I'm guessing your component has a run() 
> method on the component that access a service, so iPOJO caches the 
> services until the thread exits the run() method, which in your case 
> doesn't happen.
> 
> -> richard
> 
> On 12/18/11 20:49 , Fabio Fonseca wrote:
>> Hi Richard,
>>
>> Thanks for your response. I'd say that's definitely some basic mistake.
>> As
>> you'd said, it is basic behavior (and I was hoping to read that). The
>> problem is that I can't find where my mistake is... Yes, I tried field
>> injection and I also tried method injection using the bind and unbind
>> methods in the consumer, but they weren't called when I thought they
>> should
>> be.
>>
>> The code that I have attached in my original post is my test with method
>> injection. I was hoping anybody more experienced than me could find what
>> I'm
>> doing wrong.
>>
>> Anyway, in the following lines you can find some parts of the code.
>> Perhaps
>> there is something that I'm missing but that is obvious to you.
>>
>> . consumer.xml:
>> <?xml version="1.0" encoding="UTF-8"?>
>> <iPOJO>
>>    <component classname="org.test.iPOJO.consumer.Consumer">
>> 	<requires field="inter" id="Inter">
>> 	  	<callback transition="bind" method="bindInter"/>
>>    		<callback transition="unbind" method="unbindInter"/>
>> 	</requires>
>>    	<callback transition="validate" method="start"/>
>>    	<callback transition="invalidate" method="stop"/>
>>    </component>
>>    <instance component="org.test.iPOJO.consumer.Consumer"/>
>> </iPOJO>
>>
>> . consumer.java:
>> public class Consumer
>> implements Runnable
>> {
>> 	private InterfaceOne inter;
>>
>> 	public void start() {
>> 		System.out.println("[Consumer] Validating");
>> 		run();
>> 	}
>>
>> 	public void stop()	{
>> 		System.out.println("[Consumer] Invalidating");
>> 		stopRequestReceiver();
>> 	}
>> 	
>> 	// This was never called
>> 	public synchronized void bindInter (InterfaceOne i) {
>> 		System.out.println("[Consumer] Binding");
>> 	}
>> 	
>> 	// This was never called
>> 	public synchronized void unbindInter (InterfaceOne i) {
>> 		System.out.println("[Consumer] Unbinding");		
>> 	}
>>
>> 	(...)
>> }
>>
>> . providerA.xml (providerB is similar):
>> <?xml version="1.0" encoding="UTF-8"?>
>> <iPOJO>
>>    <component classname="org.test.iPOJO.providerA.ProviderA">
>>    	<provides/>
>>    	<callback transition="validate" method="start"/>
>>    	<callback transition="invalidate" method="stop"/>
>>    </component>
>>
>>    <instance component="org.test.iPOJO.providerA.ProviderA"/>
>> </iPOJO>
>>
>> . providerA.java:
>> public class ProviderA
>> implements InterfaceOne
>> {
>> 	private int state = 1;
>> 	
>> 	public void start()
>> 	{
>> 		System.out.println("[ProviderA] Validating");
>> 		state = 1;
>> 	}
>>
>> 	public void stop()
>> 	{
>> 		System.out.println("[ProviderA] Invalidating");
>> 		state = 0;
>> 	}
>>
>> 	(...)
>> }
>>
>> Thanks,
>> Fabio Fonseca
>>
>>
>> Richard S. Hall wrote:
>>> That doesn't sound right. I'd say there is something else simple going
>>> wrong. If you are using field injection in the consumer, you could look
>>> to add method injection too to see if you are getting proper callbacks
>>> when services come and go. Regardless, this sounds like pretty basic
>>> behavior, so I have to assume there is a simple mistake.
>>>
>>> ->  richard
>>>
>>> On 12/18/11 5:38 PM, Fabio Fonseca wrote:
>>>> Hello all,
>>>>
>>>> I'm starting to develop my master thesis and this is my first post to
>>>> this
>>>> forum. My research concerns the challenges of developing Self-Adaptable
>>>> software (software that can change its behavior in response to a change
>>>> in
>>>> its operation context). Right now I'm doing an assessment aiming to
>>>> find
>>>> which technologies are available today that could help achieving a
>>>> self-adaptable software.
>>>>
>>>> I'm using Apache Felix + iPOJO to develop a simple test. I have a
>>>> consumer
>>>> which wants to consume providers that implement a interface named
>>>> InterfaceOne. I have two providers that fits this requirement (named
>>>> ProviderA and ProviderB). They all do nothing useful, I am just trying
>>>> to
>>>> produce a self-adaptable behavior.
>>>>
>>>> I am using the launcher.jar which is provided with the code that comes
>>>> with
>>>> the great book "OSGi in Action". This launcher creates an instance of
>>>> the
>>>> Felix Framework and loads the bundles found in the bundles/ directory
>>>> passed
>>>> as a parameter when running the launcher.jar.
>>>>
>>>> So I have 4 bundles. Each one of them has an iPOJO component inside it,
>>>> except the first one that just has the InterfaceOne interface:
>>>> . services-1.0.jar
>>>> . consumer-1.0.jar
>>>> . providerA-1.0.jar
>>>> . providerB-1.0.jar
>>>>
>>>> The consumer is a simple http listener that uses localhost port 8080 to
>>>> listen to anything that may appear. When something access the port
>>>> 8080,
>>>> it
>>>> calls the available provider.
>>>>
>>>> When I start the launcher, all bundles are active and OSGi chooses one
>>>> of
>>>> the providers and binds it to the consumer. Using the shell commands
>>>> I'm
>>>> able to stop the providers' bundles and when I do it, the consumer is
>>>> invalidated (as per the iPOJO lifecycle).
>>>>
>>>> I concluded that when I start the consumer bundle the available
>>>> provider
>>>> is
>>>> bound to the consumer and it remains bound even when I stop its bundle
>>>> (in
>>>> the OSGi lifecycle). The cenario is:
>>>>
>>>> - start ProviderA
>>>> - start Consumer (consumer starts since its dependency is satisfied)
>>>> - start ProviderB
>>>> - stop ProviderA (consumer is still valid in the OSGI's lifecycle,
>>>> since
>>>> there is a provider (ProviderB) that satisfy its dependency)
>>>>
>>>> At this moment, if I call localhost:8080, the consumer uses ProviderA,
>>>> even
>>>> when ProviderA is not available anymore. I conclude that the binding
>>>> between
>>>> Consumer and its provider (which is in this case still the ProviderA)
>>>> continues to exist even when I stop ProviderA. I read somewhere that
>>>> iPOJO
>>>> lifecycle takes over OSGi's lifecycle, but when I stop ProviderA, the
>>>> component becames Invalidated (I know because I placed a method that is
>>>> called when the provider is invalidated). So, even with the provider
>>>> Invalidated, it is still called. I  also read somewhere that each
>>>> component
>>>> is implemented as a Singleton by default, and I have not changed its
>>>> behavior. So, I'm lost here. I expected that, in the above cenario,
>>>> ProviderB would be called instead of ProviderA.
>>>>
>>>> Anyone has a clue that could help me understand how this mechanism
>>>> works?
>>>> Attached you can find a file with all my source code and ant tasks I'm
>>>> using
>>>> to play with iPOJO and OSGi.
>>>>
>>>> http://old.nabble.com/file/p32999833/OIA%2BCode.zip OIA+Code.zip
>>>>
>>>> Thanks a lot in advance!
>>>> Fabio Fonseca
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>>>
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 
> 
> 

-- 
View this message in context: http://old.nabble.com/Dynamically-change-the-bound-service-tp32999833p33007245.html
Sent from the Apache Felix - Users mailing list archive at Nabble.com.


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


Mime
View raw message