Skip to content

Commit 1bdaecb

Browse files
authored
Merge pull request #78 from maxmind/horgh/exceptions
Turn new exceptions into unchecked runtime exceptions
2 parents e10c374 + 13b1ee4 commit 1bdaecb

16 files changed

Lines changed: 124 additions & 483 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ CHANGELOG
99
`MaxMindDbConstructor` and `MaxMindDbParameter` annotations to identify
1010
the constructors and parameters to deserialize into.
1111
* `jackson-databind` is no longer a dependency.
12+
* The `Record` class is now named `DatabaseRecord`. This is to avoid a
13+
conflict with `java.lang.Record` in Java 14.
1214

1315
1.4.0 (2020-06-12)
1416
------------------

README.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,10 @@ import com.maxmind.db.Record;
6666

6767
import java.io.File;
6868
import java.io.IOException;
69-
import java.lang.IllegalAccessException;
70-
import java.lang.InstantiationException;
71-
import java.lang.reflect.InvocationTargetException;
7269
import java.net.InetAddress;
7370

7471
public class Lookup {
75-
public static void main(String[] args)
76-
throws IOException,
77-
InstantiationException,
78-
IllegalAccessException,
79-
InvocationTargetException {
72+
public static void main(String[] args) throws IOException {
8073
File database = new File("/path/to/database/GeoIP2-City.mmdb");
8174
try (Reader reader = new Reader(database)) {
8275
InetAddress address = InetAddress.getByName("24.24.24.24");

sample/Benchmark.java

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import java.io.File;
22
import java.io.IOException;
3-
import java.lang.IllegalAccessException;
4-
import java.lang.InstantiationException;
5-
import java.lang.reflect.InvocationTargetException;
63
import java.net.InetAddress;
74
import java.util.Map;
85
import java.util.Random;
@@ -21,12 +18,7 @@ public class Benchmark {
2118
private final static int BENCHMARKS = 5;
2219
private final static boolean TRACE = false;
2320

24-
public static void main(String[] args)
25-
throws IOException,
26-
InstantiationException,
27-
IllegalAccessException,
28-
InvocationTargetException,
29-
NoSuchMethodException {
21+
public static void main(String[] args) throws IOException, InvalidDatabaseException {
3022
File file = new File(args.length > 0 ? args[0] : "GeoLite2-City.mmdb");
3123
System.out.println("No caching");
3224
loop("Warming up", file, WARMUPS, NoCache.getInstance());
@@ -37,12 +29,7 @@ public static void main(String[] args)
3729
loop("Benchmarking", file, BENCHMARKS, new CHMCache());
3830
}
3931

40-
private static void loop(String msg, File file, int loops, NodeCache cache)
41-
throws IOException,
42-
InstantiationException,
43-
IllegalAccessException,
44-
InvocationTargetException,
45-
NoSuchMethodException {
32+
private static void loop(String msg, File file, int loops, NodeCache cache) throws IOException {
4633
System.out.println(msg);
4734
for (int i = 0; i < loops; i++) {
4835
Reader r = new Reader(file, FileMode.MEMORY_MAPPED, cache);
@@ -51,12 +38,7 @@ private static void loop(String msg, File file, int loops, NodeCache cache)
5138
System.out.println();
5239
}
5340

54-
private static void bench(Reader r, int count, int seed)
55-
throws IOException,
56-
InstantiationException,
57-
IllegalAccessException,
58-
InvocationTargetException,
59-
NoSuchMethodException {
41+
private static void bench(Reader r, int count, int seed) throws IOException {
6042
Random random = new Random(seed);
6143
long startTime = System.nanoTime();
6244
byte[] address = new byte[4];

src/main/java/com/maxmind/db/CHMCache.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import java.io.IOException;
44
import java.util.concurrent.ConcurrentHashMap;
5-
import java.lang.IllegalAccessException;
6-
import java.lang.InstantiationException;
7-
import java.lang.reflect.InvocationTargetException;
85

96
/**
107
* A simplistic cache using a {@link ConcurrentHashMap}. There's no eviction
@@ -29,12 +26,7 @@ public CHMCache(int capacity) {
2926
}
3027

3128
@Override
32-
public Object get(CacheKey key, Loader loader)
33-
throws IOException,
34-
InstantiationException,
35-
IllegalAccessException,
36-
InvocationTargetException,
37-
NoSuchMethodException {
29+
public Object get(CacheKey key, Loader loader) throws IOException {
3830
Object value = cache.get(key);
3931
if (value == null) {
4032
value = loader.load(key);

src/main/java/com/maxmind/db/ConstructorNotFoundException.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package com.maxmind.db;
22

3-
import java.io.IOException;
4-
53
/**
64
* Signals that no annotated constructor was found. You should annotate a
75
* constructor in the class with the MaxMindDbConstructor annotation.
86
*/
9-
public class ConstructorNotFoundException extends IOException {
7+
public class ConstructorNotFoundException extends RuntimeException {
108
private static final long serialVersionUID = 1L;
119

1210
ConstructorNotFoundException(String message) {

src/main/java/com/maxmind/db/Record.java renamed to src/main/java/com/maxmind/db/DatabaseRecord.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
import java.net.InetAddress;
44

55
/**
6-
* Record represents the data and metadata associated with a database lookup.
6+
* DatabaseRecord represents the data and metadata associated with a database
7+
* lookup.
78
*/
8-
public final class Record<T> {
9+
public final class DatabaseRecord<T> {
910
private final T data;
1011
private final Network network;
1112

@@ -16,7 +17,7 @@ public final class Record<T> {
1617
* @param ipAddress the IP address used in the lookup.
1718
* @param prefixLength the network prefix length associated with the record in the database.
1819
*/
19-
public Record(T data, InetAddress ipAddress, int prefixLength) {
20+
public DatabaseRecord(T data, InetAddress ipAddress, int prefixLength) {
2021
this.data = data;
2122
this.network = new Network(ipAddress, prefixLength);
2223
}

src/main/java/com/maxmind/db/Decoder.java

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.io.IOException;
44
import java.lang.annotation.Annotation;
5-
import java.lang.IllegalAccessException;
6-
import java.lang.InstantiationException;
75
import java.lang.reflect.Array;
86
import java.lang.reflect.Constructor;
97
import java.lang.reflect.InvocationTargetException;
@@ -68,12 +66,7 @@ final class Decoder {
6866

6967
private final NodeCache.Loader cacheLoader = this::decode;
7068

71-
public <T> T decode(int offset, Class<T> cls)
72-
throws IOException,
73-
InstantiationException,
74-
IllegalAccessException,
75-
InvocationTargetException,
76-
NoSuchMethodException {
69+
public <T> T decode(int offset, Class<T> cls) throws IOException {
7770
if (offset >= this.buffer.capacity()) {
7871
throw new InvalidDatabaseException(
7972
"The MaxMind DB file's data section contains bad data: "
@@ -84,12 +77,7 @@ public <T> T decode(int offset, Class<T> cls)
8477
return cls.cast(decode(cls, null));
8578
}
8679

87-
private <T> T decode(CacheKey<T> key)
88-
throws IOException,
89-
InstantiationException,
90-
IllegalAccessException,
91-
InvocationTargetException,
92-
NoSuchMethodException {
80+
private <T> T decode(CacheKey<T> key) throws IOException {
9381
int offset = key.getOffset();
9482
if (offset >= this.buffer.capacity()) {
9583
throw new InvalidDatabaseException(
@@ -103,11 +91,7 @@ private <T> T decode(CacheKey<T> key)
10391
}
10492

10593
private <T> Object decode(Class<T> cls, java.lang.reflect.Type genericType)
106-
throws IOException,
107-
InstantiationException,
108-
IllegalAccessException,
109-
InvocationTargetException,
110-
NoSuchMethodException {
94+
throws IOException {
11195
int ctrlByte = 0xFF & this.buffer.get();
11296

11397
Type type = Type.fromControlByte(ctrlByte);
@@ -173,11 +157,7 @@ private <T> Object decodeByType(
173157
int size,
174158
Class<T> cls,
175159
java.lang.reflect.Type genericType
176-
) throws IOException,
177-
InstantiationException,
178-
IllegalAccessException,
179-
InvocationTargetException,
180-
NoSuchMethodException {
160+
) throws IOException {
181161
switch (type) {
182162
case MAP:
183163
return this.decodeMap(size, cls, genericType);
@@ -302,12 +282,7 @@ private <T, V> List<V> decodeArray(
302282
int size,
303283
Class<T> cls,
304284
Class<V> elementClass
305-
) throws IOException,
306-
InstantiationException,
307-
IllegalAccessException,
308-
InvocationTargetException,
309-
DeserializationException,
310-
NoSuchMethodException {
285+
) throws IOException {
311286
if (!List.class.isAssignableFrom(cls) && !cls.equals(Object.class)) {
312287
throw new DeserializationException();
313288
}
@@ -316,11 +291,22 @@ private <T, V> List<V> decodeArray(
316291
if (cls.equals(List.class) || cls.equals(Object.class)) {
317292
array = new ArrayList<>(size);
318293
} else {
319-
Constructor<T> constructor = cls.getConstructor(Integer.TYPE);
294+
Constructor<T> constructor;
295+
try {
296+
constructor = cls.getConstructor(Integer.TYPE);
297+
} catch (NoSuchMethodException e) {
298+
throw new DeserializationException("No constructor found for the List: " + e);
299+
}
320300
Object[] parameters = {size};
321-
@SuppressWarnings("unchecked")
322-
List<V> array2 = (List<V>) constructor.newInstance(parameters);
323-
array = array2;
301+
try {
302+
@SuppressWarnings("unchecked")
303+
List<V> array2 = (List<V>) constructor.newInstance(parameters);
304+
array = array2;
305+
} catch (InstantiationException |
306+
IllegalAccessException |
307+
InvocationTargetException e) {
308+
throw new DeserializationException("Error creating list: " + e);
309+
}
324310
}
325311

326312
for (int i = 0; i < size; i++) {
@@ -335,11 +321,7 @@ private <T> Object decodeMap(
335321
int size,
336322
Class<T> cls,
337323
java.lang.reflect.Type genericType
338-
) throws IOException,
339-
InstantiationException,
340-
IllegalAccessException,
341-
InvocationTargetException,
342-
NoSuchMethodException {
324+
) throws IOException {
343325
if (Map.class.isAssignableFrom(cls) || cls.equals(Object.class)) {
344326
Class<?> valueClass = Object.class;
345327
if (genericType instanceof ParameterizedType) {
@@ -365,20 +347,27 @@ private <T, V> Map<String, V> decodeMapIntoMap(
365347
Class<T> cls,
366348
int size,
367349
Class<V> valueClass
368-
) throws IOException,
369-
InstantiationException,
370-
IllegalAccessException,
371-
InvocationTargetException,
372-
NoSuchMethodException {
350+
) throws IOException {
373351
Map<String, V> map;
374352
if (cls.equals(Map.class) || cls.equals(Object.class)) {
375353
map = new HashMap<>(size);
376354
} else {
377-
Constructor<T> constructor = cls.getConstructor(Integer.TYPE);
355+
Constructor<T> constructor;
356+
try {
357+
constructor = cls.getConstructor(Integer.TYPE);
358+
} catch (NoSuchMethodException e) {
359+
throw new DeserializationException("No constructor found for the Map: " + e);
360+
}
378361
Object[] parameters = {size};
379-
@SuppressWarnings("unchecked")
380-
Map<String, V> map2 = (Map<String, V>) constructor.newInstance(parameters);
381-
map = map2;
362+
try {
363+
@SuppressWarnings("unchecked")
364+
Map<String, V> map2 = (Map<String, V>) constructor.newInstance(parameters);
365+
map = map2;
366+
} catch (InstantiationException |
367+
IllegalAccessException |
368+
InvocationTargetException e) {
369+
throw new DeserializationException("Error creating map: " + e);
370+
}
382371
}
383372

384373
for (int i = 0; i < size; i++) {
@@ -391,11 +380,7 @@ private <T, V> Map<String, V> decodeMapIntoMap(
391380
}
392381

393382
private <T> Object decodeMapIntoObject(int size, Class<T> cls)
394-
throws IOException,
395-
InstantiationException,
396-
IllegalAccessException,
397-
InvocationTargetException,
398-
NoSuchMethodException {
383+
throws IOException {
399384
CachedConstructor<T> cachedConstructor = this.constructors.get(cls);
400385
Constructor<T> constructor;
401386
Class<?>[] parameterTypes;
@@ -448,11 +433,17 @@ private <T> Object decodeMapIntoObject(int size, Class<T> cls)
448433
);
449434
}
450435

451-
return constructor.newInstance(parameters);
436+
try {
437+
return constructor.newInstance(parameters);
438+
} catch (InstantiationException |
439+
IllegalAccessException |
440+
InvocationTargetException e) {
441+
throw new DeserializationException("Error creating object: " + e);
442+
}
452443
}
453444

454445
private static <T> Constructor<T> findConstructor(Class<T> cls)
455-
throws ConstructorNotFoundException {
446+
throws ConstructorNotFoundException {
456447
Constructor<?>[] constructors = cls.getConstructors();
457448
for (Constructor<?> constructor : constructors) {
458449
if (constructor.getAnnotation(MaxMindDbConstructor.class) == null) {

src/main/java/com/maxmind/db/DeserializationException.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package com.maxmind.db;
22

3-
import java.io.IOException;
4-
53
/**
64
* Signals that the value could not be deserialized into the type.
75
*/
8-
public class DeserializationException extends IOException {
6+
public class DeserializationException extends RuntimeException {
97
private static final long serialVersionUID = 1L;
108

119
DeserializationException() {

src/main/java/com/maxmind/db/NoCache.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package com.maxmind.db;
22

33
import java.io.IOException;
4-
import java.lang.IllegalAccessException;
5-
import java.lang.InstantiationException;
6-
import java.lang.reflect.InvocationTargetException;
74

85
/**
96
* A no-op cache singleton.
@@ -16,12 +13,7 @@ private NoCache() {
1613
}
1714

1815
@Override
19-
public Object get(CacheKey key, Loader loader)
20-
throws IOException,
21-
InstantiationException,
22-
IllegalAccessException,
23-
InvocationTargetException,
24-
NoSuchMethodException {
16+
public Object get(CacheKey key, Loader loader) throws IOException {
2517
return loader.load(key);
2618
}
2719

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
11
package com.maxmind.db;
22

33
import java.io.IOException;
4-
import java.lang.IllegalAccessException;
5-
import java.lang.InstantiationException;
6-
import java.lang.reflect.InvocationTargetException;
74

85
public interface NodeCache {
96

107
interface Loader {
11-
Object load(CacheKey key)
12-
throws IOException,
13-
InstantiationException,
14-
IllegalAccessException,
15-
InvocationTargetException,
16-
NoSuchMethodException;
8+
Object load(CacheKey key) throws IOException;
179
}
1810

19-
Object get(CacheKey key, Loader loader)
20-
throws IOException,
21-
InstantiationException,
22-
IllegalAccessException,
23-
InvocationTargetException,
24-
NoSuchMethodException;
11+
Object get(CacheKey key, Loader loader) throws IOException;
2512

2613
}

0 commit comments

Comments
 (0)