The annotation for the exported services/classes is what is at issue here.  
Here’s the perspectives I’m trying to make sure everyone sees.

1) Somehow, exported classes from one JVM need to be resolved in another JVM 
(at a minimum).  The source of those classes today, is the codebase specified 
by the service.  A directed graph of JVMs exchanging classes demands that all 
service like JVMs provide a codebase for client like JVMs to be able to resolve 
the classes for objects traveling to the client form the service.  This is 
nothing we all don’t already know I believe.

2) If there is a 3rd party user of a class from one JVM which is handed objects 
resolved by a middle man JVM (as Michal is mentioning here), there is now a 
generally required class which all 3 JVMs need to be able to resolve.  As we 
know, Jini’s current implementation and basic design is that a services 
codebase has to provide a way for clients to resolve the classes it exports in 
its service implementation.  In the case Michal is mentioning, the demand would 
be for the middle man service to have the classes that it wants the 3rd service 
to resolve, in some part of its codebase.  This is why I mentioned Objectspace 
Voyage earlier.  I wanted to use it as an example of a mechanism which always 
packages class definitions into the byte stream that is used for sending 
objects between VMs.  Voyager would extract the class definitions from the 
jars, wrap them into the stream, and the remote JVM would be able to then 
resolve the classes by constructing instances of the class using the byte[] 
data for the class definition. 

Ultimately, no matter what the source of the byte[] data for the class 
definition is, it has to be present, at some point in all VMs using that 
definition/version of the class.  That’s what I am trying to say.  The issue is 
simply where would the class resolve from?  I think that class definition 
conveyance, between JVMs is something that we have choices on.  But, 
practically, you can’t change “annotations” to make this work.  If the middle 
man above is a “proxy” service which bridges two different networks, neither 
JVM on each network would have routing to get to the one on the other side of 
the proxy JVM.  This is why a mechanism like Objectspace Voyager would be one 
way to send class definitions defined on one network to another JVM on another 
network via this proxy service.

Of course other mechanisms for class conveyance are possible and in fact 
already exist.  Maven and even OSGi provide class, version oriented conveyance 
from a distribution point, into a particular JVM instance.  Once the class 
definition exists inside of one of those JVMs then we have all the other 
details about TCCL and creation of proper versions and resolution from proper 
class loaders.

I don’t think we have to dictate that a particular class conveyance mechanism 
is the only one.  But, to solve the problem of how to allow classes hop between 
multiple JVMs, we have to  specify how that might work at the level that 
service instances are resolved and some kind of class loading context is 
attached to that service.  

The reason I am talking specifically about directed graphs of class loading is 
because I am first focused on the fact that there is a lot less flexibility in 
trying to resolve through a large collection of specific classes rather than an 
open set of classes resolved through a directed graph of the code execution 
path which exposes the places and moments of object use in a much more 
controlled and natural way to me.

Gregg

