@ 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)
@ 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)
- relates to
-
JDK-6261502 (reflect) Add the functionality to screen out the "inappropriate" modifier bits
- Resolved