Java plugin for Orthanc

Overview

This plugin can be used to write Orthanc plugins using the Java programming language instead of the more complex C/C++ programming languages.

Java applications for Orthanc have access to more features and a more consistent SDK than Lua scripts. The largest part of the Java API is automatically generated from the Orthanc plugin SDK in C using the Clang compiler front-end.

As of release 1.0 of the plugin, the coverage of the C SDK is about 74% (122 functions are automatically wrapped in Java out of a total of 165 functions from the Orthanc SDK 1.10.0).

For researchers: Please cite this paper.

How to get it ?

Binaries are included in:

Release notes are available here.

Compilation instructions are available below.

Compilation

The Java plugin for Orthanc implies the compilation of two modules:

  • The plugin shared library, which is needed for all users to run Java applications from within Orthanc, and

  • The Orthanc Java SDK, which is needed for developers of Java applications for Orthanc.

Shared library

If targeting GNU/Linux distributions, compiling the shared library of the Java plugin (which is written in C++) works as follows:

$ mkdir BuildPlugin
$ cd BuildPlugin
$ cmake ../Plugin -DCMAKE_BUILD_TYPE=Release
$ make

This requires the JNI (Java Native Interface) to be installed on your system (on Ubuntu setups, you can simply install the default-jdk package). This produces the libOrthancJava.so shared library. This shared library depends on the very specific configuration of your system, so precompiled binaries are not available.

If targeting Microsoft Windows, the supported way of compiling the plugin consists in using the MinGW toolchains to cross-compile the shared library on a GNU/Linux host:

$ mkdir BuildWindows64
$ cd BuildWindows64
$ cmake ../Plugin -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_TOOLCHAIN_FILE=../Resources/Orthanc/Toolchains/MinGW-W64-Toolchain64.cmake
$ make

This produces the libOrthancJava.dll shared library. Contrarily to GNU/Linux distributions, precompiled binaries are available:

Java SDK

In addition to the shared library that is needed by all the users, the developers of Java applications for Orthanc need a set of Java classes that provide access to the native functions of the Orthanc plugin SDK.

The Orthanc Java SDK is available in the folder JavaSDK of the source distribution. A .jar file containing the Orthanc Java SDK can be compiled as follows:

$ mkdir BuildJavaSDK
$ cd BuildJavaSDK
$ cmake ../JavaSDK
$ make

This requires a JDK to be installed on your computer. This generates the file OrthancJavaSDK.jar. Alternatively, this cross-platform .jar library is available in a precompiled form at:

  • The following location (evidently, make sure to download the version that matches your version of the libOrthancJava.so|.dll shared library).

Usage

Here is a minimal example of a Java application for Orthanc:

import be.uclouvain.orthanc.Functions;

public class HelloWorld {
    static {
        Functions.logWarning("Hello from Java!");
    }
}

If both the shared library and the Java SDK are located in the current directory, here is a configuration file to run this sample Java application on a GNU/Linux distribution:

{
  "Plugins" : [ "./libOrthancJava.so" ],
  "Java" : {
    "Enabled" : true,
    "Classpath" : "./OrthancJavaSDK.jar:.",
    "InitializationClass" : "HelloWorld"
  }
}

Orthanc can then be started as follows (the path to libjvm.so must be adapted depending on your configuration):

$ javac HelloWorld.java -classpath ./OrthancJavaSDK.jar
$ LD_PRELOAD=/usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so ./Orthanc ./HelloWorld.json

On Microsoft Windows, one would use the following configuration file (beware of the : that is replaced by ; in the Classpath option):

{
  "Plugins" : [ "./OrthancJava.dll" ],
  "Java" : {
    "Enabled" : true,
    "Classpath" : "./OrthancJavaSDK.jar;.",
    "InitializationClass" : "HelloWorld"
  }
}

This example simply outputs a line in the logs of Orthanc. Indeed, the static section of the class that is specified in the InitializationClass option is executed during the initialization of the plugin.

You can find the full Javadoc documentation of the Orthanc Java SDK at the following location.

Troubleshooting

Pre-compiled binaries for Microsoft Windows are now part of the Windows installers but not installed by default. They are also available here.

Pay also attention to pick the right 32/64 bits version. If you are running Orthanc 64bits, install Java in 64bits and select the 64bits Java plugin too.

When you install Java on your Windows machine, make sure to add the path to jvm.dll to your Path environment variable for at System level, not user level. E.g: C:\Program Files\Java\jre-1.8\bin\server\.

If you get the following error:

LoadLibrary(C:\Program Files\Orthanc Server\Plugins\OrthancJava.dll) failed: Error 126

This very likely means that OrthancJava.dll can not find the jvm.dll. Check your system Path.

If you get the following errors:

LoadLibrary(C:\Program Files\Orthanc Server\Plugins\OrthancJava.dll) failed: Error 193
Error while using a shared library (plugin): You are most probably trying to load a 32bit plugin into a 64bit version of Orthanc

This very likely means that Java 32bits has been installed on a 64bits version of Windows.

Process Monitor should allow you to debug this type of errors.

Examples

Adding a route in the REST API of Orthanc

New routes can be added to the REST API of Orthanc as follows:

import be.uclouvain.orthanc.Callbacks;
import be.uclouvain.orthanc.HttpMethod;
import be.uclouvain.orthanc.RestOutput;

import java.util.Map;

public class ExtendingRest {
    static {
        Callbacks.register("/java", new Callbacks.OnRestRequest() {
            @Override
            public void call(RestOutput output,
                             HttpMethod method,
                             String uri,
                             String[] regularExpressionGroups,
                             Map<String, String> headers,
                             Map<String, String> getParameters,
                             byte[] body) {
                output.answerBuffer("Hello from Java!\n".getBytes(), "text/plain");
            }
        });
    }
}

Reacting to events

Java applications can react to Orthanc events as follows:

import be.uclouvain.orthanc.Callbacks;
import be.uclouvain.orthanc.ChangeType;
import be.uclouvain.orthanc.Functions;
import be.uclouvain.orthanc.ResourceType;

public class Changes {
    static {
        Callbacks.register(new Callbacks.OnChange() {
            @Override
            public void call(ChangeType changeType, ResourceType resourceType, String resourceId) {
                switch (changeType) {
                case ORTHANC_STARTED:
                    Functions.logWarning("Orthanc has started");
                    break;

                case ORTHANC_STOPPED:
                    Functions.logWarning("Orthanc has stopped");
                    break;

                default:
                    break;
                }
            }
        });
    }
}

Additional samples

More advanced samples using Maven can be found in the source distribution of the Java plugin.

FHIR server for Orthanc

Instructions for using the sample FHIR server for Orthanc that is described in the reference paper can be found in the source distribution.

A precompiled version of the FHIR server is also available at the following location.

Licensing

This plugin is licensed under the terms of the GPLv3+ license, which is the same as the core of Orthanc.

This has an important consequence: If you distribute Orthanc to clients together with one Java plugin, you must disclose the source code of your Java plugins to the Orthanc community under the terms of the GPL or AGPL licenses.

We suggest you to put the source code of your Java plugins on the dedicated “OrthancContributed” repository on GitHub, and/or to send it to the Orthanc Users discussion forum.

Check out the FAQ about licensing for more context.