15 RFR(XS): 8165276: Spec states that invoke the premain method in an agent class if it's public but implementation differs

serguei.spitsyn at oracle.com serguei.spitsyn at oracle.com
Mon Jun 29 17:44:38 UTC 2020


Hi David,

Thank you a lot for review and tweaking the bug title.
I've re-targeted this to 16 as was suggested by Joe.

Thanks,
Serguei


On 6/28/20 19:37, David Holmes wrote:
> Hi Serguei,
>
> These changes look good to me.
>
> Note that I tweaked the bug synopsis to make it slightly more 
> grammatically correct: that invoke -> to invoke
>
> Thanks,
> David
>
> On 26/06/2020 2:17 am, serguei.spitsyn at oracle.com wrote:
>>
>> New wevrev version is:
>> http://cr.openjdk.java.net/~sspitsyn/webrevs/2020/instr-setAccessible.2/
>>
>> Now the InstrumentationImpl.java has this new check to throw IAE with 
>> the meaningful error message:
>>
>> + // reject non-public premain or agentmain method
>> + if (!m.canAccess(null)) {
>> + String msg = "method " + classname + "." + methodname + " must be 
>> declared public";
>> + throw new IllegalAccessException(msg);
>> + }
>>
>>
>> It also includes a new negative test for non-public premain method:
>> test/jdk/java/lang/instrument/NonPublicPremainAgent.java
>>
>> I've tested the non-public agentmain as well with one of the hacked 
>> JVMTI aod tests.
>> But I gave up to make it a stand alone test as this testing framework 
>> is tricky to use for negative testing.
>> The implementation is common for premain and agentmain cases, so 
>> probably, one test
>>
>>
>> Also, I had to fix all impacted java/lang/instrument tests to make 
>> the Agent classes public.
>> The following tests required a refactoring:
>>
>> || test/jdk/java/lang/instrument/PremainClass/InheritAgent0100.java
>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1000.java
>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1100.java
>>
>>
>> They define an agent as extending an agent super class which has the 
>> premain methods defined:
>>
>>    37 class InheritAgent0101 extends InheritAgent0101Super {
>>    38
>>    39     //
>>    40     // This agent has a single argument premain() method which
>>    41     // is the one that should be called.
>>    42     //
>>    43     public static void premain (String agentArgs) {
>>    44         System.out.println("Hello from Single-Arg 
>> InheritAgent0101!");
>>    45     }
>>    46
>>    47     // This agent does NOT have a double argument premain() 
>> method.
>>    48 }
>>    49
>>    50 class InheritAgent0101Super {
>>    51
>>    52     //
>>    53     // This agent has a single argument premain() method which
>>    54     // is NOT the one that should be called.
>>    55     //
>>    56     public static void premain (String agentArgs) {
>>    57         System.out.println("Hello from Single-Arg 
>> InheritAgent0101Super!");
>>    58         throw new Error("ERROR: THIS AGENT SHOULD NOT HAVE BEEN 
>> CALLED.");
>>    59     }
>>    60
>>    61     // This agent does NOT have a double argument premain() 
>> method.
>>    62 }
>>
>>
>> Above, just one class can be made public.
>> But the InheritAgent0101Super has to be public as well as has the 
>> premain method defined.
>> These agent super classes are separated to their own files.
>> To make this refactoring to work new || customized script is introduced:
>>    test/jdk/java/lang/instrument/PremainClass/MakeJAR.sh
>>
>> The java/lang/instrument tests are passed locally.
>> I'll submit a mach5 test jobs to make sure nothing is broken.
>>
>> Thanks,
>> Serguei
>>
>>
>>
>> On 6/24/20 13:07, serguei.spitsyn at oracle.com wrote:
>>> On 6/24/20 12:44, Mandy Chung wrote:
>>>>
>>>>
>>>> On 6/24/20 12:26 PM, serguei.spitsyn at oracle.com wrote:
>>>>> On 6/24/20 05:25, David Holmes wrote:
>>>>>>
>>>>>> Ah! The test class SimpleAgent is what is not public. That seems 
>>>>>> a bug in the test.
>>>>>
>>>>> There are many such tests.
>>>>> We can break some of the existing agents by rejecting non-public 
>>>>> agent classes.
>>>>> I'm inclined to continue using the setAccessible and just add an 
>>>>> extra check for non-public premain/agentmain methods.
>>>>
>>>> There is only one non-public SimpleAgent which is shared by 
>>>> j.l.instrument tests.
>>>>   test/jdk/java/lang/instrument/SimpleAgent.java
>>>
>>> There are many such tests:
>>>
>>> test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/TestLambdaFormRetransformation.java:class 
>>> Agent implements ClassFileTransformer {
>>>
>>> test/jdk/java/lang/instrument/NativeMethodPrefixAgent.java:class 
>>> NativeMethodPrefixAgent {
>>> test/jdk/java/lang/instrument/PremainClass/NoPremainAgent.java:class 
>>> NoPremainAgent {
>>> test/jdk/java/lang/instrument/SimpleAgent.java:class SimpleAgent {
>>> test/jdk/java/lang/instrument/RetransformAgent.java:class 
>>> RetransformAgent {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0001.java:class 
>>> InheritAgent0001 extends InheritAgent0001Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0001.java:class 
>>> InheritAgent0001Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0010.java:class 
>>> InheritAgent0010 extends InheritAgent0010Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0010.java:class 
>>> InheritAgent0010Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0011.java:class 
>>> InheritAgent0011 extends InheritAgent0011Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0011.java:class 
>>> InheritAgent0011Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0100.java:class 
>>> InheritAgent0100 extends InheritAgent0100Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0100.java:class 
>>> InheritAgent0100Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0101.java:class 
>>> InheritAgent0101 extends InheritAgent0101Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0101.java:class 
>>> InheritAgent0101Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0110.java:class 
>>> InheritAgent0110 extends InheritAgent0110Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0110.java:class 
>>> InheritAgent0110Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0111.java:class 
>>> InheritAgent0111 extends InheritAgent0111Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent0111.java:class 
>>> InheritAgent0111Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1000.java:class 
>>> InheritAgent1000 extends InheritAgent1000Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1000.java:class 
>>> InheritAgent1000Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1001.java:class 
>>> InheritAgent1001 extends InheritAgent1001Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1001.java:class 
>>> InheritAgent1001Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1010.java:class 
>>> InheritAgent1010 extends InheritAgent1010Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1010.java:class 
>>> InheritAgent1010Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1011.java:class 
>>> InheritAgent1011 extends InheritAgent1011Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1011.java:class 
>>> InheritAgent1011Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1100.java:class 
>>> InheritAgent1100 extends InheritAgent1100Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1100.java:class 
>>> InheritAgent1100Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1101.java:class 
>>> InheritAgent1101 extends InheritAgent1101Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1101.java:class 
>>> InheritAgent1101Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1110.java:class 
>>> InheritAgent1110 extends InheritAgent1110Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1110.java:class 
>>> InheritAgent1110Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1111.java:class 
>>> InheritAgent1111 extends InheritAgent1111Super {
>>> test/jdk/java/lang/instrument/PremainClass/InheritAgent1111.java:class 
>>> InheritAgent1111Super {
>>>
>>>
>>> But is is not a big problem - all can be fixed.
>>>
>>>> test/hotspot/jtreg/runtime/cds/appcds/jvmti/dumpingWithAgent 
>>>> implements the agent properly (a public class and a public static 
>>>> void premain method).
>>>>
>>>> As the popular Java agents are conforming the spec (publicly 
>>>> accessible premain method), the compatibility risk is low.
>>>>
>>>> Unless such a  java agent exists and finds a strong compelling 
>>>> reason to argue that its premain method must be allowed non-public, 
>>>> I do not see the argument to change the spec to allow non-public 
>>>> agent classes.
>>>>
>>>> A bad test case is not a representative existing java agent.
>>>
>>> Okay, thanks.
>>> I'll prepare a fix with a removed setAccessible.
>>>
>>> Thanks,
>>> Serguei
>>>
>>>>
>>>> Mandy
>>>
>>



More information about the serviceability-dev mailing list