Skip to content

Commit af724ea

Browse files
committed
synchronize access to IdentityHashMap instances
... to avoid concurrency issues like in build https://github.com/datafaker-net/datafaker/actions/runs/23618303854/job/68791305528?pr=1785: ``` java.lang.ClassCastException: class net.datafaker.providers.base.Color cannot be cast to class net.datafaker.providers.base.Vehicle (net.datafaker.providers.base.Color and net.datafaker.providers.base.Vehicle are in unnamed module of loader 'app') at net.datafaker.providers.base.BaseProviders.vehicle(BaseProviders.java:506) at net.datafaker.providers.base.VehicleLocaleTest.lambda$localeProviderListTest$3(VehicleLocaleTest.java:23) ``` Class `IdentityHashMap` is not thread-safe, all accesses to this class should be synchronized.
1 parent 8018cca commit af724ea

File tree

4 files changed

+11
-6
lines changed

4 files changed

+11
-6
lines changed

src/main/java/net/datafaker/providers/base/BaseFaker.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import java.util.function.Predicate;
2323
import java.util.function.Supplier;
2424

25+
import static java.util.Collections.synchronizedMap;
26+
2527
/**
2628
* Provides utility methods for generating fake strings, such as names, phone
2729
* numbers, addresses. generate random strings with given patterns
@@ -32,7 +34,7 @@ public class BaseFaker implements BaseProviders {
3234
private static final Predicate<Class<?>> EVERY_PROVIDER_ALLOWED = t -> true;
3335
private final FakerContext context;
3436
private final FakeValuesService fakeValuesService;
35-
private final Map<Class<?>, AbstractProvider<?>> providersCache = new IdentityHashMap<>();
37+
private final Map<Class<?>, AbstractProvider<?>> providersCache = synchronizedMap(new IdentityHashMap<>());
3638
private final Predicate<Class<?>> whiteListPredicate;
3739

3840
public BaseFaker() {

src/main/java/net/datafaker/providers/base/ObjectMethods.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
import java.util.Set;
88
import java.util.stream.Stream;
99

10+
import static java.util.Collections.synchronizedMap;
1011
import static java.util.stream.Collectors.toMap;
1112

1213
public class ObjectMethods {
13-
private static final Map<Class<?>, Map<String, Method>> METHODS_BY_NAME = new IdentityHashMap<>();
14-
private static final Map<Class<?>, Map<String, Method>> METHODS_BY_RETURN_TYPE = new IdentityHashMap<>();
14+
private static final Map<Class<?>, Map<String, Method>> METHODS_BY_NAME = synchronizedMap(new IdentityHashMap<>());
15+
private static final Map<Class<?>, Map<String, Method>> METHODS_BY_RETURN_TYPE = synchronizedMap(new IdentityHashMap<>());
1516
private static final Set<String> IGNORED_METHODS = Set.of("equals", "hashCode", "toString", "Builder", "stream");
1617

1718
private static synchronized Map<String, Method> scanMethodsByName(Class<?> clazz) {

src/main/java/net/datafaker/service/FakerContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class FakerContext {
2020
private static final Pattern LOCALE = Pattern.compile("[-_]");
2121
private static final Map<SingletonLocale, List<SingletonLocale>> LOCALE_2_LOCALES_CHAIN = new IdentityHashMap<>();
2222
private static final Map<SingletonLocale, SingletonLocale> STRING_LOCALE_HASH_MAP = new IdentityHashMap<>();
23-
public static final List<SingletonLocale> DEFAULT_SINGLETON_LOCALE_LIST = List.of(DEFAULT_LOCALE);
23+
private static final List<SingletonLocale> DEFAULT_SINGLETON_LOCALE_LIST = List.of(DEFAULT_LOCALE);
2424
private static final Map<String, String> LANGUAGE_DEFAULT_COUNTRY = Map.ofEntries(
2525
Map.entry("be", "BY"),
2626
Map.entry("cs", "CZ"),

src/main/java/net/datafaker/transformations/JavaObjectTransformer.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
import java.util.stream.Collectors;
1919
import java.util.stream.Stream;
2020

21+
import static java.util.Collections.synchronizedMap;
22+
2123
public class JavaObjectTransformer implements Transformer<Object, Object> {
22-
private static final Map<Schema<Object, ?>, Consumer<Object>> SCHEMA2CONSUMER = new IdentityHashMap<>();
23-
private static final Map<Class<?>, Constructor<?>> CLASS2CONSTRUCTOR = new IdentityHashMap<>();
24+
private static final Map<Schema<Object, ?>, Consumer<Object>> SCHEMA2CONSUMER = synchronizedMap(new IdentityHashMap<>());
25+
private static final Map<Class<?>, Constructor<?>> CLASS2CONSTRUCTOR = synchronizedMap(new IdentityHashMap<>());
2426

2527
private Optional<Object> sourceClazz = Optional.empty();
2628

0 commit comments

Comments
 (0)