Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Equinox » Equinox hooks removed in Luna
Equinox hooks removed in Luna [message #1442031] Fri, 10 October 2014 14:20 Go to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
hello,
we are migrating from Eclipse 3.6 to E4.4 (yes..., I know).
We have implemented an equinox hook (org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook) to override the inner jar class loading mechanism to use jars outside the bundle in our own jar libraries manager (a maven like repo).

but reading this (and noticing it cause it does not compile anymore), the old equinox hooks have been removed.
I am not sure that I can achieve what I want with the OSGI hooks and this page mentioned above does not give any pointer.
does anyone have an idea on how to acheive my goal with the OSGI hooks ?
Is the org.osgi.framework.hooks.resolver.ResolverHook this right one ?

Thanks for any hints.

SeB.
Re: Equinox hooks removed in Luna [message #1442089 is a reply to message #1442031] Fri, 10 October 2014 15:49 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
I'm not sure what methods of the old org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook you are implementing. But most (if not all) things you could accomplish with that old interface is now available with extending the abstract class org.eclipse.osgi.internal.hookregistry.ClassLoaderHook

I imagine you would using something like the following method to add additional classpath entries.
org.eclipse.osgi.internal.hookregistry.ClassLoaderHook.addClassPathEntry(ArrayList<ClasspathEntry>, String, ClasspathManager, Generation)

Please note that we put the hooks in an 'internal' package. This is to make implementors more aware that this is an mechanism we are providing to framework extensions that exposes internal implementation details. While we don't intent to break equinox adaptor hook implementations each release we do need the freedom to do so from time to time.
Re: Equinox hooks removed in Luna [message #1442104 is a reply to message #1442089] Fri, 10 October 2014 16:13 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Thank you for this very quick answer.

Do you think I could use OSGI hooks do intercept the Class-Path directive resolution to point to jar that are externally provided by some other mechanism such as maven repos ?

Thanks.
Re: Equinox hooks removed in Luna [message #1442136 is a reply to message #1442104] Fri, 10 October 2014 17:15 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
I would imagine so. How are you doing it with the old hooks?

You should be able to do something like the DevClassLoadingHook does for supporting loading bundles out of the workspace for self-hosting:

http://git.eclipse.org/c/equinox/rt.equinox.framework.git/tree/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hooks/DevClassLoadingHook.java?id=I20141008-1300#n35

The trick is to use the org.eclipse.osgi.internal.loader.classpath.ClasspathManager.getExternalClassPath(String, Generation)

Where the passed in String is an absolute path to the jar you want to create a ClasspathEntry for the generation is the Generation object that represents the bundle where you got the Bundle-ClassPath from. So you can invent your own classpath prefix (e.g. mvn: that tells you how to lookup the jar:

Bundle-ClassPath: mvn:someMavenThing1, mvn:someMavenThing2

Note that the framework must have a local jar file to work with so you need to get that locally somehow.
Re: Equinox hooks removed in Luna [message #1443815 is a reply to message #1442136] Mon, 13 October 2014 08:37 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Thanks for the info,
today we are just checking the jar is present or missing and if missing we retrieve it. We do not use any specific prefix (yet).
The thing is that you are still using internal packages, and I'd like to use the standard OSGI APIs.
I'll try first the standard way and if I get stuck I'll use the internal equinox APIs (reluctantly Wink ).
Re: Equinox hooks removed in Luna [message #1443941 is a reply to message #1443815] Mon, 13 October 2014 12:39 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
To use Standard OSGi APIs you would need to create a bundle on the fly by pulling in the content from maven locally and construct the bundle jar with content you get from maven embedded directly in the bundle.
Re: Equinox hooks removed in Luna [message #1443971 is a reply to message #1443941] Mon, 13 October 2014 13:38 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Ok I' think I'll use the org.eclipse.osgi.internal.hookregistry.ClassLoaderHook, the main method I was using is the addClassPathEntry which is still there.

I have one more question though, how can I get the bundleContext from my "org.eclipse.osgi.internal.hookregistry.HookConfigurator" implementation because I need to register an OSGI service (the class lies in a org.eclipse.osgi fragment).
In my previous implementation I was registering an AdaptorHook which does not exist anymore ?

[Updated on: Mon, 13 October 2014 13:39]

Report message to a moderator

Re: Equinox hooks removed in Luna [message #1443990 is a reply to message #1443971] Mon, 13 October 2014 14:06 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
There is a standard way to do this now with the header ExtensionBundle-Activator which specifies a BundleActivator for you framework extension fragement. For example, the following is used by equinox regions:

ExtensionBundle-Activator: org.eclipse.equinox.internal.region.RegionManager
Re: Equinox hooks removed in Luna [message #1444057 is a reply to message #1443990] Mon, 13 October 2014 15:25 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Thanks a lot for this last tip, my Activator get called and I can register my service from my fragment of org.eclipse.osgi bundle.
But my framework extension does not get loaded.
I launch an "OSGI Framework" launch config from eclipse, with my fragment (org.talend.osgi.lib.loader) along with the org.eclipse.osgi bundle in my workspace.
I specify the following vm arg :
-Dosgi.framework.extensions=org.talend.osgi.lib.loader

and my bundle contains a root file called hookconfigurators.properties, like before, and it is declaring my HookConfigurator implementation.

When I launch my configuration (of type OSGI Framework) it calls the Activator that I specified thanks to your above tip, and then I get
!ENTRY org.eclipse.osgi 4 0 2014-10-13 17:21:17.987
!MESSAGE Bundle org.talend.osgi.lib.loader not found.


I wanted to try to change the start level from the launch config but this is not possible for fragments. I am a bit confused now....
Re: Equinox hooks removed in Luna [message #1444072 is a reply to message #1444057] Mon, 13 October 2014 15:40 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Forget my previous issue, my project was imported and not copied in the workspace, this is why I had some trouble.
Thank for you answers, I'll be able to test everything now and it should be ok.
Re: Equinox hooks removed in Luna [message #1444552 is a reply to message #1444072] Tue, 14 October 2014 08:15 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Thank you Thomas, you helped me a lot.
One more comment, the Activator of my fragment gets called after the HookAdaptor and even my hook get called, this means my classes in my fragment gets instantiated before the activator get called.
I kind of see that as an bug because the usual OSGI lifecycle is calling the Activator before any class get instantiated. But I know this is a Fragment so I guess it could behave differently ?
What do you think about this.
Re: Equinox hooks removed in Luna [message #1444705 is a reply to message #1444552] Tue, 14 October 2014 12:41 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
This is not a bug. The hooks need to provide functionality before even the framework has created a valid BundleContext for the system bundle (for which the extension is a fragment of. The activator is a way for the hook to get plug'ed into the lifecycle of the system bundle's context. I don't think this is any different than the hooks from previous releases. I am fairly certain the hook that got the BundleContext of the system bundle could be called after calling methods on other hooks.
Re: Equinox hooks removed in Luna [message #1444782 is a reply to message #1444705] Tue, 14 October 2014 14:47 Go to previous messageGo to next message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
Ok I got it.
I have another problem.
In 3.6, the hook was called when the one of the class or resource was being loaded in the inner jar, or I just discovered that in 4.4 that my hook gets called during some early OSGI initialization phase, where it is looking for some i18n resource :
OSGI-INF/l10n/bundle.properties
.
The thing is that I really need to know in my hook that it is called from our actual code activation and not some internal resolution ?
My hook eventually ask the user to accept some license before downloading the library and should therefore be delayed when the actual inner jar is needed to be used.
I have tried to create the searched file (OSGI-INF/l10n/bundle.properties) but the hook gets called anyway.
Do you have any idea ?
Thanks.


here is the stack trace
	org.talend.osgi.hook.JarLoaderClassLoadingHook.addClassPathEntry(java.util.ArrayList<org.eclipse.osgi.internal.loader.classpath.ClasspathEntry>, java.lang.String, org.eclipse.osgi.internal.loader.classpath.ClasspathManager, org.eclipse.osgi.storage.BundleInfo.Generation) line: 92	
	org.eclipse.osgi.internal.loader.classpath.ClasspathManager.findClassPathEntry(java.util.ArrayList<org.eclipse.osgi.internal.loader.classpath.ClasspathEntry>, java.lang.String, org.eclipse.osgi.internal.loader.classpath.ClasspathManager, org.eclipse.osgi.storage.BundleInfo.Generation) line: 173	
	org.eclipse.osgi.internal.loader.classpath.ClasspathManager.buildClasspath(java.lang.String[], org.eclipse.osgi.internal.loader.classpath.ClasspathManager, org.eclipse.osgi.storage.BundleInfo$Generation) line: 154	
	org.eclipse.osgi.internal.loader.classpath.ClasspathManager.<init>(org.eclipse.osgi.storage.BundleInfo$Generation, org.eclipse.osgi.internal.loader.ModuleClassLoader) line: 83	
	org.eclipse.osgi.internal.loader.EquinoxClassLoader.<init>(java.lang.ClassLoader, org.eclipse.osgi.internal.framework.EquinoxConfiguration, org.eclipse.osgi.internal.loader.BundleLoader, org.eclipse.osgi.storage.BundleInfo$Generation) line: 57	
	org.eclipse.osgi.internal.loader.BundleLoader.createClassLoaderPrivledged(java.lang.ClassLoader, org.eclipse.osgi.internal.framework.EquinoxConfiguration, org.eclipse.osgi.internal.loader.BundleLoader, org.eclipse.osgi.storage.BundleInfo.Generation, java.util.List<org.eclipse.osgi.internal.hookregistry.ClassLoaderHook>) line: 268	
	org.eclipse.osgi.internal.loader.BundleLoader.getModuleClassLoader() line: 225	
	org.eclipse.osgi.internal.loader.BundleLoader.findEntries(java.lang.String, java.lang.String, int) line: 761	
	org.eclipse.osgi.container.ModuleWiring.findEntries(java.lang.String, java.lang.String, int) line: 285	
	org.eclipse.osgi.storage.ManifestLocalization.findResource(java.lang.String) line: 183	
	org.eclipse.osgi.storage.ManifestLocalization.lookupResourceBundle(java.lang.String) line: 126	
	org.eclipse.osgi.storage.ManifestLocalization.getResourceBundle(java.lang.String, boolean) line: 102	
	org.eclipse.osgi.storage.BundleInfo$Generation.getResourceBundle(java.lang.String) line: 133	
	org.eclipse.osgi.storage.BundleLocalizationImpl.getLocalization(org.osgi.framework.Bundle, java.lang.String) line: 40	
	org.eclipse.core.internal.runtime.Activator.getLocalization(org.osgi.framework.Bundle, java.lang.String) line: 241	
	org.eclipse.core.internal.runtime.ResourceTranslator.getResourceBundle(org.osgi.framework.Bundle, java.lang.String) line: 69	
	org.eclipse.core.internal.runtime.ResourceTranslator.getResourceBundle(org.osgi.framework.Bundle) line: 61	
	org.eclipse.core.internal.registry.osgi.EclipseBundleListener.addBundle(org.osgi.framework.Bundle, boolean) line: 174	
	org.eclipse.core.internal.registry.osgi.EclipseBundleListener.processBundles(org.osgi.framework.Bundle[]) line: 90	
	org.eclipse.core.internal.registry.osgi.EquinoxRegistryStrategy(org.eclipse.core.internal.registry.osgi.RegistryStrategyOSGI).onStart(org.eclipse.core.runtime.IExtensionRegistry, boolean) line: 224	
	org.eclipse.core.internal.registry.ExtensionRegistry.<init>(org.eclipse.core.runtime.spi.RegistryStrategy, java.lang.Object, java.lang.Object) line: 725	
	org.eclipse.core.runtime.RegistryFactory.createRegistry(org.eclipse.core.runtime.spi.RegistryStrategy, java.lang.Object, java.lang.Object) line: 58	
	org.eclipse.core.internal.registry.osgi.Activator.startRegistry() line: 137	
	org.eclipse.core.internal.registry.osgi.Activator.start(org.osgi.framework.BundleContext) line: 56	
Re: Equinox hooks removed in Luna [message #1444817 is a reply to message #1444782] Tue, 14 October 2014 15:40 Go to previous messageGo to next message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 486
Registered: July 2009
Senior Member
The ClasspathManager.<init> method is getting called in response to needing to create a bundle class loader. It is responsible for building the complete classpath of the bundle class loader. I'm not sure how this behavior could have changed from the pre 4.4 version. The eclipse extension registry is calling a localization service (BundleLocalizationImpl) which essentially does the a resource load of the osgi file OSGI-INF/l10n/bundle.properties from the bundle. This requests leads to the need to create the classloader of the bundle to find the resource.

Actually I just realized the difference in behavior. The BundleWiring.findEntries now aggressively creates class loaders in Luna (4.4) https://bugs.eclipse.org/bugs/show_bug.cgi?id=403657.
I don't have a good suggestion at this point on how to prevent that from happening.

It would be complicated, but you could implement org.eclipse.osgi.internal.hookregistry.BundleFileWrapperFactoryHook which allows you to intercept calls to a BundleFile. When looking for ClassPathEntry from addClassPathEntry you would have to use a 'dummy' jar file as the base bundle file 'cp' when calling ClasspathManager.getExternalClassPath(String, Generation). Then in your wrapper you would postpone any license questions until the first request for an entry.
Re: Equinox hooks removed in Luna [message #1448898 is a reply to message #1444817] Mon, 20 October 2014 15:54 Go to previous message
Sébastien  Gandon is currently offline Sébastien GandonFriend
Messages: 184
Registered: July 2009
Senior Member
I did manage to only use the BundleFileWrapperFactoryHook, and avoid creating a 'dummy' jar file, that seemed to much and too time consuming for loading many bundles.
I finally used the WrappedBundleFile.getEntry() instead of the getFile() because the file returned is checked for existence and not the BundleEntry returned by the getEntry().
I you are interested, the implementation can be found here : https://github.com/Talend/tcommon-studio-se/blob/51fe5eb893a16bcc162632caaa3eb7d8c5abc24d/main/plugins/org.talend.osgi.lib.loader/src/org/talend/osgi/hook/JarLoaderBundleFileWrapperFactory.java

By the way I think creating the Classloader aggressively even when the bundle is not active seems to me a bad behavior because it does not fit the lazy loading strategy adopted everywhere in eclipse, I am afraid it also increase the time to load the application as well as increasing the memory consumption for bundles that may never be activated. I would suggest you re-open the bugzilla you have created for that.

I thank you for all your help.
Previous Topic:Fooling Equinox......
Next Topic:NoClassDefFoundError if class is accessed second time
Goto Forum:
  


Current Time: Wed Sep 19 08:41:06 GMT 2018

Powered by FUDForum. Page generated in 0.02524 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top