From: Richard E. de C. <ric...@gm...> - 2014-04-08 08:58:16
|
Hi all, I want to define a class in Jython and instantiate it in Java. I am using a Java framework which allows users to create custom components (classes implementing specific interfaces). The framework is built in such a way that it instantiates these components itself based on a description containing a class name and a set of parameters. My goal is to define a new component within Jython and to use it with the framework. Here some pseudocode: class MyComponent(Component): def run(self, *args): // do something run(createComponent(MyComponent)) (btw. in Java I would have written: run(createComponent(MyComponent.class)) That gives me an error along the lines of InitializationException: Component class "org.python.proxies.__main__$MyComponent$1" was not found. Reading a bit in [1], I now believe that what I want to do is not really possible without modifying the framework that I am using because classes defined in Jython do not actually have a java.lang.Class instance associated with them and there is actually no classloader which would be able to return such an instance when Class.forName("org.python.proxies.__main__$MyComponent$1") is called. Is this correct, or is there a way to do what I want to do? Cheers, -- Richard [1] http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html |
From: Alan K. <jyt...@xh...> - 2014-04-09 17:03:35
|
Hi Richard, Without seeing your java code, it's hard to state what exactly might be wrong. But there is a simple conversion process that you need to go through to obtain a java object equivalent of a class implemented in jython. 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 You should try that approach. Alan. On Tue, Apr 8, 2014 at 9:58 AM, Richard Eckart de Castilho < ric...@gm...> wrote: > Hi all, > > I want to define a class in Jython and instantiate it in Java. > > I am using a Java framework which allows users to create custom > components (classes implementing specific interfaces). The framework > is built in such a way that it instantiates these components itself > based on a description containing a class name and a set of parameters. > > My goal is to define a new component within Jython and to use it with > the framework. Here some pseudocode: > > class MyComponent(Component): > def run(self, *args): > // do something > > run(createComponent(MyComponent)) > > (btw. in Java I would have written: run(createComponent(MyComponent.class)) > > That gives me an error along the lines of > > InitializationException: Component class > "org.python.proxies.__main__$MyComponent$1" was not found. > > Reading a bit in [1], I now believe that what I want to do is not really > possible without modifying the framework that I am using because classes > defined in Jython do not actually have a java.lang.Class instance > associated with them and there is actually no classloader which would be > able > to return such an instance when > Class.forName("org.python.proxies.__main__$MyComponent$1") > is called. > > Is this correct, or is there a way to do what I want to do? > > Cheers, > > -- Richard > > [1] http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html > > ------------------------------------------------------------------------------ > Put Bad Developers to Shame > Dominate Development with Jenkins Continuous Integration > Continuously Automate Build, Test & Deployment > Start a new project now. Try Jenkins in the cloud. > http://p.sf.net/sfu/13600_Cloudbees > _______________________________________________ > Jython-users mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-users > |
From: Jim B. <jb...@zy...> - 2014-04-09 17:31:33
|
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. Here's an example of Clamp in action. Let's assume the BarClamp class is defined in the Python module clamped; then BarBase is setting it up so that the classname for Java will be ".".join(["bar", "clamped", "BarClamp"]) or bar.clamped.BarClamp. That prefix is arbitrary; it could be com.example.baz: from java.io import Serializablefrom java.util.concurrent import Callablefrom clamp import clamp_base BarBase = clamp_base("bar") # metaclass to map to Java packages class BarClamp(BarBase, Callable, Serializable): def call(self): return 42 To then use that clamped class, you can simply import it: import bar.clamped.BarClamp; // yes, you can now just import Python classes! public class UseClamped { public static void main(String[] args) { BarClamp barclamp = new BarClamp(); try { System.out.println("BarClamp: " + barclamp.call()); } catch (Exception ex) { System.err.println("Exception: " + ex); } }} Clamp is under active development, but it's definitely stable enough for testing. - Jim On Wed, Apr 9, 2014 at 11:03 AM, Alan Kennedy <jyt...@xh...> wrote: > Hi Richard, > > Without seeing your java code, it's hard to state what exactly might be > wrong. > > But there is a simple conversion process that you need to go through to > obtain a java object equivalent of a class implemented in jython. > > 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 > > You should try that approach. > > Alan. > > > > On Tue, Apr 8, 2014 at 9:58 AM, Richard Eckart de Castilho < > ric...@gm...> wrote: > >> Hi all, >> >> I want to define a class in Jython and instantiate it in Java. >> >> I am using a Java framework which allows users to create custom >> components (classes implementing specific interfaces). The framework >> is built in such a way that it instantiates these components itself >> based on a description containing a class name and a set of parameters. >> >> My goal is to define a new component within Jython and to use it with >> the framework. Here some pseudocode: >> >> class MyComponent(Component): >> def run(self, *args): >> // do something >> >> run(createComponent(MyComponent)) >> >> (btw. in Java I would have written: >> run(createComponent(MyComponent.class)) >> >> That gives me an error along the lines of >> >> InitializationException: Component class >> "org.python.proxies.__main__$MyComponent$1" was not found. >> >> Reading a bit in [1], I now believe that what I want to do is not really >> possible without modifying the framework that I am using because classes >> defined in Jython do not actually have a java.lang.Class instance >> associated with them and there is actually no classloader which would be >> able >> to return such an instance when >> Class.forName("org.python.proxies.__main__$MyComponent$1") >> is called. >> >> Is this correct, or is there a way to do what I want to do? >> >> Cheers, >> >> -- Richard >> >> [1] http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html >> >> ------------------------------------------------------------------------------ >> Put Bad Developers to Shame >> Dominate Development with Jenkins Continuous Integration >> Continuously Automate Build, Test & Deployment >> Start a new project now. Try Jenkins in the cloud. >> http://p.sf.net/sfu/13600_Cloudbees >> _______________________________________________ >> Jython-users mailing list >> Jyt...@li... >> https://lists.sourceforge.net/lists/listinfo/jython-users >> > > > > ------------------------------------------------------------------------------ > Put Bad Developers to Shame > Dominate Development with Jenkins Continuous Integration > Continuously Automate Build, Test & Deployment > Start a new project now. Try Jenkins in the cloud. > http://p.sf.net/sfu/13600_Cloudbees > _______________________________________________ > Jython-users mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-users > > |
From: Jim B. <jb...@zy...> - 2014-04-09 18:38:48
|
One more thing: it's a known problem that Clamp does not currently build jars correctly on Windows. Another issue seen on Windows is sys.executable does not get set. See the Clamp issues in https://github.com/jythontools/clamp/ To address both the Clamp issues and in Jython proper, as of yesterday I now have a MSDN license so that we can test in this environment. (This license is courtesy of a program Microsoft has for Python committers.) Hopefully this will help get us to better Windows support for Jython. - Jim On Wed, Apr 9, 2014 at 11:31 AM, Jim Baker <jb...@zy...> wrote: > 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. > > Here's an example of Clamp in action. Let's assume the BarClamp class is > defined in the Python module clamped; then BarBase is setting it up so that > the classname for Java will be ".".join(["bar", "clamped", "BarClamp"]) or > bar.clamped.BarClamp. That prefix is arbitrary; it could be com.example.baz: > > from java.io import Serializablefrom java.util.concurrent import Callablefrom clamp import clamp_base > BarBase = clamp_base("bar") # metaclass to map to Java packages > class BarClamp(BarBase, Callable, Serializable): > def call(self): > return 42 > > To then use that clamped class, you can simply import it: > > import bar.clamped.BarClamp; // yes, you can now just import Python classes! > public class UseClamped { > public static void main(String[] args) { > BarClamp barclamp = new BarClamp(); > try { > System.out.println("BarClamp: " + barclamp.call()); > } catch (Exception ex) { > System.err.println("Exception: " + ex); > } > }} > > > Clamp is under active development, but it's definitely stable enough for > testing. > > - Jim > > > On Wed, Apr 9, 2014 at 11:03 AM, Alan Kennedy <jyt...@xh...>wrote: > >> Hi Richard, >> >> Without seeing your java code, it's hard to state what exactly might be >> wrong. >> >> But there is a simple conversion process that you need to go through to >> obtain a java object equivalent of a class implemented in jython. >> >> 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 >> >> You should try that approach. >> >> Alan. >> >> >> >> On Tue, Apr 8, 2014 at 9:58 AM, Richard Eckart de Castilho < >> ric...@gm...> wrote: >> >>> Hi all, >>> >>> I want to define a class in Jython and instantiate it in Java. >>> >>> I am using a Java framework which allows users to create custom >>> components (classes implementing specific interfaces). The framework >>> is built in such a way that it instantiates these components itself >>> based on a description containing a class name and a set of parameters. >>> >>> My goal is to define a new component within Jython and to use it with >>> the framework. Here some pseudocode: >>> >>> class MyComponent(Component): >>> def run(self, *args): >>> // do something >>> >>> run(createComponent(MyComponent)) >>> >>> (btw. in Java I would have written: >>> run(createComponent(MyComponent.class)) >>> >>> That gives me an error along the lines of >>> >>> InitializationException: Component class >>> "org.python.proxies.__main__$MyComponent$1" was not found. >>> >>> Reading a bit in [1], I now believe that what I want to do is not really >>> possible without modifying the framework that I am using because classes >>> defined in Jython do not actually have a java.lang.Class instance >>> associated with them and there is actually no classloader which would be >>> able >>> to return such an instance when >>> Class.forName("org.python.proxies.__main__$MyComponent$1") >>> is called. >>> >>> Is this correct, or is there a way to do what I want to do? >>> >>> Cheers, >>> >>> -- Richard >>> >>> [1] >>> http://www.jython.org/jythonbook/en/1.0/JythonAndJavaIntegration.html >>> >>> ------------------------------------------------------------------------------ >>> Put Bad Developers to Shame >>> Dominate Development with Jenkins Continuous Integration >>> Continuously Automate Build, Test & Deployment >>> Start a new project now. Try Jenkins in the cloud. >>> http://p.sf.net/sfu/13600_Cloudbees >>> _______________________________________________ >>> Jython-users mailing list >>> Jyt...@li... >>> https://lists.sourceforge.net/lists/listinfo/jython-users >>> >> >> >> >> ------------------------------------------------------------------------------ >> Put Bad Developers to Shame >> Dominate Development with Jenkins Continuous Integration >> Continuously Automate Build, Test & Deployment >> Start a new project now. Try Jenkins in the cloud. >> http://p.sf.net/sfu/13600_Cloudbees >> _______________________________________________ >> Jython-users mailing list >> Jyt...@li... >> https://lists.sourceforge.net/lists/listinfo/jython-users >> >> > |
From: Richard E. de C. <ric...@gm...> - 2014-04-24 20:31:57
|
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 |
From: Richard E. de C. <ric...@gm...> - 2014-04-24 20:40:10
|
On 24.04.2014, at 22:31, Richard Eckart de Castilho <ric...@gm...> wrote: >> 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? Looking at the code again, I believe it does not want I need. I do not want to access an object instantiated in Jython from Java. I want to access a class defined in Jython from Java as a java.lang.Class object which I can then use to instantiate said class from Java. -- Richard |
From: Jim B. <jb...@zy...> - 2014-04-24 21:22:24
|
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 < ric...@gm...> 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 > > > |