asciidoctor / asciidoctorj

:coffee: Java bindings for Asciidoctor. Asciidoctor on the JVM!
http://asciidoctor.org
Apache License 2.0
622 stars 173 forks source link

automatically resolved gems in OSGi bundles need .jrubydir files #357

Open ginseil opened 9 years ago

ginseil commented 9 years ago

Hi,

I was playing around with asciiidoctorj in an OSGi environment within the Eclipse BNDTools toolcahin.

Because asciidoctor itself is not an OSGi bundle I unroled it's contents into one unsing BNDTools. Each time I tried to create an Asciidoctor instance I got some class / module loading exceptions.

Yes it is possible to manually reference the required gems but wouldn't it be nice if they were automatically resolved? See pros & cons in your README.

I took a look into the jruby.jar and found a loot of ".jrubydir" files pointing to files located next to them (embedded gems need directory file .jrubydir). So I just tried to manually add those files into my unrolled asciidoctor bundle and it worked like a charm.

The only code needed is:

    OSGiScriptingContainer container = new OSGiScriptingContainer(context.getBundle());
    Asciidoctor asciidoctor = Factory.create(container.getOSGiBundleClassLoader());
    System.out.println(asciidoctor.asciidoctorVersion()); // --> prints 1.5.2

The unrolled contents in my asciidoctor bundle:

image

lefou commented 9 years ago

Might be related to #297

mojavelinux commented 9 years ago

@lefou indeed. @ginseil could you try a SNAPSHOT (you need to build it yourself). We know at least have some OSGi information in the AsciidoctorJ jar. We are trying to determine what is still missing so we can fill in the voids.

lefou commented 9 years ago

@ginseil In master, asciidoctor is a bundle nowadays, but we are still in the process of figuring out, what is required to provide a fully functional Asciidoctor service via the OSGi service registry. Your setup might help with this.

I don't use Eclipse BNDTools myself, so it's a bit hard to understand, what's behind your screenshots. Could you please post the content of your bnd.bnd and also the .jrubydir files?

ginseil commented 9 years ago

@mojavelinux I tried to build the SNAPSHOT on my own. The result is I did not work with jruby 1.7.20. I always got the following exception, even if I explicitly point to the asciidoctor gem:

org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- asciidoctor
    at org.jruby.RubyKernel.require(org/jruby/RubyKernel.java:1040)
    at RUBY.require(classpath:/META-INF/jruby.home/lib/ruby/shared/rubygems/core_ext/kernel_require.rb:54)
    at RUBY.(root)(<script>:9)

Therefore I switched to jruby 9.0.0.0RC2:

.
gems
specifications
..
.
asciidoctor-1.5.2.gemspec
coderay-1.1.0.gemspec
erubis-2.7.0.gemspec
haml-4.0.5.gemspec
open-uri-cached-0.0.5.gemspec
slim-2.0.3.gemspec
temple-0.6.10.gemspec
thread_safe-0.3.4-java.gemspec
tilt-2.0.1.gemspec

The last thing to do is to ensure these files are included in the target jar:

def gemFiles = fileTree(jruby.gemInstallDir) {
  include 'specifications/*.gemspec'
  include 'specifications/.jrubydir'
  include '.jrubydir'
  include 'gems/*/lib/**'
  include "gems/asciidoctor-${asciidoctorGemVersion}/data/**"
}

Keep in mind that the passed bundle when creating the OSGiScriptingContainer container = new OSGiScriptingContainer(bundle); must be the asciidoctor bundle.

mojavelinux commented 9 years ago

Therefore I switched to jruby 9.0.0.0RC2:

This is the direction we're headed. It just has far less bugs.

ginseil commented 9 years ago

@lefou The contents of the related files of first post:

bnd.bnd:

Bundle-Version: 0.0.0.${tstamp}
-buildpath:  \
    asciidoctorj-1.5.2.jar;version=file,\
    osgi.core;version=6.0,\
    osgi.cmpn;version=5.0,\
    com.beust.jcommander;version=1.48,\
    slf4j.api;version=1.7.12,\
    slf4j.simple;version=1.7.12,\
    org.jruby.jruby;version=9.0
Private-Package:  \
    de.stoehr.asciidoctorj.sample
-runfw: org.eclipse.osgi;version='[3.10.1.v20140909-1633,3.10.1.v20140909-1633]'
-runee: JavaSE-1.8
-runrequires:  \
    osgi.identity;filter:='(&(osgi.identity=de.stoehr.asciidoctorj.sample)(version>=0.0.0.201507130550))',\
    osgi.identity;filter:='(&(osgi.identity=org.eclipse.equinox.ds)(version>=1.4.200.v20131126-2331))',\
    osgi.identity;filter:='(&(osgi.identity=slf4j.api)(version>=1.7.12))',\
    osgi.identity;filter:='(&(osgi.identity=slf4j.simple)(version>=1.7.12))'
-dsannotations:  \
    *
Include-Resource: @asciidoctorj-1.5.2.jar, \
    .jrubydir=jrubydir_tpl,\
    specifications/.jrubydir=jrubydir_tpl2,\
    {test.adoc}
-resolve: auto
-runsystempackages: sun.misc
-runbundles:  \
    com.beust.jcommander;version='[1.48.0,1.48.1)',\
    de.stoehr.asciidoctorj.sample;version=latest,\
    org.apache.felix.configadmin;version='[1.8.0,1.8.1)',\
    org.eclipse.equinox.ds;version='[1.4.200,1.4.201)',\
    org.eclipse.equinox.util;version='[1.0.500,1.0.501)',\
    org.jruby.jruby;version='[9.0.0,9.0.1)',\
    osgi.cmpn;version='[5.0.0,5.0.1)',\
    slf4j.api;version='[1.7.12,1.7.13)',\
    slf4j.simple;version='[1.7.12,1.7.13)'

The most relevant lines are Include-Resource and following.

The contents of the .jrubydir files are the same as in previous post.

lefou commented 9 years ago

Great! I was able to reproduce that setup. At least when using JRuby 9 I get the version number output. I will report further findings in #297.

@ginseil Thanks for sharing!

ginseil commented 9 years ago

I'm glad I could help. If there still are any questions, let me know.

mojavelinux commented 9 years ago

Great work clan!