Introduction
I added several improvements to Jython MVP framework. The source code is available here. Demo version running in Google App Engine is here.
Change focus
This feature allows an automatic jump to the particular field in the form. Is useful at the beginning allowing user start entering data in the proper field or, in case of error detected, move to the wrong field. This option is demonstrated in the demo application, Alerts -> Dialog with focus.
More detailed description.
Field with dynamic list of images
This option was created firstly for the editable list. But now it is extended to form as well. Declaration and handling are very similar. More details. The option is showed in the demo application, Alerts -> Dialog with image field.
Blog do projektu Open Source JavaHotel
Pokazywanie postów oznaczonych etykietą jython. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą jython. Pokaż wszystkie posty
czwartek, 8 października 2015
poniedziałek, 17 listopada 2014
Google App Engine and Jython 2.7beta3
Problem
I spent several sleepless nights trying to figure out why Jython 2.7beta3 suddenly refused to work in Google App Engine while Jython 2.7 beta2 worked nicely.
It crashes while initializing site.py standard package because Google App Engine blocks any attempt to use ProcessBuilder.
But then came up the second one which unveils only in Production mode (works in Development mode).
Solution
But finally I found the solution and it was simple as usual.
I spent several sleepless nights trying to figure out why Jython 2.7beta3 suddenly refused to work in Google App Engine while Jython 2.7 beta2 worked nicely.
It crashes while initializing site.py standard package because Google App Engine blocks any attempt to use ProcessBuilder.
com.jythonui.client.service.JythonService.runAction(com.jythonui.shared.RequestContext,com.jythonui.shared.DialogVariables,java.lang.String,java.lang.String)' threw an unexpected exception: Traceback (most recent call last): File "/base/data/home/apps/s~testjavahotel/5.380117830403911812/WEB-INF/lib/jython-standalone-2.7-b3.jar/Lib/site.py", line 571, inThis exception (raised in Development and Production mode) can be resolved easy by setting Options.no_user_site = true; before starting the Jython interpreter.File "/base/data/home/apps/s~testjavahotel/5.380117830403911812/WEB-INF/lib/jython-standalone-2.7-b3.jar/Lib/site.py", line 552, in main File "/base/data/home/apps/s~testjavahotel/5.380117830403911812/WEB-INF/lib/jython-standalone-2.7-b3.jar/Lib/site.py", line 231, in check_enableusersite at jnr.posix.JavaPOSIX.geteuid(JavaPOSIX.java:102) at jnr.posix.LazyPOSIX.geteuid(LazyPOSIX.java:115) at org.python.modules.posix.PosixModule.geteuid(PosixModule.java:343) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:45) java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: Could not initialize class jnr.posix.JavaPOSIX$LoginInfo at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:389) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:579) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:265) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:305) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
But then came up the second one which unveils only in Production mode (works in Development mode).
javax.servlet.ServletContext log: Exception while dispatching incoming RPC call com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract com.jythonui.shared.DialogVariables com.jythonui.client.service.JythonService.runAction(com.jythonui.shared.RequestContext,com.jythonui.shared.DialogVariables,java.lang.String,java.lang.String)' threw an unexpected exception: Traceback (most recent call last): File "__pyclasspath__/site$py.class", line 571, inAttribute sys.prefix is None for some mysterious reason. Because debugging in Production mode is impossible the only way was to compile Jython from sources (which is not trivial for the first time), add logging messages and trying to encircle the bug. Finally I realized that in Google App Engine Production mode system property "java.class.path" is null. So the codeFile "__pyclasspath__/site$py.class", line 553, in main File "__pyclasspath__/site$py.class", line 286, in addusersitepackages File "__pyclasspath__/site$py.class", line 261, in getusersitepackages File "__pyclasspath__/site$py.class", line 250, in getuserbase File "__pyclasspath__/sysconfig$py.class", line 112, in File "__pyclasspath__/posixpath$py.class", line 391, in normpath AttributeError: 'NoneType' object has no attribute 'startswith' at com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:389) at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:579) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteService
if (root == null) {
String classpath = preProperties.getProperty("java.class.path");
ll.warning("classpath=" + classpath + "!");
if (classpath != null) {
String lowerCaseClasspath = classpath.toLowerCase();
int jarIndex = lowerCaseClasspath.indexOf(JYTHON_JAR);
if (jarIndex < 0) {
jarIndex = lowerCaseClasspath.indexOf(JYTHON_DEV_JAR);
}
if (jarIndex >= 0) {
int start = classpath.lastIndexOf(File.pathSeparator, jarIndex) + 1;
root = classpath.substring(start, jarIndex);
} else if (jarFileName != null) {
// in case JYTHON_JAR is referenced from a MANIFEST inside another jar on the
// classpath
root = new File(jarFileName).getParent();
}
}
}
if (root == null) {
return null;
}
does not find the root path for Jython libraries. There is a bug in this code because clause:
} else if (jarFileName != null) {
// in case JYTHON_JAR is referenced from a MANIFEST inside another jar on the
// classpath
root = new File(jarFileName).getParent();
}
}
should be placed outside if classpath != null clause (not inside) and root directory cannot be extracted from Jython jar file path as well.Solution
But finally I found the solution and it was simple as usual.
protected PythonInterpreter(PyObject dict, PySystemState systemState, boolean useThreadLocalState) {
if (dict == null) {
dict = Py.newStringMap();
}
globals = dict;
if (systemState == null)
systemState = Py.getSystemState();
this.systemState = systemState;
setSystemState();
this.useThreadLocalState = useThreadLocalState;
if (!useThreadLocalState) {
PyModule module = new PyModule("__main__", dict);
systemState.modules.__setitem__("__main__", module);
}
if (Options.importSite) {
// Ensure site-packages are available
imp.load("site");
}
So it was enough to set Options.importSite = false; before launching PythonInterpreter and the whole stuff related to site.py (useless in Google App Engine restricted environment) is disabled.
wtorek, 15 października 2013
JavaHotel, first version
First version
I uploaded the first version of JavaHotel to Google App Engine. Test version is available: Java hotel for user (U/P user/user) and Java hotel for administrator (U/P admin/admin). Source files are available here. It is Google App Engine version but I'm planning to use it only for demo purpose. Also regular JEE version is created as a primary target. It will be available for Tomcat and Glassfish. Tomcat version is a single web application, Glassfish version is divided into persistence layer available as Session Stateless Bean and business logic layer. It was tested with Derby, Postgress and DB2.
It is the first version and everything is rough. But basic functionality is covered.
Empty places denote free rooms, green booked and yellow with guests currently checked-in. Clicking at the empty place allows to make reservation starting from this day forward, clicking at the green allows to make check-in if customer just arrived and clicking at the yellow gives access to options related to stay (for instance: billing)
Reservation
It is the reservation dialog available after clicking at the empty room. User can modify number of days (default is one), calculate rating and enter the customer data. It is also possible to select the customer from the list of customers already registered.
Check-in
Check-in dialog pops up after clicking at the green (reservation) place. It allows transforming reservation to stay and starting billing the guest. In the check-in dialog it is also possible to register additional guests if the booking was done for more then one person.
Registering additional services
After stay has been started it is possible to append additional services to the stay. User can select a standard service prepared before or add a new services ad-hoc.
Billing
During and after the stay a bill can be issued. It is possible to issue more then one bill for one stay and every bill having a different payer. In the tab panel 'Not paid yet' page contains services not paid yet (without the bill issued for them) and 'All billable' contains the list of all services. The payment can be specified as 'Pay now' or 'Not paid now'. There is also possibility to register payment later for bills not paid now.
Conclusion
It is the first version so everything is basic and rough. But the most important functionality is implemented already. Next steps:
I uploaded the first version of JavaHotel to Google App Engine. Test version is available: Java hotel for user (U/P user/user) and Java hotel for administrator (U/P admin/admin). Source files are available here. It is Google App Engine version but I'm planning to use it only for demo purpose. Also regular JEE version is created as a primary target. It will be available for Tomcat and Glassfish. Tomcat version is a single web application, Glassfish version is divided into persistence layer available as Session Stateless Bean and business logic layer. It was tested with Derby, Postgress and DB2.
It is the first version and everything is rough. But basic functionality is covered.
- Prepare database: hotel, users, room, services, pricelist
- Reservation panel
- Booking
- Check-in
- Registering additional services during the stay
- Billing
Reservation panel
Empty places denote free rooms, green booked and yellow with guests currently checked-in. Clicking at the empty place allows to make reservation starting from this day forward, clicking at the green allows to make check-in if customer just arrived and clicking at the yellow gives access to options related to stay (for instance: billing)
Reservation
It is the reservation dialog available after clicking at the empty room. User can modify number of days (default is one), calculate rating and enter the customer data. It is also possible to select the customer from the list of customers already registered.
Check-in
Check-in dialog pops up after clicking at the green (reservation) place. It allows transforming reservation to stay and starting billing the guest. In the check-in dialog it is also possible to register additional guests if the booking was done for more then one person.
Registering additional services
After stay has been started it is possible to append additional services to the stay. User can select a standard service prepared before or add a new services ad-hoc.
Billing
During and after the stay a bill can be issued. It is possible to issue more then one bill for one stay and every bill having a different payer. In the tab panel 'Not paid yet' page contains services not paid yet (without the bill issued for them) and 'All billable' contains the list of all services. The payment can be specified as 'Pay now' or 'Not paid now'. There is also possibility to register payment later for bills not paid now.
Conclusion
It is the first version so everything is basic and rough. But the most important functionality is implemented already. Next steps:
- Booking of more then one room, searching. For instance: implement scenario like: "Find the first available reservation for 5 persons: two double rooms and one single".
- Issuing and printing the invoice.
- Synchronization with calendar. Alerts when reservation or stay expires.
niedziela, 22 września 2013
MVP framework, new features
Introduction
I added several enhancements to the MVP Jython framework. Source code is available here, sample application developed for Google App Engine can be launched using this web URL.
New types of main menu
So far only left side list of button has been available. Two new types of main menus have been added: "Up" menu and stack menu. "Up" menu is nothing more then image at the top status bar which expands after clicking giving a list of choices. Stack menu is an implementation of GWT StackPanel. "Up" menu can coexist with tab menu and stack menu but stack menu and tab menu excludes each otther. An example of stack menu is available here. More technical description.
"Up" menu
Stack menu
Image column
Image column contains icon or list of icons instead of text or number. Image list can be static or dynamic. In the second case a JavaScript code is executed to determine the list of images displayed depending on the row content. More detailed description. Icons plays also a role of buttons. After user clicks the icon a Jython server side action is raised. This way it is possible to implement an action depending on the row content and which icon has been clicked.
A running example is available here. Click "up" menu -> "List with icon". The up arrow is displayed for positive number and down arror for negative number. Left and right arrow is displayed depending if number is odd or even.
Different type for column and footer
As a default the footer type (and other properties like align and decimal position) are copied from column type. But it is possible to change this behavior.
A running example is available here. "Status" -> "List footer". The footer is under string column but the footer content is a number. Also align schema is different. More detailed description is available here.
Other changes
I added several enhancements to the MVP Jython framework. Source code is available here, sample application developed for Google App Engine can be launched using this web URL.
New types of main menu
So far only left side list of button has been available. Two new types of main menus have been added: "Up" menu and stack menu. "Up" menu is nothing more then image at the top status bar which expands after clicking giving a list of choices. Stack menu is an implementation of GWT StackPanel. "Up" menu can coexist with tab menu and stack menu but stack menu and tab menu excludes each otther. An example of stack menu is available here. More technical description.
"Up" menu
Stack menu
Image column
Image column contains icon or list of icons instead of text or number. Image list can be static or dynamic. In the second case a JavaScript code is executed to determine the list of images displayed depending on the row content. More detailed description. Icons plays also a role of buttons. After user clicks the icon a Jython server side action is raised. This way it is possible to implement an action depending on the row content and which icon has been clicked.
Different type for column and footer
As a default the footer type (and other properties like align and decimal position) are copied from column type. But it is possible to change this behavior.
A running example is available here. "Status" -> "List footer". The footer is under string column but the footer content is a number. Also align schema is different. More detailed description is available here.
Other changes
- Dynamically modify the content of the status bar. The the status bar content can be customized depending on the context. More detailed description is available here. Running example can be launched. "Status" - > "Status text".
- Load tab panel page on demand. An action is raised after clicking the page header. This way the tab panel page can be modified dynamically. More detailed description.
- XML usage. XML format is often connected with love-hate relationship. But it is very convenient if data schema is not stable or can be changed. It is also very convenient if we want to pack a lot information in one entry without creating a table with tens or hundreds of columns. So I added some automation for packing and unpacking forms using XML file. More information is available here. A running example (although nothing spectacular is visible) can be launched here. Click on "Dialog base xml".
niedziela, 24 marca 2013
MVC (MVP) framework, the show must go on
MVP framewok
I created the next version of Jython/GWT MVC framework. But I would rather call it following MVP (not MVC) framework. Current demo version (Google App Engine implementation) is available here. The demo was also tested with Tomcat and Glassfish. Prerequisite: Derby database (should be available somewhere in tha class path). Instruction how to setup Eclipse project is available here. Pom.xml file (maven) will be provided later. Current state of art is described here.
General description
The general structure is presented below :
I created the next version of Jython/GWT MVC framework. But I would rather call it following MVP (not MVC) framework. Current demo version (Google App Engine implementation) is available here. The demo was also tested with Tomcat and Glassfish. Prerequisite: Derby database (should be available somewhere in tha class path). Instruction how to setup Eclipse project is available here. Pom.xml file (maven) will be provided later. Current state of art is described here.
General description
The general structure is presented below :
- VIEW part. Based on GWT. Consisting of two packages. GWT UI and Jython UI. Creates UI components and interacts with PRESENTER via server Java code.
- DTO (Data Transient Objects). Transfers data between client (browser) side and server side. It is simple Java maps and lists of maps (as rows). Java shared (shared between GWT and server code) code (the same for application data and XML metadata) is available here.
- Server side Java code. Receiver of GWT RPC calls. Adapter between client (browser) side and PRESENTER Jython code. Transform Java maps and list to Jython data structures (dictionary and sequences) and vice versa. Source code.
- MODEL. Jython dictionaries and sequences of dictionaries (rows). Carriers of data between application code and VIEW part.
- PRESENTER. Jython code, application logic. Responses to the client action, sends data to background database and extracts data. Sample application code.
- XML metadata. Is used by VIEW to create UI widgets and objects. Sample data is available here.
Features implemented so far
- Reading lists in pages (chunks). It is necessary for big lists (of course - it depends what one means by "big").
- Alert and error windows messages.
- Simple data validation at the client side (more complicated validation should be performed at the application-Jython code).
- Additional UI widgets: date and time picker, rich text format, mulitline editing.
- Confirmation for add/delete/change CRUD actions.
- Custom helpers, also "select" tag.
Testing
GUI testing (additionally to JUnit tests). GUI testing is performed by Selenium extension to BoaTester. The 'selenium' best test cases are available here.
Next step
Next step is to implement security: authorization and authentication. I plan to use Apache Shiro. It is simple and seems to cover all topic necessary here.
wtorek, 22 stycznia 2013
Just another MVC framework
Introduction
I came to the conclusion that creating Web interface (even if one uses GWT) is complicated and dotted with problems so I decided to create next MVC framework utilizing what I have done so far. There are plenty of MVC frameworks so why create next one instead of using existing already.
I do not know but I really like the idea of having separated UI and business rule, Web/AJAX approach allowing interaction to every user action (not only submit/response) and rich programming language to create business rule with full access to all background environment (datastore). "Programming language" on one hand simple enough without all Java/C++ bargains like interfaces/headers/declarations but on the other hand rich enough to do what you want, "hot deployment" during development, modify source code and framework runs it immediately. Cutting long story short - I mean Python/Jython. And also do not bother with all details related Web/Ajax programming especially asynchronous requests and responses. And also ready to run on any Web container and interacting with any database.
Source code for the first version of framework is available here (Cache, GwtUI, JythonUI, Test). Source code for the first sample application is available here. Sample CRUD application is deployed to Google App Engine infrastructure. Also Tomcat (not Google App Engine) application has been created. How to assemble Tomcat (and Junit test) Eclipse project is described in this document.
General idea
I came to the conclusion that creating Web interface (even if one uses GWT) is complicated and dotted with problems so I decided to create next MVC framework utilizing what I have done so far. There are plenty of MVC frameworks so why create next one instead of using existing already.
I do not know but I really like the idea of having separated UI and business rule, Web/AJAX approach allowing interaction to every user action (not only submit/response) and rich programming language to create business rule with full access to all background environment (datastore). "Programming language" on one hand simple enough without all Java/C++ bargains like interfaces/headers/declarations but on the other hand rich enough to do what you want, "hot deployment" during development, modify source code and framework runs it immediately. Cutting long story short - I mean Python/Jython. And also do not bother with all details related Web/Ajax programming especially asynchronous requests and responses. And also ready to run on any Web container and interacting with any database.
Source code for the first version of framework is available here (Cache, GwtUI, JythonUI, Test). Source code for the first sample application is available here. Sample CRUD application is deployed to Google App Engine infrastructure. Also Tomcat (not Google App Engine) application has been created. How to assemble Tomcat (and Junit test) Eclipse project is described in this document.
General idea
- User interfaces are described in XML document. Current xsd schema file is available here. Sample xml user interfaces definition file for CRUD application is available here. Framework provides default layout but it is planned to add also the possibility to specify HTMLPanel for more rich layout.
- There are four user action for CRUD dialog : read all records, add new, remove and modify. There is also special "before" action for the form initialization. For every user action a Jython script is called on the server side. Sample Jython script is available here. The current field values (Web form) are available for Jython script as map/dictionary (pairs: "key"->"value", "field name" -> "field value"). Jython script should recognize user action ("action" parameter in "dialogaction" method), read current field values and perform server action. For "add" action add new record to datastore. It is also possible to return error message (for instance key is duplicated). Results are also stored as Jython dictionary.
- Server side of the framework translates again Jython dictionary to Java Map and sends this map back to the client.
- Client reads the answer and performs next actions. For instance displays error message in case of error, refresh list in case of success, navigate to next dialog etc.
- For the time being very limited subset of actions and user interface widgets are implemented but it will be enhanced gradually.
- Developing client application with this framework means adding new XML documents and developing business logic with Jython scripts. Database access can be achieved via Jython directly or (like in the sample application) by creating Java DAO (Data Access Objects). Jython can interact with Java smoothly so any method is feasible.
Framework structure, source code
- GwtUI. There are three packages: client code, server code and shared (between client and server) code. It is a framework interacting directly with GWT. Is is based on publish/subscribe pattern I found well fitted for asynchronous nature of Ajax applications. It adds a logic for displaying and executing forms, lists, menus, CRUD lists etc. Firstly I wanted to develop client application by using this framework directly but after some time and developing a lot of code I realized that it was too complicated.
- JythonUI. Consists of three packages: client code, server code and shared code. Is based on GwtUI (does not interact with GWT directly) and provides interaction between XML documents and Jython user actions.
- Cache : Support for GAE MemCache. Allows using JCache in application. For Tomcat application there is a simple Map implementation.
- Test : Meaningful implementation is only for Google App Engine JUnit tests. Allows creating the same JUnit test suite for Google App Engine datastore and JPA implementation.
Third party tools
- Jython. Interpreted language for developing server side business logic. During development Jython code can be modified directly and being effective immediately without any recompiling, one can call it hot reloading. For production Jython can be translated to byte code and executed directly without recompiling. JythonUI server code translates Java Map to Jython dictionary and vice versa.
- Guice. Although now it ties together only several modules (sample AbstractModule) I found it very useful. For every four applications (WebGooleAppEngine, WebTomcat, JunitTestGoogleAppEngine and JUnitJPA) I created separated AbstractModule and this way I was able to put together all pieces. For instance: provide JPA implementation for datastore in case of JPA application and Google App Engine implementation of the same datastore for Google App Engine application.
- GIN (GWT INjection) : Code injection framework for GWT. Used intensively in GwtUI.
Third party tools used for Sample application
- Objectify : I decided to use Objectify instead of JPA/JDO Google App Engine implementation. I fully agree with a simple statement found here: " The GAE datastore is not an RDBMS" and found that Objectify is a good answer to that issue. The general idea behind JPA/JDO is that we put simple interface on more complex RBDM/JDBC concept. But in case of Google App Engine it is just opposite : JPA/JDO is something more complicated put on something simple: NoSQL key/value database.
- EclipseLink : Outside Google App Engine world I still think that traditional RDBS is a good choice and JPA layer gives a lot of advantages comparing to bare JDBC.
- Apache Derby : Good choice in case of testing or developing. Does not require installing or tuning, just put derby.jar everywhere on java class path, create URL, connect and use it.
Future development
It is only the first stage, "proof of concept". It looks promising I created fully tested two (simple) web applications for Google App Engine and Tomcat (JPA/RDBS). Future development means enabling more GWT widgets and user actions. I'm also planning to extend business logic programming by adding more JVM bases languages, Java and also add bridge to CPython (by means of JNI).
Problems
The most important problem is running Jython on Google App Engine. Because Google App Engine can create a new JVM at any time so also Jython should be initialized. It means very long delays unexpectedly (10-15 sec) which makes all solution almost useless. For Tomcat based application it is only a delay once at the beginning of the session and then it runs smoothly all the time. I will try to understand what is the reason for this delay, may be deployment of already compiled Jython packages will resolve the problem.
wtorek, 8 stycznia 2013
Google App Engine and Jython
Introduction
I'm planning to use Jython with Google App Engine for Java. My purpose is to use Jython as a scripting language for Java based solution, not to use Jython for server code development. I was interested to check if I can launch Jython (Python) packages at the server side. It was successful but with several drawbacks. The source code (Java and simple Jython package) is uploaded. The application (simple extension to default Eclipse plugin application) is available here.
Problem, strange behaviour in Development Mode
While running the application in Development Mode the following exception was thrown
The following exception is also thrown
Performance
F1, F2 and F4 are described here.
Moment 3-4 is related to the compiling of the junit package and can be improved by precompiling the jython package before deploying. Moment 1-2 is the time consumed by the initialization of the Jython. I do not understand why there is a such difference between local desktop and Google App Engine environment and do not see any solution to that problem.
I'm planning to use Jython with Google App Engine for Java. My purpose is to use Jython as a scripting language for Java based solution, not to use Jython for server code development. I was interested to check if I can launch Jython (Python) packages at the server side. It was successful but with several drawbacks. The source code (Java and simple Jython package) is uploaded. The application (simple extension to default Eclipse plugin application) is available here.
Problem, strange behaviour in Development Mode
While running the application in Development Mode the following exception was thrown
Caused by: java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google App Engine developer's guide for more details. at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51) at org.python.core.io.StreamIO.getOutputFileDescriptor(StreamIO.java:205) at org.python.core.io.StreamIO.getOutputFileDescriptor(StreamIO.java:212) at org.python.core.io.StreamIO.getOutputFileDescriptor(StreamIO.java:212)I found that the culprit is the following method in PySystemState.java
private void initEncoding() {
String encoding = registry.getProperty(PYTHON_CONSOLE_ENCODING);
if (encoding == null) {
return;
}
for (PyFile stdStream : new PyFile[] {(PyFile)this.stdin, (PyFile)this.stdout,
(PyFile)this.stderr}) {
if (stdStream.isatty()) {
stdStream.encoding = encoding;
}
}
}
The java.io.FileOutputStream is not on the Google App Engine "white list" but the same code is running after deploying to Google App Engine environment.
The solution is to remove file.encoding property (although this property is set to not null value in Google App Engine).
System.getProperties().remove("file.encoding");
Not blocking exception The following exception is also thrown
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThreadGroup) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:289) at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkAccess(DevAppServerFactory.java:314) at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:299) at java.lang.Thread.init(Thread.java:336) at java.lang.Thread.It seems to be related to the fact that threads are not allowed in Google App Engine. But this exceptions seems to be not blocking.(Thread.java:462)
Performance
static String getrVal() {
putMessage("Moment 1");
String encoding = System.getProperty("file.encoding");
putMessage("Encoding:" + encoding);
System.getProperties().remove("file.encoding");
PythonInterpreter interp = new PythonInterpreter();
URL ur = JythonMeth.class.getClassLoader().getResource("resource");
String sRe = ur.getFile();
interp.exec("import sys");
interp.exec("print sys.path");
interp.exec("sys.path.append('" + sRe + "')");
interp.exec("import sys");
interp.exec("print sys.path");
putMessage("Moment 2");
interp.exec("import mypack");
putMessage("Moment 3");
interp.exec("from mypack import myprint");
putMessage("Moment 4");
interp.exec("myprint.myprint()");
putMessage("Moment 5");
interp.exec("GG = myprint.getVal()");
PyObject sy = interp.get("GG");
PyString u = (PyString) sy;
String ss = u.getString();
putMessage(ss);
Map<object pyobject="pyobject"> m = new HashMap<object pyobject="pyobject">();
PyObject keyS = new PyString("value1");
m.put("key1", keyS);
keyS = new PyString("value2");
m.put("key2", keyS);
keyS = new PyString("value3");
m.put("key3", keyS);
PyStringMap pyMap = new PyStringMap(m);
interp.set("GG", pyMap);
interp.exec("myprint.myprintMap(GG)");
return ss;
}
The performance after deploying to Google App Engine is not satisfactory. But it depends on the machine type set as a host. This time table is related only when server is running the code for the first time, the second and the next are executed in no time. But in case of Google App Engine a request can be redirected to a fresh machine any time, so this problem really matters.
| Machine | Moment 1-2 (sec) | Moment 3-4 (sec) |
|---|---|---|
| F1 | 11 | 6 |
| F2 | 7 | 6 |
| F4 | 5 | 3 |
| Desktop | 2 | 4 |
Subskrybuj:
Posty (Atom)











