[jruby] 02/03: Bundle psych Java native extension

Miguel Landaeta nomadium at moszumanska.debian.org
Sat Mar 4 13:31:58 UTC 2017


This is an automated email from the git hooks/post-receive script.

nomadium pushed a commit to branch experimental
in repository jruby.

commit 8a38bcc85aa762604a897c1389efb8ccf8abc621
Author: Miguel Landaeta <nomadium at debian.org>
Date:   Sat Mar 4 11:33:12 2017 +0000

    Bundle psych Java native extension
---
 debian/changelog                                   |   3 +
 debian/control                                     |   2 +
 debian/jruby.links                                 |   2 +
 .../patches/0009-Bundle-psych-java-extension.patch | 995 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 debian/psych-java-ext-build-classpath              |  12 +
 debian/psych-java-ext-class-entries                |  18 +
 debian/psych-java-ext-source-files                 |   6 +
 debian/rules                                       |   9 +
 9 files changed, 1048 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 21c38e7..3733efe 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,9 @@
 jruby (9.1.6.0-1~exp2) UNRELEASED; urgency=medium
 
   * Don't hard-code libyaml-snake-java version in psych stdlib module.
+  * Bundle psych Java native extension:
+    - Add patch 0009-Bundle-psych-java-extension.patch.
+    - Add again dependency on libyaml-snake-java.
 
  -- Miguel Landaeta <nomadium at debian.org>  Sat, 04 Mar 2017 11:23:24 +0000
 
diff --git a/debian/control b/debian/control
index 34e760f..72a7d16 100644
--- a/debian/control
+++ b/debian/control
@@ -41,6 +41,7 @@ Build-Depends: ant-optional,
                libosgi-core-java,
                libruby2.3,
                libunsafe-mock-java,
+               libyaml-snake-java,
                maven-debian-helper (>= 2.0~),
                nailgun,
                rake,
@@ -79,6 +80,7 @@ Depends: default-jre | java7-runtime,
          libjzlib-java,
          libosgi-core-java,
          libunsafe-mock-java,
+         libyaml-snake-java,
          nailgun,
          ${misc:Depends}
 Recommends: jruby-openssl,
diff --git a/debian/jruby.links b/debian/jruby.links
index abefe2e..63b7c48 100644
--- a/debian/jruby.links
+++ b/debian/jruby.links
@@ -20,3 +20,5 @@ usr/lib/arm-linux-gnueabi/jni/libjffi-1.2.so      usr/share/jruby/lib/jni/arm-Li
 usr/lib/aarch64-linux-gnu/jni/libjffi-1.2.so      usr/share/jruby/lib/jni/aarch64-Linux/libjffi-1.2.so
 usr/lib/powerpc64-linux-gnu/jni/libjffi-1.2.so    usr/share/jruby/lib/jni/ppc64-Linux/libjffi-1.2.so
 usr/lib/powerpc64le-linux-gnu/jni/libjffi-1.2.so  usr/share/jruby/lib/jni/ppc64le-Linux/libjffi-1.2.so
