VTK/Java Wrapping

From KitwarePublic
Revision as of 17:02, 19 August 2011 by Jeff (talk | contribs)
Jump to navigationJump to search


You basically just need to turn VTK_WRAP_JAVA on in CMake and build.

Bartlomiej Wilkowski has created a nice tutorial of configuring Java wrapping with VTK.

Mac (Snow Leopard)

To build a sample application provided in VTK against your VTK build directory (with an installed VTK replace "bin" with "lib"):

$ export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:your_vtk_build_dir/bin
$ javac -cp your_vtk_build_dir/bin/vtk.jar your_vtk_source_dir/Wrapping/Java/vtk/sample/Demo.java
$ java -cp your_vtk_build_dir/bin/vtk.jar:your_vtk_source_dir/Wrapping/Java vtk.sample.Demo

Sample Code (from VTK/Wrapping/Java/vtk/sample/SimpleVTK.java)

 * An application that displays a 3D cone. A button allows you to close the
 * application.
public class SimpleVTK extends JPanel implements ActionListener {
    private static final long serialVersionUID = 1L;
    private vtkPanel renWin;
    private JButton exitButton;

    // -----------------------------------------------------------------
    // Load VTK library and print which library was not properly loaded
    static {
        if (!vtkNativeLibrary.LoadAllNativeLibraries()) {
            for (vtkNativeLibrary lib : vtkNativeLibrary.values()) {
                if (!lib.IsLoaded()) {
                    System.out.println(lib.GetLibraryName() + " not loaded");

    // -----------------------------------------------------------------
    public SimpleVTK() {
        super(new BorderLayout());

        // build VTK Pipeline
        vtkConeSource cone = new vtkConeSource();

        vtkPolyDataMapper coneMapper = new vtkPolyDataMapper();

        vtkActor coneActor = new vtkActor();

        renWin = new vtkPanel();

        // Add Java UI components
        exitButton = new JButton("Exit");

        add(renWin, BorderLayout.CENTER);
        add(exitButton, BorderLayout.SOUTH);

    /** An ActionListener that listens to the button. */
    public void actionPerformed(ActionEvent e) {
        if (e.getSource().equals(exitButton)) {

    public static void main(String s[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame("SimpleVTK");
                frame.getContentPane().setLayout(new BorderLayout());
                frame.getContentPane().add(new SimpleVTK(), BorderLayout.CENTER);
                frame.setSize(400, 400);

Some key points from this code to note:

  • vtkNativeLibrary.LoadAllNativeLibraries() is required to load the dynamic libraries from VTK's C++ core. This call must happen before any VTK code executes, which is why it is put in a static block in our application class.
  • vtkNativeLibrary.DisableOutputWindow(null) simply hides any debugging information that may otherwise pop up in a dialog box when any warnings are reached. This is good to call when releasing an application.
  • SwingUtilities.invokeLater(...) is called because technically all GUI code, including setting up and using a VTK render window, should happen in the Swing event thread.

Java Wrapper Refactoring (Oct 8, 2007)

There were a few problems with the old Java wrappers. One was that, as you said, objects were being deleted before they were supposed to. We hacked in a fix at one point about a year ago which basically made all VTK objects accessed from Java stay around forever, but this was not acceptable either.


The other major concern was that the map from Java objects to VTK objects was in the C++ JNI layer, and while we tried to keep this map synchronized with a mutex, race conditions could still occur because other Java threads could advance while the JNI layer was being called (a thread could access a C++ object just as it is being garbage-collected and deleted). There does not seem to be a way to atomically call a JNI method, or ensure the collector doesn't run while a method is called. This second issue forced us to rethink how the map is done, and the solution was to keep the map in Java instead of C++. But we didn't want this Java map to prohibit objects from being garbage collected. Fortunately, Java has a WeakReference class for just this type of purpose. When accessed, the reference will either be valid or null depending on whether it has been garbage-collected.


Thus, the wrapper code can lookup objects in this map when returning objects from methods, and if it is not there, or null, it creates a new Java object representing that C++ object.

A final issue was that we wanted a way to guarantee all C++ destructors are called before the program exits. The natural place to decrement the reference count of the C++ object is in finalize(), which works when things are garbage-collected, but Java does not guarantee that finalize will ever be called. So the method vtkGlobalJavaHash.DeleteAll() will plow through the remaining VTK objects and call Delete on them.