sorry for the late response. I looked again into this
so, yes, first of all, I encountered this in ARQ 2.8.7 and indeed in later
ARQs, the path seems different
Trunk ARQ:
private void readImpl(Model model, Tokenizer tokenizer, String base)
{
try {
model.notifyEvent( GraphEvents.startRead );
readWorker(model, tokenizer, base) ;
}
ARQ 2.8.5:
private void readImpl(Model model, Tokenizer tokenizer, String base)
{
// The reader has been checked, if possible, by now or
// constructed correctly by code here.
if ( base != null )
base = IRIResolver.resolveGlobalToString(base) ;
try {
model.notifyEvent( GraphEvents.startRead );
readWorker(model, tokenizer, base) ;
}
So, perhaps we circumvent the problem using a later ARQ (we are looking to
adopt ARQ 2.8.8 in the near future)
However, independent of that, when I look at IRIResolverNormal, it has a
cache
private Cache<String, IRI> resolvedIRIs = CacheFactory.createCache(getter
, CacheSize) ;
which is not thread-safe. So public IRI resolveSilent(String relURI)
could not be used from multiple threads.
@Andy: are you saying that access to resolveSilent is definitely
single-threaded, even if there are multiple concurrent reads?
thanks
Simon
From:
Andy Seaborne <andy@apache.org>
To:
jena-dev@incubator.apache.org
Date:
10/31/2011 06:08 PM
Subject:
Re: IRIResolver cache not thread safe?
On 31/10/11 16:34, Simon Helsen wrote:
> Hi all,
>
> very sometimes (it is a rare and impossibly difficult to reproduce) we
run
> into a problem which I can only explain by a concurrency violation. The
> stack trace we typically encounter is below. I know that the concrete
NPE
> which comes as a result is specific to the IBM JDK because of the way
they
> implement LinkedHashMap, but the bug is not theirs. That the Sun SDK
does
> not immediately expose the issue is mere luck. Looking at the
IRIResolver
> code, it seems to me that the cache inside the IRIResolveNormal (
> resolvedIRIs) ought to be using a concurrent linked hashMap since there
is
> only one global cache which can be used by many threads.
>
> Any thoughts?
There is no such operation IRIResolver.resolveGlobalToString anymore.
Which version are you using?
Use of private static "globalResolver" may need protecting (see the
current system) which has one IRIResolverNormal - there may be others
and the class itself IRIResolverNormal does not need it (it has no
statics) and there are ways to create new ones.
Andy
>
> Thanks
>
> Simon
>
> java.lang.NullPointerException
> at java.util.LinkedHashMap.get(LinkedHashMap.java:324)
> at org.openjena.atlas.lib.cache.CacheLRU.get(CacheLRU.java:41)
> at
> org.openjena.atlas.lib.cache.CacheWrapper.get(CacheWrapper.java:29)
> at
>
org.openjena.atlas.lib.cache.CacheWithGetter.get(CacheWithGetter.java:26)
> at
>
org.openjena.riot.IRIResolver$IRIResolverNormal.resolveSilent(IRIResolver.java:377)
> at
>
org.openjena.riot.IRIResolver$IRIResolverNormal.resolveToString(IRIResolver.java:363)
> at
> org.openjena.riot.IRIResolver.resolveGlobalToString(IRIResolver.java:78)
> at
> org.openjena.riot.JenaReaderRIOT.readImpl(JenaReaderRIOT.java:121)
> at
org.openjena.riot.JenaReaderRIOT.read(JenaReaderRIOT.java:40)
> at
>
com.ibm.team.jfs.indexing.service.internal.rdf.RDFUtil.readNTriples(RDFUtil.java:166)
|