+
+usr/share/maven-repo/org/yaml/snakeyaml/1.x/snakeyaml-1.x.jar  usr/share/jruby/lib/ruby/stdlib/org/yaml/snakeyaml/1.x/snakeyaml-1.x.jar
diff --git a/debian/patches/0009-Bundle-psych-java-extension.patch b/debian/patches/0009-Bundle-psych-java-extension.patch
new file mode 100644
index 0000000..b7a5444
--- /dev/null
+++ b/debian/patches/0009-Bundle-psych-java-extension.patch
@@ -0,0 +1,995 @@
+Description: Bundle psych Java extension
+ This patch must be removed as soon as jruby-psych is packaged.
+ This was bundled with jruby in 1.7.x releases but now is provided by
+ ruby-psych gem when Java extension is built.
+Author: Miguel Landaeta <nomadium at debian.org>
+Forwarded: no
+Last-Update: 2017-03-03
+
+--- /dev/null
++++ jruby-9.1.6.0/ext/java/PsychEmitter.java
+@@ -0,0 +1,347 @@
++/***** BEGIN LICENSE BLOCK *****
++ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Eclipse Public
++ * License Version 1.0 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.eclipse.org/legal/epl-v10.html
++ *
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ *
++ * Copyright (C) 2010 Charles O Nutter <headius at headius.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of the GNU General Public License Version 2 or later (the "GPL"),
++ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the EPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the EPL, the GPL or the LGPL.
++ ***** END LICENSE BLOCK *****/
++package org.jruby.ext.psych;
++
++import java.io.IOException;
++import java.io.OutputStreamWriter;
++import java.nio.charset.Charset;
++import java.util.HashMap;
++import java.util.Map;
++
++import org.jcodings.Encoding;
++import org.jruby.Ruby;
++import org.jruby.RubyArray;
++import org.jruby.RubyClass;
++import org.jruby.RubyFixnum;
++import org.jruby.RubyModule;
++import org.jruby.RubyObject;
++import org.jruby.RubyString;
++import org.jruby.anno.JRubyMethod;
++import org.jruby.runtime.ObjectAllocator;
++import org.jruby.runtime.ThreadContext;
++import org.jruby.runtime.builtin.IRubyObject;
++import org.jruby.util.IOOutputStream;
++import org.yaml.snakeyaml.DumperOptions;
++import org.yaml.snakeyaml.emitter.Emitter;
++import org.yaml.snakeyaml.emitter.EmitterException;
++import org.yaml.snakeyaml.error.Mark;
++import org.yaml.snakeyaml.events.AliasEvent;
++import org.yaml.snakeyaml.events.DocumentEndEvent;
++import org.yaml.snakeyaml.events.DocumentStartEvent;
++import org.yaml.snakeyaml.events.Event;
++import org.yaml.snakeyaml.events.ImplicitTuple;
++import org.yaml.snakeyaml.events.MappingEndEvent;
++import org.yaml.snakeyaml.events.MappingStartEvent;
++import org.yaml.snakeyaml.events.ScalarEvent;
++import org.yaml.snakeyaml.events.SequenceEndEvent;
++import org.yaml.snakeyaml.events.SequenceStartEvent;
++import org.yaml.snakeyaml.events.StreamEndEvent;
++import org.yaml.snakeyaml.events.StreamStartEvent;
++
++import static org.jruby.runtime.Visibility.*;
++
++public class PsychEmitter extends RubyObject {
++    public static void initPsychEmitter(Ruby runtime, RubyModule psych) {
++        RubyClass psychHandler = runtime.defineClassUnder("Handler", runtime.getObject(), runtime.getObject().getAllocator(), psych);
++        RubyClass psychEmitter = runtime.defineClassUnder("Emitter", psychHandler, new ObjectAllocator() {
++            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
++                return new PsychEmitter(runtime, klazz);
++            }
++        }, psych);
++
++        psychEmitter.defineAnnotatedMethods(PsychEmitter.class);
++    }
++
++    public PsychEmitter(Ruby runtime, RubyClass klass) {
++        super(runtime, klass);
++    }
++
++    @JRubyMethod(visibility = PRIVATE)
++    public IRubyObject initialize(ThreadContext context, IRubyObject io) {
++        options = new DumperOptions();
++        options.setIndent(2);
++
++        this.io = io;
++
++        return context.nil;
++    }
++
++    @JRubyMethod(visibility = PRIVATE)
++    public IRubyObject initialize(ThreadContext context, IRubyObject io, IRubyObject rbOptions) {
++        IRubyObject width     = rbOptions.callMethod(context, "line_width");
++        IRubyObject canonical = rbOptions.callMethod(context, "canonical");
++        IRubyObject level     = rbOptions.callMethod(context, "indentation");
++
++        options = new DumperOptions();
++
++        options.setCanonical(canonical.isTrue());
++        options.setIndent((int)level.convertToInteger().getLongValue());
++        line_width_set(context, width);
++
++        this.io = io;
++
++        return context.nil;
++    }
++
++    @JRubyMethod
++    public IRubyObject start_stream(ThreadContext context, IRubyObject encoding) {
++        if (!(encoding instanceof RubyFixnum)) {
++            throw context.runtime.newTypeError(encoding, context.runtime.getFixnum());
++        }
++
++        initEmitter(context, encoding);
++
++        StreamStartEvent event = new StreamStartEvent(NULL_MARK, NULL_MARK);
++
++        emit(context, event);
++
++        return this;
++    }
++
++    @JRubyMethod
++    public IRubyObject end_stream(ThreadContext context) {
++        StreamEndEvent event = new StreamEndEvent(NULL_MARK, NULL_MARK);
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod
++    public IRubyObject start_document(ThreadContext context, IRubyObject _version, IRubyObject tags, IRubyObject implicit) {
++        DumperOptions.Version version = null;
++        boolean implicitBool = implicit.isTrue();
++        Map<String, String> tagsMap = null;
++
++        RubyArray versionAry = _version.convertToArray();
++        if (versionAry.size() == 2) {
++            int versionInt0 = (int)versionAry.eltInternal(0).convertToInteger().getLongValue();
++            int versionInt1 = (int)versionAry.eltInternal(1).convertToInteger().getLongValue();
++
++            if (versionInt0 == 1) {
++                if (versionInt1 == 0) {
++                    version = DumperOptions.Version.V1_0;
++                } else if (versionInt1 == 1) {
++                    version = DumperOptions.Version.V1_1;
++                }
++            }
++            if (version == null) {
++                throw context.runtime.newArgumentError("invalid YAML version: " + versionAry);
++            }
++        }
++
++        RubyArray tagsAry = tags.convertToArray();
++        if (tagsAry.size() > 0) {
++            tagsMap = new HashMap<String, String>(tagsAry.size());
++            for (int i = 0; i < tagsAry.size(); i++) {
++                RubyArray tagsTuple = tagsAry.eltInternal(i).convertToArray();
++                if (tagsTuple.size() != 2) {
++                    throw context.runtime.newRuntimeError("tags tuple must be of length 2");
++                }
++                IRubyObject key = tagsTuple.eltInternal(0);
++                IRubyObject value = tagsTuple.eltInternal(1);
++                tagsMap.put(
++                        key.asJavaString(),
++                        value.asJavaString());
++            }
++        }
++
++        DocumentStartEvent event = new DocumentStartEvent(NULL_MARK, NULL_MARK, !implicitBool, version, tagsMap);
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod
++    public IRubyObject end_document(ThreadContext context, IRubyObject implicit) {
++        DocumentEndEvent event = new DocumentEndEvent(NULL_MARK, NULL_MARK, !implicit.isTrue());
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod(required = 6)
++    public IRubyObject scalar(ThreadContext context, IRubyObject[] args) {
++        IRubyObject value = args[0];
++        IRubyObject anchor = args[1];
++        IRubyObject tag = args[2];
++        IRubyObject plain = args[3];
++        IRubyObject quoted = args[4];
++        IRubyObject style = args[5];
++        
++        if (!(value instanceof RubyString)) {
++            throw context.runtime.newTypeError(value, context.runtime.getString());
++        }
++
++        ScalarEvent event = new ScalarEvent(
++                anchor.isNil() ? null : anchor.asJavaString(),
++                tag.isNil() ? null : tag.asJavaString(),
++                new ImplicitTuple(plain.isTrue(),
++                quoted.isTrue()),
++                value.asJavaString(),
++                NULL_MARK,
++                NULL_MARK,
++                SCALAR_STYLES[(int)style.convertToInteger().getLongValue()]);
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod(required = 4)
++    public IRubyObject start_sequence(ThreadContext context, IRubyObject[] args) {
++        IRubyObject anchor = args[0];
++        IRubyObject tag = args[1];
++        IRubyObject implicit = args[2];
++        IRubyObject style = args[3];
++
++        final int SEQUENCE_BLOCK = 1; // see psych/nodes/sequence.rb
++
++        SequenceStartEvent event = new SequenceStartEvent(
++                anchor.isNil() ? null : anchor.asJavaString(),
++                tag.isNil() ? null : tag.asJavaString(),
++                implicit.isTrue(),
++                NULL_MARK,
++                NULL_MARK,
++                SEQUENCE_BLOCK != style.convertToInteger().getLongValue());
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod
++    public IRubyObject end_sequence(ThreadContext context) {
++        SequenceEndEvent event = new SequenceEndEvent(NULL_MARK, NULL_MARK);
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod(required = 4)
++    public IRubyObject start_mapping(ThreadContext context, IRubyObject[] args) {
++        IRubyObject anchor = args[0];
++        IRubyObject tag = args[1];
++        IRubyObject implicit = args[2];
++        IRubyObject style = args[3];
++
++        final int MAPPING_BLOCK = 1; // see psych/nodes/mapping.rb
++
++        MappingStartEvent event = new MappingStartEvent(
++                anchor.isNil() ? null : anchor.asJavaString(),
++                tag.isNil() ? null : tag.asJavaString(),
++                implicit.isTrue(),
++                NULL_MARK,
++                NULL_MARK,
++                MAPPING_BLOCK != style.convertToInteger().getLongValue());
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod
++    public IRubyObject end_mapping(ThreadContext context) {
++        MappingEndEvent event = new MappingEndEvent(NULL_MARK, NULL_MARK);
++        emit(context, event);
++        return this;
++    }
++    
++    @JRubyMethod
++    public IRubyObject alias(ThreadContext context, IRubyObject anchor) {
++        AliasEvent event = new AliasEvent(anchor.asJavaString(), NULL_MARK, NULL_MARK);
++        emit(context, event);
++        return this;
++    }
++
++    @JRubyMethod(name = "canonical=")
++    public IRubyObject canonical_set(ThreadContext context, IRubyObject canonical) {
++        // TODO: unclear if this affects a running emitter
++        options.setCanonical(canonical.isTrue());
++        return canonical;
++    }
++
++    @JRubyMethod
++    public IRubyObject canonical(ThreadContext context) {
++        // TODO: unclear if this affects a running emitter
++        return context.runtime.newBoolean(options.isCanonical());
++    }
++
++    @JRubyMethod(name = "indentation=")
++    public IRubyObject indentation_set(ThreadContext context, IRubyObject level) {
++        // TODO: unclear if this affects a running emitter
++        options.setIndent((int)level.convertToInteger().getLongValue());
++        return level;
++    }
++
++    @JRubyMethod
++    public IRubyObject indentation(ThreadContext context) {
++        // TODO: unclear if this affects a running emitter
++        return context.runtime.newFixnum(options.getIndent());
++    }
++
++    @JRubyMethod(name = "line_width=")
++    public IRubyObject line_width_set(ThreadContext context, IRubyObject width) {
++        int newWidth = (int)width.convertToInteger().getLongValue();
++        if (newWidth <= 0) newWidth = Integer.MAX_VALUE;
++        options.setWidth(newWidth);
++        return width;
++    }
++
++    @JRubyMethod
++    public IRubyObject line_width(ThreadContext context) {
++        return context.runtime.newFixnum(options.getWidth());
++    }
++
++    private void emit(ThreadContext context, Event event) {
++        try {
++            if (emitter == null) throw context.runtime.newRuntimeError("uninitialized emitter");
++
++            emitter.emit(event);
++        } catch (IOException ioe) {
++            throw context.runtime.newIOErrorFromException(ioe);
++        } catch (EmitterException ee) {
++            throw context.runtime.newRuntimeError(ee.toString());
++        }
++    }
++
++    private void initEmitter(ThreadContext context, IRubyObject _encoding) {
++        if (emitter != null) throw context.runtime.newRuntimeError("already initialized emitter");
++
++        Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding;
++        Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding);
++
++        emitter = new Emitter(new OutputStreamWriter(new IOOutputStream(io, encoding), charset), options);
++    }
++
++    Emitter emitter;
++    DumperOptions options = new DumperOptions();
++    IRubyObject io;
++
++    private static final Mark NULL_MARK = new Mark(null, 0, 0, 0, null, 0);
++
++    // Map style constants from Psych values (ANY = 0 ... FOLDED = 5)
++    // to SnakeYaml values; see psych/nodes/scalar.rb.
++    private static final Character[] SCALAR_STYLES = new Character[] {
++        null, // ANY; we'll choose plain
++        null, // PLAIN
++        '\'', // SINGLE_QUOTED
++        '"',  // DOUBLE_QUOTED
++        '|',  // LITERAL
++        '>',  // FOLDED
++    };
++}
+--- /dev/null
++++ jruby-9.1.6.0/ext/java/PsychLibrary.java
+@@ -0,0 +1,93 @@
++/***** BEGIN LICENSE BLOCK *****
++ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Eclipse Public
++ * License Version 1.0 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.eclipse.org/legal/epl-v10.html
++ *
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ *
++ * Copyright (C) 2010 Charles O Nutter <headius at headius.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of the GNU General Public License Version 2 or later (the "GPL"),
++ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the EPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the EPL, the GPL or the LGPL.
++ ***** END LICENSE BLOCK *****/
++package org.jruby.ext.psych;
++
++import java.io.InputStream;
++import java.io.IOException;
++import java.util.Properties;
++
++import org.jcodings.Encoding;
++import org.jcodings.specific.UTF16BEEncoding;
++import org.jcodings.specific.UTF16LEEncoding;
++import org.jcodings.specific.UTF8Encoding;
++import org.jruby.Ruby;
++import org.jruby.RubyArray;
++import org.jruby.RubyModule;
++import org.jruby.RubyString;
++import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodZero;
++import org.jruby.runtime.ThreadContext;
++import org.jruby.runtime.Visibility;
++import org.jruby.runtime.builtin.IRubyObject;
++import org.jruby.runtime.load.Library;
++
++public class PsychLibrary implements Library {
++    public void load(final Ruby runtime, boolean wrap) {
++        RubyModule psych = runtime.defineModule("Psych");
++
++        // load version from properties packed with the jar
++        Properties props = new Properties();
++        try( InputStream is = runtime.getJRubyClassLoader().getResourceAsStream("META-INF/maven/org.yaml/snakeyaml/pom.properties") ) {
++            props.load(is);
++        }
++        catch( IOException e ) {
++            // ignored
++        }
++        RubyString version = runtime.newString(props.getProperty("version", "0.0") + ".0");
++        version.setFrozen(true);
++        psych.setConstant("SNAKEYAML_VERSION", version);
++
++        String[] versionParts = version.toString().split("\\.");
++        final RubyArray versionElements = runtime.newArray(runtime.newFixnum(Integer.parseInt(versionParts[0])), runtime.newFixnum(Integer.parseInt(versionParts[1])), runtime.newFixnum(Integer.parseInt(versionParts[2])));
++        versionElements.setFrozen(true);
++
++        psych.getSingletonClass().addMethod("libyaml_version", new JavaMethodZero(psych, Visibility.PUBLIC) {
++            @Override
++            public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
++                return versionElements;
++            }
++        });
++        
++        PsychParser.initPsychParser(runtime, psych);
++        PsychEmitter.initPsychEmitter(runtime, psych);
++        PsychToRuby.initPsychToRuby(runtime, psych);
++        PsychYamlTree.initPsychYamlTree(runtime, psych);
++    }
++
++    public enum YAMLEncoding {
++        YAML_ANY_ENCODING(UTF8Encoding.INSTANCE),
++        YAML_UTF8_ENCODING(UTF8Encoding.INSTANCE),
++        YAML_UTF16LE_ENCODING(UTF16LEEncoding.INSTANCE),
++        YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE);
++
++        YAMLEncoding(Encoding encoding) {
++            this.encoding = encoding;
++        }
++
++        public final Encoding encoding;
++    }
++}
+--- /dev/null
++++ jruby-9.1.6.0/ext/java/PsychParser.java
+@@ -0,0 +1,398 @@
++/***** BEGIN LICENSE BLOCK *****
++ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Eclipse Public
++ * License Version 1.0 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.eclipse.org/legal/epl-v10.html
++ *
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ *
++ * Copyright (C) 2010 Charles O Nutter <headius at headius.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of the GNU General Public License Version 2 or later (the "GPL"),
++ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the EPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the EPL, the GPL or the LGPL.
++ ***** END LICENSE BLOCK *****/
++package org.jruby.ext.psych;
++
++import java.io.ByteArrayInputStream;
++import java.io.InputStreamReader;
++import java.nio.charset.Charset;
++import java.util.Map;
++
++import org.jcodings.Encoding;
++import org.jcodings.specific.UTF8Encoding;
++import org.jcodings.unicode.UnicodeEncoding;
++import org.jruby.Ruby;
++import org.jruby.RubyArray;
++import org.jruby.RubyClass;
++import org.jruby.RubyEncoding;
++import org.jruby.RubyIO;
++import org.jruby.RubyKernel;
++import org.jruby.RubyModule;
++import org.jruby.RubyObject;
++import org.jruby.RubyString;
++import org.jruby.anno.JRubyMethod;
++import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
++import org.jruby.runtime.Block;
++import org.jruby.runtime.Helpers;
++import org.jruby.runtime.ObjectAllocator;
++import org.jruby.runtime.ThreadContext;
++import org.jruby.runtime.builtin.IRubyObject;
++import org.jruby.util.IOInputStream;
++import org.jruby.util.io.EncodingUtils;
++import org.jruby.util.log.Logger;
++import org.jruby.util.log.LoggerFactory;
++import org.yaml.snakeyaml.DumperOptions;
++import org.yaml.snakeyaml.error.Mark;
++import org.yaml.snakeyaml.error.MarkedYAMLException;
++import org.yaml.snakeyaml.events.AliasEvent;
++import org.yaml.snakeyaml.events.DocumentEndEvent;
++import org.yaml.snakeyaml.events.DocumentStartEvent;
++import org.yaml.snakeyaml.events.Event;
++import org.yaml.snakeyaml.events.Event.ID;
++import org.yaml.snakeyaml.events.MappingStartEvent;
++import org.yaml.snakeyaml.events.ScalarEvent;
++import org.yaml.snakeyaml.events.SequenceStartEvent;
++import org.yaml.snakeyaml.parser.Parser;
++import org.yaml.snakeyaml.parser.ParserException;
++import org.yaml.snakeyaml.parser.ParserImpl;
++import org.yaml.snakeyaml.reader.ReaderException;
++import org.yaml.snakeyaml.reader.StreamReader;
++import org.yaml.snakeyaml.scanner.ScannerException;
++import static org.jruby.runtime.Helpers.invoke;
++import org.jruby.util.ByteList;
++
++public class PsychParser extends RubyObject {
++
++    private static final Logger LOG = LoggerFactory.getLogger(PsychParser.class);
++    
++    public static void initPsychParser(Ruby runtime, RubyModule psych) {
++        RubyClass psychParser = runtime.defineClassUnder("Parser", runtime.getObject(), new ObjectAllocator() {
++            public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
++                return new PsychParser(runtime, klazz);
++            }
++        }, psych);
++
++        RubyKernel.require(runtime.getNil(),
++                runtime.newString("psych/syntax_error"), Block.NULL_BLOCK);
++        psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
++        psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal()));
++        psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal()));
++        psychParser.defineConstant("UTF16BE", runtime.newFixnum(YAML_UTF16BE_ENCODING.ordinal()));
++
++        psychParser.defineAnnotatedMethods(PsychParser.class);
++    }
++
++    public PsychParser(Ruby runtime, RubyClass klass) {
++        super(runtime, klass);
++    }
++
++    @JRubyMethod
++    public IRubyObject parse(ThreadContext context, IRubyObject yaml) {
++        Ruby runtime = context.runtime;
++
++        return parse(context, yaml, runtime.getNil());
++    }
++
++    private IRubyObject stringOrNilFor(Ruby runtime, String value, boolean tainted) {
++        if (value == null) return runtime.getNil(); // No need to taint nil
++
++        return stringFor(runtime, value, tainted);
++    }
++    
++    private RubyString stringFor(Ruby runtime, String value, boolean tainted) {
++        Encoding encoding = runtime.getDefaultInternalEncoding();
++        if (encoding == null) {
++            encoding = UTF8Encoding.INSTANCE;
++        }
++
++        Charset charset = RubyEncoding.UTF8;
++        if (encoding.getCharset() != null) {
++            charset = encoding.getCharset();
++        }
++
++        ByteList bytes = new ByteList(value.getBytes(charset), encoding);
++        RubyString string = RubyString.newString(runtime, bytes);
++        
++        string.setTaint(tainted);
++        
++        return string;
++    }
++    
++    private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
++        Ruby runtime = context.runtime;
++
++        if (yaml instanceof RubyString) {
++            ByteList byteList = ((RubyString)yaml).getByteList();
++            Encoding enc = byteList.getEncoding();
++
++            // if not unicode, transcode to UTF8
++            if (!(enc instanceof UnicodeEncoding)) {
++                byteList = EncodingUtils.strConvEnc(context, byteList, enc, UTF8Encoding.INSTANCE);
++                enc = UTF8Encoding.INSTANCE;
++            }
++
++            ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
++
++            Charset charset = enc.getCharset();
++
++            assert charset != null : "charset for encoding " + enc + " should not be null";
++
++            InputStreamReader isr = new InputStreamReader(bais, charset);
++
++            return new StreamReader(isr);
++        }
++
++        // fall back on IOInputStream, using default charset
++        if (yaml.respondsTo("read")) {
++            Encoding enc = (yaml instanceof RubyIO)
++                ? ((RubyIO)yaml).getReadEncoding()
++                : UTF8Encoding.INSTANCE;
++            Charset charset = enc.getCharset();
++            return new StreamReader(new InputStreamReader(new IOInputStream(yaml), charset));
++        } else {
++            throw runtime.newTypeError(yaml, runtime.getIO());
++        }
++    }
++
++    @JRubyMethod
++    public IRubyObject parse(ThreadContext context, IRubyObject yaml, IRubyObject path) {
++        Ruby runtime = context.runtime;
++        boolean tainted = yaml.isTaint() || yaml instanceof RubyIO;
++
++        try {
++            parser = new ParserImpl(readerFor(context, yaml));
++
++            if (path.isNil() && yaml.respondsTo("path")) {
++                path = yaml.callMethod(context, "path");
++            }
++
++            IRubyObject handler = getInstanceVariable("@handler");
++
++            while (true) {
++                event = parser.getEvent();
++
++                // FIXME: Event should expose a getID, so it can be switched
++                if (event.is(ID.StreamStart)) {
++                    invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
++                } else if (event.is(ID.DocumentStart)) {
++                    handleDocumentStart(context, (DocumentStartEvent) event, tainted, handler);
++                } else if (event.is(ID.DocumentEnd)) {
++                    IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).getExplicit());
++                    
++                    invoke(context, handler, "end_document", notExplicit);
++                } else if (event.is(ID.Alias)) {
++                    IRubyObject alias = stringOrNilFor(runtime, ((AliasEvent)event).getAnchor(), tainted);
++
++                    invoke(context, handler, "alias", alias);
++                } else if (event.is(ID.Scalar)) {
++                    handleScalar(context, (ScalarEvent) event, tainted, handler);
++                } else if (event.is(ID.SequenceStart)) {
++                    handleSequenceStart(context,(SequenceStartEvent) event, tainted, handler);
++                } else if (event.is(ID.SequenceEnd)) {
++                    invoke(context, handler, "end_sequence");
++                } else if (event.is(ID.MappingStart)) {
++                    handleMappingStart(context, (MappingStartEvent) event, tainted, handler);
++                } else if (event.is(ID.MappingEnd)) {
++                    invoke(context, handler, "end_mapping");
++                } else if (event.is(ID.StreamEnd)) {
++                    invoke(context, handler, "end_stream");
++                    
++                    break;
++                }
++            }
++        } catch (ParserException pe) {
++            parser = null;
++            raiseParserException(context, yaml, pe, path);
++
++        } catch (ScannerException se) {
++            parser = null;
++            StringBuilder message = new StringBuilder("syntax error");
++            if (se.getProblemMark() != null) {
++                message.append(se.getProblemMark().toString());
++            }
++            raiseParserException(context, yaml, se, path);
++
++        } catch (ReaderException re) {
++            parser = null;
++            raiseParserException(context, yaml, re, path);
++
++        } catch (Throwable t) {
++            Helpers.throwException(t);
++            return this;
++        }
++
++        return this;
++    }
++    
++    private void handleDocumentStart(ThreadContext context, DocumentStartEvent dse, boolean tainted, IRubyObject handler) {
++        Ruby runtime = context.runtime;
++        DumperOptions.Version _version = dse.getVersion();
++        IRubyObject version = _version == null ?
++            RubyArray.newArray(runtime) :
++            RubyArray.newArray(runtime, runtime.newFixnum(_version.major()), runtime.newFixnum(_version.minor()));
++        
++        Map<String, String> tagsMap = dse.getTags();
++        RubyArray tags = RubyArray.newArray(runtime);
++        if (tagsMap != null && tagsMap.size() > 0) {
++            for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
++                IRubyObject key   = stringFor(runtime, tag.getKey(), tainted);
++                IRubyObject value = stringFor(runtime, tag.getValue(), tainted);
++
++                tags.append(RubyArray.newArray(runtime, key, value));
++            }
++        }
++        IRubyObject notExplicit = runtime.newBoolean(!dse.getExplicit());
++
++        invoke(context, handler, "start_document", version, tags, notExplicit);
++    }
++    
++    private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) {
++        Ruby runtime = context.runtime;
++        IRubyObject anchor = stringOrNilFor(runtime, mse.getAnchor(), tainted);
++        IRubyObject tag = stringOrNilFor(runtime, mse.getTag(), tainted);
++        IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
++        IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
++
++        invoke(context, handler, "start_mapping", anchor, tag, implicit, style);
++    }
++        
++    private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) {
++        Ruby runtime = context.runtime;
++        IRubyObject anchor = stringOrNilFor(runtime, se.getAnchor(), tainted);
++        IRubyObject tag = stringOrNilFor(runtime, se.getTag(), tainted);
++        IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
++        IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
++        IRubyObject style = runtime.newFixnum(translateStyle(se.getStyle()));
++        IRubyObject val = stringFor(runtime, se.getValue(), tainted);
++
++        invoke(context, handler, "scalar", val, anchor, tag, plain_implicit,
++                quoted_implicit, style);
++    }
++    
++    private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) {
++        Ruby runtime = context.runtime;
++        IRubyObject anchor = stringOrNilFor(runtime, sse.getAnchor(), tainted);
++        IRubyObject tag = stringOrNilFor(runtime, sse.getTag(), tainted);
++        IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
++        IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
++
++        invoke(context, handler, "start_sequence", anchor, tag, implicit, style);
++    }
++
++    private static void raiseParserException(ThreadContext context, IRubyObject yaml, ReaderException re, IRubyObject rbPath) {
++        Ruby runtime;
++        RubyClass se;
++        IRubyObject exception;
++
++        runtime = context.runtime;
++        se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
++
++        exception = se.newInstance(context,
++                new IRubyObject[] {
++                    rbPath,
++                    runtime.newFixnum(0),
++                    runtime.newFixnum(0),
++                    runtime.newFixnum(re.getPosition()),
++                    (null == re.getName() ? runtime.getNil() : runtime.newString(re.getName())),
++                    (null == re.toString() ? runtime.getNil() : runtime.newString(re.toString()))
++                },
++                Block.NULL_BLOCK);
++
++        RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
++    }
++
++    private static void raiseParserException(ThreadContext context, IRubyObject yaml, MarkedYAMLException mye, IRubyObject rbPath) {
++        Ruby runtime;
++        Mark mark;
++        RubyClass se;
++        IRubyObject exception;
++
++        runtime = context.runtime;
++        se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
++
++        mark = mye.getProblemMark();
++
++        exception = se.newInstance(context,
++                new IRubyObject[] {
++                    rbPath,
++                    runtime.newFixnum(mark.getLine() + 1),
++                    runtime.newFixnum(mark.getColumn() + 1),
++                    runtime.newFixnum(mark.getIndex()),
++                    (null == mye.getProblem() ? runtime.getNil() : runtime.newString(mye.getProblem())),
++                    (null == mye.getContext() ? runtime.getNil() : runtime.newString(mye.getContext()))
++                },
++                Block.NULL_BLOCK);
++
++        RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
++    }
++
++    private static int translateStyle(Character style) {
++        if (style == null) return 0; // any
++
++        switch (style) {
++            case 0: return 1; // plain
++            case '\'': return 2; // single-quoted
++            case '"': return 3; // double-quoted
++            case '|': return 4; // literal
++            case '>': return 5; // folded
++            default: return 0; // any
++        }
++    }
++    
++    private static int translateFlowStyle(Boolean flowStyle) {
++        if (flowStyle == null) return 0; // any
++
++        if (flowStyle) return 2;
++        return 1;
++    }
++
++    @JRubyMethod
++    public IRubyObject mark(ThreadContext context) {
++        Ruby runtime = context.runtime;
++
++        Event event = null;
++
++        if (parser != null) {
++            event = parser.peekEvent();
++
++            if (event == null) event = this.event;
++        }
++
++        if (event == null) {
++            return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
++                    context,
++                    runtime.newFixnum(0),
++                    runtime.newFixnum(0),
++                    runtime.newFixnum(0),
++                    Block.NULL_BLOCK
++            );
++        }
++
++        Mark mark = event.getStartMark();
++
++        return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
++                context,
++                runtime.newFixnum(mark.getIndex()),
++                runtime.newFixnum(mark.getLine()),
++                runtime.newFixnum(mark.getColumn()),
++                Block.NULL_BLOCK
++        );
++    }
++
++    private Parser parser;
++    private Event event;
++}
+--- /dev/null
++++ jruby-9.1.6.0/ext/java/PsychToRuby.java
+@@ -0,0 +1,79 @@
++/***** BEGIN LICENSE BLOCK *****
++ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Eclipse Public
++ * License Version 1.0 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.eclipse.org/legal/epl-v10.html
++ *
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ *
++ * Copyright (C) 2010 Charles O Nutter <headius at headius.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of the GNU General Public License Version 2 or later (the "GPL"),
++ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the EPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the EPL, the GPL or the LGPL.
++ ***** END LICENSE BLOCK *****/
++package org.jruby.ext.psych;
++
++import org.jruby.Ruby;
++import org.jruby.RubyClass;
++import org.jruby.RubyModule;
++import org.jruby.RubyObject;
++import org.jruby.RubyException;
++import org.jruby.anno.JRubyMethod;
++import org.jruby.exceptions.RaiseException;
++import org.jruby.runtime.ThreadContext;
++import org.jruby.runtime.builtin.IRubyObject;
++import static org.jruby.runtime.Visibility.*;
++
++public class PsychToRuby {
++    public static void initPsychToRuby(Ruby runtime, RubyModule psych) {
++        RubyClass classLoader = runtime.defineClassUnder("ClassLoader", runtime.getObject(), RubyObject.OBJECT_ALLOCATOR, psych);
++
++        RubyModule visitors = runtime.defineModuleUnder("Visitors", psych);
++        RubyClass visitor = runtime.defineClassUnder("Visitor", runtime.getObject(), runtime.getObject().getAllocator(), visitors);
++        RubyClass psychToRuby = runtime.defineClassUnder("ToRuby", visitor, RubyObject.OBJECT_ALLOCATOR, visitors);
++
++        psychToRuby.defineAnnotatedMethods(ToRuby.class);
++        classLoader.defineAnnotatedMethods(ClassLoader.class);
++    }
++
++    public static class ToRuby {
++        @JRubyMethod(visibility = PRIVATE)
++        public static IRubyObject build_exception(ThreadContext context, IRubyObject self, IRubyObject klass, IRubyObject message) {
++            if (klass instanceof RubyClass) {
++                IRubyObject exception = ((RubyClass)klass).allocate();
++                ((RubyException)exception).setMessage(message);
++                return exception;
++            } else {
++                throw context.runtime.newTypeError(klass, context.runtime.getClassClass());
++            }
++        }
++    }
++
++    public static class ClassLoader {
++        @JRubyMethod(visibility = PRIVATE)
++        public static IRubyObject path2class(ThreadContext context, IRubyObject self, IRubyObject path) {
++            try {
++                return context.runtime.getClassFromPath(path.asJavaString());
++            } catch (RaiseException re) {
++                if (re.getException().getMetaClass() == context.runtime.getNameError()) {
++                    throw context.runtime.newArgumentError("undefined class/module " + path);
++                }
++                throw re;
++            }
++        }
++    }
++}
+--- /dev/null
++++ jruby-9.1.6.0/ext/java/PsychYamlTree.java
+@@ -0,0 +1,55 @@
++/***** BEGIN LICENSE BLOCK *****
++ * Version: EPL 1.0/GPL 2.0/LGPL 2.1
++ *
++ * The contents of this file are subject to the Eclipse Public
++ * License Version 1.0 (the "License"); you may not use this file
++ * except in compliance with the License. You may obtain a copy of
++ * the License at http://www.eclipse.org/legal/epl-v10.html
++ *
++ * Software distributed under the License is distributed on an "AS
++ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
++ * implied. See the License for the specific language governing
++ * rights and limitations under the License.
++ *
++ * Copyright (C) 2010 Charles O Nutter <headius at headius.com>
++ *
++ * Alternatively, the contents of this file may be used under the terms of
++ * either of the GNU General Public License Version 2 or later (the "GPL"),
++ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
++ * in which case the provisions of the GPL or the LGPL are applicable instead
++ * of those above. If you wish to allow use of your version of this file only
++ * under the terms of either the GPL or the LGPL, and not to allow others to
++ * use your version of this file under the terms of the EPL, indicate your
++ * decision by deleting the provisions above and replace them with the notice
++ * and other provisions required by the GPL or the LGPL. If you do not delete
++ * the provisions above, a recipient may use your version of this file under
++ * the terms of any one of the EPL, the GPL or the LGPL.
++ ***** END LICENSE BLOCK *****/
++package org.jruby.ext.psych;
++
++import org.jruby.Ruby;
++import org.jruby.RubyClass;
++import org.jruby.RubyModule;
++import org.jruby.RubyObject;
++import org.jruby.anno.JRubyMethod;
++import org.jruby.runtime.ThreadContext;
++import org.jruby.runtime.builtin.IRubyObject;
++import static org.jruby.runtime.Visibility.*;
++
++public class PsychYamlTree {
++    public static void initPsychYamlTree(Ruby runtime, RubyModule psych) {
++        RubyModule visitors = (RubyModule)psych.getConstant("Visitors");
++        RubyClass visitor = (RubyClass)visitors.getConstant("Visitor");
++        RubyClass psychYamlTree = runtime.defineClassUnder("YAMLTree", visitor, RubyObject.OBJECT_ALLOCATOR, visitors);
++
++        psychYamlTree.defineAnnotatedMethods(PsychYamlTree.class);
++    }
++
++    @JRubyMethod(visibility = PRIVATE)
++    public static IRubyObject private_iv_get(ThreadContext context, IRubyObject self, IRubyObject target, IRubyObject prop) {
++        IRubyObject obj = (IRubyObject)target.getInternalVariables().getInternalVariable(prop.asJavaString());
++        if (obj == null) obj = context.nil;
++
++        return obj;
++    }
++}
diff --git a/debian/patches/series b/debian/patches/series
index 6e302c4..8df7404 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -6,3 +6,4 @@
 0006-Disable-maven-jruby-jars-artifact.patch
 0007-Add-usr-lib-ruby-vendor-ruby-to-load-path.patch
 0008-Configure-unit-tests-to-run-at-build-time.patch
