On 19 sep. 2013, at 20:25, Daniel McGreal wrote:
> Space constraints.
Wow! You must code in a tightly constrained embedded environment if 195k is too 
much for something soooo valuable .... :-)

Kind regards,

        Peter Kriens



> 
> On 19 Sep 2013, at 18:55, Peter Kriens <[email protected]> wrote:
> 
>> Why not use DS?
>> 
>> 
>> On 19 sep. 2013, at 18:02, Daniel McGreal wrote:
>> 
>>> Hi OSGi-devs,
>>> 
>>> I have a question about utilising ServiceTracker to manage a class's 
>>> dependencies and blocking during the call, which I confess is probably well 
>>> trodden ground but for which I can't apparently find the right Google 
>>> terminology. Perhaps because I've been, until now, coddled by higher-level 
>>> service dynamism, like Blueprint.
>>> 
>>> I have a java.util.logging.Handler whose publish method needs a couple of 
>>> OSGi services to operate. Any LogRecords that are published during a 
>>> refresh of either of the dependencies should not be lost and should be 
>>> reattempted when services resume (which in practice might be a long time, 
>>> the device this application targets is incredibly primitive).
>>> 
>>> Currently I have the Activator and Handler in the same implementation 
>>> (which seems like it might be bad practice, if it is, I'd love to know 
>>> why). Here's a trimmed down version, with just one dependency:
>>> 
>>> public class RemoteLoggingHandler extends Handler implements 
>>> BundleActivator {
>>>     private volatile Channel channel;
>>>     
>>>     private ServiceTracker<IAmqpChannelProvider, IAmqpChannelProvider> 
>>> channelProviderTracker;
>>>     
>>>     @Override public void start(BundleContext context) throws Exception {   
>>>         
>>>             channelProviderTracker = new 
>>> ServiceTracker<IAmqpChannelProvider, IAmqpChannelProvider>(context, 
>>> IAmqpChannelProvider.class, null){
>>>                     @Override public IAmqpChannelProvider 
>>> addingService(ServiceReference<IAmqpChannelProvider> reference) {
>>>                             IAmqpChannelProvider channelProvider = 
>>> super.addingService(reference);
>>>                             try {
>>>                                     channel = 
>>> channelProvider.createChannel();
>>>                                     //Some initialisation, can happen once 
>>> or multiple times, no problem.
>>>                                     
>>> channel.exchangeDeclare(LoggingConstants.LOGGING_EXG_NAME, "topic", true);
>>>                                     notifyAll();
>>>                             } catch (IOException e) {
>>>                                     e.printStackTrace();
>>>                             }
>>>                             return channelProvider;
>>>                     }
>>>                     
>>>                     @Override public synchronized void 
>>> modifiedService(ServiceReference<IAmqpChannelProvider> reference, 
>>> IAmqpChannelProvider service) {
>>>                             removedService(reference, service);
>>>                             addingService(reference);
>>>                     }
>>>                     
>>>                     @Override public void 
>>> removedService(ServiceReference<IAmqpChannelProvider> reference, 
>>> IAmqpChannelProvider service) {
>>>                             super.removedService(reference, service);
>>>                             channel = null;
>>>                     }
>>>             };
>>>             channelProviderTracker.open();
>>>                             
>>>             LogManager.getLogManager().getLogger("").addHandler(this);
>>>     }
>>> 
>>>     @Override public void stop(BundleContext context) throws Exception {
>>>             LogManager.getLogManager().getLogger("").removeHandler(this);
>>>     }
>>> 
>>>     @Override
>>>     public void publish(LogRecord record) {
>>>             try {
>>>                     synchronized (channelProviderTracker) {
>>>                             while(channel == null) 
>>> channelProviderTracker.wait();
>>>                             
>>>                             
>>> channel.basicPublish(LoggingConstants.LOGGING_EXG_NAME, 
>>> record.getLoggerName(),
>>>                                             null, 
>>> record.getMessage().getBytes());
>>>                     }
>>>             } catch (Exception e) {
>>>                 reportError(null, e, ErrorManager.WRITE_FAILURE);
>>>                 return;
>>>             }
>>>     }
>>>     
>>>     //Some boilerplate....
>>>     
>>>     @Override public void flush() {} //Unnecessary.
>>> 
>>>     @Override
>>>     public void close() throws SecurityException {
>>>             flush();
>>>             try {
>>>                     channel.close();
>>>             } catch (IOException e) {
>>>                     reportError("Amqp channel could not be closed", e, 
>>> ErrorManager.CLOSE_FAILURE);                 
>>>             }
>>>     }
>>>     
>>> }
>>> 
>>> I don't feel that I've been successful. The channel member field can still 
>>> go to null while it's being used in publish, and probably many other 
>>> problems I've missed! Can anyone point out to me either the standard 
>>> procedure for this, or any comments on my above attempt?
>>> 
>>> Many thanks,
>>> Dan.
>>> 
>>> 
>>> _______________________________________________
>>> OSGi Developer Mail List
>>> [email protected]
>>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>> 
>> _______________________________________________
>> OSGi Developer Mail List
>> [email protected]
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
> _______________________________________________
> OSGi Developer Mail List
> [email protected]
> https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to