Java interop via inline Java code in Haskell modules.

Version on this page:0.6.5
LTS Haskell 12.26:0.8.4
Stackage Nightly 2018-09-28:0.8.4
Latest on Hackage:0.10.0@rev:1

See all snapshots inline-java appears in

BSD-3-Clause licensed by Tweag I/O
Maintained by [email protected]
This version can be pinned in stack with:inline-java-0.6.5@sha256:97b61f314596ec19c700372e27907ca75c0870864f7da70d25381e8308eb7e36,1622

Module documentation for 0.6.5

inline-java: Call any JVM function from Haskell

wercker status

NOTE: you’ll need GHC >= 8.0.2 to compile and use this package. Use

stack --nix build

ahead of a new GHC release to build using GHC 8.0.2-rc2.

The Haskell standard includes a native foreign function interface (FFI). Using it can be a bit involved and only C support is implemented in GHC. inline-java lets you call any JVM function directly, from Haskell, without the need to write your own foreign import declarations using the FFI. In the style of inline-c for C and inline-r for calling R, inline-java lets you name any function to call inline in your code. It is implemented on top of the jni and jvm packages.


Graphical Hello World using Java Swing:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where

import Data.Int
import Data.Text (Text)
import Language.Java
import Language.Java.Inline

main :: IO Int32
main = withJVM [] $ do
    -- Extra type annotation workaround for current GHC HEAD.
    message :: J ('Class "java.lang.String") <- reflect ("Hello World!" :: Text)
    [java| { javax.swing.JOptionPane.showMessageDialog(null, $message);
             return 0; } |]

Building it


  • the Stack build tool (version 1.2 or above);
  • either, the Nix package manager,
  • or, OpenJDK, Gradle and Spark (version 1.6) installed from your distro.

On OS X, you’ll need to install the Legacy Java SE 6 runtime when prompted, even when using Nix.

To build:

$ stack build

You can optionally get Stack to download a JDK in a local sandbox (using Nix) for good build results reproducibility. This is the recommended way to build inline-java. Alternatively, you’ll need it installed through your OS distribution’s package manager for the next steps (and you’ll need to tell Stack how to find the JVM header files and shared libraries).

To use Nix, set the following in your ~/.stack/config.yaml (or pass --nix to all Stack commands, see the Stack manual for more):

  enable: true


Copyright (c) 2015-2016 EURL Tweag.

All rights reserved.

inline-java is free software, and may be redistributed under the terms specified in the LICENSE file.


Tweag I/O

inline-java is maintained by Tweag I/O.

Have questions? Need help? Tweet at @tweagio.


Change Log

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog.

[0.6.4] - 2017-04-09


  • Fixed handling of repeated antiquotation variables, which in some cases was causing a compilation error.

[0.6.3] - 2017-03-12


  • Setting the CLASSPATH using Gradle is now fully supported. It was previously unusable due to a bug (see #42).

[0.6.2] - 2017-02-21

  • Avoid producing warnings about unused inlinejava_bytecode0 bindings.
  • Support type synonyms in variable antiquotation.
  • Update lower bounds of jni to 0.3 and jvm to 0.2.

[0.6.1] - 2016-12-27

  • Support passing array objects as arguments / return values.
  • More robust mangling of inline class name.

[0.6.0] - 2016-12-13


  • Can set a custom CLASSPATH in Setup.hs from Gradle build configurations to use when compiling inline expressions.
  • GHC 8 compatibility
  • Support inline expressions that compile to multiple .class files (e.g for anonymous classes and anonymous function literals).


  • The return type of inline expressions no longer needs Reify/Reflect instances.


  • Fix antiquotation: in [java| $ |], obj is now recognized as an antiquotation variable.
  • Passing multiple options to the JVM using withJVM.

[0.5.0] - 2016-12-13


  • First release with support for inline Java expressions.


  • Split lower-level and mid-level bindings into separate packages: jni and jvm.