Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CHANGELOG
=========

5.0.2 (unreleased)
5.0.2 (2025-12-08)
------------------

* Fixed an issue where decoding `IpRiskResponse` from the IP Risk database would
Expand All @@ -10,6 +10,11 @@ CHANGELOG
that the risk score was not set in the database. In a future major release,
this field may be changed to a nullable `Double` to better distinguish between
"no data" and "zero risk". Reported by Fabrice Bacchella. GitHub #644.
* Updated `maxmind-db` dependency to 4.0.2. This fixes a bug where enums with
`@MaxMindDbCreator` would throw `ConstructorNotFoundException` when the data
was stored via a pointer in the database, commonly occurring with deduplicated
data in larger databases. It also improves error messages when constructor
invocation fails. Reported by Fabrice Bacchella. GitHub #644.

5.0.1 (2025-12-02)
------------------
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ To do this, add the dependency to your pom.xml:
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>5.0.1</version>
<version>5.0.2</version>
</dependency>
```

Expand All @@ -30,7 +30,7 @@ repositories {
mavenCentral()
}
dependencies {
compile 'com.maxmind.geoip2:geoip2:5.0.1'
compile 'com.maxmind.geoip2:geoip2:5.0.2'
}
```

Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>5.0.1</version>
<version>5.0.2</version>
<packaging>jar</packaging>
<name>MaxMind GeoIP2 API</name>
<description>GeoIP2 webservice client and database reader</description>
Expand Down Expand Up @@ -53,7 +53,7 @@
<dependency>
<groupId>com.maxmind.db</groupId>
<artifactId>maxmind-db</artifactId>
<version>4.0.1</version>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
Expand Down
77 changes: 77 additions & 0 deletions src/test/java/com/maxmind/geoip2/DatabaseReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.maxmind.db.Networks;
import com.maxmind.db.Reader;
import com.maxmind.geoip2.exception.AddressNotFoundException;
import com.maxmind.geoip2.exception.GeoIp2Exception;
Expand All @@ -27,6 +28,8 @@
import java.net.InetAddress;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -475,4 +478,78 @@ private File getFile(String filename) throws URISyntaxException {
.getResource("/maxmind-db/test-data/" + filename);
return new File(resource.toURI());
}

/**
* Tests that all records in each test database can be deserialized.
* This test iterates over every network in the database and performs
* a lookup to ensure no deserialization errors occur.
*
* <p>Based on the reproduction test from GitHub issue #644.
* https://github.com/maxmind/GeoIP2-java/issues/644
*/
@Test
public void testAllRecordsDeserialize() throws Exception {
var testDataDir = Paths.get(
getClass().getResource("/maxmind-db/test-data").toURI()
);

try (var stream = Files.newDirectoryStream(testDataDir, "*.mmdb")) {
for (var dbPath : stream) {
var filename = dbPath.getFileName().toString();

if (shouldSkipDatabase(filename)) {
continue;
}

try (var reader = new Reader(dbPath.toFile());
var dbReader = new DatabaseReader.Builder(dbPath.toFile()).build()) {

var dbType = reader.getMetadata().databaseType();
var networks = reader.networks(Object.class);

while (networks.hasNext()) {
var ip = networks.next().network().networkAddress();
lookupByDatabaseType(dbReader, dbType, ip);
}
}
}
}
}

private boolean shouldSkipDatabase(String filename) {
// Skip internal test databases and those without model classes in GeoIP2-java
return filename.startsWith("MaxMind-DB-")
|| filename.contains("Broken")
|| filename.contains("Invalid")
|| filename.contains("DensityIncome")
|| filename.contains("User-Count")
|| filename.contains("Static-IP-Score");
}

private void lookupByDatabaseType(DatabaseReader reader, String dbType, InetAddress ip)
throws IOException, GeoIp2Exception {
if (dbType.contains("City")) {
reader.city(ip);
} else if (dbType.contains("Country")) {
reader.country(ip);
} else if (dbType.contains("Enterprise")) {
reader.enterprise(ip);
} else if (dbType.equals("GeoIP-Anonymous-Plus")) {
reader.anonymousPlus(ip);
} else if (dbType.equals("GeoIP2-Anonymous-IP")) {
reader.anonymousIp(ip);
} else if (dbType.equals("GeoIP2-ISP")) {
reader.isp(ip);
} else if (dbType.equals("GeoIP2-IP-Risk")) {
reader.ipRisk(ip);
} else if (dbType.equals("GeoIP2-Domain")) {
reader.domain(ip);
} else if (dbType.equals("GeoLite2-ASN")) {
reader.asn(ip);
} else if (dbType.equals("GeoIP2-Connection-Type")) {
reader.connectionType(ip);
} else {
throw new IllegalArgumentException("Unknown database type: " + dbType);
}
}
}
Loading