Re: Jython Caching Argv
Jeff Allen <[email protected]> Mon, 13 Aug 2018 18:50:10 +0100
| Newsgroups | gmane.comp.lang.jython.user |
|---|---|
| Message-ID | <[email protected]> |
Deb:
You could try building your JAR from the contents extracted from the
Jython standalone JAR. Most build tools can treat a JAR as a source in
this way. e.g. Ant: https://stackoverflow.com/a/185116 , or Gradle:
https://docs.gradle.org/current/userguide/working_with_files.html#sec:creating_uber_jar_example
.
In my example, argv is a reference to a PyList. This has an API by which
you could add/remove items without setting sys.argv. It may be clearer
like this:
PySystemState sys = pyInterpreter.getSystemState();
sys.argv.__add__(Py.newString("hello"));
sys.argv.__add__(Py.newString("world"));
Although I think you could safely make a new PyList and replace it if
you wanted:
sys.argv = new PyList()
Jeff Allen
On 13/08/2018 09:53, Debashish wrote:
> Hi Jeff,
>
> Sorry but my requirement is not to run the Jython standalone JAR. The
> Jython JAR will be packaged (along with other dependency JARs) inside
> my application JAR and I have to run this application JAR. This is my
> primary pain point, that there is no obvious way to specify the Jythin
> library files to the running application, even after putting Jythin
> JAR on classpath. Here I have no way to supply an absolute, file
> system path to the library.
>
> Also I am not sure I understand how we can manipulaet the argv we get
> from:
> PyList argv = pyInterpreter.getSystemState().argv;
>
> I see no setter method inside pyInterpreter to set the modified argv back.
>
> Thanks,
>
> Deb
>
> On Sun, 12 Aug 2018 at 18:41, Jeff Allen <[email protected]
> <mailto:[email protected]>> wrote:
>
> Hi Deb:
>
> By CPython I mean the implementation of the Python language
> written in C, which is the one most people mean when they just say
> "Python".
>
> Do not put the copy of the standard library that comes with
> CPython on the path for Jython. It may seem to work, but then
> bizarre things start to happen and no-one can help you. Jython has
> its own copy with many small adaptations, which (for you) is in
> the standalone JAR and need not be extracted.
>
> You probably don't need python.home. It is as easy as this to run
> Jython (in an empty directory that I just created):
>
> PS here> java -cp "C:\Jython\2.7.1-sa\jython-standalone-2.7.1.jar" org.python.util.jython
> Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
> [Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.7.0_60
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import sys, colorsys
> >>> sys.path
> ['', 'C:\\Jython\\2.7.1-sa\\Lib', 'C:\\Jython\\2.7.1-sa\\jython-standalone-2.7.1.jar\\Lib', '__classpath__', '__pyclasspath__/', 'C:\\Users\\Jeff\\.local\\lib\\jython2.7\\site-packages']
>
> I'm not sure why we have the second entry as well as the third on
> the path in this case as the library is in the JAR:
>
> >>> colorsys.__file__
> 'C:\\Jython\\2.7.1-sa\\*jython-standalone-2.7.1.jar**\\Lib\\*colorsys.py'
> >>> exit()
>
> Now, if I define python.home to a folder that contains an
> alternate library:
>
> PS here> java "-Dpython.home=..\271-sa" -cp "C:\Jython\2.7.1-sa\jython-standalone-2.7.1.jar" org.python.util.jython
> Jython 2.7.1 (default:0df7adb1b397, Jun 30 2017, 19:02:43)
> [Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.7.0_60
> Type "help", "copyright", "credits" or "license" for more information.
> >>> import sys, colorsys
> >>> sys.path
> ['', 'C:\\Users\\Jeff\\Documents\\Jython\\271-sa\\Lib', 'C:\\Jython\\2.7.1-sa\\jython-standalone-2.7.1.jar\\Lib', '__classpath__', '__pyclasspath__/', 'C:\\Users\\Jeff\\.local\\lib\\jython2.7\\site-packages', 'C:\\Users\\Jeff\\Documents\\Jython\\271-sa\\Lib\\site-packages']
> >>> colorsys.__file__
> 'C:\\Users\\Jeff\\Documents\\Jython\\271-sa\\Lib\\colorsys.py'
>
> You see that Jython has looked there first and found the colorsys
> module.
>
> It's always worth exploring Python at the prompt first, but I'm
> aware you want to call interpreters from Java. I'm pretty sure
> argv is just:
>
> PyList argv = pyInterpreter.getSystemState().argv;
>
> This will be a copy of the default you supplied, that you can
> manipulate as you wish.
>
> Jeff
>
> Jeff Allen
>
> On 12/08/2018 10:53, Debashish wrote:
>> Sorry, I got confused by the term CPython, I guess if I have
>> Python installed its already CPython that I am using :) So the
>> first bullet in my reply should only read that "Indeed I set
>> /python.home/ to my local CPython installation". And that worked
>> (somehow).
>>
>> On Sun, 12 Aug 2018 at 15:11, Debashish <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> Hi Jeff, Adam,
>>
>> Thanks a ton for the prompt reply. Few clarifications:
>>
>> 1. The /python.home/ path I gave is the /local/ Python 2.7
>> installation path. I assume you are saying this should be
>> /CPython/ home rather. I will try this after installing
>> CPython locally.
>> 2. The problem is that I wish to deploy my code on Pivotal
>> Cloud Foundry (PCF) where I would not be able to install
>> anything else apart from the application JAR, no
>> file-system access is available as since the code runs
>> inside PCF containers, I cannot expect Python or CPython
>> to be installed on that system.
>> 3. I tried several thing to make it work (for e.g. extracted
>> the /Lib/ folder from the JAR and added it on the
>> classpath, also renamed the JAR to /jython.jar/ and added
>> it to classpath, supplied the Lib folder path as
>> /python.path/ as well), none of these worked. It seems if
>> there is no way to supply the absolute path, then there
>> is no way to make it work from within a Java JAR.
>> 4. My Python script is current 400 LOCs and will keep on
>> growing, so I cannot possibly call its /functions/ from
>> my Java code as it would couple it to the Python code. I
>> guess the only better option would be to port this Python
>> code to Java.
>> 5. I am using Jython Standalone JAR 2.7.1 from Maven
>> central. I think what you are saying is that instead of
>> passing command line arguments (argv) to the static
>> /initialize/ method I can pass it to the
>> /PythonInterpreter/ object rather. I am not sure how, as
>> I do not such any such method in the API. Is there a code
>> example available?
>>
>> Thanks again for your help.
>>
>> Deb
>>
>> On Sun, 12 Aug 2018 at 03:26, Adam Burke
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>> Hi Deb
>>
>> On top of that, depending on how the script you’re
>> calling is written, it might be useful to call one layer
>> down instead of using I/O. Jython lets you work with
>> python objects fairly directly from Java, and call Python
>> functions directly as well. So if your python script has
>> internal functions and classes, you could call straight
>> into them.
>>
>> YMMV.
>>
>> Adam
>>
>> > 在 2018年8月12日,上午7:41,Jeff Allen <[email protected]
>> <mailto:[email protected]>> 写道:
>> >
>> > I don't know anything about Spring Boot, but the
>> standalone JAR must be on your path for you to be able to
>> refer to "PythonInterpreter" in your code. So by "not
>> detected" I guess you mean that Jython appear not to find
>> its library (which is in the standalone JAR). Jython
>> guesses based on the path to the JAR it seems to be
>> running from (that org.python.core.Py
>> <http://org.python.core.Py> was loaded from) but telling
>> it is safer.
>> >
>> > This bit struck me as odd:
>> >
>> > props.put("python.home", "C:\\Dev\\Python27");
>> >
>> > That's not the location of CPython is it? That would
>> cause you a world of confusion.
>> >
>> > However, none of that addresses your question about
>> argv (meaning sys.argv I suppose). The important
>> observation here is that "PythonInterpreter.initialize"
>> is a static method that sets a default argv that all
>> interpreters will see as they are created. It makes a big
>> difference now what version you are using. In 2.7.0, all
>> interpreters were really the same interpreter: you got a
>> separate namespace for your main, but the modules where
>> all the same, in particular every interpreter shared sys.
>> In 2.7.1, each interpreter gets its own sys, and so each
>> module used is loaded again for each interpreter.
>> >
>> > I cannot say off the top of my head what the behaviour
>> of the default argv and sys.argv is, but I'm pretty sure
>> the interpreter you make in the next line has its own sys
>> and the sys.argv you could set independently, although
>> not in the constructor.
>> >
>> > Jeff Allen
>> >
>> >> On 11/08/2018 20:16, Debashish wrote:
>> >> Hi,
>> >>
>> >> I am trying to call a Python Script from a Spring Boot
>> applications. There are two issues I am facing:
>> >> (1) The Jython Standalone JAR is not detected and I am
>> forced to supply the local install path as "python.home"
>> to make it work.
>> >> (2) Once I initialize the /PythonInterpreter/ class,
>> it seems it caches the argv I supply to it as for the
>> subsequent invocation it uses the same argv values. I do
>> call the close() method to do cleanup, but it doesn't help :(
>> >>
>> >> Properties preprops =
>> System.getProperties();
>> >> Properties props = new Properties();
>> >>
>> >> props.put("python.home", "C:\\Dev\\Python27");
>> >> props.put("python.console.encoding", "UTF-8");
>> >> props.put("python.security.respectJavaAccessibility",
>> "false");
>> >> props.put("python.import.site", "false");
>> >>
>> >> PythonInterpreter.initialize(preprops, props, arguments);
>> >> PythonInterpreter pyInterpreter = new PythonInterpreter();
>> >>
>> >> try {
>> >> resource = new ClassPathResource("mypyscript.py");
>> >> out = new ByteArrayOutputStream();
>> >> err = new ByteArrayOutputStream();
>> >> pyInterpreter.setOut(out);
>> >> pyInterpreter.setErr(err);
>> >> pyInterpreter.execfile(resource.getInputStream());
>> >> result[0] = out.toString(); // reading the output
>> >> result[1] = err.toString(); // reading any error
>> >> } catch (Exception e) {
>> >> throw new Exception(e);
>> >> } finally {
>> >> try {
>> >> if (out != null)
>> >> out.close();
>> >> if (err != null)
>> >> err.close();
>> >> pyInterpreter.close();
>> >> } catch (IOException e) {
>> >> e.printStackTrace();
>> >> }
>> >> }
>> >>
>> >> Please help.
>> >>
>> >> Thanks,
>> >>
>> >> Deb
>> >>
>> >>
>> >>
>> ------------------------------------------------------------------------------
>> >> Check out the vibrant tech community on one of the
>> world's most
>> >> engaging tech sites, Slashdot.org!
>> http://sdm.link/slashdot
>> >>
>> >>
>> >> _______________________________________________
>> >> Jython-users mailing list
>> >> [email protected]
>> <mailto:[email protected]>
>> >> https://lists.sourceforge.net/lists/listinfo/jython-users
>> >
>> >
>> >
>> ------------------------------------------------------------------------------
>> > Check out the vibrant tech community on one of the
>> world's most
>> > engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>> > _______________________________________________
>> > Jython-users mailing list
>> > [email protected]
>> <mailto:[email protected]>
>> > https://lists.sourceforge.net/lists/listinfo/jython-users
>>
>> ------------------------------------------------------------------------------
>> Check out the vibrant tech community on one of the
>> world's most
>> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>> _______________________________________________
>> Jython-users mailing list
>> [email protected]
>> <mailto:[email protected]>
>> https://lists.sourceforge.net/lists/listinfo/jython-users
>>
>
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Jython-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jython-users