Spring Python for Java developers

Java developers often seek ways to increase productivity. With the incredible growth of alternative languages on the Java Virtual Machine (JVM), it is no wonder developers are looking into Jython (http://www.jython.org) as an alternative way to write scripts, segments, and subsystems. While it's convenient to use the Java libraries you already know, it can sometimes be rough interacting with the Java idioms of the library.

Spring Python is written in pure Python, which makes it easy to use inside Jython as well. You may find it easier and more appealing to utilize the pythonic APIs of Spring Python rather than the Java idioms of the Spring Framework. The choice ultimately is yours, and it's not an either/or decision; you can use both libraries in both your Java and Python segments.

The following diagram shows a combination of Python, Jython, and pure Java as a stack.

Spring Python for Java developers

With Spring Python, it's easy to mix Java and Python together. Let's code a simple example, where we write a Jython client that talks to the TV service shown in the previous section. By reusing that code, we can easily code a client. To really show the power of Python/Jython/Java integration, let's expose our Jython client to a pure Java consumer.

  1. To begin, we need a pure Java interface that our Jython code can extend.
    import org.python.core.PyList;
    public interface JavaTvShowService {
    public PyList getTvShows();
    }
    
  2. Next, we write our Jython class to extend this interface.
    class JythonTvShowService(JavaTvShowService):
    def __init__(self):
    self.container = ApplicationContext(TvShowContainer())
    self.client = container.get_object("web_client")
    def getTvShows(self):
    return self.client.get_tv_shows()
    
  3. For Java clients to call Jython, we need to create a factory that creates an embedded Jython interpreter.
    import org.python.core.PyObject;
    import org.python.util.PythonInterpreter;
    public class TvShowServiceFactory {
    private PyObject clazz;
    public TvShowServiceFactory() {
    PythonInterpreter interp = new PythonInterpreter();
    interp.exec("import JythonTvShowService");
    clazz = interp.get("JythonTvShowService");
    }
    public JavaTvShowService createTvShowService() {
    PyObject tvShowService = clazz.__call__();
    return (JavaTvShowService)
    tvShowService.__tojava__(JavaTvShowService.class);
    }
    }
    
  4. Finally, we can write a main function that invokes the factory first, and then the JavaTvShowService.
    public class Main {
    public static void main(String[] args) {
    TvShowServiceFactory factory =
    new TvShowServiceFactory();
    JavaTvShowService service =
    factory.createTvShowService();
    PyList tvShows = service.getTvShows();
    for (int i = 0; i < tvShows.__len__(); i++) {
    PyObject obj = tvShows.__getitem__(i);
    PyTuple tvShow =
    (PyTuple)obj.__tojava__(PyTuple.class);
    System.out.println("Tv show title=" + tvShow.get(0) +
    " airDate=" + tvShow.get(1) +
    " episode=" + tvShow.get(2) +
    " writer=" + tvShow.get(3));
    }
    }
    }
    

We defined an interface, providing a good boundary to code both Java consumers and Jython services against. Our Jython class extends the interface and when created, creates an IoC container which requests a web_client object. This is our PyroProxyFactory that uses Pyro to call our pure Python service over the wire. By implementing the interface, we conveniently expose our remote procedure call to the Java consumers. Our Java app needs a factory class to create a Jython interpreter which in turn creates an instance of our Jython class. We use this in our application main to get an instance of our TV service. Using the service, we call the exposed method which makes our Pyro remote call. We iterate over the received list and extract a tuple in order to print out results.

After taking a glance at how to expose a pure Python service to a pure Java consumer, the options from here are endless. We could use Spring Java's RmiServiceExporter or HessianServiceExporter to expose our Python service to other protocols. This service could be integrated into a Spring Integration workflow or made part of a Spring Batch job. There really is no limit. We will explore this in more detail in Chapter 10 with our case study.

We have already looked at how easy it is to expose Python services to Java consumers. If you are already familiar with Spring Java, hopefully as you read this book, you will notice that the Spring way works not only in Java but in Python as well. Spring Python uses the same concepts as Spring Java, shares some class names with Spring Java, and even has an XML parser that can read Spring Java's format. All of these things increase the ability to rewrite some parts in Python while making small changes in the configuration files. All of these aspects make it easier to incrementally move our application to the sweet spot we need for improved productivity.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.149.255.168