This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 201740

Summary: Don't fake bundles for modules with friend only packages
Product: platform Reporter: Jaroslav Tulach <jtulach>
Component: NetigsoAssignee: Jaroslav Tulach <jtulach>
Status: RESOLVED FIXED    
Severity: normal CC: apireviews, jglick, jtulach, tpavek
Priority: P1 Keywords: API_REVIEW_FAST
Version: 7.1   
Hardware: Other   
OS: Linux   
Issue Type: DEFECT Exception Reporter:
Bug Depends on: 198275    
Bug Blocks:    
Attachments: Bundle cannot depend on friend bundles
Also with support for Netigso-Export-Package

Description Jaroslav Tulach 2011-09-07 13:01:20 UTC
After integration of bug 198275, there is more than 400 of faked OSGi bundles (representing various NetBeans APIs) ready for being consumed by real OSGi bundles.

I've just realized thta I made a mistake and by an accident I faked all bundles with OpenIDE-Module-Public-Packages and forget to exlude friend packages. I'd like to fix that, but the change is not backward compatible (someone may have already depend from a bundle on a module with public packages):

# This patch file was generated by NetBeans IDE
# It uses platform neutral UTF-8 encoding and \n newlines.
--- Base (BASE)
+++ Locally Modified (Based On LOCAL)
@@ -424,7 +424,7 @@
      */
     private static InputStream fakeBundle(ModuleInfo m) throws IOException {
         String exp = (String) m.getAttribute("OpenIDE-Module-Public-Packages"); // NOI18N
-        if ("-".equals(exp)) { // NOI18N
+        if ("-".equals(exp) || m.getAttribute("OpenIDE-Module-Friends") != null) { // NOI18N
             return null;
         }
         ByteArrayOutputStream os = new ByteArrayOutputStream();
Comment 1 Jesse Glick 2011-09-07 13:58:14 UTC
(In reply to comment #0)
> someone may have
> already depend from a bundle on a module with public packages

In dev builds? It seems unlikely. Anyway if they did it would be incorrect since the OIDE-M-Friends declaration is supposed to serve to prevent such dependencies.

(A more precise simulation would actually export the packages but with a mandatory qualifier, or use the Eclipse-specific "buddy" header.)
Comment 2 Jaroslav Tulach 2011-09-07 14:46:24 UTC
Created attachment 110476 [details]
Bundle cannot depend on friend bundles

I am sure nobody depends on friend modules in the NetBeans IDE. But I know Tomáš was prototyping another implementation of java.source.queries without being listed as a friend and there may be other people out there relying on this in NetBeans based applications.

Right, it was incorrect since beggining to do this, but anyway we may need some kind of migration for those who did it (if they complain a lot).
Comment 3 Tomas Pavek 2011-09-07 15:31:40 UTC
Java Source Queries (bug 199405) was designed as friend API and from the beginning was planned to be used out of NetBeans from an OSGi bundle (and there already is an implementation module in JDev).

Whether it is correct or not is questionable (I thought it was when it passed the review), but now we need to keep it working somehow, i.e. have a way to depend on friend packages from an OSGi bundle. I'm not sure if making Java Source Queries fully public API is a good option.
Comment 4 Jaroslav Tulach 2011-09-07 16:25:57 UTC
(In reply to comment #3)
> now we need to keep it working somehow, i.e. have a way to
> depend on friend packages from an OSGi bundle. I'm not sure if making Java
> Source Queries fully public API is a good option.

Option 1: Add a new module into bridge-suite that would be the friend. It would call into matissequeries bundle directly.

Option 2: Add a tag into manifest of java.source.queries, so the system knows that it should be made available to OSGi bundles in spite of being a friend API.

Suggest name for the tag and I can prepare variant #2.
Comment 5 Jesse Glick 2011-09-07 16:56:06 UTC
Option 3: create bundles for modules with friend APIs but mandatory qualifiers on the exports. E.g.

Export-Package: stuff.api;stuff.spi;friend=org.netbeans.modules.friend;mandatory:=friend, stuff.api;stuff.spi;friend=com.jdev.otherfriend;mandatory:=friend

This permits other bundles to import the packages, but only with e.g.

Import-Package: stuff.api;friend=com.jdev.otherfriend

thus indicating that the author acknowledges this is not a public API.

(There is intentionally no facility in pure OSGi for restricting imports based on symbolic name of importing bundle, so it is on the honor system for the importer to make imported-from be its own name.)
Comment 6 Tomas Pavek 2011-09-07 18:18:14 UTC
I like option 3 as it makes both sides "acknowledge this is not a public API".

I think it would be an addition to option 2 that actually says which modules should export friend packages as OSGi bundles, then option 3 is a possible way how to do it. (A drawback is it needs changes in JDev build to generate the special Import-Package statement.)

Perhaps we could start with plain option 2 to keep things working, then possibly extend with option 3.
Comment 7 Jaroslav Tulach 2011-09-14 19:35:00 UTC
Option #3 is not very effective. It does not lower the number of modules that need to be faked. Better to explicitly identify those with friend packages that are supposed to be visible to OSGi framework with some special tag.

I hoped to reuse the tag from issue 197908, but that one has been backed out. Thus I think will use

Netigso-Export-Package: <osgi-format>

if the tag is present, it will be directly used for Export-Package: tag of the faked bundle.
Comment 8 Jaroslav Tulach 2011-09-14 20:35:16 UTC
Created attachment 110764 [details]
Also with support for Netigso-Export-Package
Comment 9 Jaroslav Tulach 2011-09-14 20:36:29 UTC
I'd like to integrate tomorrow.
Comment 10 Tomas Pavek 2011-09-15 09:11:58 UTC
Ok with me. If I understand it correctly, It's a more general solution allowing to export any non-public package, not just friends.

Re: Comment #7
> Option #3 is not very effective. It does not lower the number of modules
> that need to be faked.

Why not? If the tag from option #2 was not present in the module manifest, you would not generate the fake bundle with option #3 syntax.

Anyway, the use of Netigso-Export-Package works well for what I need. I don't have a strong opinion on whether also the consumer of friend API needs to acknowledge somehow the dependency on a more restricted API (which would be the addition of option #3).
Comment 11 Jaroslav Tulach 2011-09-15 10:11:22 UTC
(In reply to comment #10)
> Re: Comment #7
> > Option #3 is not very effective. It does not lower the number of modules
> > that need to be faked.
> Why not? If the tag from option #2 was not present in the module manifest, you
> would not generate the fake bundle with option #3 syntax.

I am not sure about the wording, but I think that Jesse's #3 suggests to do the mapping for all friend modules. That would not be efficient.

You have then proposed to use #2+#3. That would be fine. But the problem is that OSGi itself does not have clear concept of friends and the qualifiers used in suggestion #3 are (as far as I know) only voluntary. One can just "Import-Package: stuff.api" without any qualifier and the system will work. 

Thus I decided to use #2. It gives the same level of control as #2+#3 and is significantly easier to implement.

core-main#82d668c5f9ee, please update java.source.queries accordingly.
Comment 12 Quality Engineering 2011-09-17 14:21:59 UTC
Integrated into 'main-golden'
Changeset: http://hg.netbeans.org/main-golden/rev/82d668c5f9ee
User: Jaroslav Tulach <jtulach@netbeans.org>
Log: #201740: Export only public APIs to OSGi bundles
Comment 13 Jesse Glick 2011-09-20 14:00:55 UTC
[JG02] Why Netigso-Export-Package? Seems simpler and more intuitive to just permit the standard Export-Package to be given in a NB module manifest, in which case it will be honored in OSGi mode.


(In reply to comment #11)
> I think that Jesse's #3

(let's call it JG01 for future reference)

> suggests to do the mapping for all friend modules.

Right.

> That would not be efficient.

Perhaps not; I was leaving aside the question of performance of implementation. We already have 189 modules w/ public packages, vs. 228 more w/ friend packages. The overhead per faked bundle may need to be optimized in any event.

> the qualifiers used
> in suggestion #3 are (as far as I know) only voluntary. One can just
> "Import-Package: stuff.api" without any qualifier and the system will work.

No, the 'mandatory' directive should prevent that.

Possibly of interest - <makeosgi> used by http://wiki.netbeans.org/NetBeansInOSGi currently ignores OpenIDE-Module-Friends and treats all such packages as public. It could I think use the policy suggested by JG01 instead. (Tricky since OpenIDE-Module-Module-Dependencies given no indication of whether a given spec version dependency is on a friend or public module, so the task would not know whether to use Require-Bundle (for a public dep) or Import-Package (for a friend dep), nor in the latter case would it know which actual packages to import, unless the API module were also present in the input fileset.)
Comment 14 Quality Engineering 2011-11-19 16:16:45 UTC
Integrated into 'main-golden', will be available in build *201111190600* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/ba65d526b85f
User: Jaroslav Tulach <jtulach@netbeans.org>
Log: #201740: Export only public APIs to OSGi bundles