diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/DisallowedImageHeapObjects.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/DisallowedImageHeapObjects.java index 23397515364a..0880d0698138 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/DisallowedImageHeapObjects.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/image/DisallowedImageHeapObjects.java @@ -30,6 +30,9 @@ import java.lang.reflect.Field; import java.nio.Buffer; import java.nio.MappedByteBuffer; +import java.util.Random; +import java.util.SplittableRandom; +import java.util.concurrent.ThreadLocalRandom; import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.ReflectionUtil; @@ -55,6 +58,13 @@ public interface DisallowedObjectReporter { } public static void check(Object obj, DisallowedObjectReporter reporter) { + /* Random/SplittableRandom can not be in the image heap. */ + if (((obj instanceof Random) && !(obj instanceof ThreadLocalRandom)) || obj instanceof SplittableRandom) { + throw reporter.raise("Detected an instance of Random/SplittableRandom class in the image heap. " + + "Instances created during image generation have cached seed values and don't behave as expected.", + obj, "Try avoiding to initialize the class that caused initialization of the object."); + } + /* Started Threads can not be in the image heap. */ if (obj instanceof Thread) { final Thread asThread = (Thread) obj; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RandomNumbersFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RandomNumbersFeature.java deleted file mode 100644 index a45e4fd8f6cc..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/RandomNumbersFeature.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019, 2019, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.svm.core.jdk; - -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.hosted.Feature; -import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; - -import com.oracle.svm.core.annotate.AutomaticFeature; - -@AutomaticFeature -public class RandomNumbersFeature implements Feature { - - @Override - public void duringSetup(DuringSetupAccess access) { - /* - * The random number provider classes should be reinitialized at runtime to reset their - * values properly. Otherwise the numbers generated will be fixed for each generated image. - */ - ImageSingletons.lookup(RuntimeClassInitializationSupport.class).rerunInitialization(access.findClassByName("java.lang.Math$RandomNumberGeneratorHolder"), "for random number generator"); - } -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ThreadLocalRandomAccessors.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ThreadLocalRandomAccessors.java index 28ca4acdd76e..c2a93a91a76b 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ThreadLocalRandomAccessors.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ThreadLocalRandomAccessors.java @@ -55,7 +55,7 @@ public static AtomicLong getSeeder() { return SINGLETON.getOrInitializeSeeder(); } - /** The setter is necessary if ThreadLocalRandom is initilized at run time. */ + /** The setter is necessary if ThreadLocalRandom is initialized at run time. */ public static void setSeeder(AtomicLong value) { SINGLETON.seeder = value; } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java index 249b1868ffdf..50bd1db6fe08 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java @@ -117,7 +117,14 @@ public void afterRegistration(AfterRegistrationAccess access) { RuntimeClassInitialization.initializeAtBuildTime("sun.security.x509", "Core JDK classes are initialized at build time"); RuntimeClassInitialization.initializeAtBuildTime("sun.security.smartcardio", "Core JDK classes are initialized at build time"); - // contains a SecureRandom reference, therefore it can't be included in the image heap + // contain Random references, therefore can't be included in the image heap RuntimeClassInitialization.initializeAtRunTime(com.sun.jndi.dns.DnsClient.class); + RuntimeClassInitialization.initializeAtRunTime("sun.net.www.protocol.http.DigestAuthentication$Parameters"); + RuntimeClassInitialization.initializeAtRunTime("sun.security.krb5.KrbServiceLocator"); + + // The random number provider classes should be reinitialized at runtime to reset their + // values properly. Otherwise the numbers generated will be fixed for each generated image. + RuntimeClassInitialization.initializeAtRunTime("java.lang.Math$RandomNumberGeneratorHolder"); + RuntimeClassInitialization.initializeAtRunTime("java.lang.StrictMath$RandomNumberGeneratorHolder"); } }