Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [equinox-dev] Roadmap?


John,

This discussion triggers several questions in my mind.

1) You are pointing that it would be nice to have a more standard way to do IoC, but you want OSGi to be optional.
But OSGi is a standard way to do IoC. So I am guessing there are other characteristics of OSGi that creates the problem.

One that I could see is that OSGi is perceived to have to be in control (bootstrapping) and everything being a bundle,
where OSGi adoption is not so widely spread that it is de-facto available. Another could see that bundles are installed
from inside OSGi rather than dropped on the class path? What is the list of problems?

So is the problem to have an embedded OSGi within a normal Java client? Is it something else?

2) Another question is about IoC and lifecycle. Our experience with dynamic service-oriented environment is that it is very
difficult for developers to track services. This was the original intention behind the service tracker. But even the service tracker
is not enough, for different reasons. We designed DS so to combine IoC and lifecycle so that tracking would be done by the system,
invisible to developers. Your service is activated if and only if it has all its necessary dependencies. This makes development much
easier. This also enhances performance where services are activated when they can only run, not before just waiting on their dependencies.
The immediate result is a better startup time, but also overall a smaller footprint, etc...

So, why do you want only IoC and no lifecycle?

3) This leads to my last question. While I perfectly understand your requirement (OSGi is not widely adopted that it is always available),
the path you are following is very difficult to sustain in the long run. It is really hard to control dependencies on APIs and on available services.
Hiding a few OSGi APIs, like the bundle context, is not so hard at the beginning. But your code, through IoC, will use services and now the availability
of those services are also an issue on the normal Java client. How are those services available in a non-OSGi client?
It is much harder to hide OSGi for service providers that for service clients, you may not have the source for those... etc.

So while I am not questioning the requirement, the proposed path does not seem to provide any long term solution.
I don't mean to sound harsh here, just sharing my own experience with the same issues and other people.

Some thoughts for another approach:

The basic idea is the following: instead of trying to make OSGi optional and introduce another framework,
why not play on the OSGi implementation to make it always available?

So to me, there may be two avenues we haven't talked about yet.

        - a slave approach, where OSGi is embedded in a larger context  (mentioned above)
        - shell OSGi (where APIs are available but with simplistic implementation)

I will let you comment on the slave approach. It is a full OSGi environment, but capable of starting slave to a JRE. The main issue to solve here is the
cross-visibility of classes between the JRE and OSGi. If it is unclear, feel free to ask... :-)

For the shell approach, here is what I mean... let suppose that we consider the OSGi API as mandatory, you code is always written using these APIs.
It obviously runs in any OSGi environment. Now, in a client environment, we need those APIs, but we can play on the quality of service of those APIs.
These APIs are interfaces, we have freedom regarding the implementation, especially that we are not going for legal compliance (we are not trying to
certify an OSGi platform) we are enabling portability in non OSGi environments.

In some sense, this is the "more standard library" you are talking about... standard APIs (OSGi) but an implementation that is suited to run in a normal JRE.
Basically, you need an OSGi DS implemented on a bare minimum OSGi environment. Probably no special class loading, but the service framework.

I am not saying I have all the details worked out, but it seems to me an interesting avenue. In fact, the more I think about it, the more the two proposals are
not that far from each other (slave and shell OSGi), but they both assume the adoption of OSGi as the standard IoC and lifecycle,
and they play with the implementation so to enable the availability in a standard client. Depending on how we play, we could allow a lot of bundles to run
in both environments, helping overall portability.

Just some thoughts...
Best regards,

Olivier Gruber, Ph.D.
Persistent & Distributed Object Platforms and Frameworks
IBM TJ Watson Research Center




"John Wells" <jwells@xxxxxxx>
Sent by: equinox-dev-bounces@xxxxxxxxxxx

11/22/2005 10:00 PM
Please respond to Equinox development mailing list

       
        To:        "Equinox development mailing list" <equinox-dev@xxxxxxxxxxx>
        cc:        
        Subject:        RE: [equinox-dev] Roadmap?



Yes, the code using the LogService would have to explicitly check (with a synchronized block) whether or not the logger exists.  The code would be something like:
 
LogService localLogger;
synchronized (this) {
  localLogger = logService;
}
 
If (localLogger != null) {
  localLogger(“This is fun!!!”);
}
 
 
This will work whether or not we are in the OSGi environment.
 
Also very interesting “trick” to getting the bundle.  Thanks.  I wish there was a more “framework independent” way to do this.
 
