JDK-6868371 : Javac creates method signatures with volatile accessor
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u14
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_2.5.1
  • CPU: sparc
  • Submitted: 2009-08-04
  • Updated: 2017-05-19
  • Resolved: 2009-08-04
Related Reports
Relates :  
Description
@ An incorrect modifier value (volatile on a method) is being returned while calling
@ java.lang.reflect.Method.getModifiers() when compared JDK 1.6.0 with JDK 1.5.0 for a
@ method after loading the class.
@ .
@ The issue has been reproduced with both JRockit and Sun JDK.
@
@ The produced byte code reflects this fact as it contains the volatile description for certain method when using JDK 1.6.0.
@ .
@ Reproducer
@ ----------
@ Please find the Sun_javac_bug_repro.zip enclosed. Please note that it has
@ dependency on javax.ejb and javax.naming packages, and these are included in the lib folder. So, please add the
@ javax.ejb_3.0.1.jar to the CLASSPATH (fully qualified).
@ .
@ To run the testcase, just ensure you have . in CLASSPATH as well.
@ javac *.java
@ java -cp .;%classpath% Test
@ .
@ .
@ Please note the values returned for ejb*() methods has different
@ modifiers (the addition of volatile in JDK 1.6.0) in both JDKs as per output from testcase below.
@ .
@ Output from standalone JDK testcase
@ .
@ For JDK 1.5.0_15 (also tried with JDK 1.5.0_19)
@ ----------------
@ Method writeSessionData() has Modifier Value public
@ Method writeTransaction() has Modifier Value public
@ Method readTransaction() has Modifier Value public
@ Method writeTransactionToBackend() has Modifier Value public abstract
@ Method ejbActivate() has Modifier Value public
@ Method ejbPassivate() has Modifier Value public
@ Method ejbRemove() has Modifier Value public
@ Method ejbCreate() has Modifier Value public
@ Method setSessionContext() has Modifier Value public abstract
@ .
@ For JDK 1.6.0_05 (also tried with JDK 1.6.0_14)
@ ----------------
@ Method writeSessionData() has Modifier Value public
@ Method writeTransaction() has Modifier Value public
@ Method readTransaction() has Modifier Value public
@ Method writeTransactionToBackend() has Modifier Value public abstract
@ Method ejbRemove() has Modifier Value public volatile
@ Method ejbPassivate() has Modifier Value public volatile
@ Method ejbCreate() has Modifier Value public volatile
@ Method ejbActivate() has Modifier Value public volatile
@ Method setSessionContext() has Modifier Value public abstract
@
@ ------------------------------------------------------
@  
@ Internal analysis:
@ .
@ Both JRockit and SUN JVM displays the same output, both for 1.5.0 and 1.6.0.
@ If one takes a look at the bytecode generated between 1.6.0 and 1.5.0, one
@ can see that there has been some changes to the bytecode layout.
@ .
@ In addition, the "weird" output with for instance:
@ .
@ Method ejbRemove() has Modifier Value public volatile (1.6.0) compared to
@ Method ejbRemove() has Modifier Value public (1.5.0)
@ .
@ has a logical explanation. Of course volatile cannot be applied to methods,
@ but this is just an output error since the methods for 1.6.0 has become what
@ is called Java Bridge Methods (designated internally in the JVM with
@ constant ACC_BRIDGE. This constant has the same value as ACC_VOLATILE so
@ thats why the output looks a bit strange. ACC_BRIDGE has practically no
@ purpose except for the internal compiler and javac will generate such
@ bridgemethods in different contexts, like for internal classes, interfaces,
@ co-variant returns etc...)
@ .
@ The code runs ok even after adding -Xverify:all (bytecode verification) so
@ the code is absolutely valid and is probably correct. Its only the output
@ which gives volatile keyword instead of ACC_BRIDGE (for which there is no
@ keyword).
@ .
@ I hope this explains things a bit. Im not considering this to be a JRockit
@ issue or even a SUN issue (with javac) at the moment.
@ .
@
@  ### From customer that reported the problem ###
@ .
@ So, output needs to be corrected, it cannot just reuse the same volatile
@ modifier. Hence, it still looks like a bug to me as output value needs to be
@ fixed.
*** MGRONLUN  07/30/09 08:13 am ***
@ Hmm...I dont know straightoff. Since we are using the javac compiler which
@ comes from SUN i guess we need to file a bug with SUN on this issue. It might
@ be possible for us to suppress the output in someway in JRockit, but I would
@ rather have us compatible with SUN javac compiler.
@ .
@ So if you dont get the volatile modifier in the output for this, you are ok?
@ .
@ Let me investigate what needs to be done here.
@ .
@ /Markus JRockit Sustaining Engineering
*** VIKBHATI  07/30/09 10:01 am ***
@ Yes. If volatile cannot be used for methods, it needs to return either a
@ different modifier or exclude volatile.
*** VIKBHATI  07/30/09 11:30 pm ***
@ If we change InfrastructureStatefulBean class from package access to public
@ access, it returns correct modifier.
@ .
@  public abstract class InfrastructureStatefulBean
@     implements SessionBean
@ .
@   from
@ .
@  abstract class InfrastructureStatefulBean
@     implements SessionBean
@ .
@ So, this will need to be classified as bug if one of the classes in hierarchy
@ has package access.
@
@
@ Thank you in advance for your help
@ Markus Gronlund
@ Oracle JRockit
@ Sustaining Engineering
@ ###@###.###

Please contact me for the reproducer


Excerpt of compiled byte code (1.6.0):

 public volatile void ejbPassivate() throws java.rmi.RemoteException
   *) 0 Code [maxstack=1 , maxlocals=1, length=5] {
         0:    aload_0
         1:    invokespecial	InfrastructureStatefulBean.ejbPassivate ()V (4)
         4:    return
      }
      *) 0 LineNumberTable[pc, line] (
            0 : 11
         )
      1 Exceptions(java.rmi.RemoteException)

Comments
PUBLIC COMMENTS A limitation of the core reflection API is that modifiers are the JVM-level modifiers as opposed to language-level modifiers and that the modifiers are represented as the bits of an integer without the context of the kind of element the modifier came from. This leads to the "volatile method" problem. It would be possible to add API to filter out the inappropriate bits; see 6261502 (reflect) Add the functionality to screen out the "inappropriate" modifier bits
05-08-2009

EVALUATION There is no such thing as "volatile" for a method. The access flag 0x0040 is defined to mean "volatile" for fields *only*. For methods, it is a special flag, added in v49 class files, that indicates the method is a bridge method. Any tool that claims to read v49 class files must be aware of the changes that were made for v49 class files. See JVMS 2nd ed, at http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#29882 In particular, refer to sections 2.9.1. Field modifiers, which lists "volatile" as a valid modifier and 2.10.3, "Method modifiers" which does not. Also see sections 4.5. and 4.6. Bridge methods, and ACC_BRIDGE, are defined in Clarifications and Amendments to the Java Virtual Machine Specification, available at http://java.sun.com/docs/books/jvms/second_edition/jvms-clarify.html. In particular, see section 4.7 in http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf which is linked to from the Clarifications and Amendments page.
04-08-2009