+0009-Bundle-psych-java-extension.patch
diff --git a/debian/psych-java-ext-build-classpath b/debian/psych-java-ext-build-classpath
new file mode 100755
index 0000000..7a4d841
--- /dev/null
+++ b/debian/psych-java-ext-build-classpath
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -e
+
+JAVA_HOME="/usr/lib/jvm/java-8-openjdk-`dpkg-architecture --query DEB_HOST_ARCH`"
+
+for JAR in resources.jar rt.jar sunrsasign.jar jsse.jar jce.jar charsets.jar jfr.jar; do
+    echo -n "${JAVA_HOME}/jre/lib/${JAR}:"
+done
+
+echo -n "${JAVA_HOME}/jre/classes:"
+echo -n "${PWD}/lib/jruby.jar:"
+echo -n /usr/share/maven-repo/org/yaml/snakeyaml/1.x/snakeyaml-1.x.jar
diff --git a/debian/psych-java-ext-class-entries b/debian/psych-java-ext-class-entries
new file mode 100755
index 0000000..1bf699f
--- /dev/null
+++ b/debian/psych-java-ext-class-entries
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -e
+
+for ENTRY in                   \
+    PsychEmitter\$1            \
+    PsychEmitter               \
+    PsychLibrary\$1            \
+    PsychLibrary\$YAMLEncoding \
+    PsychLibrary               \
+    PsychParser\$1             \
+    PsychParser                \
+    PsychToRuby\$ClassLoader   \
+    PsychToRuby\$ToRuby        \
+    PsychToRuby                \
+    PsychYamlTree              \
+; do
+    echo -n "-C tmp/java/psych org/jruby/ext/psych/${ENTRY}.class "
+done
diff --git a/debian/psych-java-ext-source-files b/debian/psych-java-ext-source-files
new file mode 100755
index 0000000..2e9cb61
--- /dev/null
+++ b/debian/psych-java-ext-source-files
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+for FILE in PsychEmitter.java PsychLibrary.java PsychParser.java PsychToRuby.java PsychYamlTree.java; do
+    echo -n "ext/java/${FILE} "
+done
diff --git a/debian/rules b/debian/rules
index a59de2d..d4f8dee 100755
--- a/debian/rules
+++ b/debian/rules
@@ -18,6 +18,7 @@ override_dh_auto_clean:
 	-cd ./lib/ruby/stdlib/ && rm -r psych* *openssl* org/ jar* ./rubygems_plugin.rb
 	-rm ./core/dependency-reduced-pom.xml ./link* test/jruby/testapp/testapp
 	-find . -name pom.xml.save -delete