My more general question remains though:  is this a requirement that more people than me have faced?  Would a Dynamic IoC utility be of interest to the OSGi community?  At this point I’m writing this thing anyway, I just want to know if people here would be interested in me contributing the code?  Since this is a utility (of course it would be a Bundle as well) I’m not exactly sure where the proper place would be to put such a thing, or if people are even interested in such a facility.
 
John Wells (Aziz)
jwells@xxxxxxx



From: equinox-dev-bounces@xxxxxxxxxxx [mailto:equinox-dev-bounces@xxxxxxxxxxx] On Behalf Of Jeremy Volkman
Sent:
Tuesday, November 22, 2005 2:57 PM
To:
Equinox development mailing list
Subject:
Re: [equinox-dev] Roadmap?

 
John,

When writing a component to be environment-agnostic, how do you handle the case when
LogService may not be available at the time of your POJO's instantiation (only in the OSGi environment, of course)?  Will the programmer have to explicitly check the value of the logger member before attempting to use it?   If so, doesn't this go against your wishes that the programmer not care what environment he/she is writing for?

Also, on getting a caller's BundleContext: it is possible, but it get ugly.  I had to do something similar to get per-bundle logging working with the Apache Commons Logging API.  Commons Logging provides the static LogFactory class to get Log instances, and I wanted Log instances to know which Bundle had created them (so I could print out the name of the Bundle logging a message).  

One way would be to include a separate copy of my modified LogFactory class with each bundle, and provide the Bundle's personal LogFactory instance with a reference to the Bundle at start up, but this seemed like a maintenance nightmare, and it negated OSGi's nifty code sharing feature.

So i went with the following approach:

1. Subclass SecurityManager and gain access to the getClassContext() method
2. Pick the Class of the caller off the stack
3. Use OSGi's PackageAdmin and its getBundle( java.lang.Class) method to get the Bundle containing a particular class

Since the BundleContext instance is supposed to be private to its associated Bundle, OSGi provides no way of getting a BundleContext for a given Bundle (the DS spec mentions this).  With Equinox, this can be done through reflection, as Equniox's AbstractBundle class defines a method "getContext":
           
  Bundle bundle = ...
  Method contextMethod = bundle.getClass().getDeclaredMethod("getContext", (Class[]) null);
  contextMethod.setAccessible(true);
  BundleContext context = (BundleContext) contextMethod.invoke(bundle, (Object[]) null);

Of course there are numerous possible issues with this method (can't create new SecurityManagers, can't change Method accessibility, etc.), but perhaps it will be food for thought.

Jeremy Volkman

On 11/22/05, John Wells < jwells@xxxxxxx> wrote:

Thanks for your response Olivier.

 

In an earlier response I talked about the requirement I would like to see satisfied that would make the IoC pattern work in both a dynamic and a static environment.  Basically, I want to write code that dynamically tells the IoC system that it wants to depend on some other type and I want this to work both in a "client" environment where the classes are linked together via the system class-loader as well in the dynamic environment afforded by OSGi.  To me what is interesting is to be able to write code that runs in both a "hosted" and "client" environment without modification.

 

What I do not want is for the programmers writing the code to know the difference between the two environments.  Furthermore, I think that this could be a common programming pattern when writing modular code.  I want the service writers to have simple instructions for how to write their services, and then I want the framework to do the "correct" thing based on whether or not we are running in the OSGi framework or on a client that has not started the OSGi kernel.  Yes, I want my cake and I want to eat it too ;-)

 

Let's take something as simple as a log service.  I want to have a pojo that says something like:

 

private LogServer logger;

 

 

// inside some method of my pojo

IoC.createDependency("com.acme.LogService", "setLogger", this);

 

 

public synchronized void setLogger(com.acme.LogService logger) {

  this.logger = logger;

}

 

When in the OSGi world, the LogService might be satisified by lots of different implementations.  However, in the client world there may be only the one that is satisfied on the client classpath..  One problem we run up against right away is that com.acme.LogService is very likely an interface, and hence cannot be instantiated directly on the client.  In order to solve this problem I was thinking that it would be necessary to define a generic sort of factory interface like this:

 

public interface GenericFactory<T> {

  public <T> create(…);

  public <T> find(…) throws NotFoundException;

}

 

