我们的生产系统(Java7运行时)中的XSLT转换不时失败,下面提供了NullPointerException。据我从Saxon9源代码了解,LRUCache类是AnyURIValue类中的静态类成员。我对此做了一些研究,并读到这可能是由于对底层LinkedHashMap的并发和非同步调用,这将解释问题似乎出现在对我们来说是随机的时间点。
The [java.lang.NullPointerException] occurred during XSLT transformation: java.lang.NullPointerException
at com.tibco.plugin.xml.XMLTransformActivity.eval(Unknown Source)
at com.tibco.pe.plugin.Activity.eval(Unknown Source)
at com.tibco.pe.core.TaskImpl.eval(Unknown Source)
at com.tibco.pe.core.Job.a(Unknown Source)
at com.tibco.pe.core.Job.k(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.a(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.run(Unknown Source)
caused by: java.lang.NullPointerException at java.util.LinkedHashMap$Entry.remove(Unknown Source)
at java.util.LinkedHashMap$Entry.recordRemoval(Unknown Source)
at java.util.HashMap.removeEntryForKey(Unknown Source)
at java.util.LinkedHashMap.addEntry(Unknown Source)
at java.util.HashMap.put(Unknown Source)
at net.sf.saxon.sort.LRUCache.put(LRUCache.java:47)
at net.sf.saxon.value.AnyURIValue.isValidURI(AnyURIValue.java:103)
at net.sf.saxon.instruct.Namespace.checkPrefixAndUri(Namespace.java:184)
at net.sf.saxon.instruct.Namespace.processLeavingTail(Namespace.java:144)
at net.sf.saxon.instruct.Block.processLeavingTail(Block.java:399)
at net.sf.saxon.instruct.Instruction.process(Instruction.java:94)
at net.sf.saxon.instruct.ElementCreator.processLeavingTail(ElementCreator.java:298)
at net.sf.saxon.instruct.Template.applyLeavingTail(Template.java:175)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:343)
at net.sf.saxon.instruct.ApplyTemplates.defaultAction(ApplyTemplates.java:376)
at net.sf.saxon.instruct.ApplyTemplates.applyTemplates(ApplyTemplates.java:331)
at net.sf.saxon.Controller.transformDocument(Controller.java:1735)
at net.sf.saxon.Controller.transform(Controller.java:1559)
at com.tibco.plugin.xml.XMLTransformActivity.new(Unknown Source)
at com.tibco.plugin.xml.XMLTransformActivity.eval(Unknown Source)
at com.tibco.pe.plugin.Activity.eval(Unknown Source)
at com.tibco.pe.core.TaskImpl.eval(Unknown Source)
at com.tibco.pe.core.Job.a(Unknown Source)
at com.tibco.pe.core.Job.k(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.a(Unknown Source)
at com.tibco.pe.core.JobDispatcher$JobCourier.run(Unknown Source)发布于 2013-09-20 13:07:32
Saxon9不是一个版本,而是一个由6个主要版本(9.0到9.5)组成的序列,在大约7年的时间内发布了更多的维护版本。您需要更精确地说明您使用的是哪个版本。
多年来,对于涉及LRUCache的问题,有几个解决方法,例如
https://saxonica.plan.io/issues/1481 https://saxonica.plan.io/issues/1619
虽然这两种方法都没有将NullPointerException描述为观察到的症状,但它们可以反映相同的潜在原因。
在需要ConcurrentHashMap的情况下,Saxon9.5代码使用它,而AnyURIValue类不再使用LRUCache。
发布于 2013-09-20 10:34:14
复制了这种行为,它似乎是Saxon9 9名称空间LRUCache中的一个并发问题。对于put和缓存上的get操作都会发生错误。下面的代码模拟了这个问题。LRUCache是撒克逊的AnyURIValue.class中的静态类成员,对底层LinkedHashMap的访问是不同步的。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
private static final int NTHREDS = 100;
private static final int EXECUTION_COUNT = 10000;
public static void main(String[] args) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
for (int i = 0; i < EXECUTION_COUNT; i++) {
Runnable worker = new TestRunnable(i);
executor.execute(worker);
}
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
}
}
import net.sf.saxon.sort.LRUCache;
public class TestRunnable implements Runnable {
private static LRUCache cache = new LRUCache(20); // The LRUCache is a static member in Saxon's AnyURIValue.class!
private int number;
public TestRunnable(int number){
this.number = number;
}
@Override
public void run() {
/**
* Access elements in ascending order to trigger the call to LinkedHashMap$Entry.remove;
*/
for(int i = 0; i < number; i++){
cache.get(new Integer(i));
}
/**
* Add the new element to the cache.
* As soon as the cacheSize exceeds 20, the cache is starting to remove the last accessed element.
*/
cache.put(new Integer(number), new Integer(number));
}
}https://stackoverflow.com/questions/18895833
复制相似问题