+	-rm -r ./tmp/
 	mh_clean
 
 override_dh_auto_configure:
@@ -32,6 +33,13 @@ override_dh_auto_build:
 	dh_auto_build -- -Pcomplete
 	dh_auto_build -- -Pdist package
 	dh_auto_build -- -Pall
+	# bundle ruby/psych jar with jruby until jruby-psych is packaged
+	mkdir -p tmp/java/psych
+	javac -extdirs "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext"   \
+		-target 1.7 -source 1.7 -Xlint:unchecked                 \
+		-cp "`./debian/psych-java-ext-build-classpath`"          \
+		-d tmp/java/psych `./debian/psych-java-ext-source-files`
+	jar cf tmp/java/psych/psych.jar `./debian/psych-java-ext-class-entries`
 
 DIST_TARBALL=./maven/jruby-dist/target/jruby-dist-$(DEB_VERSION_UPSTREAM)-bin.tar.gz
 DIST_TARGET_DIR=./target/package/
@@ -46,6 +54,7 @@ override_dh_prep:
 		&& mkdir -p ./lib/jni/                                                 \
 		&& find ./lib/ruby/truffle -name LICENSE -delete                       \
 	        && cp -a /usr/lib/ruby/2.3.0/psych* ./lib/ruby/stdlib/                 \
+	        && cp -a ../../tmp/java/psych/psych.jar ./lib/ruby/stdlib/             \
 	        && sed 's/1\.[0-9]\{1,2\}/1.x/' -i ./lib/ruby/stdlib/psych/versions.rb \
 		&& sed '1d' -i ./lib/ruby/truffle/jruby+truffle/bin/jruby+truffle      \
 		&& rm -r ./tool/nailgun/*                                              )

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jruby.git



More information about the pkg-java-commits mailing list