Jigsaw EA feedback for elasticsearch

Peter Levart peter.levart at gmail.com
Sat Sep 12 12:18:19 UTC 2015


Right,

So even the interface is optional (as it does not exist on some 
platforms). The important thing is that it is public and exported. The 
following idiom might have been OK before jigsaw:

instance.getClass().getMethod(...);

But even then you might have ended up with a Method in a non-public 
class, so you were forced to use .setAccessible(true) to invoke it.

After jigsaw, it is very likely that the implementation class is not 
even exported.


Regards, Peter

On 09/12/2015 01:14 PM, Uwe Schindler wrote:
> Hi Peter,
>
> we fixed that already (in Elasticsearch and Apache Solr): https://goo.gl/st9mm7 (variant of Apache Solr)
>
> The issue is: you cannot "import" the sun.management bean into your source code, because this makes it fail to compile with other non-Oracle/OpenJDK JVMs, like IBM's J9 or Android. So we need reflection here.
> But what you can do is: use Class#forName() to look up the sun.management bean interface class and then reflect on that one. As the interface is public and exported, this works without setAccessible. You then just need to cast the OperatingSystemMXBean to that interface and invoke the previously reflected "public" interface method. This is what the above patch does.
>
> Uwe
>
> P.S.: This is why we use the "forbidden-apis" Maven/Ant/Gradle plugin to detect stuff like using non-standardized or unsafe APIs: https://github.com/policeman-tools/forbidden-apis ; this tool will fail your build whenever you use methods wich are not part of the Standard JDK. You can also forbid methods like String#toLowerCase(), because its locale dependent... You will not find any use of String#toLowerCase() without an explicit Locale anywhere in Lucene/Solr/Elasticsearch source code.
>
> -----
> Uwe Schindler
> uschindler at apache.org
> ASF Member, Apache Lucene PMC / Committer
> Bremen, Germany
> http://lucene.apache.org/
>> -----Original Message-----
>> From: jigsaw-dev [mailto:jigsaw-dev-bounces at openjdk.java.net] On Behalf
>> Of Peter Levart
>> Sent: Saturday, September 12, 2015 12:27 PM
>> To: Robert Muir; Alan Bateman
>> Cc: jigsaw-dev at openjdk.java.net
>> Subject: Re: Jigsaw EA feedback for elasticsearch
>>
>> Hi Robert,
>>
>> On 09/11/2015 10:58 PM, Robert Muir wrote:
>>> On Fri, Sep 11, 2015 at 6:09 AM, Alan Bateman
>> <Alan.Bateman at oracle.com> wrote:
>>>> I'm not sure that I understand the issue here but just to say that
>>>> the com.sun.management API is a documented/supported API and it
>>>> exported by module jdk.management:
>>>>
>>>> $ java -listmods:jdk.management
>>>>
>>>> jdk.management at 9.0
>>>>     requires public java.management
>>>>     requires mandated java.base
>>>>     exports com.sun.management
>>>>     conceals com.sun.management.internal
>>>>     provides sun.management.spi.PlatformMBeanProvider with
>>>> com.sun.management.internal.PlatformMBeanProviderImpl
>>>>
>>> Here is code that fails:
>>>
>>> import java.lang.reflect.*;
>>> import java.lang.management.*;
>>>
>>> public class test {
>>>     public static void main(String args[]) throws Exception {
>>>       OperatingSystemMXBean osMxBean =
>>> ManagementFactory.getOperatingSystemMXBean();
>>>       Method getTotalPhysicalMemorySize =
>>> osMxBean.getClass().getMethod("getTotalPhysicalMemorySize");
>>>       getTotalPhysicalMemorySize.setAccessible(true);
>>>       System.out.println(getTotalPhysicalMemorySize.invoke(osMxBean));
>>>     }
>>> }
>>>
>>> Exception in thread "main"
>>> java.lang.reflect.InaccessibleObjectException: Unable to make member
>>> of class com.sun.management.internal.OperatingSystemImpl accessible:
>>> module jdk.management does not export com.sun.management.internal
>> to
>>> <unnamed module @5f375618>
>>>       at
>> sun.reflect.Reflection.throwInaccessibleObjectException(java.base at 9.0/Ref
>> lection.java:462)
>>>       at
>> java.lang.reflect.AccessibleObject.checkCanSetAccessible(java.base at 9.0/Ac
>> cessibleObject.java:194)
>>>       at
>> java.lang.reflect.AccessibleObject.setAccessible(java.base at 9.0/AccessibleO
>> bject.java:157)
>>>       at test.main(test.java:8)
>> I guess there will be lots of similar issues discovered in various codebases
>> when trying to run them with jigsaw. The problem of the above code is that it
>> uses reflection to look up the optional method on the implementation class
>> of the object (and that class is in some internal package, not exported and
>> inaccessible to other modules) instead of looking it up on the public API class
>> (the interface). You get two different methods that way - one is accessible
>> and the other is not, but invoking either of them should be equivalent, since
>> the dispatch is always virtual. So the correct way to "test" whether the
>> method exists (maybe because it has been added on a praticular version of
>> the
>> platform) and then to invoke it is the following:
>>
>> public class test {
>>     public static void main(String args[]) throws Exception {
>>       Method getTotalPhysicalMemorySize =
>> OperatingSystemMXBean.class.getMethod("getTotalPhysicalMemorySize");
>>       OperatingSystemMXBean osMxBean =
>> ManagementFactory.getOperatingSystemMXBean();
>>       System.out.println(getTotalPhysicalMemorySize.invoke(osMxBean));
>>     }
>> }
>>
>>
>> And you don't even need to set it Method.setAccessible(true), since both
>> the interface and method are public.
>>
>>
>> Regards, Peter



More information about the jigsaw-dev mailing list