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 Fri, 23 Dec 2011 12:19:55 GMT

Hi Richard and Clement,

I could finally manage to get back to coding. I have just done what you have
suggested and everything worked perfectly! Thanks a lot for your help and
availability!

But I was wondering if there are any mechanism to tell iPOJO to avoid
creating this cache. I can't see now a reason why someone would like to do
it, but just as a matter of curiosity. Is this possible?

Thanks!!!
Fabio


clement escoffier wrote:
> 
> Hi,
> 
> As explained by Richard, iPOJO uses some advanced caching technics to
> avoid server switch during an execution flow. So if you have a method
> using service objects but never return, it will use the same service
> objects forever. To avoid it, isolate the service manipulation in another
> method. 
> 
> Regards,
> 
> Clement
> 
> On 20.12.2011, at 04:20, Richard S. Hall wrote:
> 
>> On 12/19/11 21:53 , Fabio Fonseca wrote:
>>> 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.
>> 
>> As I said, it will work with a thread, but you cannot have the thread's
>> run() methodaccess the services directly, since that method never exits
>> until the thread exits, so iPOJO will cache the service references the
>> entire time. If you create some method
>> MyComponent.doSomethingWithAService() and then call it from your run()
>> method, then I believe it should work.
>> 
>> -> richard
>> 
>>> 
>>> 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
>>>> 
>>>> 
>>>> 
>> 
>> ---------------------------------------------------------------------
>> 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-tp32999833p33028476.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