Call Java code from Iron Python

As we’ve said before, you can fight developer fatigue by easing into the new technology, making use of tools and libraries that are already familiar to you. For example, let’s say  you have a Java library that you need to access, and are also familiar with Visual Studio tooling. If you’re assigned to create a Python application that reproduces the functionality of the Java library, why reinvent the wheel? Why not call the existing functionality of your Java library?  And, if you’re comfortable with Visual Studio, why not use Iron Python, a .NET-based Python that includes Visual Studio tools? In a technology mix like this, JNBridgePro can help.

In a previous post, we showed how .NET dlls can be called from Jython (a Java-based Python implementation).  This can be useful in situations where there is a need to call .NET from Python and either Jython is already being used (or is required), or if the Python application needs to call both Java and .NET code.

Here, we’re going to turn things around and show how a Java library can be called from Iron Python. It’s similar to the previous Python example, but we’ve rewritten it so that the target library is written in Java.

Let’s start with a simple Java library:

package javaLibrary;

public class HelloWorldFromJava
{
     private String theString = "";

     public HelloWorldFromJava()
     {
          theString = "Hello World from Java!";
     }

     public HelloWorldFromJava(String s)
     {
          theString = s;
     }

     public String returnString()
     {
          return theString;
     }
}

Once it’s compiled, and the proxy dll has been generated, we create our Iron Python application. You can use the Visual Studio tools, or the interactive console window.

Here’s the simple Iron Python application that instantiates the HelloWorldFromJava class and exercises the API:

import sys
sys.path.append(r"C:\Program Files (x86)\IronPython 2.7\Lib")
sys.path.append(r"C:\Program Files (x86)\JNBridge\JNBridgePro v7.2\4.0-targeted")
sys.path.append(r"D:\Data\JNBridge\IronPython example")

import clr
clr.AddReferenceToFile("proxies")
clr.AddReferenceToFile("jnbshare")

from com.jnbridge.jnbproxy import JNBRemotingConfiguration, JavaScheme
JNBRemotingConfiguration.specifyRemotingConfiguration(JavaScheme.sharedmem, r"C:\Program Files (x86)\Java\jre8\bin\client\jvm.dll", r"C:\Program Files (x86)\JNBridge\JNBridgePro v7.2\jnbcore\jnbcore.jar", r"C:\Program Files (x86)\JNBridge\JNBridgePro v7.2\jnbcore\bcel-5.1-jnbridge.jar", r"D:\Data\JNBridge\IronPython example\Java\bin")

from javaLibrary import HelloWorldFromJava
h = HelloWorldFromJava()
print h.returnString()
h = HelloWorldFromJava("Test string from Java")
print h.returnString()

There are a couple of things we need to note here.  First, we need to add the folders containing the JNBridgePro runtime components and the proxy dll to the Python path. We could have copied these runtime dlls into a single folder along with the proxies, but we have chosen to leave them where they were installed. The paths will likely be different on your machine, and, depending on your deployment, you may be able to omit one or more of these lines.

Once we’ve added these folders to the path, we can reference the two .NET dlls, proxies.dll and jnbshare.dll, that we will be accessing directly. Note that we only need to explicitly reference the dlls we’re accessing directly; all indirectly accessed dlls will be automatically loaded, as long as they are in the path, too.

After we’ve referenced the relevant dlls, we need to configure the JNBridgePro Java side. We need to do this programmatically, as Iron Python doesn’t easily support app.config files. In our example, we call JNBRemotingConfiguration.specifyRemotingConfiguration(), a programmatic configuration API that we provide, and which is part of jnbshare.dll (which is why we need to have explicitly referenced jnbshare.dll).

Finally, unlike in Jython, it is safe to use the fromimport form of the import statement in Iron Python; using fromimport doesn’t call static initializers to be called prematurely, so exceptions aren’t thrown. Using this form of the import statement makes the code cleaner.

Once everything is set up, we can run the Iron Python program, and we get the following expected output:

Hello World from Java!

Test string from Java

It’s just as simple as the Jython-to-.NET example! We’ve shown how you can use JNBridgePro to write a Python (actually, Iron Python) program that can call both Java (through the proxies) and .NET code (the JNBridgePro configuration API).

Do you see other scenarios where interoperability technologies like JNBridgePro might help fight developer fatigue? If so, please let us know.