dimanche 22 janvier 2017

Can't use reflection library to call private method, get NoSuchMethodException

I'm trying to write my own implementation of the Miller Rabin primality test. I could get it working, but it was very slow for values larger than 64 bits.

In the draft standard ANSI X9.80, "PRIME NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES", they specify behavior up to 1024 bits. My program (on a i7 6700k) would take months at best to run on a single 1024 bit integer.

So I turned to the java implementation of the Miller Rabin test to see what micro-optimizations they used to make the performance tenable.

I've been working my way through their source code, but I've run up against a wall. A lot of the methods they use are private, and testing your codes behavior against code you can't execute is quite difficult.For starters, the first internal method I wanted to call is BigInteger.mod2( int )

I've not programmed extensively in java before, but here's where I got stuck:

import java.lang.reflect.*;
import java.math.BigInteger;

public class HelloWorld
{
    public static void main(String[] args)
    {
        BigInteger a = new BigInteger( "123456789101112" );
        Method mod2 = BigInteger.class.getDeclaredMethod( "mod2", int.class );
        //Class[] arg_types = new Class[1];
        //arg_types[0] = int.class;
        //Method mod2 = BigInteger.class.getDeclaredMethod( "mod2", arg_types );
        mod2.setAccessible( true );
        Object b = mod2.invoke( a, 32 );
        System.out.print( b );
    }
}

Both version of the 'getDeclaredMethod' call throw NoSuchMethodException exceptions. I've looked at the documentation for 'getDeclaredMethod' and they say to do exactly what I'm currently doing when people are asking how to get this function to work.

Any advice on how to invoke the private methods of BigInteger, in particular BigInteger.mod2( int ) would be greatly appreciated. Thanks!





Aucun commentaire:

Enregistrer un commentaire