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>:

>
> 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>
> Sent: 21/02/2017 12:24:39 am
> To: OSGi Developer Mail List <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> 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
>
> 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
>
>
> On 20 Feb 2017, at 05:13, Peter <j...@zeus.net.au <mailto:j...@zeus.net.au
> <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
>
> Regards,
>
> Peter.
>
> _______________________________________________
> 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
>
>
> _______________________________________________
> 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
>



-- 
-- 
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

Reply via email to