我应该如何调试Nokogiri Null Pointer异常?

时间:2017-07-06 00:46:02

标签: ruby xslt nokogiri jruby

承包商为我的客户创建了一个相当复杂的XSLT。它在各种转换测试工具中运行良好,使用我们应用程序中的真实数据。但是Nokogiri在改造期间对它进行了解决。设置$ VERBOSE和$ DEBUG后,我仍然无法获得信息:

Exception `RuntimeError' at nokogiri/XsltStylesheet.java:231 - java.lang.NullPointerException

所以我想我会创建一个带有一些调试代码的自定义Nokogiri Gem,在我的Gemfile中使用它:

gem 'nokogiri', :git => 'ssh://git@192.168.185.65:7999/bssc/nokogiri.git'

由于版本问题,我无法理解如何解决这个问题:

Source does not contain any versions of 'nokogiri java'

所以在这一点上,我想我会伸出援手让社区有更好的想法。我确信Nokogiri对样式表中的内容并不满意,但由于XSLT的复杂性,很难找到它。

连连呢?

2 个答案:

答案 0 :(得分:2)

...使用Nokogiri完成了一些Java原生扩展(1.7 / 1.8中的性能/清理更新)

这取决于你是否有指向合理位置的痕迹,如果没有显示你可能需要自己构建宝石的宝贵见解,请尝试jruby -Xbacktrace.style=raw ...(这里只有一个rake任务确保你在JRuby下做这件事。)

您不能将Bundler与:git一起使用,因为.gemspec是根据Ruby平台生成的,因此您需要构建并手动gem install(调整版本并使用Bundler进行设置,以便您知道你正在使用哪一个。

祝你好运!

答案 1 :(得分:0)

我不确定这是最好的方法,但是在我的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;
    }

这是我的build-all脚本:

#! /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不支持XSLT 2.这是令人失望的,不是因为限制,而是因为它没有很好地记录,并且使用空指针异常失败充其量是不友好的。我认为我们有足够的信息来创建一个最小的失败案例,作为增强请求提交。

参考:

Nokogiri does not intend to support XSLT 2

Nokogiri does not support XSLT 2