Richard,

Clamp does assume an ahead-of-time model in terms of its setuptools integration. However, you should just be able to use Clamp as is for your case, with a little ClassLoader work.

This is because of the two steps used by Clamp:

1. CustomMaker.makeClass, as seen in clamp.proxymaker - this ensures that class is built just once for a given name resolvable by Py.findClass. However this is not the same class loading resolution as Class.forName, so this is where you will have to do some extra work, as explained below.

2. CustomMaker.saveBytes uses the builder returned by clamp.build.get_builder, which by default - unless in a setuptools build step - is going to be a NullBuilder, which simply doesn't write out the proxy bytecode. This saveBytes step is ordinarily to ensure that you have class bytes for a jar you will distribute for say every node in your Storm cluster - not applicable in your case.

With that in mind, here's the small amount of extra work you should have to do. For your Java code to get Class.forName resolvability of clamped Python classes not built ahead-of-time, you will need to use Thread.setContextClassLoader (or something comparable, class loading has a number of entry points) and set it to the same ClassLoader that Py.findClassInternal would choose. If you look at that code in org.python.core.Py, it's quite straightforward, so I'm not certain why don't expose it directly.

Hope that helps!

- Jim


On Thu, Apr 24, 2014 at 2:31 PM, Richard Eckart de Castilho <richard.eckart@gmail.com> wrote:
Jim, Alan,

thanks for the hints.

> This is the exact use case for Clamp. If interested, I have a write up that introduces this project; https://github.com/jimbaker/clamped, along with a talk, https://github.com/jimbaker/clamped/blob/master/talk.pdf
>
> Among other things, Clamp ensures that your Python class, as wrapped by a Java proxy, can be resolved by Class.forName or be directly imported from Java. Clamp is also integrated with setuptools and is site-packages aware.


Jim, if I understand clamp correctly, it requires that the Jython code is compiled into class files at build time. I am looking for a solution that works at runtime without the need for special build tooling. I want people to be able to implement a simple Jython script and execute it. The script internally calls Java code which tries to instantiate a class defined in the script using Java reflection. Can clamp do that?

> The best way to illustrate this is with code that does it. Modjy is one example in the code base, that uses a servlet implemented in jython to provide WSGI capability to servlet containers.
>
> The key piece of code is here.
>
> http://hg.python.org/jython/file/45b3007473f9/src/com/xhaus/modjy/ModjyJServlet.java#l116

Alan, it sounds like the __tojava__ call might do what I want. I wonder, shouldn't the classloader that is used by the Jython scripts (the one which also can add additional JARs to the syspath) be able to transparently call that when a class object for a class defined in Jython is requested? Is it just that nobody implemented this so far, or is it because it is in fact not as straight forward as it seems in the sample code you offered?

Cheers,

-- Richard