Description
I am using Javers in a Multithread context to compare instances of several kinds of object. If two kind of objects have a property of type List<SomeThing> then the javers.compare(a, b) throws from time to time an ATTEMPT_TO_OVERWRITE_EXISTING_JAVERSTYPE_MAPPING exception.
Steps To Reproduce
Here is a short example that very often throws the ATTEMPT_TO_OVERWRITE_EXISTING_JAVERSTYPE_MAPPING exception.
If you decrease the number of threads of the Executors to 1, the exception is never thrown.
public class MyApp {
private static final Javers JAVERS = JaversBuilder.javers().build();
@Getter
@Setter
@NoArgsConstructor
static class StorageA {
private List<String> items;
}
@Getter
@Setter
@NoArgsConstructor
static class StorageB {
private List<String> items;
}
public static void main(final String[] args) {
// If you decrease the number of thread from 10 to 1 the exception diseapers
ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
futures.add(CompletableFuture.runAsync(() -> JAVERS.compare(new StorageA(), new StorageA()),
executorService));
futures.add(CompletableFuture.runAsync(() -> JAVERS.compare(new StorageB(), new StorageB()),
executorService));
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
} finally {
executorService.shutdown();
}
}
}
Javers' Version
7.7.0
Root cause
In my opinion, the bug comes from the class TypeMapperEngine, the synchronize(javaType) is too "weak" : https://github.com/javers/javers/blob/master/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapperEngine.java#L104
The synchronisation should be done on a dedicated LOCK object instead of the javaType function parameter.
Description
I am using Javers in a Multithread context to compare instances of several kinds of object. If two kind of objects have a property of type
List<SomeThing>then thejavers.compare(a, b)throws from time to time an ATTEMPT_TO_OVERWRITE_EXISTING_JAVERSTYPE_MAPPING exception.Steps To Reproduce
Here is a short example that very often throws the ATTEMPT_TO_OVERWRITE_EXISTING_JAVERSTYPE_MAPPING exception.
If you decrease the number of threads of the Executors to 1, the exception is never thrown.
Javers' Version
7.7.0
Root cause
In my opinion, the bug comes from the class TypeMapperEngine, the
synchronize(javaType)is too "weak" : https://github.com/javers/javers/blob/master/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapperEngine.java#L104The synchronisation should be done on a dedicated LOCK object instead of the
javaTypefunction parameter.