Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4720974
Votes 2
Synopsis @inheritDoc broken 1.4.1 beta - inheriting from abstract superclass's interface
Category doclet:tbd
Reported Against 1.4.1 , hopper-beta
Release Fixed 1.4.2(mantis)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4778264
Submit Date 25-JUL-2002
Description
The line of code to recursivly search for {@inheritDoc} was missing in the method to replace the inline tag with the appropriate documentation.  I have added it.  Here is an example of where the doclet failed:

Suppose class C implements interface I1 which is a subinterface of I2.  If I2 has documentation for method m and both C and I1 use {@inheritDoc} to inherit
documentation for m, the doclet should be able to recursively find the documentation in I2 for class C (because C implements I1 which extends I2).

 xxxxx@xxxxx  2002-07-30




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

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
SP2

A DESCRIPTION OF THE PROBLEM :
JDK1.4.1 beta 1 attempts to fix the @inheritDoc regression
in 1.4.0 but is not yet functional.  The code samples show
a method defined in an interface, an abstract class that
implements the interface, and a concrete class that extends
the abstract class.

Javadoc complains "warning - @inheritDoc used by bar
(double) does not override or implement any method".

According to my understanding of the rules, Javadoc should
find the original method declaration in the interface
implemented in the abstract class.  If the concrete class
also explicitly implements the interface, the problem goes
away...but it should not be necessary to declare that
implementation.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run 1.4.1-B1 Javadoc on the provided source.
2.
3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
------ extracted from Javadoc html output ------

bar
public void bar(double param1)This is the Javadoc for X2.bar
().
This is the second paragraph..

This implementation over-rides X2.bar().


Specified by:
bar in interface X2
Parameters:
param1 - A double.


------------

The above is produced if ConcreteX1X2 explicitly implements
X1 and X2.

If ConcreteX1X2 does not implement the interfaces, Javadoc
produces the warning shown previously, and hangs at 100%
busy.  I am using Ant to drive the process; have not tried
Javadoc directly from the command line to see if this makes
a different on hanging the process.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/**
 *      This is the Javadoc for interface X1.
 */

public interface X1
{

/**
 *      This is the Javadoc for X1.foo().
 *
 *      <p>
 *      This is the second paragraph.
 *
 *      @param param1 An integer.
 */

    public void foo(int param1);
}

/**
 *      This is the Javadoc for interface X2.
 */

public interface X2
{

/**
 *      This is the Javadoc for X2.bar().
 *
 *      <p>
 *      This is the second paragraph.
 *
 *      @param param1 A double.
 */

    public void bar(double param1);
}

/**
 *      This is the Javadoc for class AbstractX1X2.
 */

public abstract class AbstractX1X2 implements X1, X2
{

/**
 *      {@inheritDoc}.
 *
 *      <p>This implementation over-rides X1.foo().
 */

    public void foo(int param1)
    {
    }
}

/**
 *      This is the Javadoc for class ConcreteX1X2.
 */

public final class ConcreteX1X2 extends AbstractX1X2 //implements X1, X2
{

/*
 *      {@inheritDoc}.
 *
 *      <p>This implementation over-rides AbstractX1X2.foo().
 *
 *      @param param1 This description takes precedence.
 */

    public void foo(int param1)
    {
    }

/**
 *      {@inheritDoc}.
 *
 *      <p>This implementation over-rides X2.bar().
 */

    public void bar(double param1)
    {
    }
}
---------- END SOURCE ----------
(Review ID: 159796) 
======================================================================
Work Around
N/A
Evaluation
Look at for Mantis.
 xxxxx@xxxxx  2002-07-25

This bug has been fixed but is pending review.
 xxxxx@xxxxx  2002-07-30

 xxxxx@xxxxx  wrote:
> Suppose class A implements interfaces I1 and I2, and both interfaces
> specify an indentical method M.  When class A implements M, does it 
> inherit documentation from I1.M or I2.M.  Right now, it only implements 
> from I1.M.
> It would be weird to inherit from both.  How do you think we should
> handle this?

 xxxxx@xxxxx  replied:
I think this one has an good answer:  If I1 extends (perhaps indirectly)
I2, use I1's documentation.  If I2 extends (perhaps indirectly) I1, use I2's
documentation.  If I1 and I2 are unrelated, use both (in alphabetical
order).  You don't have to worry about the fourth possibility, where I1
extends I2 and I2 extends I1,  because cyclic inheritence is illegal.
Comments
  
  Include a link with my name & email   

Submitted On 15-MAY-2003
TheHawke
I have just thought of another enhancement thats needed for
the inheritDoc tag.  Take the following situation:

public interface Something
{
        /**
         * Does soomething.
         */
        public void  doSomething();

        /**
         * Does something important.
         */
        public void  doSomethingImportant();
}

public abstract class AbstractSomething implements Something
{
        /**
         * {@inheritDoc}
         * <p>
         * This uses iteration to do something interesting.
         * </p>
         */
        public void  doSomething()
        {
                for (int i=0; i<10; i++)
                {
                }
        }

        /**
         * {@inheritDoc}
         */
        public void  doSomethingImportant()
        {
                // Actually do something
        }
}

public class ConcreteSomething extends Something
{
        /**
         * {@inheritDoc}
         * <p>
         * This decides to not do anything interesting.
         * </p>
         */
        public void  doSomething()
        {
        }
}

Whilst a little contrived, the example is valid in that
often classes extend abstract classes to provide more
efficient implementations of methods, just check out the
collections API.  Here we have ConcreteSomething deciding to
override just 1 of the methods that AbstractSomething
provides, but by using the inheritDoc tag, what happens is
that the implementation comment from AbstractSomething gets
copied with the final comment being :

        Does soomething.
        This uses iteration to do something interesting.
        This decides to not do anything interesting.

when what was wanted was

        Does soomething.
        This decides to not do anything interesting.

i.e. skipping out the implementation details added by the
abstract class.  It should be possible to specify
{@inheritDoc:className} as long as className is a superclass
or superinterface of the current class.  This would solve
the problem where a class implements two interfaces with a
method of the same signature - it would actually be possible
to specify which one you are really implementing.  The
method suggested above is not suitable, simply let the
developer specify which one they want - they ought to know!

The only way to achieve the desired output currently is to
copy and paste the comment from interface Something to class
ConcreteSomething.  And if this happened you can immediately
see that the spelling mistake is now in two places.



PLEASE NOTE: JDK6 is formerly known as Project Mustang