You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Nicolas Lalevée <ni...@hibnet.org> on 2013/09/01 17:31:36 UTC

OSGi-aware resource loading

Hi,

Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?

If it's not clear, here is my context.

I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.

At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.

Here is what I have manage to do so far but I find it not pretty:

    URL buildUrl = currentClassLoader.getResource(buildFile);
    ClassLoader buildClassLoader = null;
    for (Bundle bundle : allBundles) {
        BundleWiring wiring = bundle.adapt(BundleWiring.class);
        int i = buildFile.lastIndexOf('/');
        String path = buildFile.substring(0, i);
        String name = buildFile.substring(i + 1);
        List<URL> entries = wiring.findEntries(path, name, 0);
        if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
            buildClassLoader = wiring.getClassLoader();
            break;
        }
    }
    if (buildClassLoader == null) {
        throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
    }

It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.

Nicolas


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 3 sept. 2013 à 12:49, Robert Munteanu <ro...@lmn.ro> a écrit :

> On Tue, Sep 3, 2013 at 1:42 AM, Nicolas Lalevée
> <ni...@hibnet.org> wrote:
>> 
>> Le 2 sept. 2013 à 18:15, Murad Mamedov <ma...@muradm.net> a écrit :
>> 
>>> Hello, I'm newbie here, but using OSGi for long time.
>>> 
>>> From my understanding of your problem:
>>> - you expect some bundles to have build.xml
>>> - you are a build system that does somethings with those bundles.
>>> If above is true, I would start BundleListener and listen bundle events. Of
>>> course, on startup of build system you will need to get the initial list of
>>> bundles your self.
>>> Once BundleListener gets event on installed bundle, I would check if it is
>>> my bundle (has build.xml for example) and keep it in private map (ex:
>>> taskName -> Bundle).
>>> This will be faster and more dynamic, better than traversing over bundles
>>> every time.
>> 
>> The thing is that I don't expect a "build" bundle to only have a build.xml at a precise location. I could be anywhere, named in any way. For instance there can be a bundle in which there would be a common-build-java.xml and a common-build-resources.xml, in anther bundle a common-build-webapp.xml which is importing the former ones, and my main build.xml is just importing the later one.
> 
> You could add them to the manifest of the providing bundle, using the
> Provide-Capability header [1], for instance
> 
> Provide-Capability: build.file; location=/common-build-java.xml

I like this header. But since here I manage files and not abstract concept, I can stick with the Import/Export Package headers. This would just require the common build files to be in their custom packages, just like Java classes.

Nicolas

