Community
Participate
Working Groups
Currently there is no way to check through the console which are the dynamically imported packages by a bundle. The bundle <id> command returns only the statically imported packages. Probably it should return also the dynamically imported packages, in a separate section of its output.
The difficulty with providing this information is in how the resolver works. Currently the bundle command lists imported packages as a list of "visible" packages (StateHelper.getVisiblePackages method). This is the same method used by PDE to construct a build class path for a bundle project in Eclipse. This method currently ignores dynamic imports as well as additional constraints added by fragments. One possible fix is to use PackageAdmin to get the list of imported packages, this would list all current wires including anything that got dynamically wired, but this performs very poorly because PackageAdmin API is awkward for finding out all the packages a particular bundle is wired to. We could add a new StateHelper method that provides information for all packages a bundle is wired to regardless of the type of import or if the constraint comes from a fragment. We could also easily implement this in the command implementation instead of adding a new StateHelper method to do it. It would just look at the BundleDescription.getResolvedImports and BundleDescription.getResolvedRequires methods. But it would have to do many of the same things that StateHelper.getVisiblePackages to do proper book keeping for re-exported bundles and split packages. Another approach is to add a new option to getVisiblePackages to get wires based on getResolvedImports and getResolvedRequires instead of the current approach which looks at the individual constraints using getImportedPackages and getRequiredBundles.
I will try with the PackageAdmin. If there is a significant performance degradation in comparison with the current implementation, then I will add an option to getVisiblePackages(), and use getResolvedImports and getResolvedRequires.
(In reply to comment #1) > > Another approach is to add a new option to getVisiblePackages to get wires > based on getResolvedImports and getResolvedRequires instead of the current > approach which looks at the individual constraints using getImportedPackages > and getRequiredBundles. > I implemented this, after trying the PackageAdmin. In this way all resolved packages, along with the resolved optional and resolved dynamic imports, are returned. I thought to add also to the output the optional, which are not resolved, and the dynamic, which are not resolved yet. So I wondered if it is appropriate to include in the output for each import - both resolved and unresolved - if it is optional/dynamic.
(In reply to comment #3) > I implemented this, after trying the PackageAdmin. In this way all resolved > packages, along with the resolved optional and resolved dynamic imports, are > returned. I thought to add also to the output the optional, which are not > resolved, and the dynamic, which are not resolved yet. So I wondered if it is > appropriate to include in the output for each import - both resolved and > unresolved - if it is optional/dynamic. > I think unresolved dynamic imports are going to be difficult because of wild cards. Currently the resolver adds dynamic wires to the list of packages a BundleDescription is wired (returned by BundleDescription.getResolverImports()). So an ImportPackageDescription that represents a dynamic import never actually gets a supplier assigned to it and returned by getSupplier().
(In reply to comment #4) > (In reply to comment #3) > > I implemented this, after trying the PackageAdmin. In this way all resolved > > packages, along with the resolved optional and resolved dynamic imports, are > > returned. I thought to add also to the output the optional, which are not > > resolved, and the dynamic, which are not resolved yet. So I wondered if it is > > appropriate to include in the output for each import - both resolved and > > unresolved - if it is optional/dynamic. > > > > I think unresolved dynamic imports are going to be difficult because of wild > cards. Currently the resolver adds dynamic wires to the list of packages a > BundleDescription is wired (returned by > BundleDescription.getResolverImports()). So an ImportPackageDescription that > represents a dynamic import never actually gets a supplier assigned to it and > returned by getSupplier(). > The new version of StateHelper.getVisiblePackages() (which uses getResolvedImports() and getResolvedRequires()) returns the resolved dynamic imports, along with the static ones. One simplistic solution would be to treat all imports in BindleDescription.getImportPackages(), which are not also included in the result of StateHelper.getVisiblePackages(), as unresolved dynamic imports or unresolved optional imports. Is this right, or am I missing something?
(In reply to comment #5) > The new version of StateHelper.getVisiblePackages() (which uses > getResolvedImports() and getResolvedRequires()) returns the resolved dynamic > imports, along with the static ones. One simplistic solution would be to treat > all imports in BindleDescription.getImportPackages(), which are not also > included in the result of StateHelper.getVisiblePackages(), as unresolved > dynamic imports or unresolved optional imports. Is this right, or am I missing > something? > Hi Lazar, Yes you are correct and for optional imports you can check to see if the getSupplier returns null. If so then you know the optional import is unresolved. But for dynamic imports you will have to do your own matching with the exports the bundle is wired to. You could iterate over all the getResolvedImports() and call ImportPackageSpecification.isSatisfiedBy() for each ExportPackageDescription the BundleDescription is wired to. This will do the wild card matching for the dynamic import. If you find one that satifies the import then you "may" have a dynamic wire. If you don't find any matches then you know you don't have a dynamic wire. Thanks for keeping at this.
(In reply to comment #6) > (In reply to comment #5) > > The new version of StateHelper.getVisiblePackages() (which uses > > getResolvedImports() and getResolvedRequires()) returns the resolved dynamic > > imports, along with the static ones. One simplistic solution would be to treat > > all imports in BindleDescription.getImportPackages(), which are not also > > included in the result of StateHelper.getVisiblePackages(), as unresolved > > dynamic imports or unresolved optional imports. Is this right, or am I missing > > something? > > > > Hi Lazar, > > Yes you are correct and for optional imports you can check to see if the > getSupplier returns null. If so then you know the optional import is > unresolved. But for dynamic imports you will have to do your own matching with > the exports the bundle is wired to. You could iterate over all the > getResolvedImports() and call ImportPackageSpecification.isSatisfiedBy() for > each ExportPackageDescription the BundleDescription is wired to. This will do > the wild card matching for the dynamic import. If you find one that satifies > the import then you "may" have a dynamic wire. If you don't find any matches > then you know you don't have a dynamic wire. > > Thanks for keeping at this. > Hi Tom, After I extended the implementation of StateHelperImpl.getVisiblePackages() to use getResolvedImports and getResolvedRequires (if called with a new option), this method returns the dynamic imports, which are already wired (a class was loaded from them). So I get them from there. And all dynamic imports, which are not returned in the result of this call I assume to be unwired. Currently I do not differentiate between dynamic imports, which may be wired to an exported package, but are not wired yet, and dynamic imports, for which does not exist an appropriate export to get wired to. I list both types as unwired.
(In reply to comment #7) > Currently I do not differentiate between dynamic imports, which may be wired to > an exported package, but are not wired yet, and dynamic imports, for which does > not exist an appropriate export to get wired to. I list both types as unwired. > This sounds reasonable.
(In reply to comment #8) Hi Tom, I am ready with the patch for this and it's working as expected, but before submitting it I have the following questions, which arose while making the changes. 1. When changing the StateHelper.getVisiblePackages() to use getResolvedImports() and getResolvedRequires(), I made it with a new option, so if the option is not passed, the method has the old behavior. But I checked and found out that this method - getVisiblePackages() - is called only by _bundle() and _getPackages() methods of the FrameworkCommandProvider. So the question is: are the option and the preservation of the old behavior necessary? Since the method is called only from these places, may we change it to use only getResolvedImports and getResolvedRequires, and not to use the new option? In this way getVisiblePackages will be simplified - there will be no checks for the option. The new behavior - returning the resolved dynamic imports along with the mandatory - seems not to harm other code. 2. Currently the ImportPackageSpecification of a dynamic import has null supplier even after it is resolved, which makes difficult the identification of unresolved dynamic imports. Is it possible to set the supplier of a dynamic import when it gets resolved, e.g., along with adding the resolved import to the bundle's resolved imports list? I checked the code and it seems this will not brake anything else, but I may be missing something.
(In reply to comment #9) > (In reply to comment #8) > > Hi Tom, > > I am ready with the patch for this and it's working as expected, but before > submitting it I have the following questions, which arose while making the > changes. > > 1. When changing the StateHelper.getVisiblePackages() to use > getResolvedImports() and getResolvedRequires(), I made it with a new option, so > if the option is not passed, the method has the old behavior. But I checked and > found out that this method - getVisiblePackages() - is called only by _bundle() > and _getPackages() methods of the FrameworkCommandProvider. So the question is: > are the option and the preservation of the old behavior necessary? Since the > method is called only from these places, may we change it to use only > getResolvedImports and getResolvedRequires, and not to use the new option? In > this way getVisiblePackages will be simplified - there will be no checks for > the option. The new behavior - returning the resolved dynamic imports along > with the mandatory - seems not to harm other code. > PDE UI/Build use this method so we should not change the behavior without the new option. > 2. Currently the ImportPackageSpecification of a dynamic import has null > supplier even after it is resolved, which makes difficult the identification of > unresolved dynamic imports. Is it possible to set the supplier of a dynamic > import when it gets resolved, e.g., along with adding the resolved import to > the bundle's resolved imports list? I checked the code and it seems this will > not brake anything else, but I may be missing something. > The difficulty is for wild card dynamic imports (e.g "*", "javax.*" etc.). These types of dynamic imports can have multiple suppliers, but ImportPackageSpecification currently only allows for one supplier to be set.
Created attachment 144071 [details] patch to bundle command to return dynamic imports This patch provides the discussed functionality. It adds an option in StateHelper. If StateHelper.getVisiblePackages() is called with this option, it uses getResolvedImports() and getResolvedRequires(), so that when looking for visible packages it takes into consideration the dynamic imports and the attached fragments. It also lists the unresolved optional and dynamic imports, including these of the fragments, if any.
Created attachment 144748 [details] patch Thanks Lazar. I really appreciate you providing this patch. This is not a very simple area of the code. But it looks like your fix good!! I will have to do some more testing and review. I fixed up a few small things in this patch. The main thing I did was rename the StateHelper option to VISIBLE_INCLUDE_ALL_HOST_WIRES and I attempted to change the javadoc of getVisiblePackages(BundleDescription bundle, int options) so that it no longer made a note that fragment constraints are not included. Instead I leave this description in the javadoc for the VISIBLE_INCLUDE options. Let me know what you think of the new option name and javadoc changes.
Created attachment 144750 [details] patch Updated to fix some errors in VISIBLE_INCLUDE_ALL_HOST_WIRES javadoc.
(In reply to comment #12) Thanks Tom. Excuse me for the late reply, but I was on a vacation. The changes in the option name and the javadoc are ok.
slipping this to M3.
Patch released.