Hi everyone,
I think there may be an older thread on this topic somewhere but I
couldn't immediately find it. Depending on our test scenarios, we
sometimes run into the following NPE on an IBM JRE (6 or 7)
Caused by: java.lang.NullPointerException
at java.util.LinkedHashMap.get(LinkedHashMap.java:337)
at org.apache.jena.atlas.lib.cache.CacheLRU.get(CacheLRU.java:53)
at
org.apache.jena.riot.system.IRIResolver$IRIResolverNormal.resolveSilent(
IRIResolver.java:403)
at
org.apache.jena.riot.system.IRIResolver$IRIResolverNormal.<init>(
IRIResolver.java:359)
at org.apache.jena.riot.system.IRIResolver.create(
IRIResolver.java:212)
at org.apache.jena.riot.system.RiotLib.profile(RiotLib.java:141)
at org.apache.jena.riot.system.RiotLib.profile(RiotLib.java:130)
at org.apache.jena.riot.system.RiotLib.profile(RiotLib.java:117)
at org.apache.jena.riot.RiotReader.createParserTurtle(
RiotReader.java:310)
at org.apache.jena.riot.RiotReader.createParser(
RiotReader.java:142)
at org.apache.jena.riot.RiotReader.createParser(
RiotReader.java:133)
at
org.apache.jena.riot.RDFParserRegistry$ReaderRIOTFactoryImpl$1.read(
RDFParserRegistry.java:141)
at org.apache.jena.riot.RDFDataMgr.process(RDFDataMgr.java:760)
at org.apache.jena.riot.RDFDataMgr.read(RDFDataMgr.java:258)
at org.apache.jena.riot.RDFDataMgr.read(RDFDataMgr.java:244)
at
com.ibm.team.integration.registry.index.JenaIoService.readModel(
JenaIoService.java:62)
... 20 more
This is definitely happening because of a concurrency problem, i.e.
multiple threads are resolving IRIs in similar models. The problem does
not appear on Oracle JREs AFAIK, but I found the following link indicating
that a LinkedHashMap is not expected to be threadsafe:
http://code.google.com/p/orika/issues/detail?id=74
To me, this seems to be exactly the same probem. The original call in
JenaIoService:62 is a simple isolated call to RDFDataMgr on an in-memory
model. The problem appears that the CacheLRU in
org.apache.jena.atlas.lib.cache seems to assume LinkedHashMap is
threadsafe. The fix is to make the CacheLRU itself threadsafe, possibly by
merely synchronizing the calls to get/put in CacheLRU.
Simon