(excuse any typo's, I am typing as I write, not pasting from an IDE ;-)

 

Now instead our IoC object might look like this:

 

private LogFactory logFactory = new LogFactory();   // Implements the GenericFactory interface

private LogServer logger;

 

 

// note this time I must provide the factory to use for this service

// just in case this is running in a "client" environment

IoC.createDependency("com.acme.LogService", "setLogger", this, logFactory);

 

 

public synchronized void setLogger(com.acme.LogService logger) {

  this.logger = logger;

}

 

The signature for createDependency would be something like:

 

public Object createDependency(String serviceName, String setterName, GenericFactory staticFactory, …);

 

where the extra arguments are used in the find/create methods of the factory.

 

What my IoC controller could do then would be that *if* I was running in OSGi (and could find the bundle context of this caller) then use the ServiceTracker to hook up the LogService with the implementation.  But *if* I was running in a "client" environment I would use the factory (first trying to find, then create the service).

 

Everything above is doable (with a big question mark on how to get the code's BundleContext) using home-made code.  I was wondering if anyone else has these sorts of requirements or if there is any "standard" way to accomplish what I am trying to achieve?  And does this clarify what requirements I have?

 

John Wells (Aziz)

jwells@xxxxxxx



From: equinox-dev-bounces@xxxxxxxxxxx [mailto: equinox-dev-bounces@xxxxxxxxxxx] On Behalf Of Olivier Gruber
Sent:
Tuesday, November 22, 2005 12:26 PM
To:
Equinox development mailing list
Subject:
RE: [equinox-dev] Roadmap?

 


John,


Declarative services are mostly about lifecycle and injection.
It is the combination of both that is powerful, especially regarding the linkage with the bundle lifecycle underneath.

That is, a service is created only when its dependencies are available...
and this means that the creations of class loaders are also delayed.


Without lifecycle, injection becomes service tracking with the use of setter/getter methods,
especially if you are not using a constructor-based injection.


What I am curious about is that inversion of control becomes really interesting when used with a lifecycle.

The goal is that a service code does not have to deal with the dynamic nature of its environment.
When it is activated, it has all the references it needs because they have been injected.
Before loosing  a reference, it will be deactivated.


But you are stating that you have no lifecycle, does this mean that you have injection but your code is also fully

responsible for dynamically appearing/disappearing references? Who controls that lifecyle? That is, who creates

your POJO and why.


Just trying to understand.
Best regards,

Olivier Gruber, Ph.D.
Persistent & Distributed Object Platforms and Frameworks
IBM TJ Watson Research Center

  "John Wells" < jwells@xxxxxxx>
Sent by:
equinox-dev-bounces@xxxxxxxxxxx

11/22/2005 05:25 PM
Please respond to Equinox development mailing list

       
       To:        "Equinox development mailing list" <
equinox-dev@xxxxxxxxxxx>
       cc:        

       Subject:        RE: [equinox-dev] Roadmap?




Yeah I had thought of that too.  I guess I wanted it to be sort of
"standardized" rather than having to write a layer.  But that's ok.

So...  then I also need to know if/when the "ServiceTracker" will be
implemented in Equinox.  Or perhaps it already is, since I can remember
ServiceTracker from r3?

John Wells (Aziz)

jwells@xxxxxxx

-----Original Message-----
From:
equinox-dev-bounces@xxxxxxxxxxx
[mailto:
equinox-dev-bounces@xxxxxxxxxxx] On Behalf Of Jeremy Volkman
Sent: Tuesday, November 22, 2005 11:21 AM
To: Equinox development mailing list
Subject: Re: [equinox-dev] Roadmap?

It seems as though you may be able to realize your DDS needs right now
by using the already-available ServiceTracker.  When
registerDependency() is called, create a new ServiceTracker with the
given service information and start it.  Override the addingService()
and removedService() methods (or provide a ServiceTrackerCustomizer)
and make these methods call your POJO's setter/unsetter (remember that
this is a dynamic environment, so you'll probably want an unsetter).
The only issue is that you'll need to provide ServiceTracker with a
BundleContext for it to get a ServiceReference.

Jeremy Volkman

On 11/22/05, John Wells <
jwells@xxxxxxx> wrote:
> Yes, I do like the delayed activation part of DS.  Here are some
issues
> I have with DS (since you asked - didn't you?  ;-)
>
> I would like to be able to have a POJO that uses a service which gets
> injected.  While I think that with DS I can declare a class that the
DS
> would instantiate, what I want is something more dynamic.  I want to
be
> able to have my own class (that I instantiated myself in whatever way)
> declare that it wants a service (e.g. "com.acme.Foo") injected into
it.
> This class would *not* be under the lifecycle control of DS, but would
> still be getting the dependent service injected into it appropriately
as
> the class is available in the OSGi framework.
>
> In my mind I have been calling such a facility "Dynamic DS" or DDS for
> short.  It would be a service or a class with static methods that had
> methods like the following:
>
> /**
>  * This method would call the setter on the object when the
appropriate
>  * service becomes "available", but objectToInject is *not* under the
>  * specific control of the DS framework
>  * Note:  There are likely other "registerDependency" verbs that
specify
>  * all the options available in the DS configuration file and OSGi
>  * service filters
>  * @param serviceName The name of the service I would like to depend
on
>  * @param setterName The name of the setter - a public void method
that
>  *    takes the type as the argument
>  * @param objectToInject The object (not under the control of DS) to
>  *    "inject"
>  */
> public static void registerDependency(String serviceName, String
> setterName, Object objectToInject) throws WhateverException;
>
> /**
>  * This method removes the dependency, for when the object is done
> needing
>  * the service.
>  */
> public static void unregisterDependency(String serviceName, Object
> objectToInject) throws WhateverException;
>
> Obviously, the above is pseudo-code and I wouldn't mind having the
> "registerDependency" return some form of object that can be used to
> unregister the dependency later.  I also wouldn't mind having the
> registerDependency take some form of other object (e.g. BundleContext)
> that it might need in order to make it work in OSGi.  (However, one of
> the design goals I have is to make any OSGi specific imports not
> visible, so I would almost prefer some sort of wrapper or even
> name-based mechanism).
>
> The basic idea is that independent object can register for injection
> dynamically, and would not have to muck about in the OSGi API in order
> to do service tracking or the like.
>
> Or perhaps there is already a way to do this with the current DS?  I
> looked at the spec and the API, but it is possible I missed something?
> Thanks for helping me understand this a bit more.
>
> And of course, I still need the DS like yesterday ;-).
>
> Anyway, have a nice day.
>
> John Wells (Aziz)
>
jwells@xxxxxxx
> -----Original Message-----
> From:
equinox-dev-bounces@xxxxxxxxxxx
> [mailto:
equinox-dev-bounces@xxxxxxxxxxx] On Behalf Of BJ Hargrave
> Sent: Tuesday, November 22, 2005 10:34 AM
> To: Equinox development mailing list
> Subject: Re: [equinox-dev] Roadmap?
>
> IBM is in the process of preparing a contribution of a Declarative
> Services implementation (among other selected services). Stay tuned...
>
> I would have to say Declarative Service is the best to use. But in the
> interest of full disclosure, I was the designer of Declarative
Services
> :-) I am also not very familiar with GBeans. But DS does fully
integrate
>
> with the OSGi service model and has certain desirable performance
> characteristics such as delayed activation.
>
> BJ Hargrave
> Senior Technical Staff Member, IBM
> OSGi Fellow and CTO of the OSGi Alliance
>
hargrave@xxxxxxxxxx
> Office: +1 407 849 9117 Mobile: +1 386 848 3788
>
>
>
> "John Wells" <
jwells@xxxxxxx>
> Sent by:
equinox-dev-bounces@xxxxxxxxxxx
> 2005-11-22 10:00 AM
> Please respond to
> Equinox development mailing list
>
>
> To
> <
equinox-dev@xxxxxxxxxxx>
> cc
>
> Subject
> [equinox-dev] Roadmap?
>
>
>
>
>
>
> Is there a roadmap for Equinox, especially where it concerns the
> compendium services of r4?  In particular, I am interested in using
the
> Declarative Services Specification?
>
> I have been looking around to see if I could find information about it
> (dss), but haven?t found anything other than a handful of mail in the
> archive.  In particular, I need to have a good idea when (if) dss is
> going
> to be implemented.  I?ve even considered just implementing that part
of
> the specification myself in order to get it quicker.
>
> Also:
>
> Both DSS and GBeans are IoC frameworks.  Does anyone have any opinions
> on
> which are easier to use? Better?  Any pros/cons?
>
> John Wells (Aziz)
>
jwells@xxxxxxx
>  _______________________________________________
> equinox-dev mailing list
>
equinox-dev@xxxxxxxxxxx
>
https://dev.eclipse.org/mailman/listinfo/equinox-dev
>
>
> _______________________________________________
> equinox-dev mailing list
>
equinox-dev@xxxxxxxxxxx
>
https://dev.eclipse.org/mailman/listinfo/equinox-dev
>
> _______________________________________________
> equinox-dev mailing list
>
equinox-dev@xxxxxxxxxxx
>
https://dev.eclipse.org/mailman/listinfo/equinox-dev
>
_______________________________________________
equinox-dev mailing list

equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev

_______________________________________________
equinox-dev mailing list

equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev

_______________________________________________
equinox-dev mailing list

equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev

 _______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev


Back to the top