JDK-7111664 : javac behavior and reported bug questionable
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u29
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2011-11-14
  • Updated: 2012-05-25
  • Resolved: 2011-12-12
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :

Got an interface to force clone() to be implemented (ICloneable).
This interface is used in other interfaces (NoCloneError_[1-4] and
CloneError) as type-parameter for these interfaces.

Compiling CloneError.java with javac I get the following error:

----------------------------------------------------------------------------
  strange\CloneError.java:13: clone() in java.lang.Object cannot implement
  clone() in strange.ICloneable; attempting to assign weaker access
  privileges; was public
  public interface CloneError<T extends CloneableItf & AnyItf> {
                              ^
----------------------------------------------------------------------------

... but only if it is compiled with pre-existing .class-files of the other used
interfaces (see below "javac-behavior").

Besides the behavior of javac, also the question is if this is an error, as
ICloneable requires Object clone() to be public-ly implemented for any given
class T.

javac-behavior:

  compiling all the classes at once, without any .class-file existing before
  (command: javac strange\*.java) compiles everything without errors.

  compiling the base interfaces (ICloneable, CloneableItf, AnyItf) before and
  then only CloneError.java, gives the above mentioned error
  
  special case: NoCloneError_4.java:
    compiles ok, if class CCloneable.java is compiled before, else above error



REGRESSION.  Last worked in version 6u29

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
see description


ERROR MESSAGES/STACK TRACES THAT OCCUR :
  strange\CloneError.java:13: clone() in java.lang.Object cannot implement
  clone() in strange.ICloneable; attempting to assign weaker access
  privileges; was public
  public interface CloneError<T extends CloneableItf & AnyItf> {
                              ^


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package strange;

/*
 * using this interface as substitue for "CloneableItf & AnyItf" in
 * type-parameters prevents the clone()-error (see NoCloneError1.java)
 */
public interface AnyCloneable
  extends CloneableItf, AnyItf {
  /*empty*/
}

package strange;

public interface AnyItf {
  String any();
}

package strange;

public class CCloneable
  implements ICloneable {
  @Override
  public Object clone() throws CloneNotSupportedException {
    return this;
  }
}

package strange;

public interface CloneableItf
  extends ICloneable {
  String hello();
}

package strange;

/*
 * compile-error:
 *
 * ----------------------------------------------------------------------------
 *   strange\CloneError.java:13: clone() in java.lang.Object cannot implement
 *   clone() in strange.ICloneable; attempting to assign weaker access
 *   privileges; was public
 *   public interface CloneError<T extends CloneableItf & AnyItf> {
 *                               ^
 * ----------------------------------------------------------------------------
 *
 * (mis-)behavior of javac in jdk 6 (update 29):
 *
 *   1) first remove all class-files, then just run compile
 *      "javac strange\CloneError.java" - which won't give you any errors
 *
 *   2) then run compile "javac strange\CloneError.java" again and you will
 *      get the above mentioned "clone()-error"
 *
 * javac of jdk 5 behaves similar to jdk 6
 *
 * javac of jdk 7 always produces the same error
 *
 */
public interface CloneError<T extends CloneableItf & AnyItf> {
  void dummy();
}

package strange;

public interface ICloneable {
  public Object clone() throws CloneNotSupportedException;
}

package strange;

public interface NoCloneError_1<T extends ICloneable> {
  void dummy();
}

package strange;

public interface NoCloneError_2<T extends CloneableItf> {
  void dummy();
}

package strange;

public interface NoCloneError_3<T extends AnyCloneable> {
  void dummy();
}

package strange;

/*
 * javac 6:
 *   compiles ok if CCloneable.class exists before, else clone()-error
 */
public interface NoCloneError_4<T extends CCloneable & CloneableItf & AnyItf> {
  void dummy();
}

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

CUSTOMER SUBMITTED WORKAROUND :
refactoring code

Comments
EVALUATION Duplicate of 6946211. The specification is unclear in this area: see 7120669. Until the specification can be clarified, javac's behavior is reasonable, though inconvenient.
12-12-2011