Bug 495396 - Inherited annotations are not visible on bridge methods (JDK 6695379)
Summary: Inherited annotations are not visible on bridge methods (JDK 6695379)
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.5.1   Edit
Hardware: PC Linux
: P3 normal with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Jay Arthanareeswaran CLA
QA Contact:
URL:
Whiteboard: stalebug bulk move
Keywords:
: 525922 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-06-03 08:53 EDT by Ralf Thaenert CLA
Modified: 2023-10-15 21:40 EDT (History)
9 users (show)

See Also:


Attachments
Maven Project example to reproduce this issue (10.62 KB, application/zip)
2016-06-03 08:53 EDT, Ralf Thaenert CLA
no flags Details
Version information for which this bug does NOT occur (110.33 KB, image/png)
2016-06-13 08:54 EDT, Ralf Thaenert CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Thaenert CLA 2016-06-03 08:53:18 EDT
Created attachment 262221 [details]
Maven Project example to reproduce this issue

This was apparently already reported in fixed for other versions in https://bugs.eclipse.org/437446 and https://bugs.eclipse.org/427745. 
I do get the same problem using Eclipse Mars (4.5.1) with JDT plugin version .

For the OpenJDK compiler this was fixed with JDK-6695379.

In the attached exported Project there are two classes:

@Stateless
abstract class BeanSuperclass {

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public void doSomething() {

    }
}

public class Bean extends BeanSuperclass { }

I would have expected to see the TransactionAttribute annotation on the bridge method of the inherited class.
When compiled using the OpenJDK compiler (with maven from the command line the generated class file for Bean.java shows the @TransactionAttribute annotation on the bridge method doSomething:

  public void doSomething();
    descriptor: ()V 
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #2                  // Method de/thaenert/test/BeanSuperclass.doSomething:()V
         4: return
      LineNumberTable:
        line 10: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lde/thaenert/test/Bean;
    RuntimeVisibleAnnotations:
      0: #14(#15=e#16.#17)
}

