Skip to content

Ways to mitigate overall jankyness (intermittent NoClassDefFoundError and IllegalMonitorStateException)  #132

@DrChainsaw

Description

@DrChainsaw

Sorry for vague issue, I'm just hoping there is some best practice or common pitfall to avoid this.

Symptoms are basically that attempts to interop randomly just fails, from what I can tell with either of the two exceptions in the subject line with no discernable pattern as to which operation is causing it (e.g the NoClass exception is for different classes each time).

Sometimes just re-running the command works (even for NoClass) and sometimes a Repl restart is required. In maybe 80% of the cases the operation just works as expected, but sometimes fails if called again with different input (e.g try the same operation on a different file). Searching for "julia javacall IllegalMonitorStateException" lead me to this issue which has quite similar symptoms (although it is not fully clear if they are intermittent)

julia> versioninfo()
Julia Version 1.5.1
Commit 697e782ab8 (2020-08-25 20:08 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)

For obvious reasons its hard to produce an MWE but the basic structure of the program is something like this (with maybe 10-20 classes involved):

module MyModule
using JavaCall
const JSomeClass = @jimport some.pkg.SomeClass
const JSomeOtherCalss = @jimport another.pkg.SomeOtherClass

function init()
   cp = "all;the;libs.jar"
   JavaCall.init("-Djava.class.path=$cp")
end

function doThis(args...)
     obj = JSomeClass()
     return jcall(obj, "someMethod", ....)
end

function doThat(args...)
     obj = JSomeOtherClass()
     return jcall(obj, "someOtherMethod", ....)
end

function doMore(o1, o2, ...)
     x = jcall(o1, "...", ..., o2)
     #more jcalls with o1, o2, x ect
end

function doMost(args...)
    o1 = doThis(a...)
    o2 = doThat(b...)
   doMore(o1, o2, c...)
end

end

It seems like errors are less common if functions are called directly in repl compared to if they are called through other functions. For instance, calling doThis and doThat in repl and then feed the outputs to doMore seems more likely to work than calling doMost.

Are there any "canonical packages" which use JavaCall I can look at and try to copy patterns from? I have started to look at Spark.jl, but maybe there are simpler examples.

I think I have ensured that everything runs from the main task/thread but I'm not sure if there is anything more to it than just checking that Threads.threadid() == 1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions