Error compiling package using JavaCall

I’m trying to build a package that is dependent on the JavaCall package. The JavaCall package has some known issues with Mac which can be avoided by setting the environment variable ‘JULIA_COPY_STACKS=yes’ and starting Julia using the command-line flag ‘julia --handle-signals=no’.

After doing so, on a Mac I can start the JVM from within Julia without error using ‘JavaCall.init()’. The problem is, if ‘JavaCall.init()’ is called in my package, I get a segmentation fault upon loading the package via ‘using MyPackageWithJavaCall’. I’m wondering if when compiling the package Julia is unaware of the ‘–handle-signals=no’ or if one can force the package to be compiled with this flag.

Below is a minimal working example of a package that produces this segmentation fault and the particular error stack I get. Any help on this would be greatly appreciated!!

Simple Package

module JavaTest

# Dependencies
using JavaCall

# Check for required environment variable required for JavaCall
if ~haskey(ENV,"JULIA_COPY_STACKS")
    error("Environment variable 'JULIA_COPY_STACKS=yes' is required for JavaCall package but is not defined.")
else
    if ~(ENV["JULIA_COPY_STACKS"] == "yes")
        error("Environment variable 'JULIA_COPY_STACKS=yes' is required for JavaCall package but is not defined.")
    end
end

# Initialise Java Virtual Machine--SEGMENTATION FAULT HERE
JavaCall.init()

greet() = print("Hello World!")

end

And the error

using JavaTest
[ Info: Precompiling JavaTest [40cc168c-4df6-4a30-87ce-9a1cad52c5d0]

signal (11): Segmentation fault: 11
in expression starting at /Users/bvanderbeek/research/software/JuliaProjects/JavaTest/src/JavaTest.jl:16
unknown function (ip: 0x16090651b)
Allocations: 729607 (Pool: 729209; Big: 398); GC: 1
ERROR: Failed to precompile JavaTest [40cc168c-4df6-4a30-87ce-9a1cad52c5d0] to /Users/bvanderbeek/.julia/compiled/v1.8/JavaTest/jl_7kXmSn.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
   @ Base ./loading.jl:1705
 [3] compilecache
   @ ./loading.jl:1649 [inlined]
 [4] _require(pkg::Base.PkgId)
   @ Base ./loading.jl:1337
 [5] _require_prelocked(uuidkey::Base.PkgId)
   @ Base ./loading.jl:1200
 [6] macro expansion
   @ ./loading.jl:1180 [inlined]
 [7] macro expansion
   @ ./lock.jl:223 [inlined]
 [8] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:1144

You should call JavaCall.init() within your module’s __init__.

module JavaTest

# Dependencies
using JavaCall

function __init__()

# Check for required environment variable required for JavaCall
if ~haskey(ENV,"JULIA_COPY_STACKS")
    error("Environment variable 'JULIA_COPY_STACKS=yes' is required for JavaCall package but is not defined.")
else
    if ~(ENV["JULIA_COPY_STACKS"] == "yes")
        error("Environment variable 'JULIA_COPY_STACKS=yes' is required for JavaCall package but is not defined.")
    end
end

# Initialise Java Virtual Machine--SEGMENTATION FAULT HERE
JavaCall.init()

end

greet() = print("Hello World!")

end

@mkitti Well that was easy! Appreciate the quick help as I just started writing Julia packages.

Some basics… anything at the top level of the module will be executed once at “precompile” time. This will not change until you precompile the package by changing or touching it.

Anything involving external code or pointers, you probably want to do during __init__(). __init__() runs when you use using or import.