[英]How should I debug a Nokogiri Null Pointer exception?
承包商為我的客戶創建了一個相當復雜的XSLT。 使用來自我們應用程序的真實數據,它可以在各種轉換測試工具中很好地工作。 但是Nokogiri在轉換期間拒絕了它。 在設置了$ VERBOSE和$ DEBUG的情況下,我仍然得到的信息不足:
Exception `RuntimeError' at nokogiri/XsltStylesheet.java:231 - java.lang.NullPointerException
所以我想我會在我的Gemfile中使用以下代碼創建一個自定義的Nokogiri Gem:
gem 'nokogiri', :git => 'ssh://git@192.168.185.65:7999/bssc/nokogiri.git'
由於版本問題,我無法解決該問題,因此無法使用:
Source does not contain any versions of 'nokogiri java'
所以在這一點上,我認為我會伸出援手,向社區征詢一個更好的主意。 我敢肯定Nokogiri不滿意樣式表中的某些內容,但是由於XSLT的復雜性,很難找到它。
有什么建議嗎?
...已使用Nokogiri完成了一些Java本機ext提升(1.7 / 1.8中的性能/清理更新)
這取決於您是否有指向合理位置的跡線,請嘗試jruby -Xbacktrace.style=raw ...
如果沒有顯示出有價值的見解,您可能需要自己構建寶石(這是一項艱巨的任務)只需確保您在JRuby下進行即可。
您不能將Bundler與:git
一起使用,因為.gemspec是根據Ruby平台生成的,因此,您將需要構建並手動進行gem install
(調整版本並使用Bundler進行設置,以便您知道使用的是哪個)。
祝好運!
我不確定這是否是最好的方法,但是在RVM環境中編輯源代碼,然后最小化build_all,可以刪除異常處理。 我修改的XsltStylesheet.java:
@JRubyMethod
public IRubyObject serialize(ThreadContext context, IRubyObject doc) throws IOException, TransformerException {
XmlDocument xmlDoc = (XmlDocument) doc;
TransformerImpl transformer = (TransformerImpl) this.sheet.newTransformer();
ByteArrayOutputStream writer = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(writer);
SerializationHandler serializationHandler = transformer.createSerializationHandler(streamResult);
serializationHandler.serialize(xmlDoc.getNode());
return context.getRuntime().newString(writer.toString());
}
@JRubyMethod(rest = true, required=1, optional=2)
public IRubyObject transform(ThreadContext context, IRubyObject[] args) throws TransformerException, IOException {
Ruby runtime = context.getRuntime();
System.out.println("in transform");
argumentTypeCheck(runtime, args[0]);
System.out.println("before listener");
// NokogiriXsltErrorListener elistener = new NokogiriXsltErrorListener();
System.out.println("before dom");
DOMSource domSource = new DOMSource(((XmlDocument) args[0]).getDocument());
final DOMResult result; String stringResult = null;
System.out.println("try transform");
result = tryXsltTransformation(context, args, domSource, null); // DOMResult
if (stringResult == null) {
return createDocumentFromDomResult(context, runtime, result);
} else {
return createDocumentFromString(context, runtime, stringResult);
}
}
private DOMResult tryXsltTransformation(ThreadContext context, IRubyObject[] args, DOMSource domSource, NokogiriXsltErrorListener elistener) throws TransformerException {
Transformer transf = sheet.newTransformer();
transf.reset();
// transf.setErrorListener(elistener);
if (args.length > 1) {
addParametersToTransformer(context, transf, args[1]);
}
DOMResult result = new DOMResult();
transf.transform(domSource, result);
return result;
}
這是我的全部腳本:
#! /usr/bin/env bash
#
# script to build gems for all relevant platforms:
# - MRI et al (standard gem)
# - windows (x86-mingw32 and x64-mingw32)
# - jruby
#
# Load RVM into a shell session *as a function*
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
source "/usr/local/rvm/scripts/rvm"
else
echo "ERROR: An RVM installation was not found.\n"
fi
set -o errexit
rm -rf tmp pkg
bundle exec rake clean clobber
# holding pen
rm -rf gems
mkdir -p gems
# windows
# MRI
# jruby
bundle exec rake clean clobber
bundle exec rake generate
gem install bundler --conservative
bundle install --quiet --local || bundle install
bundle exec rake gem
cp -v pkg/nokogiri*java.gem gems
這產生了輸出:
...
try transform
file:///Users/jeff/Documents/BlueSageSource/plus/dummy.xsl; Line #0; Column #0; org.apache.xpath.objects.XRTreeFrag cannot be cast to org.apache.xpath.objects.XNodeSet
file:///Users/jeff/Documents/BlueSageSource/plus/dummy.xsl; Line #0; Column #0; java.lang.NullPointerException
“無法投射”消息使我得到了其他信息,該信息指示Nokogiri不支持XSLT2。這令人失望,並不是太多,因為有限制,而是因為它沒有得到很好的記錄,並且出現空指針異常失敗是充其量是不友好的。 我認為我們有足夠的信息來創建一個最小的失敗案例,以作為增強請求。
參考資料:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.