On Mon, 13 May 2024 12:45:59 GMT, Jaikiran Pai <j...@openjdk.org> wrote:
>> All random number generator algorithms are implemented in module >> `java.base`. The usage of `ServiceLoader` in `j.u.r.RandomGeneratorFactory` >> is no longer needed. > > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line > 190: > >> 188: if (properties == null) { // double-checking idiom >> 189: RandomGeneratorProperties props = >> rgClass.getDeclaredAnnotation(RandomGeneratorProperties.class); >> 190: Objects.requireNonNull(props, rgClass + " missing >> annotation"); > > Hello Raffaello, with the `RandomGenerator` implementations now all residing > within the java.base module, I think an additional advantage of that is that, > it will now allow us to remove this internal `RandomGeneratorProperties` > annotation and thus this reflection code. > > I think one way to do that would be something like this within this > `RandomGeneratorFactory` class itself: > > > private record RandomGenEntry(Class<?> randomGenClass, int i, int j, > int k, int equiDistribution, boolean stochastic, > boolean hardware) { > > } > > private static final Map<String, RandomGenEntry> FACTORY_MAP = ... // > construct the map > > > where the `FACTORY_MAP` will be keyed to the alogrithm and the value will be > a record which holds these additional details about the `RandomGenerator`. > This current PR is about getting rid of ServiceLoader usage. So if you want > to remove the usage of this annotation and reflection is a separate PR that's > fine with me. Furthermore, although I don't see the necessity of an > annotation for what we are doing here, if you think that the removal of the > annotation and reflection isn't worth doing, that is OK too. Thinking a bit more, I think we can even get rid of the reflection used in `create()` methods implementation, if we wanted to, by doing something like this: private record RandomGenEntry(Class<? extends RandomGenerator> randomGenClass, int i, int j, int k, int equiDistribution, boolean stochastic, boolean hardware) { RandomGenerator create() { String algo = randomGenClass.getSimpleName(); return switch (algo) { case "Random" -> new Random(); case "L128X1024MixRandom" -> new L128X1024MixRandom(); case "Xoshiro256PlusPlus" -> new Xoshiro256PlusPlus(); // ... so on for the rest default -> throw new InternalError("should not happen"); }; } RandomGenerator create(long seed) { String algo = randomGenClass.getSimpleName(); return switch (algo) { case "Random", "SplittableRandom", "SecureRandom" -> { throw new UnsupportedOperationException("cannot construct with a long seed"); } case "L128X1024MixRandom" -> new L128X1024MixRandom(seed); case "Xoshiro256PlusPlus" -> new Xoshiro256PlusPlus(seed); // ... so on for the rest default -> throw new InternalError("should not happen"); }; } RandomGenerator create(byte[] seed) { String algo = randomGenClass.getSimpleName(); return switch (algo) { case "Random", "SplittableRandom", "SecureRandom" -> { throw new UnsupportedOperationException("cannot construct with a byte[] seed"); } case "L128X1024MixRandom" -> new L128X1024MixRandom(seed); case "Xoshiro256PlusPlus" -> new Xoshiro256PlusPlus(seed); // ... so on for the rest default -> throw new InternalError("should not happen"); }; } } private static final Map<String, RandomGenEntry> FACTORY_MAP = ... // construct the map ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/19212#discussion_r1598446741