Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 330629 - FUP of 330264: Eclipse compiles code rejected by javac
Summary: FUP of 330264: Eclipse compiles code rejected by javac
Status: CLOSED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.5   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-18 19:16 EST by Srikanth Sankaran CLA
Modified: 2020-04-22 15:40 EDT (History)
4 users (show)

See Also:


Attachments
Self contained project with the broken ServiceReference .class file (2.19 MB, application/zip)
2012-10-17 03:10 EDT, Andrey Loskutov CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Srikanth Sankaran CLA 2010-11-18 19:16:11 EST
HEAD

After the fix for bug# 277643 went in, we no longer error
on this code, while javac5,6,7 all do.

// ------------------------8<-------------------------
interface BundleContext {
    ServiceReference< ? > getServiceReference(String clazz);
    <S> S getService(ServiceReference<S> reference);
}
interface ServiceReference<S> extends Comparable<Object> {
}

interface Bundle extends Comparable<Bundle> {
}
public class Activator  {
    public void start(BundleContext context) throws Exception {
        ServiceReference ref = context.getServiceReference("test");
        Runnable r = context.getService(ref);
    }
}
// ------------------------8<-------------------------

Needs to be investigated.
Comment 1 Andrey Loskutov CLA 2012-10-17 03:10:59 EDT
Created attachment 222442 [details]
Self contained project with the broken ServiceReference .class file

Looking at the ServiceReference .class file, one can see that this is not valid: it has 48 (1.4) Java bytecode spec version but contains attributes allowed in 1.5 only (see "signature" below).

// Compiled from ServiceReference.java (version 1.4 : 48.0, no super bit)
// Signature: <S:Ljava/lang/Object;>Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/Object;>;
public abstract interface org.osgi.framework.ServiceReference extends java.lang.Comparable

So it looks like the JDT is not considering the version marker while reading the class file and allows client code to compile using the *generics* information retrieved from "old 1.4" (broken) .class file.

I don't now what JLS says to that, but the root cause is the bad .class file which contains information it shouldn't contain. If the .class file is generated by ecj, we may have two bugs:

1) bug in compiler which generates bad .class,
2) bug in compiler which allows to use information from broken .class file
Comment 2 Srikanth Sankaran CLA 2012-10-22 00:50:03 EDT
(In reply to comment #1)
> Created attachment 222442 [details]
> Self contained project with the broken ServiceReference .class file
> 
> Looking at the ServiceReference .class file, one can see that this is not
> valid: it has 48 (1.4) Java bytecode spec version but contains attributes
> allowed in 1.5 only (see "signature" below).


See https://bugs.eclipse.org/bugs/show_bug.cgi?id=286391
Comment 3 Andrey Loskutov CLA 2012-10-22 17:27:19 EDT
(In reply to comment #2)
> See https://bugs.eclipse.org/bugs/show_bug.cgi?id=286391

Sorry, but what do you mean by that? The root cause?
Comment 4 Srikanth Sankaran CLA 2012-10-22 18:08:11 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > See https://bugs.eclipse.org/bugs/show_bug.cgi?id=286391
> 
> Sorry, but what do you mean by that? The root cause?

That there (a) is a valid configuration (jsr14 targetted classfiles) where
in a 1.4 class file, the compiler emits generic signatures and (b) when 
generic signatures are present in a class file the compiler must read them 
even when compiling a 1.4 project:

See also:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593
https://bugs.eclipse.org/bugs/show_bug.cgi?id=330537
https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565
https://bugs.eclipse.org/bugs/show_bug.cgi?id=329584
https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
https://bugs.eclipse.org/bugs/show_bug.cgi?id=329589
https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593
https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446
https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827
https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633

I am not saying the present bug is not a bug - it was raised by me after all.
Only that:
 
(In reply to comment #1)

> I don't now what JLS says to that, 

Nothing I believe.

> generated by ecj, we may have two bugs:
> 
> 1) bug in compiler which generates bad .class,

The JSR14 targetted class files explain why this is a feature and not
a bug.

> 2) bug in compiler which allows to use information from broken .class file

The several bugs I cite above indicate why this is the way it is.
Comment 5 Andrey Loskutov CLA 2012-10-23 15:19:56 EDT
(In reply to comment #4)

> That there (a) is a valid configuration (jsr14 targetted classfiles) 

Valid point, no questions

> where in a 1.4 class file, the compiler emits generic signatures and 

Hard to understand how this can be valid - 1.4 class files can't contain any generic signatures, because they were introduced in 1.5 bytecode.

> (b) when 
> generic signatures are present in a class file the compiler must read them 
> even when compiling a 1.4 project:

Still can't get this point - if the 1.4 project is compiled compiler can't (and must not) know *anything* about generics.

> See also:
> 
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=330537
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=186565
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=329584
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=329588
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=329589
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=329593
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=331446
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=328827
> https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633

Wow.

> > I don't now what JLS says to that, 
> 
> Nothing I believe.

JLS 1.4 can't say anything about this because it doesn't know anything about generics. I'm not expert enough to state it, but I guess compilers reading class files compiled with 1.4 target can't rely on ANY feature NOT described in JLS 1.4. Just imagine what would happen if compiler would somehow interpret stackmap frames from 1.4 class files? 
 
> > generated by ecj, we may have two bugs:
> > 
> > 1) bug in compiler which generates bad .class,
> 
> The JSR14 targetted class files explain why this is a feature and not
> a bug.

I never said that compilation down to 1.4 is a bug, but preserving signatures is.
 
> > 2) bug in compiler which allows to use information from broken .class file
> 
> The several bugs I cite above indicate why this is the way it is.

