AsciidoctorJ error when using in a OSGi bundle

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

AsciidoctorJ error when using in a OSGi bundle

twasyl
Hi all,

I encountered a problem when I try to use AsciidoctorJ in a OSGi bundle (I use Apache Felix for the OSGi container). Indeed, I'm developing SlideshowFX (https://bitbucket.org/twasyl/slideshowfx/) which allows to integrate OSGi bundle that provides the support for a markup language to define slide's content. And I would like to have a OSGi bundle for supporting asciidoctor. I'm using:
- slf4j-api-1.7.7.jar
- slf4j-simple-1.7.7.jar
- jruby-complete-1.7.13.jar
- asciidoctorj-1.5.0.preview.7.jar

I have the following code to convert an asciidoctor String into an HTML one:

---
final Asciidoctor asciidoctor = Asciidoctor.Factory.create(ClassLoader.getSystemClassLoader());

return asciidoctor.render(markupString,new HashMap<String, Object>());
---

The conversion is fine when doing it in a unit test. But, when I call the same code (when it is packaged in the OSGi bundle) I get an exception:

---
Caused by: java.lang.NoClassDefFoundError: sun/misc/Unsafe
        at org.jruby.RubyEncoding.<clinit>(RubyEncoding.java:204)
        at org.jruby.RubyThread$Status.<init>(RubyThread.java:144)
        at org.jruby.RubyThread$Status.<clinit>(RubyThread.java:139)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at java.lang.Class.getEnumConstantsShared(Class.java:3209)
        at java.lang.System$2.getEnumConstantsShared(System.java:1246)
        at java.util.EnumMap.getKeyUniverse(EnumMap.java:752)
        at java.util.EnumMap.<init>(EnumMap.java:138)
        at org.jruby.Ruby.<init>(Ruby.java:4898)
        at org.jruby.Ruby.newInstance(Ruby.java:320)
        at org.jruby.embed.internal.SingletonLocalContextProvider.getRuntime(SingletonLocalContextProvider.java:95)
        at org.asciidoctor.internal.JRubyAsciidoctor.createJRubyAsciidoctorInstance(JRubyAsciidoctor.java:143)
        at org.asciidoctor.internal.JRubyAsciidoctor.create(JRubyAsciidoctor.java:84)
        at org.asciidoctor.Asciidoctor$Factory.create(Asciidoctor.java:687)
        at com.twasyl.slideshowfx.markup.asciidoctor.AsciidoctorMarkup.convertAsHtml(AsciidoctorMarkup.java:56)
        at com.twasyl.slideshowfx.controllers.SlideshowFXController.updateSlide(SlideshowFXController.java:282)
        at com.twasyl.slideshowfx.controllers.SlideshowFXController.updateSlideWithText(SlideshowFXController.java:264)
---

I tried to manually load the class this way, before creating the Asciidoctor object:
---
try {
  ClassLoader.getSystemClassLoader().loadClass("sun.misc.Unsafe");
} catch (ClassNotFoundException e) {
  LOGGER.log(Level.SEVERE, "Can not load classes required by the AsciidoctorMarkup", e);
}
---

No exception is thrown but it still doesn't work. I don't know where to look to find how to solve this problem.
I'm also using JDK 8.0_05.

Many thanks in advance
Reply | Threaded
Open this post in threaded view
|

Re: AsciidoctorJ error when using in a OSGi bundle

ch007m
Hi,

This issue is not related at all to Asciidoctor or jruby. As the class sun/misc/Unsafe is part of the JDK, it should be loaded by the Apache Felix (= OSGI container) classloader and available to the classloader of jruby bundle.
Can you add a breakpoint here (http://grepcode.com/file/repo1.maven.org/maven2/org.jruby/jruby-complete/1.7.12/org/jruby/util/unsafe/UnsafeHolder.java#47) and check if jruby is able to load the class please ?

Remark : As asciidoctor project does not generate the OSGI manifest file containing the packages list to be imported by the bundle classloader, you should take care about that

Regards,

Charles

Charles Moulliard
Apache Committer / Technologist Evangelist / Blogger / MiddleWare Specialist
Twitter : @cmoulliard
Reply | Threaded
Open this post in threaded view
|

Re: AsciidoctorJ error when using in a OSGi bundle

ch007m
If the problem is that Class.forName is not able to retrieve the sun.misc.Unsafe class, then raise a ticket to jruby project to ask them that they change the code to pass a classloader as explained here : http://njbartlett.name/2010/08/30/osgi-readiness-loading-classes.html and here http://wiki.osgi.org/wiki/Avoid_Classloader_Hacks
Charles Moulliard
Apache Committer / Technologist Evangelist / Blogger / MiddleWare Specialist
Twitter : @cmoulliard
Reply | Threaded
Open this post in threaded view
|

Re: AsciidoctorJ error when using in a OSGi bundle

twasyl
Hi all,

Sorry for my late response. I got something work but not completely. The problem was indeed a misconfiguration when creating my OSGi bundle. Now I get it work but I have another error:

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

Previously I had: Caused by: org.jruby.exceptions.RaiseException: (LoadError) no such file to load -- jruby/java

Which I solved using the following line:

this.asciidoctor = Asciidoctor.Factory.create(AsciidoctorMarkup.class.getClassLoader());

So what should I do in order to correct the error regarding the asciidoctor file?
Any help is appreciated.

Thanks a lot.