> On Jan 30, 2017, at 9:14 AM, Michał Kłeczek (XPro Sp. z o. o.) 
> <michal.klec...@xpro.biz> wrote:
> 
> It looks to me like we are talking past each other.
> 
> Thread local resolution context is needed - we both agree on this.
> What we do not agree on is that the context should be a single ClassLoader. 
> It has to be a set of ClassLoaders to support situations when dependencies 
> are not hierarchical.
> 
> The use case is simple - I want to implement "decorator" services that 
> provide smart proxies wrapping (smart) proxies of other services.
> I also want to have Exporters provided as dynamic services which would allow 
> my services to adapt to changing network environment.
> 
> And I would like to stress - I am actually quite negative about OSGI being 
> the right environment for this.
> 
> Thanks,
> Michal
> 
> Gregg Wonderly wrote:
>> Maybe you can help me out here by explaining how it is that execution 
>> context and class visibility are both handled by OSGi bundles.  For example, 
>> one of my client applications is a desktop environment.  It does service 
>> look up for all services registrations providing a “serviceUI”.  It then 
>> integrates all of those services into a desktop view where the UIs are 
>> running at the same time with each one imbedded in a JDesktopPane or a 
>> JTabbedPane or a JFrame or JDialog.  There are callbacks from parts of that 
>> environment into my application which in turn is interacting with the 
>> ServiceUI component.  You have AWT event threads which are calling out, into 
>> the ServiceUIs and lots of other threads of execution which all, ultimately, 
>> must have different class loading environments so that the ServiceUI 
>> components can know where to load code from.
>> 
>> It’s exactly TCCL that allows them to know that based on all the other class 
>> loading standards.  The ClassLoader is exactly the thing that all of them 
>> have in common if you include OSGi bundles as well.  The important detail, 
>> is that if the TCCL is not used as new ClassLoaders are created, then there 
>> is no context for those new ClassLoaders to reference, universally.
>> 
>> The important details are:
>> 
>>      1) The desktop application has to be able to prefer certain Entry 
>> classes which define details that are presented to the user.
>>      2) When the user double clicks on a services icon, or right clicks and 
>> selects “Open in new Frame”, an async worker thread needs a TCCL pointing at 
>> the correct parent class loader for the service’s URLClassLoader to 
>> reference so that the preferred classes work.
>>      3) Anytime that the AWT Event thread might be active inside of the 
>> services UI implementation, it also needs to indicate the correct parent 
>> class loader if that UI component causes other class loading to occur.
>>      4) I am speaking specifically in the context of deferred class loading 
>> which is controlled outside of the service discovery moment.
>> 
>>  
>>> On Jan 30, 2017, at 4:04 AM, Michał Kłeczek (XPro Sp. z o. o.) 
>>> <michal.klec...@xpro.biz> <mailto:michal.klec...@xpro.biz> wrote:
>>> 
>>> What I think Jini designers did not realize is that class loading can be 
>>> treated exactly as any other capability provided by a (possibly remote) 
>>> service.
>>> Once you realize that - it is possible to provide a kind of a "universal 
>>> container infrastructure" where different class loading implementations may 
>>> co-exist in a single JVM.
>> 
>> That’s precisely what ClassLoader is for.  TCCL is precisely to allow “some 
>> class” to know what context to associate newly loaded classes with, so that 
>> in such an environment, any code can load classes on behalf of some other 
>> code/context.  It doesn’t matter if it is TCCL or some other class 
>> management scheme such as OSGi bundles.  We are talking about the same 
>> detail, just implemented in a different way.
>> 
>>> What's more - these class loading implementations may be dynamic themselves 
>>> - ie. it is a service that provides the client with a way to load its own 
>>> (proxy) classes.
>>> 
>>> In other words: "there not enough Jini in Jini itself”.
>> 
>> I am not sure I understand where the short coming is at then.  Maybe you can 
>> illustrate with an example where TCCL fails to allow some piece of code to 
>> load classes on behalf of another piece of code?
>> 
>> In my desktop application environment, there is a abstract class which is 
>> used by each serviceUI to allow the desktop to know if it provides the 
>> ability to open into one of the above mentioned JComponent subclasses.  That 
>> class is preferred and provided and resolved using the codebase of the 
>> desktop client.  That class loading environment is then the place where the 
>> service is finally resolved and classes created so that the proxy can be 
>> handed to the serviceUI component which ultimately only partially resolves 
>> from the services codebase.
>> 
>> It’s this class compatibility which needs to be lightweight.
>> 
>>> We have _all_ the required pieces in place:
>>> - dynamic code loading and execution (ClassLoaders),
>>> - security model and implementation that allows restricting rights of the 
>>> downloaded code,
>>> - and a serialization/deserialization which allows sending arbitrary data 
>>> (and yes - code too) over the wire.
>>> 
>>> It is just the matter of glueing the pieces together.
>> 
>> Correct, but it’s a matter of class compatibility where a client environment 
>> has to interact with a service and the serviceUI components where TCCL 
>> excels and providing the ability to create class loaders with the correct 
>> parent context, for Java based code.  OSGi introduces the opportunity for 
>> some extra bells and whistles.  But I don’t see that it can completely 
>> eliminate the nature of TCCL and how it was intended to be used.
>> 
>>> Thanks,
>>> Michal
>>> 
>>> 
>>> Gregg Wonderly wrote:
>>>> <snip>
>>>> I am not an OSGi user.  I am not trying to be an OSGi opponent.  What I am 
>>>> trying to say is that I consider all the commentary in those articles 
>>>> about TCCL not working to be just inexperience and argument to try and 
>>>> justify a different position or interpretation of what the real problem is.
>>>> 
>>>> The real problem is that there is not one “module” concept in Java 
>>>> (another one is almost here in JDK 9/Jigsaw).  No one is working together 
>>>> on this, and OSGi is solving problems in a small part of the world of 
>>>> software.   It works well for embedded, static systems.  I think OSGi 
>>>> misses the mark on dynamic systems because of the piecemeal loading and 
>>>> resolving of classes.  I am not sure that OSGi developers really 
>>>> understand everything that Jini can do because of the choices made (and 
>>>> not made) in the design.  The people who put Jini together had a great 
>>>> deal of years of experience piecing together systems which needed to work 
>>>> well with a faster degree of variability and adaptation to the environment 
>>>> then what most people seem to experience in their classes and work 
>>>> environments which are locked down by extremely controlled distribution 
>>>> strategies which end up slowing development in an attempt to control 
>>>> everything that doesn’t actually cause quality to suffer.
>>>> 
>>>> Gregg
>>>> 
>>>> 
>> 
> 

Reply via email to