Return-Path: Delivered-To: apmail-felix-dev-archive@www.apache.org Received: (qmail 89340 invoked from network); 24 Jul 2009 19:35:14 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 24 Jul 2009 19:35:14 -0000 Received: (qmail 62371 invoked by uid 500); 24 Jul 2009 19:36:19 -0000 Delivered-To: apmail-felix-dev-archive@felix.apache.org Received: (qmail 62290 invoked by uid 500); 24 Jul 2009 19:36:18 -0000 Mailing-List: contact dev-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list dev@felix.apache.org Received: (qmail 62280 invoked by uid 99); 24 Jul 2009 19:36:18 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Jul 2009 19:36:18 +0000 X-ASF-Spam-Status: No, hits=1.2 required=10.0 tests=SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [209.85.220.212] (HELO mail-fx0-f212.google.com) (209.85.220.212) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Jul 2009 19:36:10 +0000 Received: by fxm8 with SMTP id 8so1665566fxm.22 for ; Fri, 24 Jul 2009 12:35:48 -0700 (PDT) MIME-Version: 1.0 Sender: david.savage@paremus.com Reply-To: david.savage@paremus.com Received: by 10.204.124.7 with SMTP id s7mr78214bkr.105.1248464148725; Fri, 24 Jul 2009 12:35:48 -0700 (PDT) Date: Fri, 24 Jul 2009 20:35:48 +0100 X-Google-Sender-Auth: cadbf343544d5ac9 Message-ID: Subject: Visibility semantics From: David Savage To: dev@felix.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked by ClamAV on apache.org Hi there, Having got some way into getting Sigil up and running on apache, I think it's useful to start some dialog on it's functionality and future direction. One of the open areas it would be good to get feed back from the community is around the problem of class space visibility and the different semantics at compile and runtime. That's a bit hard to digest in a single sentence so I'll try to expand on what this means... One of the goals of Sigil is to use the same semantics at compile time as used by OSGi to build a class space at runtime. To this end if you have a dependency on some package in a certain range in the sigil.properties file you say things like: -imports: org.foo.example;version=[1.0.0,2.0.0) The sigil resolver then walks it's way through the available repositories to find the "best" bundle that satisfies this import requirement via an export requirement and this bundle is added to your classpath. In eclipse we (via the jdt compiler) we have the ability to apply /real/ osgi rules to this to limit the visibility of other packages not explicitly imported so you get nice red warning signals in the IDE if you then reference another class from a different package that you have not yet imported. All good. Where this breaks down with respect to the compiler is if you have a class hierarchy as follows: package org.foo; public interface Top { public void doit(); } package org.foo.example; public interface Middle extends Top { } package org.bar.example { import org.foo.example.Middle; public class Other { public void broken() { Middle m = findMiddle(); m.doit(); } private Middle findMiddle() { // TODO find middle return null; } } If foo and bar are in different bundles and the bar bundle only imports the org.foo.example package (which is all that is necessary at runtime) this fails at compile time even if both packages are exported from foo if we apply the OSGi rules exactly as stated above - as the compiler needs visibility of the org.foo.Top class in order to know that the doit() method exists. This is not required at runtime as the org.foo bundle classloader does have visiblity of the Top class so it can do the instantiation and hand the resultant object to org.bar. The solution we've applied in Sigil up until this point is to add an extra attribute to imports "resolve=compile": -imports: \ org.foo;version=[1.0.0,2.0.0);resolve=compile, \ org.foo.example;version=[1.0.0,2.0.0) This tells Sigil to make the package available for compilation but removes the header from the manifest at runtime - as extra dependencies are bad (standard OSGi mantra). *Note* we also discussed whether to make this resolution=compile to match the OSGi semantic of resolution=optional. However we decided to use a different tag as this would actually be adding our own custom extensions to the OSGi spec which is also generally viewed as bad...the counter argument to this is you could say that the OSGi spec is a runtime spec and doesn't touch on building (yet) so why not extend it? However this is not the only problem, fragments also cause there own unique problems to compilation. Consider that the org.eclipse.swt bundle /claims/ to export a set of packages org.eclipse.swt, org.eclipse.swt.image, etc. But in actual fact the packages are not contained in this bundle but are attached via platform specific fragments org.eclipse.swt.macosx...At runtime this is all fine if you just specify import package or require bundle then you get the correct behaviour if the fragment is loaded. However at compile time this puts an implicit dependency on /some/ fragment to be available to the compiler to provide the classes. One potential solution for this I've mentioned here: https://issues.apache.org/jira/browse/FELIX-1407 This would allow the sigil.properties file to have a compile only Requires-Bundle dependency on a fragment that would make the classes visible but this would get stripped from the manifest at runtime so the bundle would function as normal. *Note* this is also a "live" problem for the conversion of Sigil to be self hosting as it depends on the SWT classes so has this exact problem. I have the current compilation working by adding the requirement for the fragment. However this causes the bundle to fail to deploy at runtime in environments that do not have this fragment (i.e. windows, linux etc :( To lay my cards on the table, I kinda like resolve=compile as it dove tails kinda neatly with resolution=optional, but equally it seems kinda bizarre to be adding another dimension to this whole problem when people are worried about the complexity of OSGi. If there is a way to do this without exposing developers to it that would be /great/ but as with OSGi I don't think we should worry about doing the right thing at the base layer IDE tools and other schemes can always simpilify this whole space down again to joe blogs. I guess it's a question of what is "right". So I guess the end result of this email is, what are your thoughts? * Is resolve=compile a good idea? * Should it be resolution=compile? * Any other options? * What to do about fragments? * Is anyone still there (i.e. has this email lost you all?)? Regards, Dave