> 
> Robert
> 
> 
>> 
>> I would really like the build files to behave like Java classes in this OSGi environment.
>> 
>>> But I'm still not sure if you can access actual ClassLoader of that bundle
>>> even if you have it and for example instantiate some class from there.
>>> You have to depend (import somethings from it) on that bundle, but as far
>>> as I understand you expect unknown user ant tasks to be around in unknown
>>> user bundles.
>>> Is it possible to get actual class loader of some bundle and do something
>>> with it?
>> 
>> Well, I don't need a classloader per se. To make a build file load an Ant task, I need something to load a class, so Bundle#loadClass() is fine. And to make a build file import another one, I need something to load a resource, so Bundle#findEntries() is fine too.
> 
> [1]: http://wiki.osgi.org/wiki/Provide-Capability
> 
>> 
>>> Using services could be a better option for this problem in my opinion.
>> 
>> Could you elaborate on that ? I know a little bit about services but not enough to understand what kind of solution you are thinking of.
>> 
>> cheers,
>> Nicolas
>> 
>>> 
>>> Regards,
>>> Murad
>>> 
>>> 
>>> 
>>> On Mon, Sep 2, 2013 at 5:59 PM, Nicolas Lalevée
>>> <ni...@hibnet.org>wrote:
>>> 
>>>> 
>>>> Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a
>>>> écrit :
>>>> 
>>>>> I think it would be a bad idea to rely on an URI scheme. After all it is
>>>> not specified in the OSGi standard.
>>>>> Can't you simply forward the bundle or classloader together with the URL?
>>>> 
>>>> The URL is pointing to a build file which I want to "run" within its
>>>> bundle just like a java class would do. When running it will probably need
>>>> to load resources, and I want this loading to follow the OSGi visibility
>>>> rules. So I would need the classloader which "owns" that resource, and I
>>>> don't have it, the OSGi framework has.
>>>> 
>>>> Nicolas
>>>> 
>>>>> 
>>>>> Christian
>>>>> 
>>>>> On 02.09.2013 10:13, Nicolas Lalevée wrote:
>>>>>> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a
>>>> écrit :
>>>>>> 
>>>>>>> I'm pretty sure this isn't possible for resources, like it is for
>>>> classes.
>>>>>>> 
>>>>>>> The OSGi spec doesn't mandate the format of bundle resource URLs,
>>>> which is what you would need if you wanted to determine from which bundle a
>>>> looked up resource comes.
>>>>>>> 
>>>>>>> Not sure about other frameworks, but this is fairly easy to determine
>>>> from a resource URL in the Felix framework, since this host is the bundle
>>>> id + revision id.
>>>>>> I can do an if(felix) in my code to optimize. In the long term can I
>>>> rely on this URL scheme ?
>>>>>> 
>>>>>> Nicolas
>>>>>> 
>>>>>> 
>>>>>>> -> richard
>>>>>>> 
>>>>>>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>>>>>>> Hi,
>>>>>>>> 
>>>>>>>> Maybe my issue has already been addressed several time, so here is
>>>> the actual question: how can I get the bundle/classloader which *owns* the
>>>> URL which I looked up through classloader.getResource(file) ?
>>>>>>>> 
>>>>>>>> If it's not clear, here is my context.
>>>>>>>> 
>>>>>>>> I am experimenting a build system where some Ant build files and Ant
>>>> task would be managed like as OSGi bundles. So I can do a modularisation of
>>>> build files and jars of Ant Tasks.
>>>>>>>> 
>>>>>>>> At some point a build file (within a bundle) will have to load some
>>>> other Ant script (through the bundle wiring). For that I simply get the
>>>> classloader of the current classloader and do a
>>>> classloader.getResource("/path/other/build.xml"). So far so good.
>>>>>>>> But when running that other build file, I would need its classloader
>>>> to do some other import of build.xml file. But I only have the resolved
>>>> URL, not the bundle which is containing the resolved script. Which java
>>>> code, it's simple, from the resolved class I can get its classloader. But I
>>>> cannot do that for a script which as been resolved as an URL.
>>>>>>>> 
>>>>>>>> Here is what I have manage to do so far but I find it not pretty:
>>>>>>>> 
>>>>>>>>   URL buildUrl = currentClassLoader.getResource(buildFile);
>>>>>>>>   ClassLoader buildClassLoader = null;
>>>>>>>>   for (Bundle bundle : allBundles) {
>>>>>>>>       BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>>>>>>       int i = buildFile.lastIndexOf('/');
>>>>>>>>       String path = buildFile.substring(0, i);
>>>>>>>>       String name = buildFile.substring(i + 1);
>>>>>>>>       List<URL> entries = wiring.findEntries(path, name, 0);
>>>>>>>>       if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>>>>>>           buildClassLoader = wiring.getClassLoader();
>>>>>>>>           break;
>>>>>>>>       }
>>>>>>>>   }
>>>>>>>>   if (buildClassLoader == null) {
>>>>>>>>       throw new RuntimeException("WTF! Unable to find the
>>>> classloader of the build file " + buildFile);
>>>>>>>>   }
>>>>>>>> 
>>>>>>>> It is working but it doesn't sound nice. Is there an API I didn't
>>>> found which allows to look for a resource and its bundle or classloader ? I
>>>> would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>>>>>> 
>>>>>>>> Nicolas
>>>>>>>> 
>>>>>>>> 
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>> 
>>>>>>> 
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>> 
>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>> 
>>>>> 
>>>>> 
>>>>> --
>>>>> Christian Schneider
>>>>> http://www.liquid-reality.de
>>>>> 
>>>>> Open Source Architect
>>>>> http://www.talend.com
>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
> 
> 
> 
> -- 
> Sent from my (old) computer
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Robert Munteanu <ro...@lmn.ro>.
On Tue, Sep 3, 2013 at 1:42 AM, Nicolas Lalevée
<ni...@hibnet.org> wrote:
>
> Le 2 sept. 2013 à 18:15, Murad Mamedov <ma...@muradm.net> a écrit :
>
>> Hello, I'm newbie here, but using OSGi for long time.
>>
>> From my understanding of your problem:
>> - you expect some bundles to have build.xml
>> - you are a build system that does somethings with those bundles.
>> If above is true, I would start BundleListener and listen bundle events. Of
>> course, on startup of build system you will need to get the initial list of
>> bundles your self.
>> Once BundleListener gets event on installed bundle, I would check if it is
>> my bundle (has build.xml for example) and keep it in private map (ex:
>> taskName -> Bundle).
>> This will be faster and more dynamic, better than traversing over bundles
>> every time.
>
> The thing is that I don't expect a "build" bundle to only have a build.xml at a precise location. I could be anywhere, named in any way. For instance there can be a bundle in which there would be a common-build-java.xml and a common-build-resources.xml, in anther bundle a common-build-webapp.xml which is importing the former ones, and my main build.xml is just importing the later one.

You could add them to the manifest of the providing bundle, using the
Provide-Capability header [1], for instance

Provide-Capability: build.file; location=/common-build-java.xml

Robert


>
> I would really like the build files to behave like Java classes in this OSGi environment.
>
>> But I'm still not sure if you can access actual ClassLoader of that bundle
>> even if you have it and for example instantiate some class from there.
>> You have to depend (import somethings from it) on that bundle, but as far
>> as I understand you expect unknown user ant tasks to be around in unknown
>> user bundles.
>> Is it possible to get actual class loader of some bundle and do something
>> with it?
>
> Well, I don't need a classloader per se. To make a build file load an Ant task, I need something to load a class, so Bundle#loadClass() is fine. And to make a build file import another one, I need something to load a resource, so Bundle#findEntries() is fine too.

[1]: http://wiki.osgi.org/wiki/Provide-Capability

>
>> Using services could be a better option for this problem in my opinion.
>
> Could you elaborate on that ? I know a little bit about services but not enough to understand what kind of solution you are thinking of.
>
> cheers,
> Nicolas
>
>>
>> Regards,
>> Murad
>>
>>
>>
>> On Mon, Sep 2, 2013 at 5:59 PM, Nicolas Lalevée
>> <ni...@hibnet.org>wrote:
>>
>>>
>>> Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a
>>> écrit :
>>>
>>>> I think it would be a bad idea to rely on an URI scheme. After all it is
>>> not specified in the OSGi standard.
>>>> Can't you simply forward the bundle or classloader together with the URL?
>>>
>>> The URL is pointing to a build file which I want to "run" within its
>>> bundle just like a java class would do. When running it will probably need
>>> to load resources, and I want this loading to follow the OSGi visibility
>>> rules. So I would need the classloader which "owns" that resource, and I
>>> don't have it, the OSGi framework has.
>>>
>>> Nicolas
>>>
>>>>
>>>> Christian
>>>>
>>>> On 02.09.2013 10:13, Nicolas Lalevée wrote:
>>>>> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a
>>> écrit :
>>>>>
>>>>>> I'm pretty sure this isn't possible for resources, like it is for
>>> classes.
>>>>>>
>>>>>> The OSGi spec doesn't mandate the format of bundle resource URLs,
>>> which is what you would need if you wanted to determine from which bundle a
>>> looked up resource comes.
>>>>>>
>>>>>> Not sure about other frameworks, but this is fairly easy to determine
>>> from a resource URL in the Felix framework, since this host is the bundle
>>> id + revision id.
>>>>> I can do an if(felix) in my code to optimize. In the long term can I
>>> rely on this URL scheme ?
>>>>>
>>>>> Nicolas
>>>>>
>>>>>
>>>>>> -> richard
>>>>>>
>>>>>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> Maybe my issue has already been addressed several time, so here is
>>> the actual question: how can I get the bundle/classloader which *owns* the
>>> URL which I looked up through classloader.getResource(file) ?
>>>>>>>
>>>>>>> If it's not clear, here is my context.
>>>>>>>
>>>>>>> I am experimenting a build system where some Ant build files and Ant
>>> task would be managed like as OSGi bundles. So I can do a modularisation of
>>> build files and jars of Ant Tasks.
>>>>>>>
>>>>>>> At some point a build file (within a bundle) will have to load some
>>> other Ant script (through the bundle wiring). For that I simply get the
>>> classloader of the current classloader and do a
>>> classloader.getResource("/path/other/build.xml"). So far so good.
>>>>>>> But when running that other build file, I would need its classloader
>>> to do some other import of build.xml file. But I only have the resolved
>>> URL, not the bundle which is containing the resolved script. Which java
>>> code, it's simple, from the resolved class I can get its classloader. But I
>>> cannot do that for a script which as been resolved as an URL.
>>>>>>>
>>>>>>> Here is what I have manage to do so far but I find it not pretty:
>>>>>>>
>>>>>>>    URL buildUrl = currentClassLoader.getResource(buildFile);
>>>>>>>    ClassLoader buildClassLoader = null;
>>>>>>>    for (Bundle bundle : allBundles) {
>>>>>>>        BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>>>>>        int i = buildFile.lastIndexOf('/');
>>>>>>>        String path = buildFile.substring(0, i);
>>>>>>>        String name = buildFile.substring(i + 1);
>>>>>>>        List<URL> entries = wiring.findEntries(path, name, 0);
>>>>>>>        if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>>>>>            buildClassLoader = wiring.getClassLoader();
>>>>>>>            break;
>>>>>>>        }
>>>>>>>    }
>>>>>>>    if (buildClassLoader == null) {
>>>>>>>        throw new RuntimeException("WTF! Unable to find the
>>> classloader of the build file " + buildFile);
>>>>>>>    }
>>>>>>>
>>>>>>> It is working but it doesn't sound nice. Is there an API I didn't
>>> found which allows to look for a resource and its bundle or classloader ? I
>>> would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>>>>>
>>>>>>> Nicolas
>>>>>>>
>>>>>>>
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>
>>>>
>>>>
>>>> --
>>>> Christian Schneider
>>>> http://www.liquid-reality.de
>>>>
>>>> Open Source Architect
>>>> http://www.talend.com
>>>>
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>



-- 
Sent from my (old) computer

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Replying on users@, you probably mistakenly reply to me only

Le 3 sept. 2013 à 12:54, Murad Mamedov <ma...@muradm.net> a écrit :

> 
> 
> 
> On 09/03/2013 01:42 AM, Nicolas Lalevée wrote:
>> Le 2 sept. 2013 à 18:15, Murad Mamedov <ma...@muradm.net> a écrit :
>> 
>>> Hello, I'm newbie here, but using OSGi for long time.
>>> 
>>> From my understanding of your problem:
>>> - you expect some bundles to have build.xml
>>> - you are a build system that does somethings with those bundles.
>>> If above is true, I would start BundleListener and listen bundle events. Of
>>> course, on startup of build system you will need to get the initial list of
>>> bundles your self.
>>> Once BundleListener gets event on installed bundle, I would check if it is
>>> my bundle (has build.xml for example) and keep it in private map (ex:
>>> taskName -> Bundle).
>>> This will be faster and more dynamic, better than traversing over bundles
>>> every time.
>> The thing is that I don't expect a "build" bundle to only have a build.xml at a precise location. I could be anywhere, named in any way. For instance there can be a bundle in which there would be a common-build-java.xml and a common-build-resources.xml, in anther bundle a common-build-webapp.xml which is importing the former ones, and my main build.xml is just importing the later one.
>> 
>> I would really like the build files to behave like Java classes in this OSGi environment.
> As you might be aware Java classes behave a bit differently in OSGi environment compared to conventional Java Classpath.
> If we drop away *.xml stuff for a moment and look into normal classes:
> - Let's assume you have bundle A and bundle B. Your bundle A has no knowledge of classes/interfaces in bundle B and vice versa. Then in very simplistic case there is noway to do something like this from Bundle A:
> 
> for (Bundle b : bundleContext.getBundles())
> {
>  if (b.getSymbolicName().equals("aha this bundle i want"))
>  {
>    b.loadClass("this.class.i.want"); // load some class by string
>  }
> }
> 
> OSGi prevents such kind of usage. loadClass will be executed on ClassLoader of bundle A, and you will probably fail although that class may actually be in bundle B.

As far as I understand, this piece of code works. I admit that the loop is ugly, but the javadoc of Bundle#loadClass seems pretty straight forward to me: "Loads the specified class using this bundle's class loader."

> From bundle A you can use class/interface in bundle B only if you either:
> - directly import its package in manifest of bundle A (this effectively makes bundle A knowledgeable about class/interface located in some bundle B or C, effectively you don't have to do loadClass in this case, because you know that class)

That is what I am experimenting. If in a bundle there is a file in com/acme/common-build/build-java.xml, then this bundle will have to export the package com.acme.common-build. And if another build file requiring it should declare in its bundle's manifest an import of that package.

> - depend on some bundle C's interface that will be exported by bundle B as a service. in bundle A you may lookup for that service
> This behavior is natural to OSGi, as it is a kind of dependency management system that allows proper dependencies to interact with each other.
> loadClass method is bad practice from OSGi perspective.

Since I am working with a scripting engine (a build.xml doesn't execute itself, the real Java code running is Ant), at some point I have to use loadClass. My issue is to use it the OSGi way. So not doing loops like the one you show or mine in my first email.

> This is pretty basics of OSGi environment. I would suggest to write some sample bundles and experiment with it, also OSGi spec is good place to start.

I did and as far as I can tell it works, but I don't like the loops I am coding, so I am looking for better ways.

> 
>>> But I'm still not sure if you can access actual ClassLoader of that bundle
>>> even if you have it and for example instantiate some class from there.
>>> You have to depend (import somethings from it) on that bundle, but as far
>>> as I understand you expect unknown user ant tasks to be around in unknown
>>> user bundles.
>>> Is it possible to get actual class loader of some bundle and do something
>>> with it?
>> Well, I don't need a classloader per se. To make a build file load an Ant task, I need something to load a class, so Bundle#loadClass() is fine. And to make a build file import another one, I need something to load a resource, so Bundle#findEntries() is fine too.
>> 
>>> Using services could be a better option for this problem in my opinion.
>> Could you elaborate on that ? I know a little bit about services but not enough to understand what kind of solution you are thinking of.
> I'm not aware about your final intentions and I'm not much familiar with Ant, because I don't like it :)

That is an understandable mistake :)

> Storing ant build files in bundles looks weird to me, as I normally use build.xml or pom.xml to build the bundles. Smells like chicken/egg problem for me.
> If you wish to share more about your final goals, may be we can come up with some solution.

There would be a build.xml in your project, but every time you load an ant task or import a common-build.xml, it would have been retrieved from a remote repository (maven plugin like), and all that dependency and modularization of the build files would be managed in an OSGi environment.

Here is what I have come to do in my experiment when running of the command "ant build-jar".
First, provided that there is a list of bundles to load associated with the build.xml file, Ant would start an OSGi Framework and install all of the listed bundles. Ant would then parse and run the build.xml.

The root build.xml is a special case that I didn't think through. When it is importing an Ant task or another build file, it is just a lookup in every bundle to be known of. The root build.xml is not in a bundle, so for now I made it work by this simple lookup looping, I'll try to fix that as soon as simpler issues are resolved.

The nice thing as running in OSGi, an import of an Ant task is as easy as declaring its use: the transitive dependencies and the actual details of the implementation are handled earlier, not in the script importing it.

Then the case which triggered my initial question: an build file being imported by the root one, is itself importing another one. For instance common-build-webapp.xml is importing common-build-java.xml. And my problem is that when running common-build-webapp.xml, I don't know in which bundle it resides. So I cannot leverage the OSGi bundle bindings.


> If you wish to properly export Ant target or task from bundle B so that bundle A without knowing about existence of bundle B could execute them, you probably could define interfaces exported by bundle A like:
> 
> interface AntTarget {
>   Resource getTarget();
> }
> 
> interface AntTask {
>  void execute();
> }
> 
> Then let bundle B (C, D, E etc.) to import these interfaces from bundle A and implement them as many times as needed and export them as services (BundleContext#registerService).
> Since bundle A has now knowledge that somebody implements AntTarget and AntTask interfaces, it can lookup for them via BundleContext#getServiceReference() and get them with Bundle#getService() or better ServiceTracker.
> This way it complicates life on first sight, but on the other it makes it much simpler, however not always applicable for every case.
> 
> That is the main purpose of OSGi framework to isolate and resolve dependencies in controllable manner.
> There are more advanced and some extent easier to use facilities like declerative service blueprints etc. But they all are based on the above principle.

Thank you for the explanation, its more clear to me now.

The point is that I would like to avoid to write java code to expose a common-build.xml file. And as far as I understand using services requires it.
And I don't see how transitive dependencies are managed here. It seems to me that if a build file in bundle D require a build file in bundle G, I would have also to handle that manually via services.
With the usual Import/Export Pakage directive, it seems just straight forward.



BTW, thank you very much for your time answering me,
Nicolas

> 
> Regards,
> Murad
> 
> 
> 
>> 
>> cheers,
>> Nicolas
>> 
>>> Regards,
>>> Murad
>>> 
>>> 
>>> 
>>> On Mon, Sep 2, 2013 at 5:59 PM, Nicolas Lalevée
>>> <ni...@hibnet.org>wrote:
>>> 
>>>> Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a
>>>> écrit :
>>>> 
>>>>> I think it would be a bad idea to rely on an URI scheme. After all it is
>>>> not specified in the OSGi standard.
>>>>> Can't you simply forward the bundle or classloader together with the URL?
>>>> The URL is pointing to a build file which I want to "run" within its
>>>> bundle just like a java class would do. When running it will probably need
>>>> to load resources, and I want this loading to follow the OSGi visibility
>>>> rules. So I would need the classloader which "owns" that resource, and I
>>>> don't have it, the OSGi framework has.
>>>> 
>>>> Nicolas
>>>> 
>>>>> Christian
>>>>> 
>>>>> On 02.09.2013 10:13, Nicolas Lalevée wrote:
>>>>>> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a
>>>> écrit :
>>>>>>> I'm pretty sure this isn't possible for resources, like it is for
>>>> classes.
>>>>>>> The OSGi spec doesn't mandate the format of bundle resource URLs,
>>>> which is what you would need if you wanted to determine from which bundle a
>>>> looked up resource comes.
>>>>>>> Not sure about other frameworks, but this is fairly easy to determine
>>>> from a resource URL in the Felix framework, since this host is the bundle
>>>> id + revision id.
>>>>>> I can do an if(felix) in my code to optimize. In the long term can I
>>>> rely on this URL scheme ?
>>>>>> Nicolas
>>>>>> 
>>>>>> 
>>>>>>> -> richard
>>>>>>> 
>>>>>>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>>>>>>> Hi,
>>>>>>>> 
>>>>>>>> Maybe my issue has already been addressed several time, so here is
>>>> the actual question: how can I get the bundle/classloader which *owns* the
>>>> URL which I looked up through classloader.getResource(file) ?
>>>>>>>> If it's not clear, here is my context.
>>>>>>>> 
>>>>>>>> I am experimenting a build system where some Ant build files and Ant
>>>> task would be managed like as OSGi bundles. So I can do a modularisation of
>>>> build files and jars of Ant Tasks.
>>>>>>>> At some point a build file (within a bundle) will have to load some
>>>> other Ant script (through the bundle wiring). For that I simply get the
>>>> classloader of the current classloader and do a
>>>> classloader.getResource("/path/other/build.xml"). So far so good.
>>>>>>>> But when running that other build file, I would need its classloader
>>>> to do some other import of build.xml file. But I only have the resolved
>>>> URL, not the bundle which is containing the resolved script. Which java
>>>> code, it's simple, from the resolved class I can get its classloader. But I
>>>> cannot do that for a script which as been resolved as an URL.
>>>>>>>> Here is what I have manage to do so far but I find it not pretty:
>>>>>>>> 
>>>>>>>>    URL buildUrl = currentClassLoader.getResource(buildFile);
>>>>>>>>    ClassLoader buildClassLoader = null;
>>>>>>>>    for (Bundle bundle : allBundles) {
>>>>>>>>        BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>>>>>>        int i = buildFile.lastIndexOf('/');
>>>>>>>>        String path = buildFile.substring(0, i);
>>>>>>>>        String name = buildFile.substring(i + 1);
>>>>>>>>        List<URL> entries = wiring.findEntries(path, name, 0);
>>>>>>>>        if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>>>>>>            buildClassLoader = wiring.getClassLoader();
>>>>>>>>            break;
>>>>>>>>        }
>>>>>>>>    }
>>>>>>>>    if (buildClassLoader == null) {
>>>>>>>>        throw new RuntimeException("WTF! Unable to find the
>>>> classloader of the build file " + buildFile);
>>>>>>>>    }
>>>>>>>> 
>>>>>>>> It is working but it doesn't sound nice. Is there an API I didn't
>>>> found which allows to look for a resource and its bundle or classloader ? I
>>>> would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>>>>>> Nicolas
>>>>>>>> 
>>>>>>>> 
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>>> 
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>> 
>>>>> 
>>>>> --
>>>>> Christian Schneider
>>>>> http://www.liquid-reality.de
>>>>> 
>>>>> Open Source Architect
>>>>> http://www.talend.com
>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>> 
>>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 2 sept. 2013 à 18:15, Murad Mamedov <ma...@muradm.net> a écrit :

> Hello, I'm newbie here, but using OSGi for long time.
> 
> From my understanding of your problem:
> - you expect some bundles to have build.xml
> - you are a build system that does somethings with those bundles.
> If above is true, I would start BundleListener and listen bundle events. Of
> course, on startup of build system you will need to get the initial list of
> bundles your self.
> Once BundleListener gets event on installed bundle, I would check if it is
> my bundle (has build.xml for example) and keep it in private map (ex:
> taskName -> Bundle).
> This will be faster and more dynamic, better than traversing over bundles
> every time.

The thing is that I don't expect a "build" bundle to only have a build.xml at a precise location. I could be anywhere, named in any way. For instance there can be a bundle in which there would be a common-build-java.xml and a common-build-resources.xml, in anther bundle a common-build-webapp.xml which is importing the former ones, and my main build.xml is just importing the later one.

I would really like the build files to behave like Java classes in this OSGi environment.

> But I'm still not sure if you can access actual ClassLoader of that bundle
> even if you have it and for example instantiate some class from there.
> You have to depend (import somethings from it) on that bundle, but as far
> as I understand you expect unknown user ant tasks to be around in unknown
> user bundles.
> Is it possible to get actual class loader of some bundle and do something
> with it?

Well, I don't need a classloader per se. To make a build file load an Ant task, I need something to load a class, so Bundle#loadClass() is fine. And to make a build file import another one, I need something to load a resource, so Bundle#findEntries() is fine too.

> Using services could be a better option for this problem in my opinion.

Could you elaborate on that ? I know a little bit about services but not enough to understand what kind of solution you are thinking of.

cheers,
Nicolas

> 
> Regards,
> Murad
> 
> 
> 
> On Mon, Sep 2, 2013 at 5:59 PM, Nicolas Lalevée
> <ni...@hibnet.org>wrote:
> 
>> 
>> Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a
>> écrit :
>> 
>>> I think it would be a bad idea to rely on an URI scheme. After all it is
>> not specified in the OSGi standard.
>>> Can't you simply forward the bundle or classloader together with the URL?
>> 
>> The URL is pointing to a build file which I want to "run" within its
>> bundle just like a java class would do. When running it will probably need
>> to load resources, and I want this loading to follow the OSGi visibility
>> rules. So I would need the classloader which "owns" that resource, and I
>> don't have it, the OSGi framework has.
>> 
>> Nicolas
>> 
>>> 
>>> Christian
>>> 
>>> On 02.09.2013 10:13, Nicolas Lalevée wrote:
>>>> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a
>> écrit :
>>>> 
>>>>> I'm pretty sure this isn't possible for resources, like it is for
>> classes.
>>>>> 
>>>>> The OSGi spec doesn't mandate the format of bundle resource URLs,
>> which is what you would need if you wanted to determine from which bundle a
>> looked up resource comes.
>>>>> 
>>>>> Not sure about other frameworks, but this is fairly easy to determine
>> from a resource URL in the Felix framework, since this host is the bundle
>> id + revision id.
>>>> I can do an if(felix) in my code to optimize. In the long term can I
>> rely on this URL scheme ?
>>>> 
>>>> Nicolas
>>>> 
>>>> 
>>>>> -> richard
>>>>> 
>>>>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>>>>> Hi,
>>>>>> 
>>>>>> Maybe my issue has already been addressed several time, so here is
>> the actual question: how can I get the bundle/classloader which *owns* the
>> URL which I looked up through classloader.getResource(file) ?
>>>>>> 
>>>>>> If it's not clear, here is my context.
>>>>>> 
>>>>>> I am experimenting a build system where some Ant build files and Ant
>> task would be managed like as OSGi bundles. So I can do a modularisation of
>> build files and jars of Ant Tasks.
>>>>>> 
>>>>>> At some point a build file (within a bundle) will have to load some
>> other Ant script (through the bundle wiring). For that I simply get the
>> classloader of the current classloader and do a
>> classloader.getResource("/path/other/build.xml"). So far so good.
>>>>>> But when running that other build file, I would need its classloader
>> to do some other import of build.xml file. But I only have the resolved
>> URL, not the bundle which is containing the resolved script. Which java
>> code, it's simple, from the resolved class I can get its classloader. But I
>> cannot do that for a script which as been resolved as an URL.
>>>>>> 
>>>>>> Here is what I have manage to do so far but I find it not pretty:
>>>>>> 
>>>>>>    URL buildUrl = currentClassLoader.getResource(buildFile);
>>>>>>    ClassLoader buildClassLoader = null;
>>>>>>    for (Bundle bundle : allBundles) {
>>>>>>        BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>>>>        int i = buildFile.lastIndexOf('/');
>>>>>>        String path = buildFile.substring(0, i);
>>>>>>        String name = buildFile.substring(i + 1);
>>>>>>        List<URL> entries = wiring.findEntries(path, name, 0);
>>>>>>        if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>>>>            buildClassLoader = wiring.getClassLoader();
>>>>>>            break;
>>>>>>        }
>>>>>>    }
>>>>>>    if (buildClassLoader == null) {
>>>>>>        throw new RuntimeException("WTF! Unable to find the
>> classloader of the build file " + buildFile);
>>>>>>    }
>>>>>> 
>>>>>> It is working but it doesn't sound nice. Is there an API I didn't
>> found which allows to look for a resource and its bundle or classloader ? I
>> would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>>>> 
>>>>>> Nicolas
>>>>>> 
>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>> 
>>> 
>>> 
>>> --
>>> Christian Schneider
>>> http://www.liquid-reality.de
>>> 
>>> Open Source Architect
>>> http://www.talend.com
>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Murad Mamedov <ma...@muradm.net>.
Hello, I'm newbie here, but using OSGi for long time.

>From my understanding of your problem:
- you expect some bundles to have build.xml
- you are a build system that does somethings with those bundles.
If above is true, I would start BundleListener and listen bundle events. Of
course, on startup of build system you will need to get the initial list of
bundles your self.
Once BundleListener gets event on installed bundle, I would check if it is
my bundle (has build.xml for example) and keep it in private map (ex:
taskName -> Bundle).
This will be faster and more dynamic, better than traversing over bundles
every time.

But I'm still not sure if you can access actual ClassLoader of that bundle
even if you have it and for example instantiate some class from there.
You have to depend (import somethings from it) on that bundle, but as far
as I understand you expect unknown user ant tasks to be around in unknown
user bundles.
Is it possible to get actual class loader of some bundle and do something
with it?

Using services could be a better option for this problem in my opinion.

Regards,
Murad



On Mon, Sep 2, 2013 at 5:59 PM, Nicolas Lalevée
<ni...@hibnet.org>wrote:

>
> Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a
> écrit :
>
> > I think it would be a bad idea to rely on an URI scheme. After all it is
> not specified in the OSGi standard.
> > Can't you simply forward the bundle or classloader together with the URL?
>
> The URL is pointing to a build file which I want to "run" within its
> bundle just like a java class would do. When running it will probably need
> to load resources, and I want this loading to follow the OSGi visibility
> rules. So I would need the classloader which "owns" that resource, and I
> don't have it, the OSGi framework has.
>
> Nicolas
>
> >
> > Christian
> >
> > On 02.09.2013 10:13, Nicolas Lalevée wrote:
> >> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a
> écrit :
> >>
> >>> I'm pretty sure this isn't possible for resources, like it is for
> classes.
> >>>
> >>> The OSGi spec doesn't mandate the format of bundle resource URLs,
> which is what you would need if you wanted to determine from which bundle a
> looked up resource comes.
> >>>
> >>> Not sure about other frameworks, but this is fairly easy to determine
> from a resource URL in the Felix framework, since this host is the bundle
> id + revision id.
> >> I can do an if(felix) in my code to optimize. In the long term can I
> rely on this URL scheme ?
> >>
> >> Nicolas
> >>
> >>
> >>> -> richard
> >>>
> >>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
> >>>> Hi,
> >>>>
> >>>> Maybe my issue has already been addressed several time, so here is
> the actual question: how can I get the bundle/classloader which *owns* the
> URL which I looked up through classloader.getResource(file) ?
> >>>>
> >>>> If it's not clear, here is my context.
> >>>>
> >>>> I am experimenting a build system where some Ant build files and Ant
> task would be managed like as OSGi bundles. So I can do a modularisation of
> build files and jars of Ant Tasks.
> >>>>
> >>>> At some point a build file (within a bundle) will have to load some
> other Ant script (through the bundle wiring). For that I simply get the
> classloader of the current classloader and do a
> classloader.getResource("/path/other/build.xml"). So far so good.
> >>>> But when running that other build file, I would need its classloader
> to do some other import of build.xml file. But I only have the resolved
> URL, not the bundle which is containing the resolved script. Which java
> code, it's simple, from the resolved class I can get its classloader. But I
> cannot do that for a script which as been resolved as an URL.
> >>>>
> >>>> Here is what I have manage to do so far but I find it not pretty:
> >>>>
> >>>>     URL buildUrl = currentClassLoader.getResource(buildFile);
> >>>>     ClassLoader buildClassLoader = null;
> >>>>     for (Bundle bundle : allBundles) {
> >>>>         BundleWiring wiring = bundle.adapt(BundleWiring.class);
> >>>>         int i = buildFile.lastIndexOf('/');
> >>>>         String path = buildFile.substring(0, i);
> >>>>         String name = buildFile.substring(i + 1);
> >>>>         List<URL> entries = wiring.findEntries(path, name, 0);
> >>>>         if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
> >>>>             buildClassLoader = wiring.getClassLoader();
> >>>>             break;
> >>>>         }
> >>>>     }
> >>>>     if (buildClassLoader == null) {
> >>>>         throw new RuntimeException("WTF! Unable to find the
> classloader of the build file " + buildFile);
> >>>>     }
> >>>>
> >>>> It is working but it doesn't sound nice. Is there an API I didn't
> found which allows to look for a resource and its bundle or classloader ? I
> would prefer an OSGi API, but if it's a Felix one I don't mind.
> >>>>
> >>>> Nicolas
> >>>>
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>>> For additional commands, e-mail: users-help@felix.apache.org
> >>>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >>> For additional commands, e-mail: users-help@felix.apache.org
> >>>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> >> For additional commands, e-mail: users-help@felix.apache.org
> >>
> >
> >
> > --
> > Christian Schneider
> > http://www.liquid-reality.de
> >
> > Open Source Architect
> > http://www.talend.com
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@felix.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: OSGi-aware resource loading

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 2 sept. 2013 à 10:34, Christian Schneider <ch...@die-schneider.net> a écrit :

> I think it would be a bad idea to rely on an URI scheme. After all it is not specified in the OSGi standard.
> Can't you simply forward the bundle or classloader together with the URL?

The URL is pointing to a build file which I want to "run" within its bundle just like a java class would do. When running it will probably need to load resources, and I want this loading to follow the OSGi visibility rules. So I would need the classloader which "owns" that resource, and I don't have it, the OSGi framework has.

Nicolas

> 
> Christian
> 
> On 02.09.2013 10:13, Nicolas Lalevée wrote:
>> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a écrit :
>> 
>>> I'm pretty sure this isn't possible for resources, like it is for classes.
>>> 
>>> The OSGi spec doesn't mandate the format of bundle resource URLs, which is what you would need if you wanted to determine from which bundle a looked up resource comes.
>>> 
>>> Not sure about other frameworks, but this is fairly easy to determine from a resource URL in the Felix framework, since this host is the bundle id + revision id.
>> I can do an if(felix) in my code to optimize. In the long term can I rely on this URL scheme ?
>> 
>> Nicolas
>> 
>> 
>>> -> richard
>>> 
>>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>>> Hi,
>>>> 
>>>> Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?
>>>> 
>>>> If it's not clear, here is my context.
>>>> 
>>>> I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.
>>>> 
>>>> At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
>>>> But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.
>>>> 
>>>> Here is what I have manage to do so far but I find it not pretty:
>>>> 
>>>>     URL buildUrl = currentClassLoader.getResource(buildFile);
>>>>     ClassLoader buildClassLoader = null;
>>>>     for (Bundle bundle : allBundles) {
>>>>         BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>>         int i = buildFile.lastIndexOf('/');
>>>>         String path = buildFile.substring(0, i);
>>>>         String name = buildFile.substring(i + 1);
>>>>         List<URL> entries = wiring.findEntries(path, name, 0);
>>>>         if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>>             buildClassLoader = wiring.getClassLoader();
>>>>             break;
>>>>         }
>>>>     }
>>>>     if (buildClassLoader == null) {
>>>>         throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
>>>>     }
>>>> 
>>>> It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>> 
>>>> Nicolas
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
> 
> 
> -- 
> Christian Schneider
> http://www.liquid-reality.de
> 
> Open Source Architect
> http://www.talend.com
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Christian Schneider <ch...@die-schneider.net>.
I think it would be a bad idea to rely on an URI scheme. After all it is 
not specified in the OSGi standard.
Can't you simply forward the bundle or classloader together with the URL?

Christian

On 02.09.2013 10:13, Nicolas Lalevée wrote:
> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a écrit :
>
>> I'm pretty sure this isn't possible for resources, like it is for classes.
>>
>> The OSGi spec doesn't mandate the format of bundle resource URLs, which is what you would need if you wanted to determine from which bundle a looked up resource comes.
>>
>> Not sure about other frameworks, but this is fairly easy to determine from a resource URL in the Felix framework, since this host is the bundle id + revision id.
> I can do an if(felix) in my code to optimize. In the long term can I rely on this URL scheme ?
>
> Nicolas
>
>
>> -> richard
>>
>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>> Hi,
>>>
>>> Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?
>>>
>>> If it's not clear, here is my context.
>>>
>>> I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.
>>>
>>> At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
>>> But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.
>>>
>>> Here is what I have manage to do so far but I find it not pretty:
>>>
>>>      URL buildUrl = currentClassLoader.getResource(buildFile);
>>>      ClassLoader buildClassLoader = null;
>>>      for (Bundle bundle : allBundles) {
>>>          BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>          int i = buildFile.lastIndexOf('/');
>>>          String path = buildFile.substring(0, i);
>>>          String name = buildFile.substring(i + 1);
>>>          List<URL> entries = wiring.findEntries(path, name, 0);
>>>          if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>              buildClassLoader = wiring.getClassLoader();
>>>              break;
>>>          }
>>>      }
>>>      if (buildClassLoader == null) {
>>>          throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
>>>      }
>>>
>>> It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>
>>> Nicolas
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


-- 
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by "Richard S. Hall" <he...@ungoverned.org>.
On 9/2/13 04:13 , Nicolas Lalevée wrote:
> Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a écrit :
>
>> I'm pretty sure this isn't possible for resources, like it is for classes.
>>
>> The OSGi spec doesn't mandate the format of bundle resource URLs, which is what you would need if you wanted to determine from which bundle a looked up resource comes.
>>
>> Not sure about other frameworks, but this is fairly easy to determine from a resource URL in the Felix framework, since this host is the bundle id + revision id.
> I can do an if(felix) in my code to optimize. In the long term can I rely on this URL scheme ?

Well, I don't think we are going to guarantee it since it is explicitly 
opaque and non-spec'ed, but it has been that way for a very long time.

-> richard

>
> Nicolas
>
>
>> -> richard
>>
>> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>>> Hi,
>>>
>>> Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?
>>>
>>> If it's not clear, here is my context.
>>>
>>> I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.
>>>
>>> At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
>>> But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.
>>>
>>> Here is what I have manage to do so far but I find it not pretty:
>>>
>>>      URL buildUrl = currentClassLoader.getResource(buildFile);
>>>      ClassLoader buildClassLoader = null;
>>>      for (Bundle bundle : allBundles) {
>>>          BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>>          int i = buildFile.lastIndexOf('/');
>>>          String path = buildFile.substring(0, i);
>>>          String name = buildFile.substring(i + 1);
>>>          List<URL> entries = wiring.findEntries(path, name, 0);
>>>          if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>>              buildClassLoader = wiring.getClassLoader();
>>>              break;
>>>          }
>>>      }
>>>      if (buildClassLoader == null) {
>>>          throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
>>>      }
>>>
>>> It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.
>>>
>>> Nicolas
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by Nicolas Lalevée <ni...@hibnet.org>.
Le 1 sept. 2013 à 22:28, Richard S. Hall <he...@ungoverned.org> a écrit :

