JDK-4780441 : stddoclet: Incorrectly documents inherited members from package-private class
  • Type: Bug
  • Component: tools
  • Sub-Component: javadoc(tool)
  • Affected Version: 1.4.1,5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,other,windows_nt
  • CPU: generic,x86
  • Submitted: 2002-11-18
  • Updated: 2022-08-24
  • Resolved: 2003-11-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b30Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description

Name: nt126004			Date: 11/18/2002


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OPERATING SYSTEM VERSION :
Windows NT Version 4.0


A DESCRIPTION OF THE PROBLEM :
When a public class extends a package-private one, 
"javadoc -private" will include the methods and fields of the base
class into the derived class, instead of merely referencing
to them as inherited.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run javadoc -private on the example classes below
(Foo.java, Bar.java).
Look at Bar.html.


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected result: In Bar class, the method doit() should be listed
under "Methods inherited from class Foo" only.
Actual result: Method doit() is listed under "Method
Summary" and under "Method Detail". Similar for field x:

Class Bar
  Field Detail
    protected int x
  Method Detail
    void another()
    public void doit()

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/* non-public */ class Foo
{
	protected int x;

	public void doit()
	{
		++x;
	}
}

public class Bar extends Foo
{
	void another()
	{
	}
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Make the base class public.
(Review ID: 167050) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger tiger-beta FIXED IN: tiger-beta INTEGRATED IN: tiger-b30 tiger-beta
14-06-2004

PUBLIC COMMENTS Fixed. ###@###.### 2003-11-15
15-11-2003

EVALUATION The members are currently documented as if they belong to the subclass rather than documenting them as inherited from an inaccessible class. > ###@###.### wrote: > What are the constraints around the members being of greater > access being in a class of lesser access? ###@###.### replied: None. > In this example, a package-private class with a public method doit() is > extended by a public class Bar. Does an instance of Bar inherit doit() and x? Yes. > This seems to be covered somewhat on page 152 JLS 2nd Ed. This is completely specified by the rules in the JLS. > When Javadoc is run on these classes with the default option > for protected access, the Foo members doit() and x show up as > if they had been declared in Bar. Does that seem reasonable, > given that it cannot generate documentation for package-private class Foo? Not really, it is misleading. You could state that these are inherited from a non-accessible superclass. Cheers, Gilad As a result of running JckApiCompare.pl on 1.4.2-b07, there are two other cases that also need to be fixed with this bugfix: Public static fields: In java.util.jar.JarEntry (and 7 other classes), fields CENATT, CENATX, etc. actually reside as public static fields in the package-private interface ZipConstants. Javadoc mistakenly documents them as residing in java.util.zip.ZipEntry, a public class that implements ZipConstants, rather than documenting them as inherited from a non-accessible interface (ZipConstants). Protected methods: In javax.swing.text.GapContent, protected methods getGapEnd(), getGapStart(), and replace(int,int,java.lang.Object,int) actually reside as protected members in GapVector, a package-private abstract class. Javadoc mistakenly documents them as residing in GapContents, a public class that extends GapVector, rather than documenting them as inherited from a non-accessible class (GapVector). See "Comments" for more details Note that if we remove them from the detail section and document them only as inherited members, then they will have neither declarations nor doc comments, which does not seem tolerable. Perhaps we should create a special, new detail section for members inherited from inaccessible classes. ###@###.### 2002-11-25 Given a package-private class Foo containing public methods that a public class Bar extends, there seem to be two cases that this bug fix needs to address: 1) Where the class page for the package-private superclass *is* being generated. This is the submitter's original bug here, where -private is passed in. In this case, the bug is that members of inherited package-private class Foo are being detailed both in Foo and its subclass Bar -- they should be detailed only in Foo. This is clearly a bug, as there is no excuse for the details of Foo members to be duplicated in Bar. 2) Where the class page for the package-private inherited class is *not* being documented. This is a separate bug where -private is not passed in. In this case, the document looks the same in Bar as in case 1 above -- that members of inherited package-private class Foo are being detailed in class Bar, indistinguishable from members of Bar. As Gilad points out, these should be documented as inherited from a non-accessible superclass. The suggested solution is to add new inherited sections: Fields inherited from inaccessible class Foo x Methods inherited from inaccessible class Foo doit() Also, the members in the above sections should link to detailed documentation of the inherited members on the *same* page (since there is no other page for it) in the "Detail" sections with the following comment ahead of the description: This method inherited from package-private class Foo. followed by the doc comment of the inherited member. (This is the only case I'm aware of where doc comments for inherited but non-overridden (or non-implemented) members are documented on the subclass's page.) How does that sound? ###@###.### 2003-03-30 Also see possible duplicate 4874845: Non public superclass mentioned in inherited javadoc ###@###.### 2003-10-29 > ###@###.### wrote: > There are 2 problems mentioned in [related] bug 4874845: > > 1. Documentation is being inherited by package-private AbstractStringBuilder. > 2. It is documented that StringBuilder extends AbstractStringBuilder (in the > class hierarchy and class signature). > > Do you think #2 is a bug? joshua.bloch wrote: Yes!! The existence of AbstractStringBuilder is an implementation detail and should have no influence on the generated documentation. ###@###.### wrote: > In this bug ###@###.### had recommended headings in similar > situations should add the word "inaccessible": > "... inherited from inaccessible class java.lang.AbstractStringBuilder" gilad.bracha wrote: > No, I recommended that you say they were inherited from an inaccessible superclass. Misunderstanding. In an ideal world, I might even agree that you could pretend they were directly part of the subclass. However, the Java language itself provides imperfect encapsulation of such decisions. Until recently, where a method was declared actually affected overload resolution, for example. I won't swear there aren't additional situations like that, so I'm somewhat more comfortable exposing where methods are declared in the javadoc. joshua.bloch wrote: I am still iffy about the need for documenting that a method is "inherited from an inaccessible superclass." While it is true, and it make affect behavior, I don't think it's part of the classes "exported API": I don't think it's something that we want to commit to for time. It seems to me to be somewhat analogous to whether a method is synchronized or not. As you know, we don't document that. gilad.bracha wrote: The point can indeed be argued both ways. I'm happy to have this one go your way. douglas.kramer wrote: Conclusion: When not documenting package-private classes (the javadoc default), document any public methods in those classes as if they're declared in the public subclass (StringBuilder or Bar) itself. Do not expose the package-private superclass (AbstractStringBuilder or Foo) anywhere. ###@###.### 2003-11-15 Fixed. Inherited members from package private classes are now documented as though they were declared in the inheriting class. ###@###.### 2003-11-15
15-11-2003