# Embedding Julia in the Java Virtual Machine

**URL:** <https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444>\
**Category:** Internals & Design\
**Tags:** embedding, java\
**Created:** [December 8, 2020, 7:11am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444 "2020-12-08T07:11:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [December 8, 2020, 7:11am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/1 "2020-12-08T07:11:18Z")

</div>

Is it easier to embed Julia into the Java Virtual Machine (JVM) or easier to embed the JVM into Julia?

**Embedding the JVM into Julia**

I’ve been working with @avik on JavaCall.jl for the better part of this year. To make JavaCall work, there have been several hoops to jump through, notably the `JULIA_COPY_STACKS` environmental variable that modifies Julia’s `Task` implementation. On Linux, I’ve found setting `JULIA_COPY_STACKS=1` works quite smoothly. However, this need is also inconsistent on the Windows operating system, which doesn’t appear to need `JULIA_COPY_STACKS=1` for single threaded operation. The main difficulty is the JVM’s dependence on using signal handling for basic operations. How Julia’s `Task`s interact with Java signal handling due to stack semantics creates an undesirable situation. The JVM is a bit challenging to embed, and Julia’s `Task` semantics make it even trickier.

**Embedding Julia into the JVM**

Embedding Julia in Java has been tried a number of times with varying success. For example, @jbytecode’s JuliaCaller connects Julia via TCP, which is great clean solution, but sharing memory becomes difficult:

> [@Calling Julia from within Java: JuliaCaller](https://discourse.julialang.org/t/calling-julia-from-within-java-juliacaller/48357):
>
> Hi folks, Due to the discussion in [Running Julia from Java - What is crazier?](https://discourse.julialang.org/t/running-julia-from-java-what-is-crazier/31662), I am introducing a new project for calling Julia from within Java. Despite it is in its early stages, the package implements basic external calling of Julia from Java and a skeleton of JSR 223 (Java scripting interface) implementation is ready for future development. The package simply starts an external Julia process, injects a script that listens TCP connections (multiple ones if needed) on a given port, accepts t…

@rssdev10’s Julia4J uses SWIG to build a Java Native Interface (JNI) integration with Julia which promises efficiency, but this requires a compiler on the user end for a specific JVM:

> **[GitHub - rssdev10/julia4j: Julia for Java binding](https://github.com/rssdev10/julia4j)**
>
> Julia for Java binding. Contribute to rssdev10/julia4j development by creating an account on GitHub.

@cnuernber recently has built [Java Native Access](https://github.com/java-native-access/jna) bindings from Clojure (a LISP dialect that runs on JVM) to Julia, meaning that libjulia can now be dynamically linked into the JVM. No compiler needed.  
[Using Julia from the JVM (Clojure)](https://discourse.julialang.org/t/using-julia-from-the-jvm-clojure/51052)

While there were some early hiccups, it turns out that Julia has enough options to allow it to play nice with others as we found in [Consistent crash attempting to embed Julia in Java via dynamically loading libjulia.so · Issue #36092 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/36092) . They key in this instance was turning off Julia’s signal handling:

```julia
jl_options.handle_signals = JL_OPTIONS_HANDLE_SIGNALS_OFF

```

Based upon libjulia-clj’s cross platform success based on Travis tests, this path is looking quite promising.

> **[GitHub - cnuernber/libjulia-clj: Julia bindings for Clojure -- Currently...](https://github.com/cnuernber/libjulia-clj)**
>
> Julia bindings for Clojure -- Currently somewhat unstable -- - GitHub - cnuernber/libjulia-clj: Julia bindings for Clojure -- Currently somewhat unstable --

Once linked together, Julia should then be able to leverage JavaCall to call back into the JVM. JavaCall, for example, has an alternate initialization routine in `JavaCall.JNI.init_current_vm`

> <https://github.com/JuliaInterop/JavaCall.jl/blob/4625a51e640745fce659d10f4265e84ea30b1374/src/JNI.jl#L160>

I don’t mean to disparage the prior methods. Each has it’s own advantages and disadvantages. Network based integration via TCP should be quite robust and scalable. Java Native Interface comes with a low overhead. The Java Native Access approach is user friendly middle ground.

Overall, the approach of embedding Julia into the Java Virtual Machine using Java Native Access looks quite promising. This bodes well for future cooperation between Julia, Java, and other JVM-based languages like Clojure, Scala, and Kotlin. Embedding Julia into the JVM appears to be the easier path forward.

---

<div class="post-metadata">

**Author:** ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)\
**Post date:** [December 8, 2020, 9:06am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/2 "2020-12-08T09:06:49Z")

</div>

great summary, thank you!

---

<div class="post-metadata">

**Author:** ![rssdev10](https://avatars.discourse-cdn.com/v4/letter/r/e9a140/32.png) [@rssdev10](https://discourse.julialang.org/u/rssdev10)\
**Post date:** [December 8, 2020, 12:00pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/3 "2020-12-08T12:00:36Z")

</div>

> [@mkitti](#):
>
> @rssdev10’s Julia4J uses SWIG to build a Java Native Interface (JNI) integration with Julia which promises efficiency, but this requires a compiler on the user end for a specific JVM:

Hi, actually, it doesn’t require a compiler on a user side. A dynamic library which is built with libjulia, swig generated code and at least some compatible JDK is requied. If there is a set of these OS specifics libraries embedded into a jar file, nothing except that jar is requred for a final user. But to be able to prepare it, we need to have a building agents for at least 3 operating systems (Linux, Win, Mac for AMD64) with some actual Julia, OpenJDK, Oracle JDK. So, I prepared recomendations how to build it locally, but not able to provide a common build.

At the same time, what I tryed to implement - a wrapper which is compatible with jsr233 specification. And the purpose is not to have a way to activate Julia from Java only, but rather to have a common interface which might be reused from anywhere. Previously, I did integration of JRuby into KNIME - [GitHub - rssdev10/ruby4knime: Ruby scripting extension for knime.org](https://github.com/rssdev10/ruby4knime). The KNIME specifics is - every node has own execution container, and they can be active in parallel. The last aspect might be an issue if we have only one back VM interface from Julia to Java.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [December 8, 2020, 6:40pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/4 "2020-12-08T18:40:07Z")

</div>

We’re getting into semantics here about what a “user” is. At the moment though, someone would still need to to use your build instructions in order to use those bindings though. If there are not prebuilt binaries, then then builder might have to be the user.

I wonder if [https://binarybuilder.org/](https://binarybuilder.org/) could provide those build agents if we target specifically OpenJDK 8.

---

<div class="post-metadata">

**Author:** ![rssdev10](https://avatars.discourse-cdn.com/v4/letter/r/e9a140/32.png) [@rssdev10](https://discourse.julialang.org/u/rssdev10)\
**Post date:** [December 8, 2020, 7:56pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/5 "2020-12-08T19:56:44Z")

</div>

I think, most of MacOS and Linux PCs are with OpenJDK. But not 100% that a binary based on OpenJDK 8 is compatible with OpenJDK 11. That part it would be good to check.  
Windows users are with Oracle Java SE. Regarding my code, if I remember right, I automated it with CMAKE on Mac, but didn’t check it properly on Linux systems.

Regarding Julia use cases, the main question for me - is it possible to run these Java containers in parallel inside the same Java VM. And, also, be sure in data isolation and crash safety.

---

<div class="post-metadata">

**Author:** ![DrDaleks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drdaleks/32/28139_2.png) [@DrDaleks](https://discourse.julialang.org/u/DrDaleks)\
**Post date:** [August 12, 2021, 11:32pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/6 "2021-08-12T23:32:10Z")

</div>

What do you make of “basic” process to process communication (as in starting an external Julia process from Java and discussing with it via process input/output streams)?  
I was poking around with this idea and put some code together to do that (and support scripting via JSR223) with decent performance before I discovered the solutions you mentioned (and then realized someone had recently gone that way already [here](https://github.com/org-arl/jajub))).  
Any obvious caveat for this solution? There’s clearly no memory sharing (same goes for the socket-based solution) but this is minimally impeding depending on the use case. The rest of it is rather straightforward and only requires the presence of Julia on the host, no binding or wrappers involved.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [August 13, 2021, 3:19am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/7 "2021-08-13T03:19:09Z")

</div>

In general, I think shared memory linking is probably a no-go since Java generally doesn’t play nicely with others. My main hesitancy with any Julia java interop is that it involves java, but I understand that is sometimes necessary

---

<div class="post-metadata">

**Author:** ![DrDaleks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drdaleks/32/28139_2.png) [@DrDaleks](https://discourse.julialang.org/u/DrDaleks)\
**Post date:** [August 13, 2021, 7:32am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/8 "2021-08-13T07:32:58Z")

</div>

I’d rather rephrase (and agree) that interop _between_ JVM and other (say here LLVM) languages is complicated indeed, arguably much tougher than it is between languages _within_ the same family/VM.

I’ve been watching at GraalVM for some time now, and their proof-of-concept interop with python looks pretty decent (down to memory sharing). I’m probably going to try fiddling with that as well and see if that would play nicely with Julia.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 14, 2021, 9:01am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/9 "2021-08-14T09:01:13Z")

</div>

PyCall.jl for python?.. why VM

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 17, 2021, 8:43pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/10 "2021-08-17T20:43:53Z")

</div>

For a command-line interface, see  
[A Java Matlab/Julia Interface - Stack Overflow](https://stackoverflow.com/questions/68822890/a-java-matlab-julia-interface)

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [August 18, 2021, 1:38am UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/11 "2021-08-18T01:38:29Z")

</div>

> [@Oscar\_Smith](#):
>
> In general, I think shared memory linking is probably a no-go since Java generally doesn’t play nicely with others

One stable memory API is is the `java.nio.Buffer` API:  
[https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html](https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html)  
It has a corresponding Java Native Interface support:  
[https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#nio\_support](https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#nio_support)

The above is mainly limited to 31-bit addressing (2 GB)…

There are several incubating Java APIs in `jdk.incubator.foreign`, part of Project Panama, that improve this situation greatly.

> **[jdk.incubator.foreign (Java SE 16 & JDK 16)](https://docs.oracle.com/en/java/javase/16/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/package-summary.html)**
>
> declaration: module: jdk.incubator.foreign, package: jdk.incubator.foreign

---

<div class="post-metadata">

**Author:** ![sashmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sashmit/32/18791_2.png) [@sashmit](https://discourse.julialang.org/u/sashmit)\
**Post date:** [October 5, 2021, 1:55pm UTC](https://discourse.julialang.org/t/embedding-julia-in-the-java-virtual-machine/51444/12 "2021-10-05T13:55:06Z")

</div>

How about sulong?

[https://github.com/oracle/graal/tree/master/sulong](https://github.com/oracle/graal/tree/master/sulong)
