pegdown icon indicating copy to clipboard operation
pegdown copied to clipboard

java.lang.ExceptionInInitializerError -> Is this support for Android ?

Open TakWolf opened this issue 8 years ago • 6 comments

I do not find an information about Android, do it support ?

When I use pegdown on android, it got a exception :

 private static final PegDownProcessor md = new PegDownProcessor();
 FATAL EXCEPTION: main
Process: org.cnodejs.android.md, PID: 502
java.lang.ExceptionInInitializerError
    at org.cnodejs.android.md.display.activity.MainActivity.updateMessageCountViews(MainActivity.java:486)
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:119)
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:114)
    at org.cnodejs.android.md.model.api.CallbackAdapter.onResponse(CallbackAdapter.java:15)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5343)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
 Caused by: java.lang.RuntimeException: Error creating extended parser class: Class not found
    at org.parboiled.Parboiled.createParser(Parboiled.java:58)
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:94)
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:73)
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:54)
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:47)
    at org.cnodejs.android.md.util.FormatUtils.<clinit>(FormatUtils.java:125)
    at org.cnodejs.android.md.display.activity.MainActivity.updateMessageCountViews(MainActivity.java:486) 
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:119) 
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:114) 
    at org.cnodejs.android.md.model.api.CallbackAdapter.onResponse(CallbackAdapter.java:15) 
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5343) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 
 Caused by: java.io.IOException: Class not found
    at org.objectweb.asm.ClassReader.a(Unknown Source)
    at org.objectweb.asm.ClassReader.<init>(Unknown Source)
    at org.parboiled.transform.AsmUtils.createClassReader(AsmUtils.java:56)
    at org.parboiled.transform.ClassNodeInitializer.process(ClassNodeInitializer.java:62)
    at org.parboiled.transform.ParserTransformer.extendParserClass(ParserTransformer.java:44)
    at org.parboiled.transform.ParserTransformer.transformParser(ParserTransformer.java:38)
    at org.parboiled.Parboiled.createParser(Parboiled.java:54)
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:94) 
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:73) 
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:54) 
    at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:47) 
    at org.cnodejs.android.md.util.FormatUtils.<clinit>(FormatUtils.java:125) 
    at org.cnodejs.android.md.display.activity.MainActivity.updateMessageCountViews(MainActivity.java:486) 
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:119) 
    at org.cnodejs.android.md.presenter.implement.MainPresenter$4.onResultOk(MainPresenter.java:114) 
    at org.cnodejs.android.md.model.api.CallbackAdapter.onResponse(CallbackAdapter.java:15) 
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5343) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700) 

It seem that the problem is org.objectweb.asm

TakWolf avatar May 26 '16 16:05 TakWolf

I had the same problem: final PegDownProcessor processor = new PegDownProcessor();

AndroidRuntime: FATAL EXCEPTION: 
...
java.lang.RuntimeException: Error creating extended parser class: Class not found
      at org.parboiled.Parboiled.createParser(Parboiled.java:58)
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:94)
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:73)
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:54)
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:47)
      at ...
   Caused by: java.io.IOException: Class not found
      at org.objectweb.asm.ClassReader.a(Unknown Source)
      at org.objectweb.asm.ClassReader.<init>(Unknown Source)
      at org.parboiled.transform.AsmUtils.createClassReader(AsmUtils.java:56)
      at org.parboiled.transform.ClassNodeInitializer.process(ClassNodeInitializer.java:62)
      at org.parboiled.transform.ParserTransformer.extendParserClass(ParserTransformer.java:44)
      at org.parboiled.transform.ParserTransformer.transformParser(ParserTransformer.java:38)
      at org.parboiled.Parboiled.createParser(Parboiled.java:54)
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:94) 
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:73) 
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:54) 
      at org.pegdown.PegDownProcessor.<init>(PegDownProcessor.java:47) 
      at...

yhonet avatar Jul 28 '16 10:07 yhonet

I too have the same problem

SreenuAndroid avatar Aug 10 '16 13:08 SreenuAndroid

same to me thanks~~

LeadroyaL avatar Nov 21 '16 13:11 LeadroyaL

Seems that ASM can't transform classes on Android because they have different format. PegDownProcessor has another constructor that accepts Parser, we should try creating parser ourselves without ASM. I've tried reproducing conditions that had originally been achieved by using ASM:

/* Kotlin */
val parser =
        Parser(
                Extensions.NONE,
                PegDownProcessor.DEFAULT_MAX_PARSING_TIME,
                Parser.DefaultParseRunnerProvider,
                PegDownPlugins.NONE)
val matcher = SequenceMatcher(Array<Rule?>(0, { null /* original object has an instance of dynamically generated class here */ }))
parser.context = MatcherContext(
        DefaultInputBuffer(chars),
        DefaultValueStack<Any>(),
        ArrayList<ParseError>(),
        BasicParseRunner<Any>(matcher),
        matcher,
        true)
return PegDownProcessor(parser)

But now I'm getting org.parboiled.errors.GrammarException: Illegal call to getMatch(), getMatchStartIndex(), getMatchEndIndex() or getMatchRange(), only valid in Sequence rule actions that are not in first position.

Miha-x64 avatar Dec 04 '16 12:12 Miha-x64

To enable Android support someone's going to have to look at adding a configuration to use ASMDEX instead of ASM: http://asm.ow2.org/doc/tutorial-asmdex.html

fiskurgit avatar Dec 12 '16 12:12 fiskurgit

If you need android support it is probably easier to switch to another parser rather than trying to wrestle with pegdown.

commonmark-java is an excellent choice if you don't need source element based AST (it generates output based AST), don't need a lot of extensions and can work with CommonMark markdown format https://github.com/atlassian/commonmark-java, Java 1.7 and android compatible.

I rewrote commonmark-java to replace pegdown in my Markdown Navigator plugin for IntelliJ IDEs: https://github.com/vsch/idea-multimarkdown. The parser project is https://github.com/vsch/flexmark-java. It has very detailed source based AST with source offset for every part of the element. I need that for syntax highlighting and other plugin source reliant features.

It is CommonMark 0.27 (GitHub Comments) compliant but has parser configuration options to emulate list indentation rules used by: markdown.pl, MultiMarkdown (like pegdown 4 space indents) and kramdown (GitHub Docs). The only extensions that pegdown has that I did not yet implement are: typographic quotes, smarts and definition lists. The rest of the extensions are available, with some extra ones that pegdown does not have.

As an added bonus and what motivated me to switch the parsing is 30-50x faster than pegdown on average documents and several thousand times faster on pegdown's pathological input like [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[.

Right now it is Java language level 1.8 because I used lambda syntax but if you are interested in having it support android I can refactor all the 1.8 constructs to downgrade it to 1.7 for android compatibility or just convert it to Kotlin then can have even better syntax and Java 1.6 compatibility.

vsch avatar Dec 13 '16 00:12 vsch