If compiled from Eclipse however the annotation is not visible:

  public void doSomething();
    descriptor: ()V 
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    RuntimeVisibleAnnotations:
      0: #16(#17=e#18.#19)
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #20                 // Method de/thaenert/test/BeanSuperclass.doSomething:()V
         4: return
      LineNumberTable:
        line 1: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
}
Comment 1 Ralf Thaenert CLA 2016-06-03 08:56:00 EDT
Forgot the JDT plugin version: 3.11.1.v20150904-0015.
Comment 2 Jay Arthanareeswaran CLA 2016-06-03 10:15:28 EDT
We will look at it during 4.7
Comment 3 Stephan Herrmann CLA 2016-06-03 12:37:20 EDT
In the forum you said this worked with older versions of JDT. If that's true, can you please also state the exact version where you see it working - ideally as the version of plugin org.eclipse.jdt.core? TIA.
Comment 4 Ralf Thaenert CLA 2016-06-06 02:56:18 EDT
Sorry, forgot that: On a colleagues machine using Eclipse Luna the bug does not appear. That was Eclipse with JDT plugin version:  3.10.1.v20150204-1700.
Comment 5 Stephan Herrmann CLA 2016-06-07 17:33:29 EDT
(In reply to Ralf Thaenert from comment #4)
> Sorry, forgot that: On a colleagues machine using Eclipse Luna the bug does
> not appear. That was Eclipse with JDT plugin version:  3.10.1.v20150204-1700.

That's the version I cannot identify. 3.10.1 should be time-stamped v20140902-0626. 
Closest to 20150204 would be 3.10.2.v20150120-1634 - neither the micro version nor the qualifier really matches.

Where did he get that version from??
Comment 6 Ralf Thaenert CLA 2016-06-13 08:54:49 EDT
Created attachment 262405 [details]
Version information for which this bug does NOT occur
Comment 7 Ralf Thaenert CLA 2016-06-13 08:56:22 EDT
This version was at some point downloaded regularly from http://www.eclipse.org/downloads/ as far as i know. Updates might have been installed. 

Maybe the attachment helps?
Comment 8 Stephan Herrmann CLA 2016-06-13 10:35:53 EDT
I see the misunderstanding now: I asked for version of plugin org.eclipse.jdt.core, you answered the version of feature org.eclipse.jdt.

At that level, what you show perfectly matches 4.4.2.

BTW, @Jay: is that intended or a process glitch: to have jdt feature 3.10.1 in 4.4.2 holding jdt.core at 3.10.2? What I'm surprised about is the .1 in the feature version.
Comment 9 Jay Arthanareeswaran CLA 2016-06-13 23:09:36 EDT
(In reply to Stephan Herrmann from comment #8)
> I see the misunderstanding now: I asked for version of plugin
> org.eclipse.jdt.core, you answered the version of feature org.eclipse.jdt.
> 
> At that level, what you show perfectly matches 4.4.2.
> 
> BTW, @Jay: is that intended or a process glitch: to have jdt feature 3.10.1
> in 4.4.2 holding jdt.core at 3.10.2? What I'm surprised about is the .1 in
> the feature version.

Let me also mention that jdt.ui might have a different version too. Anyway, I don't know the answer to your question.

Dani would know.
Comment 10 Dani Megert CLA 2017-01-06 12:20:23 EST
(In reply to Jay Arthanareeswaran from comment #9)
> > BTW, @Jay: is that intended or a process glitch: to have jdt feature 3.10.1
> > in 4.4.2 holding jdt.core at 3.10.2? What I'm surprised about is the .1 in
> > the feature version.

> Dani would know.

Sorry for the late reply guys!

This is a bug. Whenever a plug-in of a feature increases a segment (major, minor or service), the feature needs to adopt this.  For details see https://wiki.eclipse.org/Version_Numbering#Versioning_features.
Comment 11 Jay Arthanareeswaran CLA 2017-01-09 00:04:03 EST
(In reply to Dani Megert from comment #10)
> This is a bug. Whenever a plug-in of a feature increases a segment (major,
> minor or service), the feature needs to adopt this.  For details see
> https://wiki.eclipse.org/Version_Numbering#Versioning_features.

For the records, since then, the version of jdt.core and jdt.feature have aligned to be 3.13.0.
Comment 12 Stephan Herrmann CLA 2017-05-25 16:38:32 EDT
In all the discussion about versions I missed this:

(In reply to Ralf Thaenert from comment #0)
> [...]
> When compiled using the OpenJDK compiler (with maven from the command line
> the generated class file for Bean.java shows the @TransactionAttribute
> annotation on the bridge method doSomething:
> 
>   public void doSomething();
>     descriptor: ()V 
>     flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
>     Code:
>       stack=1, locals=1, args_size=1
>          0: aload_0
>          1: invokespecial #2                  // Method
> de/thaenert/test/BeanSuperclass.doSomething:()V
>          4: return
>       LineNumberTable:
>         line 10: 0
>       LocalVariableTable:
>         Start  Length  Slot  Name   Signature
>             0       5     0  this   Lde/thaenert/test/Bean;
>     RuntimeVisibleAnnotations:
>       0: #14(#15=e#16.#17)
> }
> 
> If compiled from Eclipse however the annotation is not visible:
> 
>   public void doSomething();
>     descriptor: ()V 
>     flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
>     RuntimeVisibleAnnotations:
>       0: #16(#17=e#18.#19)
>     Code:
>       stack=1, locals=1, args_size=1
>          0: aload_0
>          1: invokespecial #20                 // Method
> de/thaenert/test/BeanSuperclass.doSomething:()V
>          4: return
>       LineNumberTable:
>         line 1: 0
>       LocalVariableTable:
>         Start  Length  Slot  Name   Signature
> }

The main difference I'm seeing is in the order of attributes:
- javac produces RuntimeVisibleAnnotations after Code
- ecj produces RuntimeVisibleAnnotations *before* Code

Am I missing anything?
Comment 13 Stephan Herrmann CLA 2017-10-12 08:32:02 EDT
*** Bug 525922 has been marked as a duplicate of this bug. ***
Comment 14 Stephan Herrmann CLA 2017-10-12 08:32:57 EDT
(In reply to Stephan Herrmann from comment #13)
> *** Bug 525922 has been marked as a duplicate of this bug. ***

See javap output in bug 525922 comment 1, which indeed indicates a difference between compilers.
Comment 15 Thomas Schindl CLA 2017-10-12 17:38:29 EDT
Before this change goes in we need to make sure that eg Eclipse DI who currently relies on ecj behavior is fixed - see bug 525925 which i'll fix in M3 and even most likely backport to Oxygen.2
Comment 16 Antonio Bustorff CLA 2018-02-12 15:12:10 EST
Just an additional info: this depends on the order that *.java files are passed to compiler.

consider the following example (that has no dependencies besides JRE) using the compiler http://central.maven.org/maven2/org/eclipse/jdt/ecj/3.13.100/ecj-3.13.100.jar

Base.java:
----------------------------------------------
import javax.annotation.PostConstruct;

abstract class Base {
    @PostConstruct
    public void update() {
    }
}
----------------------------------------------

Concrete.java:
----------------------------------------------
public class Concrete extends Base {
}
----------------------------------------------

when compiling with:
    java -jar ecj-3.13.100.jar -1.8 Concrete.java Base.java 

every is ok, the @PostContruct annotation was properly copied to the bridge method

but if we reserve the java files order and compile with:   
    java -jar ecj-3.13.100.jar -1.8 Base.java Concrete.java

then there is the error where the annotation is not in the bridge method.

(you can check it using javap, I didn't add it here to avoid creating distractions)

For me this is a critical error as the ecj result is erratic, untrustful and almost impossible to detect until we get stuck in strange runtime problems.
We have behaviour that depends on runtime annotations (like in Ralf's example we depend on those annotations to control transactions)

in this small example is easy to control the arguments order but in the real project it is something that we cant control. 

Considering this, the comment from Thomas Schindl  "Before this change goes in we need to make sure that eg Eclipse DI who currently relies on ecj behavior is fixed "
should be reconsidered as currently there is no expected behaviour, so no one can rely on it.
Comment 17 Manoj N Palat CLA 2018-05-21 06:22:50 EDT
Bulk move out of 4.8

@Jay - retargetting to 4.9 - please modify the target as appropriate
Comment 18 Sam Brannen CLA 2018-08-16 05:09:25 EDT
(In reply to Manoj Palat from comment #17)
> Bulk move out of 4.8
> 
> @Jay - retargetting to 4.9 - please modify the target as appropriate

I see that the "Target Milestone 4.9" just got removed.

When can we expect to see this fix?
Comment 19 Jay Arthanareeswaran CLA 2018-08-16 06:22:03 EDT
This was part of a bulk move and I hadn't made any progress on this. Will see if this can be fit in during RC1 after I am done with remaining Java 11 support.
Comment 20 Sam Brannen CLA 2018-08-16 10:42:07 EDT
(In reply to Jay Arthanareeswaran from comment #19)
> This was part of a bulk move and I hadn't made any progress on this. Will
> see if this can be fit in during RC1 after I am done with remaining Java 11
> support.

OK. Thanks for the clarification!
Comment 21 Jay Arthanareeswaran CLA 2018-08-30 12:03:54 EDT
Moving out to 4.10
Comment 22 Eclipse Genie CLA 2018-11-27 05:02:08 EST
New Gerrit change created: https://git.eclipse.org/r/133108
Comment 23 Stephan Herrmann CLA 2018-11-27 06:22:32 EST
(In reply to Eclipse Genie from comment #22)
> New Gerrit change created: https://git.eclipse.org/r/133108

Jay, which problem are you addressing here? Is it bug 525922 comment 1? Did you see (comment 12) that in one situation the difference is only in the order of classfile attributes?
Comment 24 Jay Arthanareeswaran CLA 2018-11-27 08:22:35 EST
(In reply to Stephan Herrmann from comment #23)
> (In reply to Eclipse Genie from comment #22)
> > New Gerrit change created: https://git.eclipse.org/r/133108
> 
> Jay, which problem are you addressing here? Is it bug 525922 comment 1? Did
> you see (comment 12) that in one situation the difference is only in the
> order of classfile attributes?

Yes, but I thought the issue you observed in comment #12 was a non-issue. BTW, the patch I posted is an experimental one, just wanted to know how many tests I will break :)
Comment 25 Manoj N Palat CLA 2019-02-11 04:28:00 EST
Bulk move out of 4.11
Comment 26 Jay Arthanareeswaran CLA 2019-05-20 08:02:40 EDT
I updated the path to take care of the failures. But still better to push it out to 4.13 when I will release this after a once-over and a test.
Comment 27 Manoj N Palat CLA 2019-08-27 02:37:17 EDT
Bulk Move Out of 4.13
Comment 28 Eclipse Genie CLA 2021-08-17 01:16:13 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.

If you have further information on the current state of the bug, please add it. 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.
Comment 29 Sam Brannen CLA 2022-07-06 05:40:20 EDT
This is still a bug in Eclipse.

Without the `!runningInEclipse` check, the following test in the Spring Framework still fails in Eclipse IDE 4.24.0.

https://github.com/spring-projects/spring-framework/blob/d533eb4a55baa9e03850801c30071af33bb9cbc8/spring-core/src/test/java/org/springframework/core/annotation/MergedAnnotationsTests.java#L931-L939
Comment 30 Yanming Zhou CLA 2023-10-15 21:40:33 EDT
Still not resolved by 4.29.0.

------
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class TestMe {
	public static void main(String[] args) throws Exception {
		Method bridgeMethod = MyMapper.class.getMethod("map", Object.class);
		System.out.println("Annotation on method: " + bridgeMethod.isAnnotationPresent(MyAnnotation.class));

		Parameter parameter = bridgeMethod.getParameters()[0];
		System.out.println("Annotation on parameter: " + parameter.isAnnotationPresent(MyAnnotation.class));

	}

	public class MyMapper implements Mapper<Integer, Integer> {

		@MyAnnotation
		public Integer map(@MyAnnotation Integer i) {
			return i;
		}

	}

	public interface Mapper<A, B> {
		B map(A a);
	}

	@Retention(RUNTIME)
	@Target({ METHOD, PARAMETER })
	public @interface MyAnnotation {

	}

}