Return-Path: Delivered-To: apmail-incubator-river-dev-archive@minotaur.apache.org Received: (qmail 96401 invoked from network); 20 Nov 2009 04:56:37 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 20 Nov 2009 04:56:37 -0000 Received: (qmail 10836 invoked by uid 500); 20 Nov 2009 04:56:37 -0000 Delivered-To: apmail-incubator-river-dev-archive@incubator.apache.org Received: (qmail 10685 invoked by uid 500); 20 Nov 2009 04:56:35 -0000 Mailing-List: contact river-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: river-dev@incubator.apache.org Delivered-To: mailing list river-dev@incubator.apache.org Received: (qmail 10674 invoked by uid 99); 20 Nov 2009 04:56:35 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Nov 2009 04:56:35 +0000 X-ASF-Spam-Status: No, hits=1.2 required=10.0 tests=SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (nike.apache.org: local policy) Received: from [61.9.189.140] (HELO nschwmtas02p.mx.bigpond.com) (61.9.189.140) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Nov 2009 04:56:25 +0000 Received: from nschwotgx02p.mx.bigpond.com ([120.155.156.14]) by nschwmtas02p.mx.bigpond.com with ESMTP id <20091120045601.JFNV2264.nschwmtas02p.mx.bigpond.com@nschwotgx02p.mx.bigpond.com> for ; Fri, 20 Nov 2009 04:56:01 +0000 Received: from [10.253.1.62] (really [120.155.156.14]) by nschwotgx02p.mx.bigpond.com with ESMTP id <20091120045600.KXZS19767.nschwotgx02p.mx.bigpond.com@[10.253.1.62]> for ; Fri, 20 Nov 2009 04:56:00 +0000 Message-ID: <4B06215D.4010101@zeus.net.au> Date: Fri, 20 Nov 2009 14:55:57 +1000 From: Peter Firmstone Organization: Zeus Project Services User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: river-dev@incubator.apache.org Subject: Re: River & OSGi References: <4AF391EE.70006@zeus.net.au> <0D2AF945-B7BF-4DA9-9D27-557F3D296460@topiatechnology.com> <4AF40932.5070502@zeus.net.au> <004F9331-EED2-4895-AA9A-E413FBEDB716@topiatechnology.com> <4AF4D950.1000102@zeus.net.au> <17F527F6-22B6-4C54-B7E3-E8FC9F645C28@topiatechnology.com> <4AF65C5D.3070506@zeus.net.au> <4AF76B20.7010007@zeus.net.au> <4B037920.5010501@zeus.net.au> <8D43BD10-116C-468A-BA09-ED2AC566029F@topiatechnology.com> <4B03F459.8010108@zeus.net.au> <3388C4E6-1809-4C25-9015-E231EE25DB52@gmail.com> <4B0494DB.8090508@zeus.net.au> <75174F30-B2E9-4616-8623-2ECDF5BF8776@gmail.com> <4B04A4B1.1010800@zeus.net.au> <4B05AA41.9030205@cox.net> <4B05AFB3.10409@zeus.net.au> <4B060DC9.6030405@wonderly.org> In-Reply-To: <4B060DC9.6030405@wonderly.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-RPD-ScanID: Class unknown; VirusThreatLevel unknown, RefID str=0001.0A150202.4B062161.00FB,ss=1,fgs=0 X-Virus-Checked: Checked by ClamAV on apache.org Sorry Gregg, my apologies, I was still caught in the explain loop ;) An app developer would have to specify package versions as per the OSGi bnd tool, including Packages to export, which is very simple, they don't need to utilise OSGi services, if they don't want that functionality. The Package API signatures should be auto generated by a tool at build time as an ant target, prior to generating jar files, it would be nice to create a tool that displayed Package API metadata visually as well. It's relatively straight forward to exclude a particular version of a bundle (jar file) in the bundle metadata (in the file format used by bnd), a developer might want to do this in case of bugs or concurrency issues and that's perfectly valid as we have no way of measuring the buggy-ness of code. Class metadata (its API and package version or package name and version at the very least), could be sent with the marshalled object, so the latest compatible byte code can be discovered and retrieved. Thanks, Peter. Gregg Wonderly wrote: > What I was trying to get at, was whether this was something that we > wanted the developer to have no part of specifying explicitly, or if > we might want to provide some ways for developers to draw lines in the > sand where API compatibility is not enough to suggest that a class is > okay for use. > > Gregg Wonderly > > Peter Firmstone wrote: >> Hi Gregg, >> >> The metadata represents package and class api signatures, it's a >> property of the code that already exists, that we capture. We can >> then make the information available without needing to load a class >> file first. Because Java doesn't allow reloading of class files in >> the same classloader, well not yet at least, I'd like to verify that >> the class being loaded is compatible prior to loading. >> >> Once you identify a packages API, it makes sense to catalogue it >> against a version number of some sort, OSGi already supports >> versioning metadata so it seemed logical to use that convention. >> There are some language changes in Java 7 to support modules, jsr 294 >> from memory I think. >> >> Thanks, >> >> Peter. >> >> Gregg Wonderly wrote: >>> Is this meta data something we want to extract, or is it something >>> that we want developers to designate existence of either through >>> annotations or some other visible meta information? >>> >>> Gregg Wonderly >>> >>> Peter Firmstone wrote: >>>> Dennis Reedy wrote: >>>>> So if this information is produced at build time, added into a >>>>> jar's manifest, what is the difference with using a convention of >>>>> something like a maven artifact to provide version and update >>>>> support? >>>>> >>>>> >>>>> >>>> A very brief statement is that it would describe the actual API of >>>> a package; the methods and fields of public class files, this >>>> information would be generated from the classpath, without >>>> programmer input, and stored as files in the jar file, in addition >>>> to the current bundle metadata, see below: >>>>> I haven't worked out how to represent the metadata in textual form >>>>> yet, perhaps xml? The tool, uses a number of options to define its >>>>> analysis / search scope and classpath from which it builds a >>>>> collection containing DependencyRelationship objects that contain >>>>> class metadata. Each DependencyRelationship object contains two >>>>> collections, one for dependants and one for providers, each >>>>> DependencyRelationship forms a node in the dependency graph. >>>>> >>>>> The DependencyRelationship objects can then grouped into a >>>>> collections, one for each package. You then iterate over the >>>>> collection to get all Provider's that are external to the >>>>> package. These DependencyRelationship Objects each represent a >>>>> class from an external (imported) package. This can then be >>>>> grouped into collections from different packages. Each of these >>>>> collections represent a dependency on an imported package. >>>>> >>>>> The Package API itself is determined by class visibility. When I >>>>> refer to classes here, I'm referring to class files, so this >>>>> includes interfaces and abstract classes. >>>>> >>>>> Only Public Classes form represent the Package API, from there you >>>>> drill down to the public class details: >>>>> >>>>> * all public methods and field signatures. >>>>> * all protected method and field signatures. >>>>> * serialVersionUID >>>>> >>>>> The DependencyPackageAPI signatures can be checked against the >>>>> PackageAPI signatures. >>>>> >>>>> I guess this could be done with a method such as >>>>> >>>>> public interface PackageMirror { >>>>> public boolean satisfies(DependencyPackageAPI depends); >>>>> } >>>>> >>>>> The devils in the implementation details of the above method. >>>>> >>>>> The devil is set out in Chapter 13 Binary Compatibility from the >>>>> Java Language Specification 3.0 >>>>> >>>>> Where this analysis gets really interesting is when a dependency >>>>> is published in return values of an exported PackageAPI, in this >>>>> case a client bundle importing a package from this bundle will >>>>> also have to import a Package that satisfies the common >>>>> dependency. The runtime will need to resolve all package >>>>> dependencies prior to loading. >>>>> >>>>> To generate the metadata I might persist to xml, all the >>>>> DependencyRelationship objects for a bundles exported packages as >>>>> well as the subset DepenencyRelationship objects from the import >>>>> package requirements. >>>>> >>>>> The metadata might be stored in three files in the jar: >>>>> depends.xml >>>>> provides.xml >>>>> client_requirements.xml - packages that use this package X will >>>>> depend on these other packages, Y and Z, full PackageAPI >>>>> signatures must be captured for Y and Z also. >>>>> >>>>> Or to be consistent with OSGi: >>>>> imports.xml >>>>> exports.xml >>>>> client_requirements.xml >>>>> >>>>> If the metadata is too large (though I think they'll be ok) a >>>>> SHA-1 checksum of these files might suffice, so they could be >>>>> looked up as required. >>>>> >>>>> Currently my implementation only has the dependency relationships, >>>>> it doesn't yet harvest all the method and field signatures, >>>>> although this is quite straight forward with ASM. >>>>> >>>>> As a result, a typical implentation will only depend upon the >>>>> interface, not package private classes or implementation details. >>>>> A later version of a Package could change a public class to a >>>>> public interface, and reimplement all methods in several package >>>>> private classes without altering the dependency metadata and still >>>>> satisfy backward compatibility. Just a quick question, does this >>>>> "Package API" differentiate between a bundle simply using an >>>>> interface vs one that implements it? Just wondering. >>>>> Yes, very much so, see above; one that simply uses it would not >>>>> publish it in its client requirements, however one that implements >>>>> it will. >>>> >>> >>> >> >> > >