Bug 23431

Summary: [4.0/4.1 regression] gcj allows overriding with more restrictive access
Product: gcc Reporter: nambi s <snambi>
Component: javaAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: bug-classpath, gcc-bugs, java-prs, pinskia
Priority: P3 Keywords: accepts-invalid, patch
Version: 4.0.1   
Target Milestone: 4.1.0   
URL: http://gcc.gnu.org/ml/java-patches/2005-q3/msg00266.html
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2005-08-23 09:50:28
Bug Depends on:    
Bug Blocks: 13607    

Description nambi s 2005-08-17 05:55:52 UTC
there is an abstract class, class B which implements an interface. the method
defined by the interface, is the abstract method. Another class C extends B and
implements the method. it compiles in gcj -C.

while executing in gij, it throws an IllegalAccessError from
VMClassLoader.resolveClass.

below is the sequence.

$cat B.java
abstract class B implements javax.jms.MessageListener
{
        public B()
        {
        System.out.println("Class B instantiated");
        }

        abstract void onMessage( javax.jms.Message message );
}
matrix:~/src/java/abs_classes>
$cat C.java
class C extends B
{
        public C()
        {
                System.out.println("Class C instantiated");
        }

        void onMessage(javax.jms.Message message)
        {
                System.out.println("abstract method test implemented");
        }
}

$cat A.java
class A
{
    private C c = null;
        public A()
        {
                System.out.println("A is getting instantiated");

        c = new C();
        }

        public static void main( String[] args )
        {
                A a = new A();
        }
}

matrix:~/src/java/abs_classes>
$gcj --classpath=.:jms.jar -C *.java

there is a jms.jar file in the current directry.

matrix:~/src/java/abs_classes>
$gij --cp ".:jms.jar" A
A is getting instantiated
Exception in thread "main" java.lang.IllegalAccessError: C.onMessage
(Ljavax.jms.Message;)V
   at java.lang.VMClassLoader.resolveClass(java.lang.Class)
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
   at java.lang.Class.initializeClass()
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
   at A.A() (Unknown Source)
   at A.main(java.lang.String[]) (Unknown Source)
   at gnu.java.lang.MainThread.call_main()
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
   at gnu.java.lang.MainThread.run() (/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)

sorry for pasting the source code. it is too difficult to explain it otherwise.

gcj -v --help 
.
.
.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/otp/software/gcc/4.0.1
Thread model: posix
gcc version 4.0.1
Comment 1 nambi s 2005-08-19 06:17:05 UTC
some more analysis of the problem.

looks like this bug has been introduced in gcj 4.0.1
it works correctly in gcj 3.3.3 and javac 1.4.2, ie it gives an error while
compiling. please look below, to see the messages. but gij fails to run. it
should give an compile time error message.

hope it helps.