> I'm pretty sure this isn't possible for resources, like it is for classes.
> 
> The OSGi spec doesn't mandate the format of bundle resource URLs, which is what you would need if you wanted to determine from which bundle a looked up resource comes.
> 
> Not sure about other frameworks, but this is fairly easy to determine from a resource URL in the Felix framework, since this host is the bundle id + revision id.

I can do an if(felix) in my code to optimize. In the long term can I rely on this URL scheme ?

Nicolas


> 
> -> richard
> 
> On 9/1/13 11:31 , Nicolas Lalevée wrote:
>> Hi,
>> 
>> Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?
>> 
>> If it's not clear, here is my context.
>> 
>> I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.
>> 
>> At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
>> But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.
>> 
>> Here is what I have manage to do so far but I find it not pretty:
>> 
>>     URL buildUrl = currentClassLoader.getResource(buildFile);
>>     ClassLoader buildClassLoader = null;
>>     for (Bundle bundle : allBundles) {
>>         BundleWiring wiring = bundle.adapt(BundleWiring.class);
>>         int i = buildFile.lastIndexOf('/');
>>         String path = buildFile.substring(0, i);
>>         String name = buildFile.substring(i + 1);
>>         List<URL> entries = wiring.findEntries(path, name, 0);
>>         if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>>             buildClassLoader = wiring.getClassLoader();
>>             break;
>>         }
>>     }
>>     if (buildClassLoader == null) {
>>         throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
>>     }
>> 
>> It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.
>> 
>> Nicolas
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: OSGi-aware resource loading

