Skip to content

Commit bad6ed5

Browse files
oschwaldclaude
andcommitted
Prepare documentation for 4.0.0 release
Add release date to CHANGELOG, create comprehensive upgrade guide, and update all code examples in README to use the new 4.0.0 record accessor API (data(), network() instead of getData(), getNetwork()). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 0a08799 commit bad6ed5

File tree

4 files changed

+262
-5
lines changed

4 files changed

+262
-5
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: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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)

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)