They all deal with different aspects of 1.4/1.5 interoperability. This case here is just another one.

In bug 331446 comment 9 I believe you are saying exactly what I say here: for 1.4 type you can't rely on any 1.5 features like type parameters etc. 

This is how javac does - if it sees 1.4 class file on the classpath, but compiles 1.5+ project code, it still can't use anything from 1.4 class file which is not 1.4 compatible.

Eclipse compiler tries to cheat here (which is actually not needed) and so we have a situation where the code is rejected by one compiler but accepted by other.
Comment 6 Srikanth Sankaran CLA 2012-10-23 20:41:33 EDT
(In reply to comment #5)

> > That there (a) is a valid configuration (jsr14 targetted classfiles) 
> 
> Valid point, no questions
> 
> > where in a 1.4 class file, the compiler emits generic signatures and 
> 
> Hard to understand how this can be valid - 1.4 class files can't contain any
> generic signatures, because they were introduced in 1.5 bytecode.

It is my understanding that compiling down to 1.4 from 1.5 is not a mode
blessed by the JLS. JSR14 targets are purely a convenience extended to a
class of users. As such there is no specification here to turn to for
hard and fast rules. While JLS/JVMS for 1.4 is naturally silent about 
generic signatures in the JSR14 target class files, we are actually 
using the *standard blessed way of doing non-standard things*, via 
attributes: ("... A Java virtual machine implementation is required to 
silently ignore any or all attributes in the attributes table of a 
ClassFile structure that it does not recognize ...". So there is nothing
wrong in a compiler emitting generic signatures into a 1.4 class file.

> 
> > (b) when 
> > generic signatures are present in a class file the compiler must read them 
> > even when compiling a 1.4 project:
> 
> Still can't get this point - if the 1.4 project is compiled compiler can't
> (and must not) know *anything* about generics.

The various bugs I cited have the background on why generic signatures must
be read from a 1.4 class file when present. All the information is there, it
takes time to read through them and glean the full picture: There has been
some going back and forth in the comments and it can make for confusing
reading on account of the fact that comments cannot be obsoleted in bugzilla.

I am putting together an example from my memory without rereading
all the text:

// ---- 1.5 code to be compiled into 1.4 class file.
interface I<T> {
    void foo(T t);
}

public abstract class X implements I<String> {
    public void foo(String s) {};
}
// ---- 1.4 code compiled agaist the binaries of code above
public class Y extends X implements I {

}
// ----

If generic signatures are not recognized from the 1.4 class file, the
compiler will refuse to compile Y saying it does not implement I#foo
which would be seen to be after erasure "void foo(Object)", but Y need
not implement this method at all, as its superclass already does.

> JLS 1.4 can't say anything about this because it doesn't know anything about
> generics. I'm not expert enough to state it, but I guess compilers reading
> class files compiled with 1.4 target can't rely on ANY feature NOT described
> in JLS 1.4. 

The whole thing is extra constitutional.

> In bug 331446 comment 9 I believe you are saying exactly what I say here:
> for 1.4 type you can't rely on any 1.5 features like type parameters etc.

Like I said earlier, comments are scattered over several bugs, there has
been a fair amount of going back and forth. in https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850#c10, I say, "Basically, 
it would appear it is a folly to drop any generic information if present at 
all."

This whole issue started as bug fix and ended up being a major project with
very many complex issues - some of which are still open.
Comment 7 Srikanth Sankaran CLA 2012-10-23 21:01:36 EDT
(In reply to comment #6)

> I am putting together an example from my memory without rereading
> all the text:

Actually the following is a better example:

// ---- 1.5 code to be compiled into 1.4 class file.
interface I<T> {
    void foo(T t);
}
 
public abstract class X implements I<String> {
}
    
// ---- 1.4 code compiled agaist the binaries of code above
public class Y extends X {
    public void foo(String s) {};
}
// ----

X being abstract can get away not implementing I#foo. Y being non-abstract 
must be seen to be implementing I#foo. If generic signatures are not present 
in 1.4 class file or if they are not processed at 1.4 source level when 
present, we will not recognize Y#foo as implementing I#foo and complain that I#void(Object) is not implemented by the concrete class Y.

There are so many variations of this problem, documented in the various
bugs.
Comment 8 Markus Keller CLA 2012-10-24 10:32:14 EDT
I don't have the complete picture, but I can just make one comment:
Java 1.4 and jsr14 are dead, and we shouldn't spend time on compatibility problems with 1.4 class files.

If problems can't be reproduced when compiling against 1.5 or later, then this is very low priority (though we could accept simple patches).
Comment 9 Srikanth Sankaran CLA 2012-10-24 12:11:23 EDT
(In reply to comment #8)
> I don't have the complete picture, but I can just make one comment:
> Java 1.4 and jsr14 are dead, and we shouldn't spend time on compatibility
> problems with 1.4 class files.

Indeed. This is not being actively worked on.
Comment 10 Andrey Loskutov CLA 2012-10-24 16:45:01 EDT
(In reply to comment #8)
> I don't have the complete picture, but I can just make one comment:
> Java 1.4 and jsr14 are dead, and we shouldn't spend time on compatibility
> problems with 1.4 class files.
> 
> If problems can't be reproduced when compiling against 1.5 or later, then
> this is very low priority (though we could accept simple patches).

I have probably better describe in which problem I currently run:

1) I have only 1.7 JLS level projects in the workspace and don't care about any 1.4 compatibility at all.
2) All those projects are compiled against Eclipse 3.7.2 platform and 1.7 JDK.
3) Eclipse 3.7.2 platform contains org.eclipse.osgi plugin which is compiled from 1.5 source to 1.4 class files, which unfortunately contain information about generic signatures.
4) Eclipse editor complains about missing generic information in my source code if I'm using just "ServiceReference", so I've changed it to "ServiceReference<S>" to make Eclipse compiler happy.
5) Now I can't build source code with ant since javac insists that ServiceReference is not a generic type.
6) I can of course remove the generic information from the source code, but as soon as somebody in the team decides to use ServiceReference<S> (or similar types from org.eclipse.osgi plugin) in another class (because Eclipse suggests it), the build will be broken again.
Comment 11 Srikanth Sankaran CLA 2012-10-24 21:58:51 EDT
(In reply to comment #10)
> (In reply to comment #8)
> > I don't have the complete picture, but I can just make one comment:
> > Java 1.4 and jsr14 are dead, and we shouldn't spend time on compatibility
> > problems with 1.4 class files.
> > 
> > If problems can't be reproduced when compiling against 1.5 or later, then
> > this is very low priority (though we could accept simple patches).
> 
> I have probably better describe in which problem I currently run:

I think this is very likely bug 330537. Unfortunately, there is no easy for
that problem.
Comment 12 Markus Keller CLA 2012-10-25 06:00:04 EDT
(In reply to comment #10)
Thanks for the explanation. You're running into this trouble because org.eclipse.osgi used the unsupported jsr14 target. In 3.9, OSGi moved to normal 1.5 (bug 369145), so this problem will eventually disappear.
Comment 13 Andrey Loskutov CLA 2012-10-25 16:26:46 EDT
(In reply to comment #12)
> In 3.9, OSGi moved to normal 1.5 (bug 369145), 
> so this problem will eventually disappear.

Sure, but 3.9 == 4.3 == migration in two or more years from now (for target platform).

Any solution possible for the compiler (which can be included in the developer platform)?
Comment 14 Stephan Herrmann CLA 2014-11-02 08:37:40 EST
Andrey, is this still an issue for you? You mentioned "two or more years" two years ago, so maybe the bug has expired? :)
Comment 15 Andrey Loskutov CLA 2014-11-02 09:22:08 EST
(In reply to Stephan Herrmann from comment #14)
> Andrey, is this still an issue for you? You mentioned "two or more years"
> two years ago, so maybe the bug has expired? :)

No, we've just given up here. And we are still on 3.7.2 as neither 4.3 nor 4.4 were good enough to migrate to. May be 4.5 could be of interest, if perspective customization and performance will be back to 3.8 state. I guess we will see progress in 2 years from now :)
Comment 16 Eclipse Genie CLA 2020-04-22 15:40:11 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug.

If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.

--
The automated Eclipse Genie.