Posted by "Richard S. Hall" <he...@ungoverned.org>.
I'm pretty sure this isn't possible for resources, like it is for classes.

The OSGi spec doesn't mandate the format of bundle resource URLs, which 
is what you would need if you wanted to determine from which bundle a 
looked up resource comes.

Not sure about other frameworks, but this is fairly easy to determine 
from a resource URL in the Felix framework, since this host is the 
bundle id + revision id.

-> richard

On 9/1/13 11:31 , Nicolas Lalevée wrote:
> Hi,
>
> Maybe my issue has already been addressed several time, so here is the actual question: how can I get the bundle/classloader which *owns* the URL which I looked up through classloader.getResource(file) ?
>
> If it's not clear, here is my context.
>
> I am experimenting a build system where some Ant build files and Ant task would be managed like as OSGi bundles. So I can do a modularisation of build files and jars of Ant Tasks.
>
> At some point a build file (within a bundle) will have to load some other Ant script (through the bundle wiring). For that I simply get the classloader of the current classloader and do a classloader.getResource("/path/other/build.xml"). So far so good.
> But when running that other build file, I would need its classloader to do some other import of build.xml file. But I only have the resolved URL, not the bundle which is containing the resolved script. Which java code, it's simple, from the resolved class I can get its classloader. But I cannot do that for a script which as been resolved as an URL.
>
> Here is what I have manage to do so far but I find it not pretty:
>
>      URL buildUrl = currentClassLoader.getResource(buildFile);
>      ClassLoader buildClassLoader = null;
>      for (Bundle bundle : allBundles) {
>          BundleWiring wiring = bundle.adapt(BundleWiring.class);
>          int i = buildFile.lastIndexOf('/');
>          String path = buildFile.substring(0, i);
>          String name = buildFile.substring(i + 1);
>          List<URL> entries = wiring.findEntries(path, name, 0);
>          if (!entries.isEmpty() && containsUrls(entries, buildUrl)) {
>              buildClassLoader = wiring.getClassLoader();
>              break;
>          }
>      }
>      if (buildClassLoader == null) {
>          throw new RuntimeException("WTF! Unable to find the classloader of the build file " + buildFile);
>      }
>
> It is working but it doesn't sound nice. Is there an API I didn't found which allows to look for a resource and its bundle or classloader ? I would prefer an OSGi API, but if it's a Felix one I don't mind.
>
> Nicolas
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org