Yes Peter. I used it to get the package version of a class. Please refer the following class in bootstrap bundle. org.apache.river.bootstrap.common.RiverUtils
public static Version getPackageVersion(Class<?> clazz) { Package packageName = clazz.getPackage(); Bundle bundle = FrameworkUtil.getBundle(clazz); if(bundle == null){ Bundle bundle2 = FrameworkUtil.getBundle(RiverUtils.class); bundle = bundle2.getBundleContext().getBundle(0); } BundleWiring bundleWiring = bundle.adapt(BundleWiring.class); List<BundleCapability> capabilities = bundleWiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE); for (BundleCapability bundleCapability : capabilities) { if (bundleCapability.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(packageName.getName())) { Object object = bundleCapability.getAttributes().get("version"); Version v = new Version(object.toString()); return v; } } List<BundleRequirement> requirements = bundleWiring.getRequirements(BundleRevision.PACKAGE_NAMESPACE); for (BundleRequirement requrement : requirements) { if (requrement.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(packageName.getName())) { Object object = requrement.getAttributes().get("version"); Version v = new Version(object.toString()); return v; } } // must be java interface or java class return new Version(0,0,0); } http://blog.osgi.org/2015/12/using-requirements-and-capabilities.html https://www.infoq.com/news/2011/03/osgi-43 http://bnd.bndtools.org/chapters/220-contracts.html On Wed, Feb 1, 2017 at 5:03 PM, Peter <j...@zeus.net.au> wrote: > Thanks Bharath, will have to do some reading. > > Have you some experience using the new api? > > Cheers, > > Peter. > > Sent from my Samsung device. > > Include original message > ---- Original message ---- > From: Bharath Kumar <bharathkuma...@gmail.com> > Sent: 01/02/2017 04:43:44 pm > To: dev@river.apache.org > Subject: Re: OSGi > > Peter, > Please note that Package admin service has been replaced by the Bundle > wiring api. So we may need to use this new api. > > Thanks & Regards, > Bharath > > On 01-Feb-2017 8:50 AM, "Peter" <j...@zeus.net.au> wrote: > > Thanks Nic, > > So it follows that the caller has visibility to all imported packages from > other Bundle's ClassLoaders. But not packages from those bundles that > haven't been imported. > > Which is the reason I propose switching context with each object in a > serialized graph, to gain the visibility of the current object's bundle > ClassLoader during deserialization, in order to be able to deserialize > implementation classes. > > We need the codebase annotation when a class isn't reachable from the > current context. Each class in a serialization stream is only resolved > once. > > The codebase annotation is exact, it has an identity defined by it's > normalized URI, which may be a specific version in a specific location, it > should not contain a version range, or it will cause annotation loss and > prevent loading of new proxy versions as Gregg mentioned earlier. > > A proxy class will not be visible from the clients calling stack. Hence > the proxy's exact bundle will be loaded. It is then of > critical importance > that the service api bundle is resovled, visible to both the client and > proxy. > > The way the proxy bundle is wired depends on it's manifest package imports > and the service api version currently loaded in the client jvm. Hence the > service needs to publish the api package ranges it's proxy imports in an > Entry (we need a new Entry in the Jini platform to support OSGi). > > The client must be using the latest currently loaded service api packages > within the proxy's import ranges, as they will be > selected by the framework > for the proxy. There is a special case with the uses package declaration > we need to understand and document, as this may cause selection of an > earlier api package version. > > Hence Package Admin Service will need to be utilised to update the client > before unmarshalling the proxy under rare circumstances when more than one > service api version is in use at the client. > > The codebase annotation should only be needed during deserialization for > proxy and dependency injected objects. > > Proxy's and dependency injected objects will never > be resolved to alternate > bundle versions or a range. This also prevents codebase annotation loss. > > I think we're getting closer to understanding a possible solution. > > Cheers, > > Peter. > > Sent from my Samsung device. > > Include original message > ---- Original message ---- > From: Niclas Hedhman <nic...@hedhman.org> > Sent: 01/02/2017 09:57:28 am > To: dev@river.apacheorg > Subject: Re: OSGi > > As I think you know, the whole purpose of OSGi is to > NOT tie the resolution > to Bundles, but to explicitly Exported (with versions) packages If people > screw up and don't declare the Import/Export package meta data correctly, > then ordinary OSGi may fail just as spectacularly. The difference being > that Java serialization is slightly more sensitive to class changes than > the code itself, and that was an issue from the start. "Back then" it was > quickly realized that "long-term" storage of serialized state was a bad > idea, but "long-term" is relative to code releases and with highly > distributed systems, this is now a reality in networked applications as > well as storing serialized objects to disk. With that in mind, one should > seriously reconsider the status of Java Serialization > in one's application, > realize that every serialized class, incl possible exceptions, is a > published API and needs to be treated as such, just as a REST API, SOAP > interface or HTTP itself. Sorry for the rant... > > Back to OSGi; even if you really need to tie a class to a particular > bundle, you can do that with attributes and the 'mandatory' directive. > > Cheers > Niclas > > On Wed, Feb 1, 2017 at 3:29 AM, Michał Kłeczek <michal.klec...@xpro.biz> > wrote: > > > Unfortunately it is not going to work in the general > case as I've shown in > > another message. > > > > The issue is that since you do not have influence on how the bundles of > > ServiceProxy and ImplementationDetailServicePro > xy are resolved, you cannot > > guarantee that ImplementationDetail interface is going to be > resolved from > > the same bundle for both. > > > > Michal > > > > On Tue, 31 Jan 2017 at 06:38, Bharath Kumar <bharathkuma...@gmail.com> > > wrote: > > > > > With help of some information from service > providers, we can implement > > > this use case in osgi environment easily. > > > > > > Suppose if we split these classes as separate bundles, we will have 2 > > sets > > > of bundles. > > > > > > 1. ImplementationDetail.api - contains ImplementationDetail service > > api > > > class and its dependencies > > > 2. ImplementationDetail.proxy - smart proxy for > ImplementationDetail > > > service > > > 3. ImplementationDetail.service - ImplementationDetail service > > > implementation > > > 4. ImplementationDetail.bootstrap - service bootstrap bundle for > > > ImplementationDetail > > > service. > > > > > > ImplementationDetail.bootstrap bundle creates the service and annotate > > the > > > codebase location. > > > > > > > > > 1. forClient.api - contains ForClient service and its dependencies > > > 2. forClient.proxy - smart proxy(ServiceProxy) for ForClient > > > service. It imports > > > classes from ImplementationDetail.api bundle and forClient.api > bundle. > > > 3. forClientservice - service implementation(ServiceBackend) and > > > depends on forClient.proxy and forClient.api bundles > > > 4 forClient.bootstrap - service bootstrap bundle for ForClient > > service > > > > > > > > > Here fooClient.proxy dependens on ImplementationDetail service. So it > > can't > > > be created until ImplementationDetail service is available in the > > network. > > > So forClient.bootstrap bundle registers a > ServiceTemplate instance into > > > osgi registry. This will help to find ImplementationDetail service > from > > the > > > network. > > > > > > Once ImplementationDetail service is available in the network, > > > forClient.bootstrap > > > bundle creates the ServiceBackend and creates the proxy using > > > ImplementationDetail service's proxy. Here we can pass the proxy > > locations > > > of ImplementationDetail.proxy and forClient.proxy bundles. > > > > > > > > > *How to find codebase location of a service proxy?* > > > > > > Before registering the service, we can create an > Entry object with code > > > location. This information can be used by any service which will wrap > > > another service proxy. As we know this information, we can create this > > > Entry object. > > > > > > > > > *Codebase information* > > > > > > If we have the below information in the codebase annotation, then > > > RMIClassLoaderSPI can use these information to install or find the > > correct > > > compatible bundle in the client environment. > > > > > > - Service API bundle symbolic name, its version and location > > > - Proxy bundle symbolic name , its version and location > > > - Third party osgi bundles (libraries), their version and locations > > > (optional). > > > > > > > > > Even If we annotate the JERI based proxy with service api bundle > > > information, we don't even need to patch the below classes. > > > > > > 1. BasicInvocationDispatcher > > > 2. ServiceDiscoveryManager > > > > > > Because, RMIClassLoaderSPI can find the correct compatible service api > > > bundle in client environment using codebase annotation. > > > > > > I'll create a POC and will share my experiences. > > > > > > > > > On Tue, Jan 31, 2017 at 10:01 AM, Gregg Wonderly <ge...@cox.net > > wrote: > > > > > > > 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 > > > > >>>> > > > > >>>> > > > > >> > > > > > > > > > > > > > > > > > > > > > > -- > Niclas Hedhman, Software Developer > http://polygene.apache.org <http://zest.apacheorg> - New Energy for Java > >