Skip to content

Commit c120547

Browse files
authored
Merge pull request #316 from maxmind/greg/4.0.0
Release 4.0.0
2 parents 0a08799 + 73d600c commit c120547

File tree

5 files changed

+265
-8
lines changed

5 files changed

+265
-8
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
CHANGELOG
22
=========
33

4-
4.0.0
4+
4.0.0 (2025-11-10)
55
------------------
66

7+
**This is a major release with several breaking changes. Please see
8+
[UPGRADING.md](UPGRADING.md) for detailed migration instructions.**
9+
710
* Java 17 or greater is now required.
811
* Added support for MaxMind DB files larger than 2GB. The library now uses
912
an internal Buffer abstraction that can handle databases exceeding the

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ To do this, add the dependency to your pom.xml:
1616
<dependency>
1717
<groupId>com.maxmind.db</groupId>
1818
<artifactId>maxmind-db</artifactId>
19-
<version>3.2.0</version>
19+
<version>4.0.0</version>
2020
</dependency>
2121
```
2222

@@ -29,7 +29,7 @@ repositories {
2929
mavenCentral()
3030
}
3131
dependencies {
32-
compile 'com.maxmind.db:maxmind-db:3.2.0'
32+
compile 'com.maxmind.db:maxmind-db:4.0.0'
3333
}
3434
```
3535

@@ -83,8 +83,8 @@ public class Lookup {
8383
DatabaseRecord<LookupResult> record
8484
= reader.getRecord(address, LookupResult.class);
8585

86-
System.out.println(record.getData().getCountry().getIsoCode());
87-
System.out.println(record.getNetwork());
86+
System.out.println(record.data().getCountry().getIsoCode());
87+
System.out.println(record.network());
8888
}
8989
}
9090