matrix:/home/snambi/src/java/abs_classes>
$gcj -C --classpath .:./jms.jar B.java C.java
B.java:9: error: Class `B' must override `B.onMessage(javax.jms.Message)' with a
public method in order to implement interface `javax.jms.MessageListener'.
        abstract void onMessage( javax.jms.Message message );
                         ^
1 error
matrix:/home/snambi/src/java/abs_classes>
$export JAVA_HOME=/otp/software/java/j2sdk1.4.2_08/
matrix:/home/snambi/src/java/abs_classes>
$export PATH=$PATH:$JAVA_HOME/bin
matrix:/home/snambi/src/java/abs_classes>
$javac -classpath .:./jms.jar B.java C.java
B.java:9: onMessage(javax.jms.Message) in B cannot implement
onMessage(javax.jms.Message) in javax.jms.MessageListener; attempting to assign
weaker access privileges; was public
        abstract void onMessage( javax.jms.Message message );
                      ^
C.java:8: onMessage(javax.jms.Message) in C cannot implement
onMessage(javax.jms.Message) in javax.jms.MessageListener; attempting to assign
weaker access privileges; was public
         void onMessage(javax.jms.Message message)
              ^
2 errors
matrix:/home/snambi/src/java/abs_classes>
$/otp/software/gcc/4.0.1/bin/gcj -C --classpath .:./jms.jar B.java C.java

matrix:/home/snambi/src/java/abs_classes>
$/otp/software/gcc/4.0.1/bin/gcj -C --classpath .:./jms.jar B.java C.java A.java

matrix:/home/snambi/src/java/abs_classes>
$/otp/software/gcc/4.0.1/bin/gij --classpath .:./jms.jar A
A is getting instantiated
Exception in thread "main" java.lang.IllegalAccessError: C.onMessage
(Ljavax.jms.Message;)V
   at java.lang.VMClassLoader.resolveClass(java.lang.Class)
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
   at java.lang.Class.initializeClass()
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
   at A.A() (Unknown Source)
   at A.main(java.lang.String[]) (Unknown Source)
   at gnu.java.lang.MainThread.call_main()
(/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
(In reply to comment #0)
> there is an abstract class, class B which implements an interface. the method
> defined by the interface, is the abstract method. Another class C extends B and
> implements the method. it compiles in gcj -C.
> 
> while executing in gij, it throws an IllegalAccessError from
> VMClassLoader.resolveClass.
> 
> below is the sequence.
> 
> $cat B.java
> abstract class B implements javax.jms.MessageListener
> {
>         public B()
>         {
>         System.out.println("Class B instantiated");
>         }
> 
>         abstract void onMessage( javax.jms.Message message );
> }
> matrix:~/src/java/abs_classes>
> $cat C.java
> class C extends B
> {
>         public C()
>         {
>                 System.out.println("Class C instantiated");
>         }
> 
>         void onMessage(javax.jms.Message message)
>         {
>                 System.out.println("abstract method test implemented");
>         }
> }
> 
> $cat A.java
> class A
> {
>     private C c = null;
>         public A()
>         {
>                 System.out.println("A is getting instantiated");
> 
>         c = new C();
>         }
> 
>         public static void main( String[] args )
>         {
>                 A a = new A();
>         }
> }
> 
> matrix:~/src/java/abs_classes>
> $gcj --classpath=.:jms.jar -C *.java
> 
> there is a jms.jar file in the current directry.
> 
> matrix:~/src/java/abs_classes>
> $gij --cp ".:jms.jar" A
> A is getting instantiated
> Exception in thread "main" java.lang.IllegalAccessError: C.onMessage
> (Ljavax.jms.Message;)V
>    at java.lang.VMClassLoader.resolveClass(java.lang.Class)
> (/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
>    at java.lang.Class.initializeClass()
> (/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
>    at A.A() (Unknown Source)
>    at A.main(java.lang.String[]) (Unknown Source)
>    at gnu.java.lang.MainThread.call_main()
> (/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
>    at gnu.java.lang.MainThread.run() (/otp/software/gcc/4.0.1/lib/libgcj.so.6.0.0)
> 
> sorry for pasting the source code. it is too difficult to explain it otherwise.
> 
> gcj -v --help 
> .
> .
> .
> Target: i686-pc-linux-gnu
> Configured with: ../configure --prefix=/otp/software/gcc/4.0.1
> Thread model: posix
> gcc version 4.0.1

Comment 2 Tom Tromey 2005-08-22 19:12:03 UTC
Here is a test case that needs only libgcj:

abstract class B implements Runnable
{
  public B() { }
  abstract void run();
}

class C extends B
{
  void run() { }
}

class A
{
    private C c = null;
        public A()
        {
                System.out.println("A is getting instantiated");

        c = new C();
        }

        public static void main( String[] args )
        {
                A a = new A();
        }
}


I'm changing the synopsis of this PR.  It is not a gij bug but rather
a gcj bug.
Comment 3 Ranjit Mathew 2005-08-23 09:50:27 UTC
Changed synopsis and component. Added keyword.

Interestingly, the following is (wrongly) accepted:
------------------------- 8< -------------------------
interface MyRunnable
{
  public void run( );
}

class Snafu implements MyRunnable
{
  private void run( ) { }
}
------------------------- 8< -------------------------

but *not* the following:
------------------------- 8< -------------------------
abstract class MyRunnable
{
  public abstract void run( );
}

class Snafu extends MyRunnable
{
  private void run( ) { }
}
------------------------- 8< -------------------------
Comment 4 Ranjit Mathew 2005-08-23 18:26:24 UTC
I have proposed a patch for this problem:

  http://gcc.gnu.org/ml/java-patches/2005-q3/msg00266.html
Comment 5 GCC Commits 2005-09-05 14:57:38 UTC
Subject: Bug 23431

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	rmathew@gcc.gnu.org	2005-09-05 14:57:27

Modified files:
	gcc/java       : ChangeLog typeck.c parse.y 

Log message:
	PR java/23431
	* typeck.c (lookup_do): Look up interfaces for the original class,
	not the base class.
	* parse.y (java_check_regular_methods): Fix diagnostic message for
	more restrictive overriding of a method from an interface.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/ChangeLog.diff?cvsroot=gcc&r1=1.1659&r2=1.1660
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/typeck.c.diff?cvsroot=gcc&r1=1.79&r2=1.80
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/parse.y.diff?cvsroot=gcc&r1=1.552&r2=1.553

Comment 6 GCC Commits 2005-09-05 15:04:49 UTC
Subject: Bug 23431

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	rmathew@gcc.gnu.org	2005-09-05 15:04:40

Modified files:
	libjava        : ChangeLog 
	libjava/testsuite/libjava.jacks: jacks.xfail 
Added files:
	libjava/testsuite/libjava.compile: PR23431_1.java 
	                                   PR23431_1.xfail 
	                                   PR23431_2.java 
	                                   PR23431_2.xfail 

Log message:
	Testsuite changes for PR java/23431.
	* testsuite/libjava.jacks/jacks.xfail: Remove 8.1.1.1-12 and
	8.4.6.2-hiding-5.
	* testsuite/libjava.compile/PR23431_1.java: New testcase.
	* testsuite/libjava.compile/PR23431_2.java: Likewise.
	* testsuite/libjava.compile/PR23431_1.xfail: New file.
	* testsuite/libjava.compile/PR23431_2.xfail: Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.3732&r2=1.3733
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jacks/jacks.xfail.diff?cvsroot=gcc&r1=1.30&r2=1.31
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.compile/PR23431_1.java.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.compile/PR23431_1.xfail.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.compile/PR23431_2.java.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.compile/PR23431_2.xfail.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 7 Ranjit Mathew 2005-09-05 15:06:34 UTC
Fix checked in to mainline.
Comment 8 Andrew Pinski 2005-09-05 15:09:46 UTC
*** Bug 23655 has been marked as a duplicate of this bug. ***