zonkyio / embedded-postgres

Java embedded PostgreSQL component for testing
Apache License 2.0
344 stars 43 forks source link

Remove duplicates of resource url in DefaultPostgresBinaryResolver #43

Closed mblund closed 3 years ago

mblund commented 3 years ago

After an upgrade of Coursier(After upgrade of sbt 1.3.10 to 1.3.11) the DefaultPostgresBinaryResolver starts to gets two identical urls from the classLoader when looking for binaries. I don't know the root cause of this or what has changed this behavior.

The problem is that this will trigger an IllegalStateException("Duplicate postgres binaries"). As they are identical and thereby point to the same binary, my assumption is that it fine to just remove any duplicates.

This is the url that I found 2 copies of: jar:file:/Users/.../Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/io/zonky/test/postgres/embedded-postgres-binaries-darwin-amd64/10.11.0/embedded-postgres-binaries-darwin-amd64-10.11.0.jar!/postgres-darwin-x86_64.txz

tomix26 commented 3 years ago

Based on your description, it seems to be a bug in Coursier or SBT rather than in this library. So I suggest reporting the problem there rather than fixing it here.

mblund commented 3 years ago

I agree that the cause is Coursier but I still think that is a bug in DefaultPostgresBinaryResolver.java

As the list of urls given from

List<URL> urls = Collections.list(classLoader.getResources(resourceLocation));

can contain duplicates of the path to the binary. The code

if (urls.size() > 1) {
            logger.error("Detected multiple binaries of the same architecture: {}"

creates a bug, as there is not multiple binary, just a multiple urls. Converting it to a set was just a very easy fix for this.

tomix26 commented 3 years ago

Yes, it's really easy to fix. But the root cause is that these files are physically present multiple times in the classpath. The class loader should definitely not contain duplicate resources. In general, it may lead to the problem that one class will be present more than once in the class loader, and some basic principles may not work properly. For instance, conditions like SomeObject.class == SomeObject.class may return false under certain circumstances. So it would be better to fix it at the source of the problem.

mblund commented 3 years ago

ok, no problem. I will run with a custom PostgresBinaryResolver for now and see if I can find out why I get multiple identical paths.

Thanks for a really great project, it makes it really easy for us to write really good test without the hassle of a 'real' database.