Skip to content
This repository was archived by the owner on Sep 12, 2022. It is now read-only.

Commit b26e4d1

Browse files
authored
do not silently ignore exceptions in PBF import (graphhopper#2270)
* OSM PBF import: do not silently ignore exceptions, fixes graphhopper#2269 * revert unrelated change * minor name change
1 parent 71681a1 commit b26e4d1

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

core/src/main/java/com/graphhopper/reader/osm/OSMInputFile.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ public class OSMInputFile implements Sink, OSMInput {
4646
private final InputStream bis;
4747
private final BlockingQueue<ReaderElement> itemQueue;
4848
private final Queue<ReaderElement> itemBatch;
49-
Thread pbfReaderThread;
5049
private boolean eof;
5150
// for xml parsing
52-
private XMLStreamReader parser;
51+
private XMLStreamReader xmlParser;
5352
// for pbf parsing
5453
private boolean binary = false;
54+
private PbfReader pbfReader;
55+
private Thread pbfReaderThread;
5556
private boolean hasIncomingData;
5657
private int workerThreads = -1;
5758
private OSMFileHeader fileheader;
@@ -138,17 +139,17 @@ private InputStream decode(File file) throws IOException {
138139
private void openXMLStream(InputStream in)
139140
throws XMLStreamException {
140141
XMLInputFactory factory = XMLInputFactory.newInstance();
141-
parser = factory.createXMLStreamReader(in, "UTF-8");
142+
xmlParser = factory.createXMLStreamReader(in, "UTF-8");
142143

143-
int event = parser.next();
144-
if (event != XMLStreamConstants.START_ELEMENT || !parser.getLocalName().equalsIgnoreCase("osm")) {
144+
int event = xmlParser.next();
145+
if (event != XMLStreamConstants.START_ELEMENT || !xmlParser.getLocalName().equalsIgnoreCase("osm")) {
145146
throw new IllegalArgumentException("File is not a valid OSM stream");
146147
}
147148
// See https://wiki.openstreetmap.org/wiki/PBF_Format#Definition_of_the_OSMHeader_fileblock
148-
String timestamp = parser.getAttributeValue(null, "osmosis_replication_timestamp");
149+
String timestamp = xmlParser.getAttributeValue(null, "osmosis_replication_timestamp");
149150

150151
if (timestamp == null)
151-
timestamp = parser.getAttributeValue(null, "timestamp");
152+
timestamp = xmlParser.getAttributeValue(null, "timestamp");
152153

153154
if (timestamp != null) {
154155
try {
@@ -181,7 +182,7 @@ public ReaderElement getNext() throws XMLStreamException {
181182

182183
private ReaderElement getNextXML() throws XMLStreamException {
183184

184-
int event = parser.next();
185+
int event = xmlParser.next();
185186
if (fileheader != null) {
186187
ReaderElement copyfileheader = fileheader;
187188
fileheader = null;
@@ -190,32 +191,32 @@ private ReaderElement getNextXML() throws XMLStreamException {
190191

191192
while (event != XMLStreamConstants.END_DOCUMENT) {
192193
if (event == XMLStreamConstants.START_ELEMENT) {
193-
String idStr = parser.getAttributeValue(null, "id");
194+
String idStr = xmlParser.getAttributeValue(null, "id");
194195
if (idStr != null) {
195-
String name = parser.getLocalName();
196+
String name = xmlParser.getLocalName();
196197
long id = 0;
197198
switch (name.charAt(0)) {
198199
case 'n':
199200
// note vs. node
200201
if ("node".equals(name)) {
201202
id = Long.parseLong(idStr);
202-
return OSMXMLHelper.createNode(id, parser);
203+
return OSMXMLHelper.createNode(id, xmlParser);
203204
}
204205
break;
205206

206207
case 'w': {
207208
id = Long.parseLong(idStr);
208-
return OSMXMLHelper.createWay(id, parser);
209+
return OSMXMLHelper.createWay(id, xmlParser);
209210
}
210211
case 'r':
211212
id = Long.parseLong(idStr);
212-
return OSMXMLHelper.createRelation(id, parser);
213+
return OSMXMLHelper.createRelation(id, xmlParser);
213214
}
214215
}
215216
}
216-
event = parser.next();
217+
event = xmlParser.next();
217218
}
218-
parser.close();
219+
xmlParser.close();
219220
return null;
220221
}
221222

@@ -226,8 +227,10 @@ public boolean isEOF() {
226227
@Override
227228
public void close() throws IOException {
228229
try {
229-
if (!binary)
230-
parser.close();
230+
if (binary)
231+
pbfReader.close();
232+
else
233+
xmlParser.close();
231234
} catch (XMLStreamException ex) {
232235
throw new IOException(ex);
233236
} finally {
@@ -244,8 +247,8 @@ private void openPBFReader(InputStream stream) {
244247
if (workerThreads <= 0)
245248
workerThreads = 1;
246249

247-
PbfReader reader = new PbfReader(stream, this, workerThreads);
248-
pbfReaderThread = new Thread(reader, "PBF Reader");
250+
pbfReader = new PbfReader(stream, this, workerThreads);
251+
pbfReaderThread = new Thread(pbfReader, "PBF Reader");
249252
pbfReaderThread.start();
250253
}
251254

@@ -273,7 +276,7 @@ private ReaderElement getNextPBF() {
273276
if (!hasIncomingData && itemQueue.isEmpty()) {
274277
return null; // signal EOF
275278
}
276-
279+
277280
if (itemQueue.drainTo(itemBatch, MAX_BATCH_SIZE) == 0) {
278281
try {
279282
ReaderElement element = itemQueue.poll(100, TimeUnit.MILLISECONDS);
@@ -286,7 +289,7 @@ private ReaderElement getNextPBF() {
286289
}
287290
}
288291
}
289-
292+
290293
return itemBatch.poll();
291294
}
292295
}

core/src/main/java/com/graphhopper/reader/osm/pbf/PbfBlobDecoder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ public void run() {
356356
listener.complete(decodedEntities);
357357

358358
} catch (RuntimeException e) {
359+
// exception is properly rethrown in PbfDecoder.sendResultsToSink
359360
listener.error(e);
360361
}
361362
}

core/src/main/java/com/graphhopper/reader/osm/pbf/PbfDecoder.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33

44
import com.graphhopper.reader.ReaderElement;
55

6-
import java.util.ArrayList;
76
import java.util.LinkedList;
87
import java.util.List;
98
import java.util.Queue;
10-
import java.util.concurrent.ArrayBlockingQueue;
119
import java.util.concurrent.ExecutorService;
1210
import java.util.concurrent.locks.Condition;
1311
import java.util.concurrent.locks.Lock;
@@ -20,7 +18,7 @@
2018
*
2119
* @author Brett Henderson
2220
*/
23-
public class PbfDecoder implements Runnable {
21+
public class PbfDecoder {
2422
private final PbfStreamSplitter streamSplitter;
2523
private final ExecutorService executorService;
2624
private final int maxPendingBlobs;
@@ -155,7 +153,6 @@ public void complete(List<ReaderElement> decodedEntities) {
155153
sendResultsToSink(0);
156154
}
157155

158-
@Override
159156
public void run() {
160157
lock.lock();
161158
try {

core/src/main/java/com/graphhopper/reader/osm/pbf/PbfReader.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* @author Brett Henderson
1414
*/
1515
public class PbfReader implements Runnable {
16+
private Throwable throwable;
1617
private InputStream inputStream;
1718
private Sink sink;
1819
private int workers;
@@ -33,10 +34,10 @@ public PbfReader(InputStream in, Sink sink, int workers) {
3334
@Override
3435
public void run() {
3536
ExecutorService executorService = Executors.newFixedThreadPool(workers);
36-
try {
37-
// Create a stream splitter to break the PBF stream into blobs.
38-
PbfStreamSplitter streamSplitter = new PbfStreamSplitter(new DataInputStream(inputStream));
37+
// Create a stream splitter to break the PBF stream into blobs.
38+
PbfStreamSplitter streamSplitter = new PbfStreamSplitter(new DataInputStream(inputStream));
3939

40+
try {
4041
// Process all blobs of data in the stream using threads from the
4142
// executor service. We allow the decoder to issue an extra blob
4243
// than there are workers to ensure there is another blob
@@ -46,11 +47,18 @@ public void run() {
4647
PbfDecoder pbfDecoder = new PbfDecoder(streamSplitter, executorService, workers + 1, sink);
4748
pbfDecoder.run();
4849

49-
} catch (Exception e) {
50-
throw new RuntimeException("Unable to read PBF file.", e);
50+
} catch (Throwable t) {
51+
// properly propagate exception inside Thread, #2269
52+
throwable = t;
5153
} finally {
5254
sink.complete();
5355
executorService.shutdownNow();
56+
streamSplitter.release();
5457
}
5558
}
59+
60+
public void close() {
61+
if (throwable != null)
62+
throw new RuntimeException("Unable to read PBF file.", throwable);
63+
}
5664
}

core/src/main/java/com/graphhopper/reader/osm/pbf/PbfStreamSplitter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public void release() {
110110
try {
111111
dis.close();
112112
} catch (IOException e) {
113-
log.log(Level.SEVERE, "Unable to close PBF stream.", e);
113+
throw new RuntimeException(e);
114114
}
115115
}
116116
dis = null;

0 commit comments

Comments
 (0)