@@ -214,7 +214,7 @@ while(networks.hasNext()) {
214214
DatabaseRecord<Map<String, String>> iteration = networks.next();
215215

216216
// Get the data.
217-
Map<String, String> data = iteration.getData();
217+
Map<String, String> data = iteration.data();
218218

219219
// The IP Address
220220
InetAddress ipAddress = InetAddress.getByName(data.get("ip"));

UPGRADING.md

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
# Upgrading to 4.0.0
2+
3+
This guide covers the breaking changes introduced in version 4.0.0 and how to
4+
update your code.
5+
6+
## Java Version Requirement
7+
8+
**Java 17 or greater is now required.** If you are using Java 11, you must
9+
upgrade to Java 17 or later before upgrading to 4.0.0.
10+
11+
## Record Conversion and Method Changes
12+
13+
The `DatabaseRecord`, `Metadata`, and `Network` classes have been converted to
14+
Java records. This means getter methods have been replaced with record accessor
15+
methods.
16+
17+
### DatabaseRecord Changes
18+
19+
**Before (3.x):**
20+
21+
```java
22+
DatabaseRecord<MyData> record = reader.getRecord(address, MyData.class);
23+
MyData data = record.getData();
24+
Network network = record.getNetwork();
25+
```
26+
27+
**After (4.0.0):**
28+
29+
```java
30+
DatabaseRecord<MyData> record = reader.getRecord(address, MyData.class);
31+
MyData data = record.data();
32+
Network network = record.network();
33+
```
34+
35+
**Find and replace:**
36+
37+
- `record.getData()``record.data()`
38+
- `record.getNetwork()``record.network()`
39+
40+
### Network Changes
41+
42+
**Before (3.x):**
43+
44+
```java
45+
InetAddress address = network.getNetworkAddress();
46+
int prefixLength = network.getPrefixLength();
47+
```
48+
49+
**After (4.0.0):**
50+
51+
```java
52+
InetAddress address = network.networkAddress();
53+
int prefixLength = network.prefixLength();
54+
```
55+
56+
**Find and replace:**
57+
58+
- `network.getNetworkAddress()``network.networkAddress()`
59+
- `network.getPrefixLength()``network.prefixLength()`
60+
61+
### Metadata Changes
62+
63+
All getter methods on `Metadata` have been replaced with record accessor
64+
methods. Remove the `get` prefix and use camelCase instead.
65+
66+
**Before (3.x):**
67+
68+
```java
69+
Metadata metadata = reader.getMetadata();
70+
int majorVersion = metadata.getBinaryFormatMajorVersion();
71+
String dbType = metadata.getDatabaseType();
72+
List<String> languages = metadata.getLanguages();
73+
```
74+
75+
**After (4.0.0):**
76+
77+
```java
78+
Metadata metadata = reader.getMetadata();
79+
int majorVersion = metadata.binaryFormatMajorVersion();
80+
String dbType = metadata.databaseType();
81+
List<String> languages = metadata.languages();
82+
```
83+
84+
**Common replacements:**
85+
86+
- `getBinaryFormatMajorVersion()``binaryFormatMajorVersion()`
87+
- `getBinaryFormatMinorVersion()``binaryFormatMinorVersion()`
88+
- `getDatabaseType()``databaseType()`
89+
- `getLanguages()``languages()`
90+
- `getDescription()``description()`
91+
- `getIpVersion()``ipVersion()`
92+
- `getNodeCount()``nodeCount()`
93+
- `getRecordSize()``recordSize()`
94+
95+
### Build Time Change (Date → Instant)
96+
97+
The `getBuildDate()` method has been replaced with `buildTime()`, which returns
98+
`java.time.Instant` instead of `java.util.Date`.
99+
100+
**Before (3.x):**
101+
102+
```java
103+
import java.util.Date;
104+
105+
Metadata metadata = reader.getMetadata();
106+
Date buildDate = metadata.getBuildDate();
107+
```
108+
109+
**After (4.0.0):**
110+
111+
```java
112+
import java.time.Instant;
113+
114+
Metadata metadata = reader.getMetadata();
115+
Instant buildTime = metadata.buildTime();
116+
```
117+
118+
If you need a `Date` object, you can convert:
119+
120+
```java
121+
Date buildDate = Date.from(metadata.buildTime());
122+
```
123+
124+
## DatabaseRecord Constructor Change
125+
126+
If you are manually constructing `DatabaseRecord` instances, the legacy
127+
constructor has been removed.
128+
129+
**Before (3.x):**
130+
131+
```java
132+
DatabaseRecord<MyData> record = new DatabaseRecord<>(data, ipAddress, prefixLength);
133+
```
134+
135+
**After (4.0.0):**
136+
137+
```java
138+
Network network = new Network(ipAddress, prefixLength);
139+
DatabaseRecord<MyData> record = new DatabaseRecord<>(data, network);
140+
```
141+
142+
## Deserialization Improvements
143+
144+
### Automatic Constructor Selection
145+
146+
If your classes use records or have a single public constructor, you may no
147+
longer need to annotate them with `@MaxMindDbConstructor`.
148+
149+
**Before (3.x) - Required annotations:**
150+
151+
```java
152+
public record Location(
153+
@MaxMindDbParameter(name = "latitude") Double latitude,
154+
@MaxMindDbParameter(name = "longitude") Double longitude
155+
) {}
156+
```
157+
158+
**After (4.0.0) - Annotations optional when names match:**
159+
160+
```java
161+
public record Location(
162+
Double latitude,
163+
Double longitude
164+
) {}
165+
```
166+
167+
The canonical record constructor is used automatically, and component names
168+
match the database field names.
169+
170+
### Parameter Name Support
171+
172+
For non-record classes, if you compile with the `-parameters` flag, parameter
173+
names can be used instead of requiring `@MaxMindDbParameter` annotations.
174+
175+
**Before (3.x):**
176+
177+
```java
178+
@MaxMindDbConstructor
179+
public Location(
180+
@MaxMindDbParameter(name = "latitude") Double latitude,
181+
@MaxMindDbParameter(name = "longitude") Double longitude
182+
) {
183+
this.latitude = latitude;
184+
this.longitude = longitude;
185+
}
186+
```
187+
188+
**After (4.0.0) - With `-parameters` flag:**
189+
190+
```java
191+
@MaxMindDbConstructor
192+
public Location(Double latitude, Double longitude) {
193+
this.latitude = latitude;
194+
this.longitude = longitude;
195+
}
196+
```
197+
198+
### New Injection Annotations
199+
200+
4.0.0 introduces `@MaxMindDbIpAddress` and `@MaxMindDbNetwork` annotations for
201+
injecting lookup context into your constructors.
202+
203+
**Example:**
204+
205+
```java
206+
public record EnrichedData(
207+
String city,
208+
@MaxMindDbIpAddress InetAddress lookupIp,
209+
@MaxMindDbNetwork Network network
210+
) {}
211+
```
212+
213+
## Large Database Support (>2GB)
214+
215+
Version 4.0.0 adds support for MaxMind DB files larger than 2GB. This change is
216+
transparent to most users:
217+
218+
- Files under 2GB continue to use a single `ByteBuffer` for optimal performance
219+
- Files 2GB and larger automatically use a multi-buffer implementation
220+
- No code changes required in your application
221+
222+
## Migration Checklist
223+
224+
1. ✅ Upgrade to Java 17 or later
225+
2. ✅ Update Maven/Gradle dependency to 4.0.0
226+
3. ✅ Replace `record.getData()` with `record.data()`
227+
4. ✅ Replace `record.getNetwork()` with `record.network()`
228+
5. ✅ Replace `network.getNetworkAddress()` with `network.networkAddress()`
229+
6. ✅ Replace `network.getPrefixLength()` with `network.prefixLength()`
230+
7. ✅ Update all `Metadata` getter methods (remove `get` prefix, use camelCase)
231+
8. ✅ Replace `metadata.getBuildDate()` with `metadata.buildTime()` and change
232+
type from `Date` to `Instant`
233+
9. ✅ Update any manual `DatabaseRecord` constructions to use `Network`
234+
parameter
235+
10. ✅ (Optional) Remove unnecessary `@MaxMindDbParameter` annotations if using
236+
records or `-parameters` flag
237+
238+
## Finding Issues
239+
240+
To help identify code that needs updating, you can search your codebase for:
241+
242+
- `.getData()`
243+
- `.getNetwork()`
244+
- `.getNetworkAddress()`
245+
- `.getPrefixLength()`
246+
- `.getBuildDate()`
247+
- `.getBinaryFormatMajorVersion()` (and similar Metadata getters)
248+
- `new DatabaseRecord<>` (check for three-parameter constructor)
249+
250+
## Support
251+
252+
If you encounter issues during the upgrade, please check:
253+
254+
- [GitHub Issues](https://github.com/maxmind/MaxMind-DB-Reader-java/issues)
255+
- [MaxMind Support](https://www.maxmind.com/en/support)

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>com.maxmind.db</groupId>
55
<artifactId>maxmind-db</artifactId>
6-
<version>4.0.0-SNAPSHOT</version>
6+
<version>4.0.0</version>
77
<packaging>jar</packaging>
88
<name>MaxMind DB Reader</name>
99
<description>Reader for MaxMind DB</description>

src/test/java/com/maxmind/db/ReaderTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,6 @@ private void testIpV4(Reader reader, File file) throws IOException {
20012001
}
20022002
}
20032003

2004-
// XXX - logic could be combined with above
20052004
private void testIpV6(Reader reader, File file) throws IOException {
20062005
var subnets = new String[] {"::1:ffff:ffff", "::2:0:0",
20072006
"::2:0:40", "::2:0:50", "::2:0:58"};

0 commit comments

Comments
 (0)