Skip to content

MultiThread + compare() = ATTEMPT_TO_OVERWRITE_EXISTING_JAVERSTYPE_MAPPING #1425

@Adrien-dev25

Description

@Adrien-dev25

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions