Community
Participate
Working Groups
Both org.eclipse.emf.ecore and org.eclipse.emf.common use "Require-Bundle" to depend on org.eclipse.core.runtime. This in turn uses Require-Bundle to depend on org.eclipse.osgi, i.e. Equinox. Therefore EMF depends on Equinox, and cannot run on Felix or other OSGi frameworks. If Import-Package was used for the dependencies then we would at least have a chance of constructing a set of bundles that work on other frameworks. As it is, I am forced to rebuild the EMF bundles (along with org.eclipse.core.runtime etc) using Bnd.
Just to elaborate the problem a little... by adding EMF to my model API, I now have the following mandatory dependencies as an absolute minimum: * org.eclipse.emf.common * org.eclipse.emf.ecore * org.eclipse.core.runtime * org.eclipse.equinox.common * org.eclipse.core.jobs * org.eclipse.equinox.registry * org.eclipse.equinox.preferences * org.eclipse.core.contenttype * org.eclipse.equinox.app Plus, of course, I have to run on Equinox.
We'd break existing clients if we changed this though. If you had to create bundles that satisfied the package imports (and hence had to have specific package names), you could likewise give those bundles the expected IDs as well, right?
Note too that you can reuse EMF's bundles as plain old jars and repackage them that way too, I think. I.e., as a felix bundle with several of EMF's core runtime jars in it. In the end, all EMF's dependencies on Eclipse are optional from a standalone point of view.
(In reply to comment #2) > We'd break existing clients if we changed this though. I don't think that would be the case, since you do not re-export your dependency on org.eclipse.core.runtime. That is, clients that are using Require-Bundle to depend on emf.ecore and emf.common would not break if your bundles internally switched to using Import-Package. > If you had to create bundles that satisfied the package imports (and hence had > to have specific package names), you could likewise give those bundles the > expected IDs as well, right? Right. For my own purposes this is not important, but it's possible. (In reply to comment #3) > Note too that you can reuse EMF's bundles as plain old jars and repackage them > that way too, I think. I.e., as a felix bundle with several of EMF's core > runtime jars in it. In the end, all EMF's dependencies on Eclipse are optional > from a standalone point of view. Yes that is what I'm having to do. Unfortunately, though you state that those dependencies are optional, they are indicated as mandatory in the manifest. So the OSGi Framework will refuse to resolve the bundle in the absence of all those bundles in listed in Comment 1. Also without performing a full analysis of the source code, it's difficult for me to know which dependencies are really optional vs mandatory, and what would break if they were omitted. Some guidance from you on this subject would be very helpful.
Good point about the re-export... Note that as a bundle, those dependencies are definitely required. The dependency on resources is an example where it's optional. But from a standalone point of view, all Eclipse dependencies optional, but of course that's not something that can be declared in the bundle... Isn't the approach of rebundling the best one for you? Or are you really trying to implement a Felix version of these Eclipse runtime things?
(In reply to comment #5) > Good point about the re-export... > > Note that as a bundle, those dependencies are definitely required. The > dependency on resources is an example where it's optional. But from a > standalone point of view, all Eclipse dependencies optional, but of course > that's not something that can be declared in the bundle... I don't understand this reasoning. How can the dependencies be optional when standalone, but mandatory when running as an OSGi bundle?? If EMF runs at all, even in a limited way, when the Eclipse dependencies are absent, then those dependencies should be marked as optional. For example you could use Import-Package: org.eclipse.core.runtime;resolution:="optional". If at runtime you attempted to load a class from o.e.core.runtime and the bundle was not present, you would get a NCDFE or CNFE. The effect is exactly the same as in a standalone environment if the core.runtime JAR is absent from the classpath. > Isn't the approach of rebundling the best one for you? Or are you really > trying to implement a Felix version of these Eclipse runtime things? Rebundling works, but I would rather not maintain my own set of bundles. I don't yet see any reason why the original EMF bundles could not be made more flexible so that they can be used both in non-Equinox environments, but still work exactly the same as they do now in an Eclipse runtime. My main concern is that EMF adds dependencies to my APIs, and APIs are (in my opinion) sacrosanct. They must be as portable as possible because I don't know what kind of runtime they will be used in. It's disastrous if my API bundle depends on nine bundles and only resolves on Equinox! In relation to this point, I think it would be useful to define a minimal bundle that contains ONLY the required static APIs from EMF that are required to resolve a generated model. I.e. no runtime components, just EObject and EList etc. Then somebody who didn't want to use the EMF runtime but just wanted to reference my APIs could simply include one tiny bundle.
Neil, The code is carefully written so that uses of the core runtime is carefully isolated such that failure to load these runtime classes is handled gracefully. But that's only the case when running stand alone. When running in Equinox, the bundle activator is invoked and it has hard dependencies on the core runtime being there, and does things like registry processing... What you're describing for restructuring just isn't as simple might appear. Maybe we can make the core runtime dependency optional and maybe then the bundle will just work in Felix. If that's the case, I'm happy to make the changes. In terms of a minimal runtime, EObject has eClass() and that pulls in the whole Ecore model. It also has eResource which pulls in the persistence framework. The core runtime is quite minimal already...
(In reply to comment #7) I see. That is useful information, thank you. Still, the fact that EMF works to some degree in a standalone environment -- i.e. without the activators being run -- suggests that some of the work they do is not always required. Perhaps the activators could be coded in a similar way, e.g. using a small amount of reflection to detect the presence of Eclipse Core before proceeding with their task. It would be cleaner to move the activators to a separate bundle, but I recognise that would create problems for existing clients. Incidentally after some slicing and dicing with Bnd, I have been able to build a bundle that allows me to run a simple test case on Felix. The test case just creates some model objects and persists them to an XMI, but it is a start. I will attach my rebundled EMF JARs to this bug.
> It would be cleaner to move the activators to a separate > bundle, but I recognise that would create problems for existing clients. Could it be an option to put the eclipse specific startup code in a fragment? The activator could just check for a special startup class being available and execute it. All eclipse dependencies could be put on this fragment only. For the pure OSGi use case, the bundle could be used without the fragment and the Activator would not cause any harm. Existing clients that use "require-bundle" would not have a problem as long as the fragment is part of their target platform.
(In reply to comment #9) > Could it be an option to put the eclipse specific startup code in a fragment? > The activator could just check for a special startup class being available and > execute it. All eclipse dependencies could be put on this fragment only. For > the pure OSGi use case, the bundle could be used without the fragment and the > Activator would not cause any harm. > Existing clients that use "require-bundle" would not have a problem as long as > the fragment is part of their target platform. I don't think this would be substantially different than having your special startup class being part of the same bundle, and using optional imports to get the Eclipse dependencies. Except it would increase the number of artifacts to manage, and many people would forget to include it in their TP or run configurations.
The fundamental problem is getting to be how to manage all these variations with a team of approximately one person. We must support well, Eclipse, RCP, RAP, GWT, OSGi (Equinox/Felix), standalone. By manage I mean test, build, document, support, and so on.
highly +1 for this improvement. Neil Bartlett's emf-osgi fork (https://github.com/njbartlett/emf-osgi) helps a lot, but it'd be great if the official EMF supports it, at least the three core bundles (emf.common, emf.ecore, emf.ecore.xmi).
I agree with Neil's comment here https://bugs.eclipse.org/bugs/show_bug.cgi?id=328227#c8 "Perhaps the activators could be coded in a similar way, e.g. using a small amount of reflection to detect the presence of Eclipse Core before proceeding with their task. It would be cleaner to move the activators to a separate bundle, but I recognise that would create problems for existing clients." Even after all the classpath thing has been resolved, the activators are still causing problem because it assumes it's running in Eclipse. It should be able to ignore errors when org.eclipse.core.runtime is not available. (i.e. those using Eclipse should know that org.eclipse.core.runtime is required, so there should be no problem. those using plain OSGi will get the "limited EMF" mode, without any errors in Activator)
If someone proposes a patch that doesn't break API and existing clients, I'd be happy to review that for inclusion in the base. If it appears to have minimal chance of being disruptive, I could include it in the maintenance stream. The fundamental problem appears to be that our activator implementation extends org.eclipse.core.runtime.Plugin. I think we'd need to create some type of activator that doesn't do this. Is that right? I suppose an alternative is to build that massages the normal results (perhaps just stripping out the activator declaration and the core runtime dependency) to produce Felix friendly ones...
Up!
I'd like to revive this discussion as with Eclipse Concierge we now have a second OSGi framework implementation at Eclipse; I just tried using Concierge, but I am stuck, because my application requires EMF. So what is the best practice now to get EMF running on it?
I'm not sure what can be said beyond what's already in the thread. I have no personal experience trying to get it to work on other OSGi implementations. The approach of repacking the jars into a library bundle that supports another runtime seems reasonable, but then you don't get extension point processing, which is a significant loss of functionality.
Thanks Ed. I would not mind having a new separate library bundle to circumvent backward compatibility issues for current users. But being an Eclipse project (i.e. SmartHome) that is based on an Eclipse project (i.e. EMF) that wants to run on yet another Eclipse project (i.e. Concierge), I would not expect having to do any repackaging on my end to get things working. Instead, I would prefer that the required artifacts are readily available in an official Eclipse p2 repository for consumption. Would you see a way to provide such an additional artifact on your end from the official EMF build?
Given that I'm effectively the only active committer, maintaining variants of EMF is simply prohibitive. Things like a RAP variant, a GWT variant, an Android variant, as well as variants for different OSGi implementations just get to be too much to contain. Breaking existing API is also not an option; it's simply impossible to imagine how an EMF 3.0 can ever exist (except to use new package names and new bundle IDs, essentially a renamed fork)... What specifically would be needed to support Concierge? Is it really simply a repackaging build step? In that case, if someone contributes the necessary automated build infrastructure, that's something within the realm of possibilities.
> What specifically would be needed to support Concierge? > Is it really simply a repackaging build step? Well, yes, I think it is only a repackaging, i.e. exactly what Neil did here: https://github.com/njbartlett/emf-osgi > In that case, if someone contributes the necessary automated build > infrastructure, that's something within the realm of possibilities. I had hoped that you know the EMF build infrastructure best to easily add such an additional packaging. As you seem to use buckminster, I am probably not the right guy to fiddle around there as I only have experience with Tycho as a build tool.
(In reply to Ed Merks from comment #19) > Given that I'm effectively the only active committer, maintaining variants > of EMF is simply prohibitive. Things like a RAP variant, a GWT variant, an > Android variant, as well as variants for different OSGi implementations just > get to be too much to contain. Breaking existing API is also not an option; > it's simply impossible to imagine how an EMF 3.0 can ever exist (except to > use new package names and new bundle IDs, essentially a renamed fork)... Hi Ed. Just to clarify, I don't think that anybody is asking for EMF variants for each OSGi framework implementation. That's unnecessary because OSGi is a standard; you can just have one EMF variant that supports generic OSGi, rather than needlessly coupling EMF to Equinox. > What specifically would be needed to support Concierge? Is it really simply > a repackaging build step? In that case, if someone contributes the > necessary automated build infrastructure, that's something within the realm > of possibilities. Yes I think it's a build modification. As a later comment points out, I do have a fork that repackages EMF for OSGi, but it builds with bnd and would need to be integrated back into the Eclipse build system (presumably Tycho). I don't have the skills to do that unfortunately, and also my fork is very out of date.
Certainly a build step doesn't create significant long term overhead, but I'm not the guy who maintains the build so I don't know how one would work this into our existing build infrastructure...
So who maintains the EMF build then if you are the only active committer on the project...?
Note I didn't mean to imply I'm the only committer, I'm just saying I'm the only one actively/significantly maintaining the source base: http://git.eclipse.org/c/emf/org.eclipse.emf.git/log/ I've added I added Dennis Huebner because he's actively maintaining the builds. I imagine the only bundles that are being asked for (currently) is those of the EMF core runtime with different MANIFEST.MFs, and I suppose also with corresponding source bundles? They'd need to be signed as well... In what form would those jars need to be publish? A p2 site? A zipped download? Individual jars? Dennis, how hard would be be to run additional "scripts" on the build results produced normally to produce such additional results, including signing? What form must those scripts be in to integrate with our existing build infrastructure?
First of all, making EMF useable on other OSGI containers is a great idea! Ed already mentioned, that we have to produce consumable artifacts for various kinds of frameworks and/or projects RAP, GWT, eclipse RT and other. Our build became very complex and hard to maintain. Therefore I would prefer to find a solution that doesn't require an additional build steps. A repackaging approach here https://github.com/njbartlett/emf-osgi just fix the meta-data, at least regarding to the description: "However, the OSGi metadata in these bundle is of poor quality and they result in a hard dependency on large part of the Eclipse runtime." Can we first try to get a better quality of the EMF meta-data? You guys seems to be OSGI-experts, so would an optional+greedy require bundle and an optional package import to org.eclipse.* solve the problem?
+1 !! :) Thanks for considering this :)
+1 I hope this could be finally fixed
> so would an optional+greedy require bundle and an optional package import to org.eclipse.* solve the problem? I would assume that it does, but I guess Ed and Neil will be the ones to tell for sure :-)
I expect that won't solve the problem because the bundle activator depends on the Equinox runtime.
Could the activator catch NCDFEs and continue gracefully?
If Ed Mercks (guru of modelling) and Neil Bartlett (guru of OSGi) can't solve this I don't know who can (you can read that as a challenge). :)
I expect what's needed is a different MANIFEST.MF. I.e., here's how EMF.Common looks: Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.common;singleton:=true Bundle-Version: 2.10.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.emf.common.CommonPlugin$Implementation Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.emf.common, org.eclipse.emf.common.archive, org.eclipse.emf.common.command, org.eclipse.emf.common.notify, org.eclipse.emf.common.notify.impl, org.eclipse.emf.common.util Require-Bundle: org.eclipse.core.runtime Eclipse-LazyStart: true Bundle-ActivationPolicy: lazy It should instead be like this: Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: <#Different ID? Not a singleton#> Bundle-Version: 2.10.0.qualifier Bundle-ClassPath: . <#NO Bundle-Activator: org.eclipse.emf.common.CommonPlugin$Implementation#> Bundle-Vendor: %providerName Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.emf.common, org.eclipse.emf.common.archive, org.eclipse.emf.common.command, org.eclipse.emf.common.notify, org.eclipse.emf.common.notify.impl, org.eclipse.emf.common.util <#Package imports; none for this one Require-Bundle: org.eclipse.core.runtime#> <#NO Eclipse-LazyStart: true#> Bundle-ActivationPolicy: lazy Is that right Neil? Obviously I don't want maintain clones of entire projects to produce binary bundles that look this way. The activator class extends org.eclipse.core.runtime.Plugin so loading it causes a problem so it's a question of how the OSGi runtime implementation handles that. I imagine one generally wants to be informed when the activator of a bundle is bogus, so I imagine all runtime implementations will complain to some extent...
Eike Stepper had a good idea... I could implement an activator that directly implements org.osgi.framework.BundleActivator. That activator could create the current activator implementation, but guard it for class not found exceptions; if the class can be created, we can delegate start/stop to it, if not, it's a no-op (just as in the stand alone case). I think that works, but I haven't tested it. Neil, does that sound right? Of course I can make the org.eclipse.core.runtime dependency optional; that shouldn't hurt anyone (because it's always available in an Eclipse installation anyway). Then the only small inconvenience is the unnecessary (for non-Equinox) singleton declaration, but I assume folks could live with that, especially given EMF's decade-long track record of binary compatibility. If this is the right solution, I could even modify the generator to (optionally) generate those for model and edit projects so that all the things that work stand alone, also work as OSGi bundles in any OSGi implementation...
(In reply to Ed Merks from comment #33) > Of course I can make the org.eclipse.core.runtime dependency optional; that > shouldn't hurt anyone (because it's always available in an Eclipse > installation anyway). Could we keep org.eclipse.core.* dependencies greedy? resolution:=optional;x-installation:=greedy Otherwise it could break builds/installations where clients expect, that org.eclipse.core.* stuff is automatically fetched by p2 when resolving EMF dependencies.
That sounds like a good idea (it can't hurt), though it's hard to imagine an installation that doesn't have the core runtime...
Please review these changes: https://git.eclipse.org/r/#/c/24495/ The idea is to change this in EMF Common Require-Bundle: org.eclipse.core.runtime;resolution:=optional;x-installation:=greedy Import-Package: org.osgi.framework;visibility:=reexport I.e., make the runtime dependency optional but greedy. Question for the experts: Is the package import necessary for correct behavior in a non-Equinox runtime? Note that I reexported it so I don't need to repeat this in all downstream bundles. In EMFPlugin I provide this class: public static abstract class OSGiDelegatingBundleActivator implements BundleActivator { private final BundleActivator bundle; public OSGiDelegatingBundleActivator() { bundle = createBundleHelper(); } private BundleActivator createBundleHelper() { try { return createBundle(); } catch (Throwable throwable) { return null; } } protected abstract BundleActivator createBundle(); public final void start(BundleContext context) throws Exception { if (bundle != null) { bundle.start(context); } } public final void stop(BundleContext context) throws Exception { if (bundle != null) { bundle.stop(context); } } } Note hat it catches all exceptions during creation of the delegate. In any XyxPlugin$Implementation I can then declare this: public static class Activator extends EMFPlugin.OSGiDelegatingBundleActivator { @Override protected BundleActivator createBundle() { return new Implementation(); } } And then in the MANIFEST.MF I can change it to Bundle-Activator: org.eclipse.emf.common.CommonPlugin$Implementation$Activator So the Equinox-dependent plugin will start and stop when Equinox is present. When it's not, we basically behave as we do for stand alone. Those same changes are in the Ecore and XMI bundles too. Question: Can someone confirm/test that this works? If that's all good, I will do the same thing for emf.edit *and* provide a new GenModel option to generate the Activator delegation class, to use it in the MANIFEST.MF, and to make the core.runtime bundle dependency optional in model and edit plugins.
I will take a look at this in detail when I get some time, however I'm already a bit puzzled by the visibility:=reexport on Import-Package. This directive is only valid on Require-Bundle.
Neil, Oh! I looked in the core runtime bundle, but not closely enough to notice that was indeed on the Require--Bundle dependency it has on the osgi bundle, not the osgi package. Manifest-Version: 1.0 Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Built-By: e4Build Bundle-SymbolicName: org.eclipse.core.runtime; singleton:=true Eclipse-SourceReferences: scm:git:git://git.eclipse.org/gitroot/platfo rm/eclipse.platform.runtime.git;path="bundles/org.eclipse.core.runtim e";tag="I20131015-0800";commitId=2ffc43ad76119f4d476e606dd66d7cc44553 b686 Bundle-Activator: org.eclipse.core.internal.runtime.PlatformActivator Require-Bundle: org.eclipse.osgi;bundle-version="[3.7.0,4.0.0)";visibi lity:=reexport,... So, that probably makes zero sense. I don't need the package import at development time and don't need it to run in Equinox, so it's a question of whether I need it at all to run in other OSGi runtimes. I also don't know how folks use this stuff in other OSGi runtimes. I imagine development time dependencies on Equinox are still less than ideal, even if they are optional at runtime...
I haven't read all the comments on this bug, so please forgive if this is off-base. Until recently, ECF has depended upon the extension registry for some of it's remote services behavior. With bug 421569 we've eliminated the runtime requirement for the registry and it's dependencies...and made it optional. What we've done is: 1) Added whiteboard pattern OSGi services to duplicate the registry's declarative registration of extensions. 2) Created a utility class that at bundle startup time a bundle can use to detect the presence of the extension registry (or not), and run arbitrary code...e.g. to register whiteboard services if the extension registry isn't present. If er is present then it's used. This has worked well for us so far, as it allows us and consumers to use OSGi Remote Services on multiple frameworks (e.g. karaf) with or without the extension registry. Admittedly it's not wonderful...but it does allow consumers some flexibility of framework. We intend to use this to run on Concierge as well.
I think what Scott Lewis has done is "reinventing" Eclipse extension registry for its own use, where the Eclipse extension registry just happens to be one adapter it explicitly supports. I don't think our current discussion is on that phase yet (which is runtime behavior), currently still discusses the OSGi manifest packaging. When the time comes, I hope EMF won't go to that route (wrapping Eclipse extension registry). My preference would be: if Eclipse extension registry is available, use it; otherwise, the app developer needs to configure EMF programmatically via plain Java API (which work under any OSGi container).
(In reply to Hendy Irawan from comment #40) > I think what Scott Lewis has done is "reinventing" Eclipse extension > registry for its own use, where the Eclipse extension registry just happens > to be one adapter it explicitly supports. Well...sort of. What we are really doing is using the OSGi whiteboard service pattern (new) to support what our extension points expose for extending ECF. > > I don't think our current discussion is on that phase yet (which is runtime > behavior), currently still discusses the OSGi manifest packaging. Yeah, I get that...but much of (any) manifest discussion has to do with package and bundle-level dependencies...specifically on equinox packages (core runtime in this case). > > When the time comes, I hope EMF won't go to that route (wrapping Eclipse > extension registry). I don't think it's right to characterize it as 'wrapping the extension registry'. Really what it's doing is giving the ECF provider dev the option to use OSGi whiteboard service registration (java) rather than registering extensions...thus getting the same functionality with or without the extension registry. > My preference would be: if Eclipse extension registry > is available, use it; otherwise, the app developer needs to configure EMF > programmatically via plain Java API (which work under any OSGi container). Sure. We use the OSGi whiteboard pattern...as we've found it useful for our (ECF remote services) use case. EMF may of course want to run other java code...i.e. to configure EMF programmatically. FWIW, ECF created the following utility class specifically do the runtime detection of the extension registry...and then run arbitrary code...if present/or not. It or something like it could be useful for some of the use cases under discussion here. http://git.eclipse.org/c/ecf/org.eclipse.ecf.git/tree/framework/bundles/org.eclipse.ecf.identity/src/org/eclipse/ecf/core/util/ExtensionRegistryRunnable.java
Ed, I understand that you made some changes to the bundles to make them less dependent on Equinox. I am looking forward to test EMF on Concierge and discuss any issues that I might encounter.
I am hoping for confirmation that the approach I've outlined (in the Gerrit review) actually solves the problem. There's not much time to get this into the 2.10 release (and some might argue it's too late already). Note that EMF will release early to coincide with Xtext's end-of-May release...
It looks good to me. I would like to test it on Felix but the build triggered by gerrit has failed for some reasons I don't know. If you could provide a green build, I'm ready to test some basic usages of EMF on Felix.
The build is now green but I can't access to the workspace to get the bits and there the job "emf.gerrit" does not archive any artifacts :( Could you either add the job/workspace permission to the hudson groupe "ROLE_COMMON", or configure the job "emf.gerrit" to publish its results?
I can view the configuration but there's no submit button to submit my changes so I think I'm not authorized to make changes. We'll need Dennis for that. He's on the CC list be he's on vacation. Good for him. :-) Bad for us. :-(
Maybe you could ask to the webmaster to do that?
I've made Ed an admin on the HIPP instance. -M.
Created attachment 242619 [details] patch for the bundle manifests
I don't think that it works the way you intended. First of all, visibility:=reexport only works for RequireBundle, not for package imports. I have fixed that in my patch and also provided proper version ranges. Second, (starting with the common emf.bundle) you still have a dependency on org.eclipse.runtime.Plugin (because CommonPlugin$Implementation, which you create in CommonPlugin$Activator, extends EclipsePlugin extends Plugin). I don't know if this dependency is strictly necessary but at least it is not declared as package import and therefore the bundle resolves but does not start on a regular framework.
Note that Mikael has investigated this and I helped via skype... The dependencies on things in the Equinox runtime are not generally a problem because the OSGiDelegatingBundleActivator.createBundleHelper catches the exception (all Throwables actually) that results from tying to create the Equinox-dependent bundle activator which of course fails because the classes are not found. The remaining hard-to-track-down problem is that for Felix, all dependencies on the JDK must be declared properly via package imports. So these imports in EcorePlugin import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; caused poorly diagnosed activation problems. Including package imports for this in the Ecore manifest and of course for org.osgi.framework in each model bundle allowed Mikael to properly activate EMF's core runtime. So I'm pretty confident that we can generate for all model and edit bundles results that will work in Equinox (with extension point processing) as well as stand alone or in any OSGi implementation. I'll work on a new patch and look into generator support for producing that.
I see. So the $Implementation is designed to fail on non-Equinox? I missed that. org.xml.sax is not a problem per se as it can be declared as bootdelegation but having proper package imports is indeed the better choice.
The fix is committed to master: http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/?id=fbb144808cb8121e231f932aa0d84068846808a5 The https://hudson.eclipse.org/xtext/job/emf-core/ build should be re-enabled tomorrow morning. Please provide feedback as soon as possible given the release it two weeks away.
(In reply to Ed Merks from comment #53) > The fix is committed to master: > > http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/ > ?id=fbb144808cb8121e231f932aa0d84068846808a5 > > The https://hudson.eclipse.org/xtext/job/emf-core/ build should be > re-enabled tomorrow morning. > > Please provide feedback as soon as possible given the release it two weeks > away. New emf-core build is available.
I tested the new build and there is an issue with the o.e.emf.edit MANIFEST. An unwanted space appears before the import package directive and it creates a "binary" manifest of this shape: Require-Bundle: org.eclipse.core.runtime;resolution:="optional";x-inst allation:="greedy";bundle-version="[3.5.0,4.0.0)",org.eclipse.emf.com mon;visibility:="reexport";bundle-version="[2.10.0,3.0.0)",org.eclips e.emf.ecore;visibility:="reexport";bundle-version="[2.10.0,3.0.0)",or g.eclipse.emf.ecore.change;resolution:="optional";x-installation:="gr eedyImport-Package: org.osgi.framework";visibility:="reexport";bundle -version="[2.10.0,3.0.0)" You can see that the ImportPackage appears after the greedy word. I checked the whole repository with a grep -r " Import-Package" * and it seems this is the only location where the unwanted space exist.
I just committed the fix for that. http://git.eclipse.org/c/emf/org.eclipse.emf.git/commit/?id=5403eab28f46f9d9d3f681558ae96bcff8240a07 That should trigger another build.
I tested the build #111. It works much better. Here is what I tested with Bndtools 2.2: - regeneration of the EXTLibrary example with the OSGi compatibility option set to true - Creation of a library, set a name - Create a XMI resource, and add the library to it - Save the resource to System.out - Create a composed adapter factory and add EcoreItemProviderAdapterFactory and EXTLibraryItemProviderAdapterFactory to it. - Use a AdapterFactoryItemDelegator on the composed adapter factory to call #getText on the library and EcorePackage.eINSTANCE. Everything went well. Tomorrow, I will push my test projects to my github and add a comment with the url. Thanks for this enhancement!
I tested the build #112 (N201405080702) with Concierge, at least the EMF common and EMF Ecore. EMF common and EMF core can at least be installed and resolved now without any dependencies to Equinox/Eclipse anymore. My test case looks like: @Test public void testEclipseEMFCommon() throws Exception { try { final Map<String, String> launchArgs = new HashMap<String, String>(); launchArgs.put("org.eclipse.concierge.debug", "true"); launchArgs.put("org.osgi.framework.storage.clean", "onFirstInit"); startFramework(launchArgs); final String[] bundleNames = new String[] { "org.eclipse.emf.common_2.10.0.v20140508-0700.jar", }; final Bundle[] bundles = installAndStartBundles(bundleNames); assertBundlesResolved(bundles); } finally { stopFramework(); } } I see in strack trace that Plugin class will not be found, and a ClassCircularityError will happen afterwards. ERROR in org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader@37f0c4d2: java.lang.ClassCircularityError: org/eclipse/emf/common/CommonPlugin$Implementation$Activator ERROR in org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader@37f0c4d2: java.lang.NoClassDefFoundError: org/eclipse/core/runtime/Plugin For EMF Ecore same will happen. The bundle itself will be installed, resolved and can be started/stopped. Unfortunately I do not tests yet whether the bundles will work even if these exceptions happen. This looks like what Ed described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=328227#c51 <stacktrace excerpt> --------------------------------------------------------- Concierge OSGi 5.0.0.alpha on Mac OS X 10.9.2 starting ... (default) startlevel=3 --------------------------------------------------------- [Fri May 09 11:54:26 CEST 2014] [INFO] Framework: REGISTERED SERVICE org.osgi.service.resolver.Resolver org.eclipse.emf.common Solution: MultiMap {JarBundleResource {storage/default/1/bundle0 of bundle [org.eclipse.emf.common-2.10.0.v20140508-0700]}=[{BundleRequirement {osgi.ee; filter:=(&(osgi.ee=JavaSE)(version=1.5))}->BundleCapability {osgi.ee; osgi.ee=JavaSE, version=[1.7.0, 1.6.0, 1.5.0, 1.4.0, 1.3.0, 1.2.0, 1.1.0]}}, {BundleRequirement{Import-Package org.osgi.framework}->Export-Package org.osgi.framework;version=1.7}], Concierge System Bundle=[{BundleRequirement {osgi.ee; filter:=(&(osgi.ee=JavaSE)(version=1.5))}->BundleCapability {osgi.ee; osgi.ee=JavaSE, version=[1.7.0, 1.6.0, 1.5.0, 1.4.0, 1.3.0, 1.2.0, 1.1.0]}}, {BundleRequirement{Import-Package org.osgi.framework}->Export-Package org.osgi.framework;version=1.7}]} ERROR in org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader@37f0c4d2: java.lang.ClassCircularityError: org/eclipse/emf/common/CommonPlugin$Implementation$Activator at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader.findOwnClass(BundleImpl.java:2816) ... at org.eclipse.concierge.test.AbstractConciergeTestCase.installAndStartBundle(AbstractConciergeTestCase.java:151) at org.eclipse.concierge.test.AbstractConciergeTestCase.installAndStartBundles(AbstractConciergeTestCase.java:134) at org.eclipse.concierge.test.EclipseEMFTest.testEclipseEMFCommon(EclipseEMFTest.java:34) ERROR in org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader@37f0c4d2: java.lang.NoClassDefFoundError: org/eclipse/core/runtime/Plugin at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) at org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader.findOwnClass(BundleImpl.java:2816) ... at org.eclipse.concierge.test.AbstractConciergeTestCase.installAndStartBundle(AbstractConciergeTestCase.java:151) at org.eclipse.concierge.test.AbstractConciergeTestCase.installAndStartBundles(AbstractConciergeTestCase.java:134) at org.eclipse.concierge.test.EclipseEMFTest.testEclipseEMFCommon(EclipseEMFTest.java:34) Caused by: java.lang.ClassNotFoundException: org.eclipse.core.runtime.Plugin at org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader.findClass(BundleImpl.java:2371) at org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader.loadClass(BundleImpl.java:2350) ... 53 more ERROR in org.eclipse.concierge.BundleImpl$Revision$BundleClassLoader@37f0c4d2: java.lang.NoClassDefFoundError: org/eclipse/core/runtime/Plugin at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:800) ... [Fri May 09 11:54:26 CEST 2014] [INFO] framework: Bundle [org.eclipse.emf.common-2.10.0.v20140508-0700] started. --------------------------------------------------------- Concierge OSGi shutting down ... Bye ! --------------------------------------------------------- [Fri May 09 11:54:26 CEST 2014] [INFO] framework: Bundle [org.eclipse.emf.common-2.10.0.v20140508-0700] stopped. </stacktrace excerpt>
Here my test project of EMF on felix: https://github.com/mbarbero/emf.on.felix. Especially, you may want to have a look at https://github.com/mbarbero/emf.on.felix/blob/master/emf.on.felix/src/org/example/ExampleComponent.java#L24
Jochen, How can I test this Concierge thing locally myself? Given that Throwable is caught and then ignored, what's "logging" the stack traces with Concierge? Perhaps there are other "tricks" one could do for Concierge that apparently aren't needed for Felix, but wouldn't hurt if we had them, i.e., in org.eclipse.emf.common.EMFPlugin.OSGiDelegatingBundleActivator.createBundleHelper() guard the call to org.eclipse.emf.common.EMFPlugin.OSGiDelegatingBundleActivator.createBundle() with org.eclipse.emf.common.EMFPlugin.IS_ECLIPSE_RUNNING. Mikael, I'm not sure how to run these tests, but I would expect ComposedAdapterFactory.Descriptor.Registry.INSTANCE to be empty, given it's a registry populated by extension processing, so that's not helpful in an environment that doesn't support such processing. Extension processing does work stand alone, via a call to org.eclipse.emf.ecore.plugin.EcorePlugin.ExtensionProcessor.process(ClassLoader), but that does have Equinox dependencies, though given those dependencies also work stand alone, maybe those bundles also work in other OSGi runtime environments...
(In reply to Ed Merks from comment #60) > I'm not sure how to run these tests, I used an Eclipse 4.4 M7 with Bndtools 2.2 (http://bndtools.org/). To test it, you only have to import the emf.on.felix and cnf projects in workspace and right click on any *.bndrun files and run them as "Bnd OSGi run launcher". There are two launchers, one configured with felix and the other configured with equinox. EMF core and extlibrary bundles are installed in the "Local" repository. If you want to test new version of EMF or change something in extlibrary, you have to update the repositories as explained at http://bndtools.org/faq.html#how-do-i-add-bundles-to-the-repository > but I would expect > ComposedAdapterFactory.Descriptor.Registry.INSTANCE to be empty, given it's > a registry populated by extension processing, so that's not helpful in an > environment that doesn't support such processing. You are right, the usage of ComposedAdapterFactory.Descriptor.Registry.INSTANCE was not very thoughtful and more a matter of habit. > Extension processing does work stand alone, via a call to > org.eclipse.emf.ecore.plugin.EcorePlugin.ExtensionProcessor. > process(ClassLoader), but that does have Equinox dependencies, though given > those dependencies also work stand alone, maybe those bundles also work in > other OSGi runtime environments... Actually the ExtensionProcessor should not be needed in any other OSGi environment as the Equinox registry should be usable in any other OSGi environment (AFAIK).
> Actually the ExtensionProcessor should not be needed in any other OSGi > environment as the Equinox registry should be usable in any other OSGi > environment (AFAIK). Note that in org.eclipse.emf.ecore.plugin.EcorePlugin.Implementation.start(BundleContext) it does public void start(BundleContext context) throws Exception { super.start(context); ExtensionProcessor.internalProcessExtensions(); So the extensions won't be processed unless some additional action is taken for the EcorePlugin's. I suppose I'd need to declare a dependency for OSGi to find the necessary Equinox bundle, but I suppose that should be optional. Not sure what to do... I'll try to find time this week to try out your tests.
(In reply to Mikael Barbero from comment #61) > > Extension processing does work stand alone, via a call to > > org.eclipse.emf.ecore.plugin.EcorePlugin.ExtensionProcessor. > > process(ClassLoader), but that does have Equinox dependencies, though given > > those dependencies also work stand alone, maybe those bundles also work in > > other OSGi runtime environments... > > Actually the ExtensionProcessor should not be needed in any other OSGi > environment as the Equinox registry should be usable in any other OSGi > environment (AFAIK). Yes, the equinox extension registry should be usable in other OSGi environments/frameworks. You would need the following bundles: org.eclipse.equinox.supplement org.eclipse.equinox.common org.eclipse.equinox.registry Given that you are trying to reduce dependencies it may still be a good idea to avoid a hard requirement on the equinox extension registry.
Created attachment 242945 [details] Test project for EMF in Concierge
(In reply to comment #60 https://bugs.eclipse.org/bugs/show_bug.cgi?id=328227#c60) > Jochen, > How can I test this Concierge thing locally myself? Hi Ed, I just added now the current test project where I am running EMF tests against Concierge. Thanks to comment from Mikael Barbero, I extended the test case to check if EMF is working within Concierge. Until now it looks like OK, I was able to use the EMF example with an own test bundle (at least the first parts of it). Note: I used the EMF-Examples bundle from Mikaels project, as the EMF one does have a Require-Bundle to org.eclipse.core.runtime, which does not work with Concierge. This should be fixed too, but maybe we need some systematic search for similar dependencies. To run the tests: - unpack test-project.zip (will unpack to org.eclipse.concierge) - import as project into Eclipse - Run the tests in ./test/org/eclipse/concierge/test/EclipseEMFTest.java (4 are green, the Xtext test case fails due to missing Import-Package in Xtext Manifest) - the bundles which are installed into Concierge are located in ./test/plugins - If you want to use your bundle, either copy the jar into this folder, and adapt JAR name in test case - or install JAR from your workspace location (I do not know whether it can be installed from directory) - you can simply debug from test case into Concierge framework or your bundles as complete code is included > Given that Throwable is caught and then ignored, what's "logging" the stack traces with Concierge? Good point: given the stacktrace I think Concierge will log that in BundleImpl.findOwnClass(), line 2822, handling a LinkageError exception to indicate problems loading classes.
Jochen, It's a bit painful to work with this because to test changes I must export the jars but the names of the jars are hard-coded into the tests... In any case, the circularity errors look to be more like a bug in the Concierge class loader. I made some changes in emf.common to try to eliminate such an error but then looking at emf.ecore I see it kicks of the activation process by loading org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator at BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 that gets to the point of wanting to load org.eclipse.emf.common.EMFPlugin$OSGiDelegatingBundleActivator at BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.requireBundleLookup(String, String, boolean, boolean, Vector<URL>, Set<Bundle>) line: 2991 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2588 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean) line: not available [native method] BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClassCond(String, byte[], int, int, ProtectionDomain, boolean) line: 631 BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 615 BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 That of course works fine too, but then it gets to BundleImpl$JarBundleRevision(BundleImpl$Revision).checkActivationChain(Object) line: 2281 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2591 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean) line: not available [native method] BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClassCond(String, byte[], int, int, ProtectionDomain, boolean) line: 631 BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 615 BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 Stepping from there we get to BundleImpl.activate0() line: 465 BundleImpl.triggerActivation() line: 853 BundleImpl$JarBundleRevision(BundleImpl$Revision).checkActivationChain(Object) line: 2281 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2591 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean) line: not available [native method] BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClassCond(String, byte[], int, int, ProtectionDomain, boolean) line: 631 BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 615 BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 which tries to load org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator again. But clearly there's something wrong with logic that tries to load org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator again because that gets us to BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 BundleImpl.triggerActivation() line: 853 BundleImpl$JarBundleRevision(BundleImpl$Revision).checkActivationChain(Object) line: 2281 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2591 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, boolean) line: not available [native method] BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClassCond(String, byte[], int, int, ProtectionDomain, boolean) line: 631 BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClass(String, byte[], int, int, ProtectionDomain) line: 615 BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, boolean, Vector<URL>) line: 2600 BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, boolean) line: 2550 BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 BundleImpl.activate0() line: 466 and at this point, yes, there is a circular attempt to load the org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator but it's triggered by Concierge itself by something apparently-not-quite-right in checkActivationChain. I.e., I think that any Activator that extends another Activator implementation class rather than purely implementing the org.osgi.framework.BundleActivator interface will produce this same circularity error. Given this late stage in EMF's release cycle, I feel I must defer any further changes to support pure OSGi compatibility for the maintenance stream or the next release. Please open a new bugzilla to track any further changes needed in EMF itself to support Concierge. Mikael, The same "defer" comment applies for adding support for using the Equinox registry. I'm quite sure it should be possible to optionally import and packages for the Equinox registry processor and optionally use that to do plugin.xml registration processing so that both emf.ecore and emf.edit's registrations work as normal when the Equinox registry is deployed along with EMF's core bundles. As for Jochen, please open a new bugzilla to track any further changes needed in EMF itself to support Felix, in particular for this optional extension registry support.
(In reply to Ed Merks from comment #66) > which tries to load > org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator again. > > But clearly there's something wrong with logic that tries to load > org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator again > because that gets us to > > BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 > BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, > boolean, Vector<URL>) line: 2600 > BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, > boolean) line: 2550 > BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 > BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 > BundleImpl.activate0() line: 466 > BundleImpl.triggerActivation() line: 853 > BundleImpl$JarBundleRevision(BundleImpl$Revision). > checkActivationChain(Object) line: 2281 > BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, > boolean, Vector<URL>) line: 2591 > BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, > boolean) line: 2550 > BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 > BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 > ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain, String, > boolean) line: not available [native method] > BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClassCond(String, > byte[], int, int, ProtectionDomain, boolean) line: 631 > BundleImpl$Revision$BundleClassLoader(ClassLoader).defineClass(String, > byte[], int, int, ProtectionDomain) line: 615 > BundleImpl$Revision$BundleClassLoader.findOwnClass(String) line: 2816 > BundleImpl$Revision$BundleClassLoader.findResource1(String, String, boolean, > boolean, Vector<URL>) line: 2600 > BundleImpl$Revision$BundleClassLoader.findResource0(String, String, boolean, > boolean) line: 2550 > BundleImpl$Revision$BundleClassLoader.findClass(String) line: 2368 > BundleImpl$Revision$BundleClassLoader.loadClass(String) line: 2350 > BundleImpl.activate0() line: 466 > > and at this point, yes, there is a circular attempt to load the > org.eclipse.emf.ecore.plugin.EcorePlugin$Implementation$Activator but it's > triggered by Concierge itself by something apparently-not-quite-right in > checkActivationChain. I.e., I think that any Activator that extends another > Activator implementation class rather than purely implementing the > org.osgi.framework.BundleActivator interface will produce this same > circularity error. > If I read you analysis correctly, it appears Concierge is attempting to lazy activate bundles while in the middle of a ClassLoader.defineClass call. The specification mandates that the lazy activated bundles get added to a stack which are encountered during a defineClass call and then after defineClass has completed the stack of lazy activated bundles should be activated. Here is the text from the spec <spec> When a class load triggers the lazy activation, the Framework must first define the triggering class. This definition can trigger additional lazy activations. These activations must be deferred until all transitive class loads and defines have finished. Thereafter, the activations must be executed in the reverse order of detection. That is, the last detected activation must be executed first. Only after all deferred activations are finished must the class load that triggered the activation return with the loaded class. </spec>
> If I read you analysis correctly, it appears Concierge is attempting to lazy > activate bundles while in the middle of a ClassLoader.defineClass call. The > specification mandates that the lazy activated bundles get added to a stack > which are encountered during a defineClass call and then after defineClass has > completed the stack of lazy activated bundles should be activated. It's lazy activating emf.ecore's activtor, loading the activator, recognizing that the base class from emf.common is needed, which loads properly, without circularity, and when it comes back, it tries to activate emf.ecore's bundle again? Why? So my assertion is, with Concierge, a bundle's Activator cannot have a base class or it will be diagnosed as circular. > When a class load triggers the lazy activation, the Framework must first define > the triggering class. I.e., emf.ecore's Activator. > This definition can trigger additional lazy activations. I.e., emf.common has the base class for the emf.ecore's activator. > These activations must be deferred until all transitive class loads and defines have finished. So emf.common finishes properly that bundle can load without circularity so that is finished and loaded. > Thereafter, the activations must be executed in the reverse > order of detection. So emf.common must be activated first. > That is, the last detected activation must be executed first. Yep, emf.common must activate before emf.ecore. > Only after all deferred activations are finished must the class load > that triggered the activation return with the loaded class. Yes, but it fails to do that. It decided that rather than returning the class it's in the process of defining, that it's circular because it tries to define it again ad part of some check that does not appear applicable according to the text you quote from the specification. Note that I had the same problem in emf.common when emf.common's Activator extends org.eclipse.emf.common.EMFPlugin.OSGiDelegatingBundleActivator. Again, I fail to see a circularity here. From what I see in the code, any BundleActivator implementation with a base class, will fail into this same pit, regardless of where the base class comes from. It's of course important to note that neither Equinox nor Felix diagnose a circularity problem, and both claim to be OSGi implementations...
The changes are available in the latest release.
I've been working on updating the CBI aggregator's support for Maven publishing to take package imports into account when generating dependencies in the POM. Does anyone foresee a problem with making the package import of org.osgi.framework optional? I want ensure that the corresponding Maven dependency for this too is optional...
(In reply to Ed Merks from comment #70) > I've been working on updating the CBI aggregator's support for Maven > publishing to take package imports into account when generating dependencies > in the POM. > > Does anyone foresee a problem with making the package import of > org.osgi.framework optional? I want ensure that the corresponding Maven > dependency for this too is optional... I've no idea how to answer that. Are they really optional? On the other hand, it is hard for me to imagine a bundle even existing in a framework that does not have the org.osgi.framework package. So in that regard perhaps the question of optionality doesn't matter because the package will always be there (except it could be at a different version.