My personal expectation is that Jini is entrenched on the Java serialization 
quagmire that you probably have to work around a lot more problems than the 
myriad of discovery and transport protocols that are currently available in 
Java?

It is a pity because Jini and OSGi started in the same time and we had 
discussions together.

Kind regards,

        Peter Kriens

> On 21 Feb 2017, at 07:25, Christian Schneider <ch...@die-schneider.net> wrote:
> 
> Have you thought about implementing the jini support as a discovery and 
> transport for Remote Service Admin?
> I am not sure if it fully matches as jini is special in some aspects but I 
> see many similarities.
> 
> Christian
> 
> 2017-02-21 0:56 GMT+01:00 Peter <j...@zeus.net.au <mailto:j...@zeus.net.au>>:
>  
> Sounds like you've been burnt.
> 
> Modular or die, no hacked compromises, won't support unworkable complex 
> non-modular cases, only support what works.
> 
> For updates:
> 1. Server module advises proxy's of graceful shutdown, proxy's unregister 
> services with OSGi registrar (or just stop working in hard shut or 
> disconnection, in which case they are discarded).
> 2. Server unregisters from Jini service registrar and unexports.
> 3. Server performs upgrades
> 4. Server exports and reregisters with jini service registrar
> 5. Service is dynamically discovered by ServiceDiscoveryManager in clients, 
> smart proxy's are provisioned and registered with local OSGi registrar.
> 6. Clients notified of service availability.
> 
> The smart proxy bundle must be of identical version at both endpoints, 
> connection must be refused if this is not the case.
> 
> Service api bundles are separate from smart proxy bundles.
> 
> Clients don't import packages from smart proxy.
> 
> The smart proxy contains the api for communication between proxy and remote 
> service only.  Only service implementation imports packages from smart proxy. 
>  Communication method and communication api is a private implementation 
> concern.
> 
> The services smart proxy imports the service api packages, as does the 
> client.  Service api is compatibility layer between smart proxy and client.  
> The smart proxy is a provider of the service api, the client is the consumer.
> 
> Service api update is client responsibility, not likely to update often.  
> Prefer to add mixin interfaces or replace api (new service type) over 
> breaking change.   Smart proxy needs to deregister when service api is 
> updated (should listen for event notifications).
> 
> Service will only be rediscovered if it is compatible.
> 
> As the smart proxy needs to be resourced and provisioned it is this stage of 
> the process where it may not be found api compatible with the client, in 
> which case it will not be discovered by the client...
> 
> The service can advertise its requirements (incl packages and versions) via 
> the Jini service registrar, services that are not api compatible will be 
> filtered out.
> 
> The server / service remains responsible for maintaining compatibility.
> 
> Discovery is dynamic.  
> 
> We've had some discussion on river-dev, one user wanted much wider support 
> scope including remote objects with code download that are not services, also 
> wanted to use codebase annotations and non osgi URLClassLoaders with bundle 
> ClassLoaders as parents, using Context ClassLoader to find bundle 
> ClassLoader.  Agree that's an unworkable scenario due to complexity.
> 
> I want to keep this as simple as possible for obvious reasons.  Force 
> communication method to be an implementation concern, allowing it to be 
> replaced in future.
> 
> Regards,
> 
> Peter.
> 
> Sent from my Samsung device.
>  
> ---- Original message ----
> From: Peter Kriens <peter.kri...@aqute.biz <mailto:peter.kri...@aqute.biz>>
> Sent: 21/02/2017 12:24:39 am
> To: OSGi Developer Mail List <osgi-dev@mail.osgi.org 
> <mailto:osgi-dev@mail.osgi.org>>
> Subject: Re: [osgi-dev] OSGifying an existing application
> 
> The problem is that in all distributed I’ve been involved in there were 
> rolling updates. This implies that you cannot guarantee that each server runs 
> the same bundle. And clusters that do not do rolling updates seem kind of 
> useless because they introduce a huge failure point. So I have a hard time 
> understanding how you can guarantee that invariant? Yes, it works most of the 
> time but when I learned to work with computers that tended not be good enough.
> 
> Now I do understand ( and sympathise) that you cannot change the app. I’ve 
> been there.
> 
> You indicate you have the same bundle on both sides. So the class graph on 
> both sides is equal. This implies that if you ensure that the API interface 
> is in the same bundle as the implementation classes then you’re safe as long 
> as you use the interface’s class loader as the root loader for classes you 
> find. This is of course highly not modular but then you’re not anyway under 
> the covers :-) You could also make the API bundle import the implementation 
> bundles, that should work as well.
> 
> As long as you make sure OSGi has the proper dependency information things 
> tend to work out of the box.
> 
> Kind regards,
> 
>       Peter Kriens
>       
> 
> 
>> On 20 Feb 2017, at 11:47, Peter <j...@zeus.net.au <mailto:j...@zeus.net.au>> 
>> wrote:
>> 
>> Thanks Pete, good to hear from you again, I must admit it's been too long.  
>> We last spoke when I was refactoring a class dependency tool to use ASM 
>> instead of the jdk's tools.jar.  You once asked, how do you find a 
>> dependency for calls to Class.forName?
>> 
>> The reasons you've stated are also why I've chosen to support a very narrow 
>> use case, in which you may have already noted that the serialized connection 
>> is between two identical bundles, in separate jvm's with compatible package 
>> imports.
>> 
>> There’s no intent to support transferring any classes outside of the Service 
>> Now API and that includes overriding classes.  What you describe about data 
>> hiding reminds me of Entry's, which have public fields.
>> 
>> I'll be the first to admit there are significant issues with the design of 
>> Java's Serialization's extralinguistic api.   Ironically though the wire 
>> protocol is reasonably well thought out, with regards to evolution.
>> 
>> As an exercise to fix security issues, I have reimplemented Java 
>> serialization with input validation using a public api, it has backward 
>> compatible serial form, but only supports a subset of Java serialization, it 
>> doesn't support circular object graphs for example as this would compromise 
>> security.   It performs input validation, sets resource limits and expects 
>> periodic stream resets to avoid DOS and gadget attacks. The problem is 
>> there's a lot of existing software that utilises java Serialization, that's 
>> going to need support for some time.   Things like Serialization and Remote 
>> method invocation are damaged by attempts to implement too much 
>> functionality, when a more rigid subset would avoid a number of issues.  But 
>> I guess no one was thinking of modularity and versioning when they created 
>> these frameworks either.
>> 
>> James Gosling said something once about why Generics weren't included in 
>> Java from the outset, which was because at the time they didn't know how to 
>> do it properly, it's better leaving it out until you do.
>> 
>> JBoss has a nice web page with some graphics that illustrate some major 
>> issues with implementation hiding you've mentioned with Serialization and 
>> modular frameworks here:  
>> https://developer.jboss.org/wiki/ModularSerialization 
>> <https://developer.jboss.org/wiki/ModularSerialization>
>> 
>> It's worth noting Service API of the smart proxy bundle doesn't need to be 
>> Serializable, instead it's relegated to a communication means between two 
>> identical bundles in different JVM's.   It's also important to recognise 
>> that it doesn't need to be the communcation mechanism either.   These 
>> bundles have an identical class namespace, although there may be variances 
>> in package import versions.
>> 
>> Yes we are also looking at moving away from java serialization.
>> 
>> Also over time, because this is a service interface, at some point down the 
>> track, serialization can be replaced, without impacting the public api.  So 
>> yes the underlying protocols can be stripped out to data and message passing 
>> if that's more satisfactory.
>> 
>> So yes java serialization is an existing part of our application and it has 
>> it's warts.
>> 
>> But we've also had a number of users over the years who have requested 
>> support for OSGi.
>> 
>> This is not a greenfields project, I'm hoping that I'm not going to be told 
>> that no, the chasm is too wide you can't cross over to OSGi, rewrite or 
>> start again, there's just too many LOC.
>> 
>> So you have raised some important questions.  Some of our users have had a 
>> lot of success with Maven (recognising there a pro's and cons's with module 
>> based versioning and transitive dependencies), where versioning on a module 
>> level allows codebase annotations to be utilised in remote invocation, 
>> avoiding class visibility issues by mapping module ClassLoader's directly to 
>> a URI based identity.  However with OSGi there's a mismatch between 
>> different jvm's and how bundles and packages imports will be resolved will 
>> end up being wired, so we can't rely on codebase annotations for OSGi.
>> 
>> Jvm's using OSGi frameworks are quite likely to have different dependency 
>> graphs (wires) between bundles and their package imports.
>> 
>> While I don't expect to solve the worlds problems or boil the ocean, I'm 
>> looking for the most workable compromise, one that doesn't promise the world 
>> and is easier to explain what users can and can't expect to do.  I'm 
>> relatively pragmatic.  To me it would seem logical that a subset where two 
>> identical bundles (that should have resolved similar package import 
>> versions) should be a good place to start.
>> 
>> Hence my post on this list, as I realise many of you have already spent a 
>> lot of time bumping into these issues.
>> 
>> Cheers,
>> 
>> Peter.
>> 
>> On 20/02/2017 6:38 PM, Peter Kriens wrote:
>>> After working in this area for too many years I’ve come to the conclusion 
>>> that objects cannot be really transferred to other systems in a reliable 
>>> way, only self typed data can. JPA, RMI, and many other systems promise 
>>> heaven to the programmer that they can use their objects local and remote 
>>> transparently. The consequence of this dream is a huge amount of complexity 
>>> that far outweighs any gains in programmer friendliness. Few things have 
>>> caused so much trauma in the software world as ORM. (Persistence is 
>>> communications to a future process.)
>>> 
>>> The reason objects are so complex to use in communications is that it is in 
>>> direct violation of the goal of OO to hide your data. However, once you 
>>> expose the internal data on the wire you have effectively made it public 
>>> but too many people they can still have the advantages of abstract data 
>>> types. OSGi is a bitch in this case because it tells you that you’re trying 
>>> to do something wrong by refusing to cooperate. In this case, it balks at 
>>> you because you create an invisible dependency between the sender and the 
>>> receiver. Though this is a good thing too often the receivers of this 
>>> message blame the messenger.
>>> 
>>> You can handle this dependency but you’ll find out is that it is a hugely 
>>> complex task that introduces a lot of frailty in the overall system. Having 
>>> tried this several times I can assure you that any gains in programmer 
>>> friendliness are dwarfed by the complexity of creating this facade.
>>> 
>>> The best solution I found is to give up on data hiding. The fact your 
>>> objects is on the wire means that that wire format is public. I therefore 
>>> use Data Transfer Objects, in my case objects with public fields. On both 
>>> sides I have my own objects to provide behavior to this data with methods 
>>> and classes but this data record is at the core of my code. Since this data 
>>> is public because it goes over the wire it is better to wrap you code 
>>> around that ‘standardized public’ object than to try you internal object 
>>> data.
>>> 
>>> If you look at the OSGi specifications of the past 5 year then you will 
>>> notice that all applicable APIs have been designed to be useful with 
>>> Distributed OSGi. Calls do not pass objects but they pass DTOs back and 
>>> forth. They do not rely that the receiver and sender have exactly the same 
>>> type and version. In this model it is easy to replace an endpoint using 
>>> another language, which is a really good sign.
>>> 
>>> For Java developers this is often an unpleasant message, and quite often 
>>> OSGi get the blame. However, the fact OSGi gives you these problems means 
>>> that you’re trying to do something that has hidden dependencies.
>>> 
>>> Distributed computing has 7 well known fallacies[1] but I strongly believe 
>>> that there is an eighth: ’One can communicate objects over a network’.
>>> 
>>> Now your question. Yes, you could run a resolve and load the proper bundles 
>>> but you introduce a huge amount of error cases and a large amount of 
>>> complexity and you won’t solve the fundamental problem
>>> 
>>> Kind regards,
>>> 
>>> Peter Kriens
>>> 
>>> [1]: https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing 
>>> <https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing>
>>> 
>>> 
>>>> On 20 Feb 2017, at 05:13, Peter <j...@zeus.net.au 
>>>> <mailto:j...@zeus.net.au> <mailto:j...@zeus.net.au 
>>>> <mailto:j...@zeus.net.au>>> wrote:
>>>> 
>>>> Hello,
>>>> 
>>>> I'm currently working on converting an existing application to OSGi.
>>>> 
>>>> This application has a network service architecture based on java 
>>>> interfaces.  I've broken the application into modules, using a Maven 
>>>> build, which uses bnd and bndtools to create bundle manifests.  Some of 
>>>> these modules are ServiceLoader provider's, so I've used annotations to 
>>>> ensure these are loaded into the OSGi service registry using the Service 
>>>> Loader Mediator.
>>>> 
>>>> The main issue that I face is this application is a networked application 
>>>> and has it's own Remote Invocation protocols (which currently utilise Java 
>>>> Serialization, but not Java RMI).  As you'll appreciate, class visiblity 
>>>> is a little different in OSGi.  :)
>>>> 
>>>> The services mentioned above are remote services, these remote services 
>>>> have a proxy which implements the service interface, these services are 
>>>> discovered and installed at the client.  There are two types of proxy's, 
>>>> one, called a smart proxy, requires a codebase from which to retrieve a 
>>>> jar or jar files that are downloaded and installed at the cleint 
>>>> (traditionally during deserialization),  the other type of proxy is called 
>>>> a dynamic proxy (it's basically just an instance of 
>>>> java.lang.reflect.Proxy), which is dynamically generated at the client.
>>>> 
>>>> The Service implementation is broken up into three components:
>>>> 
>>>> 1. The service api
>>>> 2. The smart proxy (resolved and provisioned into in client jvm).
>>>> 3. The server
>>>> 
>>>> The server bundle imports packages from the smart proxy bundle, while the 
>>>> smart proxy imports packages from the service api as well as exporting 
>>>> it's own packages, as required by the server bundle.
>>>> 
>>>> The server that provides the remote service has three bundles loaded; 
>>>> server-impl, smart-proxy & service-api.
>>>> 
>>>> The client only has the service api bundle installed at deployment and the 
>>>> smart proxy is resolved and provisioned before the service is made 
>>>> available via the local OSGi service registry, where the client will learn 
>>>> of it's existence using ServiceTracker.
>>>> 
>>>> At first glance only the smart proxy bundle needs to be provisioned at the 
>>>> client, however for cases where a dynamic proxy is required to implement 
>>>> interfaces from different packages, where class visibility issues may 
>>>> exist, it may be beneficial in these cases to utilise and provision a 
>>>> proxy bundle that imports all these interfaces, one might do that by 
>>>> taking advantage of java's interface multiple inheritance; create a bundle 
>>>> that contains one interface (annotated with @ProviderType) which extends 
>>>> all interfaces, which the bundle doesn't export, so we ensure that the 
>>>> dynamic proxy has a proper bundle manifest with all package imports and 
>>>> version ranges correctly defined.
>>>> 
>>>> The inbuilt remote invocation protocol has server and client endpoints, 
>>>> the protocol is extensible and has a number of implementations (for 
>>>> example https, http, tls, kerberos, tcp).   Each endpoint is assigned a 
>>>> ClassLoader when it's created.
>>>> 
>>>> For classes installed at the client, these are typically installed in a 
>>>> URLClassLoader, typically with the Application loader as parent loader.  
>>>> In an OSGi environment however, the smart proxy bundle will be installed 
>>>> at the client, it's ClassLoader utilised by the client endpoint, the smart 
>>>> proxy bundle will also be installed at the server and it's ClassLoader 
>>>> utilised by the server endpoint.   In this case the visibility of the 
>>>> bundles at each endpoint will be utilised to resolve serializable classes. 
>>>>    Private smart proxy serializable classes will be resolvable at each 
>>>> end, but only public classes from imported packages will be 
>>>> deserializable, since the client interacts using the Service API, all 
>>>> serializable classes in the Service API packages will need to be exported 
>>>> and public and imported by the client and smart proxy.
>>>> 
>>>> Once a bundle has been provisioned its ClassLoader will be given to the 
>>>> client endpoint and the marshalled state of the proxy unmarshalled into 
>>>> it.  At this point the service that the proxy provides would be registered 
>>>> with the OSGi service registry for the client to discover and consume.  
>>>> The smart proxy communicates with it's server via an internal dynamic 
>>>> proxy (java.lang.reflect.Proxy), it's used to invoke methods on the server.
>>>> 
>>>> While the existing protocol uses Java serialization, it doesn't use Java 
>>>> serialization's method of resolving classes  Java Serialization walks the 
>>>> stack and finds the first non system classloader (looking for the 
>>>> application ClassLoader).    The existing class resolution method isn't 
>>>> suitable for OSGi, however the mechanism is extensible, so can be replaced 
>>>> with something suitable.
>>>> 
>>>> 
>>>> 
>>>> Does anyone have any advise or experience utilising the OSGi Enterprise 
>>>> Resolver Service Specification (chapter 136) and the OSGi Enterprise 
>>>> Repository Service Specification (chapter 132) to resolve and provision a 
>>>> bundle for the smart proxy at the client?
>>>> 
>>>> 
>>>> 
>>>> The intent here is the bundle manifests at each endpoint will be used to 
>>>> determine class visiblity, so the resolution and provisioning process will 
>>>> be of critical importance.
>>>> 
>>>> For anyone curios, the application is a fork of Apache River / Jini and 
>>>> I'm experimenting with support for OSGi.  I'm also a committer and PMC 
>>>> member of Apache River.  This isn't the old Jini we all know and love 
>>>> however, there are some additional features that allow provisioning to 
>>>> occur using a feature called delayed unmarshalling, so we can avoid the 
>>>> need for codebase annotations and URLClassLoaders.
>>>> 
>>>> The work in progress can be found here, for anyone who's curious:
>>>> 
>>>> https://github.com/pfirmstone/JGDMS/tree/Maven_build/modularize/JGDMS 
>>>> <https://github.com/pfirmstone/JGDMS/tree/Maven_build/modularize/JGDMS>
>>>> 
>>>> Regards,
>>>> 
>>>> Peter.
>>>> 
>>>> _______________________________________________
>>>> OSGi Developer Mail List
>>>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>>> 
>>> 
>>> _______________________________________________
>>> OSGi Developer Mail List
>>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
>> 
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
>> https://mail.osgi.org/mailman/listinfo/osgi-dev 
>> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> 
> 
> 
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org <mailto:osgi-dev@mail.osgi.org>
> https://mail.osgi.org/mailman/listinfo/osgi-dev 
> <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> 
> 
> 
> -- 
> -- 
> Christian Schneider
> http://www.liquid-reality.de 
> <https://owa.talend.com/owa/redir.aspx?C=3aa4083e0c744ae1ba52bd062c5a7e46&URL=http%3a%2f%2fwww.liquid-reality.de>
> 
> Open Source Architect
> http://www.talend.com 
> <https://owa.talend.com/owa/redir.aspx?C=3aa4083e0c744ae1ba52bd062c5a7e46&URL=http%3a%2f%2fwww.talend.com>_______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to