15 RFR(XS): 8165276: Spec states that invoke the premain method in an agent class if it's public but implementation differs
David Holmes
david.holmes at oracle.com
Mon Jun 29 02:37:58 UTC 2020
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