[ 
https://issues.apache.org/jira/browse/FELIX-6284?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17125236#comment-17125236
 ] 

Tom Watson commented on FELIX-6284:
-----------------------------------

Atomos does support embedding bundle resources directly into the native image 
such that the duplicates get their own unique path (including 
META-INF/MANIFEST.MF).  All unique resources can be included in the root of the 
image.  Any duplicates are placed in a folder with an ID per bundle.  
Additionally an index file is included that lists all the bundles that got 
compiled into the image.  This file is used by Atomos at runtime to discover 
the bundles and their entry paths.

https://github.com/apache/felix-atomos/tree/master/atomos.examples/atomos.examples.index
 

An example that uses this approach to create an uber JAR that contains all the 
content from the bundles and indexes duplicates.  This is not a native-image 
example, but it shows the concept more easily than the native-image example:

https://github.com/apache/felix-atomos/tree/master/atomos.examples/atomos.examples.substrate.maven

> Felix Connect Native-Image support
> ----------------------------------
>
>                 Key: FELIX-6284
>                 URL: https://issues.apache.org/jira/browse/FELIX-6284
>             Project: Felix
>          Issue Type: Improvement
>          Components: Connect
>    Affects Versions: connect-0.2.0
>            Reporter: Pierre De Rop
>            Assignee: Pierre De Rop
>            Priority: Minor
>
> The upcoming OSGi R8 will allow to combine OSGi with application compiled 
> with graalVM/native-image, and maybe Atomos already supports this. In the 
> meantime, I need to use the old apache Felix Connect library in GraalVM 
> substrate/native-image environment.
> To do so, there might be few adaptions to be done in Felix Connect. One is 
> about how bundles are scanned by the *ClasspathScanner* class. Currently, 
> this class provides a "scanForBundles" method which looks for all bundle URLS 
> available from the classpath, using:
> {code:java}
> Enumeration<URL> ClassLoader.getResources("META-INF/MANIFEST.MF") {code}
> This works fine in classpath environment, and collected URLS (jar:file) are 
> then used to create BundleDescriptors. Each BundleDescriptor can then get 
> access to bundle content using the URL.
> The ClassLoader.getResource method returns for instance URLS like:
> {code:java}
> jar:file:/home/pderop/felix.connect/bundles/org.apache.felix.gogo.command-1.1.0.jar!/META-INF/MANIFEST.MF
> jar:file:/home/pderop/felix.connect/bundles/org.apache.felix.metatype-1.2.2.jar!/META-INF/MANIFEST.MF
> etc ...{code}
> But in compiled applications (using substrate/native image), the 
> ClassLoader.getResources("META-INF/MANIFEST.MF") method returns an 
> enumeration of URLS which are all the same (using "resource" protocol) for 
> all found bundles. For example, for gogo and metatype bundles in the example 
> above, the ClassLoader.getResources("META-INF/MANIFEST.MF") would return 
> these same urls:
> {code:java}
> resource:META-INF/MANIFEST.MF
> resource:META-INF/MANIFEST.MF {code}
> this is problematic, because it's not possible to load resources from a 
> bundle using a unique jar:file url. Moreover, in native-image, using the 
> "resource" url seems to cause problems, and it seems we can only open and 
> read "resource" input stream only one time.  I also observed some exceptions 
> when reading "resource" inputstreams, like this:
> {code:java}
> DEBUG: bundle jaxrs.hello:0.0.0 (11)BundleComponentActivator : Descriptor 
> locations OSGI-INF/sample.jaxrs.HelloDS.xml
> java.io.IOException: Stream closed
>         at 
> java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:165)
>         at java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
>         at java.io.BufferedInputStream.read(BufferedInputStream.java:271)
>         at 
> org.apache.felix.connect.URLRevision.getUrlContent(URLRevision.java:131)
>         at 
> org.apache.felix.connect.URLRevision.getEntries(URLRevision.java:73)
>         at 
> org.apache.felix.connect.EntryFilterEnumeration.<init>(EntryFilterEnumeration.java:52)
>         at 
> org.apache.felix.connect.PojoSRBundle.findEntries(PojoSRBundle.java:486)
>         at 
> org.apache.felix.scr.impl.BundleComponentActivator.findDescriptors(BundleComponentActivator.java:413)
>         at 
> org.apache.felix.scr.impl.BundleComponentActivator.initialize(BundleComponentActivator.java:313)
>         at 
> org.apache.felix.scr.impl.BundleComponentActivator.<init>(BundleComponentActivator.java:263)
>         at 
> org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:551)
>         at org.apache.felix.scr.impl.Activator.access$200(Activator.java:69)
>         at 
> org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:424)
>         at 
> org.apache.felix.scr.impl.AbstractExtender.createExtension(AbstractExtender.java:196)
>         at 
> org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:169)
>         at 
> org.apache.felix.scr.impl.AbstractExtender.modifiedBundle(AbstractExtender.java:49)
>         at 
> org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:488)
>         at 
> org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:420)
>         at 
> org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232)
>         at 
> org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:450)
>         at 
> org.apache.felix.connect.felix.framework.util.EventDispatcher.invokeBundleListenerCallback(EventDispatcher.java:821)
>         at 
> org.apache.felix.connect.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:771)
>         at 
> org.apache.felix.connect.felix.framework.util.EventDispatcher.fireBundleEvent(EventDispatcher.java:510)
>         at org.apache.felix.connect.PojoSRBundle.start(PojoSRBundle.java:157)
>         at org.apache.felix.connect.PojoSR.startBundles(PojoSR.java:286)
>         at 
> com.nokia.as.service.felixconnect.impl.Launch.start(Launch.java:161)
>         at com.nokia.as.service.felixconnect.impl.Launch.main(Launch.java:76)
> {code}
> I don't know currently if there is an API in graalvm which could be used as a 
> work around, but in the meantime, a method can be added in the 
> ClasspathScanner in order to load original jars from a directory, using 
> jar:file URL protocol. In this way, we can still use "jar:file" URLS as 
> before. So, it means the original jars must be kept beside the executable. 
> Maybe the patch can be improved later, but it's light and allows compiled 
> applications to use declarative service, configadmin, dependency manager, etc 
> ... I will create a PR for this.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to