Nice work Cliff!  This is very interesting stuff...always great to see Jython used in different ways.

I wonder if we should start a wiki page dedicated to posting solutions such as this?  Thoughts?

Josh Juneau
Twitter ID:  javajuneau

On Mon, Aug 10, 2009 at 4:52 PM, Cliff Hill <> wrote:
Ok, so my further experiments in how to make Jython work on GAE/J have led me to attempting the Google Web Toolkit example, and see if I can drive the server code using Jython, and I have success. So, with GWT, I can build a UI in Java (that compiles into JavaScript), and then I can write the server-side components in Jython (thanks to Josh's little Object Factory trick he helped me with earlier), so I can build the server-end with Jython (the only limitation is dealing with the DataStore, using JDO, I still need to build a couple Java classes to handle that gracefully, but even that works like a charm).

from import javax.jdo import JDOHelper

PMF = JDOHelper.getPersistenceManagerFactory("transactions-optional")

pm = PMF.getPersistenceManager()

    pm.makePersistent(Stock(user, symbol)) # Any class properly annotated for JDO here
This *will* fail. The reason is because the getPersistenceManager() method doesn't return a PersistenceManager object, but something else from the DataNucleus system. Building a PMF class (as outlined in the GAE/J example for "guestbook"), and adding a method to return a PersistenceManager object directly in Java like:

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {
    private static final PersistenceManagerFactory pmfInstance =

    private PMF() {}

    public static PersistenceManager getPM() {
        return (PersistenceManager) pmfInstance.getPersistenceManager();
And then loading that into the above Python code changes it to:
from import javax.jdo import JDOHelper
from import PMF

pm = PMF.getPM()

    pm.makePersistent(Stock(user, symbol)) # Any class properly annotated for JDO here
This will work correctly then.

from import RemoteServiceServlet

from import StockPrice, StockPriceService, DelistedException

import sys

sys.path.insert(0, 'WEB-INF/python-lib/')

import random

MAX_PRICE = 100.0       # $100.00
MAX_PRICE_CHANGE = 0.02 # +/- 2%

class StockPriceServiceImpl(RemoteServiceServlet, StockPriceService):
    def getPrices(self, symbols):
        prices = []
        for i in range(len(symbols)):
            if symbols[i] == "ERR":
                raise DelistedException("ERR")
            price = random.random() * MAX_PRICE
            change = price * MAX_PRICE_CHANGE * (random.random() * 2.0 - 1.0)
            prices.append(StockPrice(symbols[i], price, change))
        return prices


import org.plyjy.factory.JythonObjectFactory;


public class StockPriceServiceFacade extends RemoteServiceServlet implements StockPriceService {

    private JythonObjectFactory factory = null;

    String pyServletName = null;

    public StockPrice[] getPrices(String[] symbols) throws DelistedException {
        factory = factory.getInstance();
        pyServletName = getInitParameter("PyServletName");
        StockPriceService jythonServlet = (StockPriceService) factory.createObject(StockPriceService.class, pyServletName);
        return jythonServlet.getPrices(symbols);


So, now that I have done this... my next step is to try and build something from scratch with all of this. I'm really enjoying the ability to use Jython on the Google Apps Engine...

"I'm not responcabel fer my computer's spleling errnors" - Xlorep DarkHelm
Sent from Santa Maria, California, United States

Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.
Jython-users mailing list