Mittwoch, 29. Juni 2011

"An internal error occurred while showing an internal error"

What a great error-message showed up while doing some trivial work with eclipse helios! It made me think about recursions (remember: before you can understand recursions you first need to understand recursions).
My first reaction on the question "Do you want to exit the workbench?" was (after making a screenshot) pressing "No". I hoped to see an error-message like that: "An internal error occurred while showing an internal error while showing an internal error".
But i did not see that message - eclipse presented the "white bar of death" and silently stopped working ...

Mittwoch, 15. Juni 2011

JTalk Server now using Backends on Google App Engine

My JTalk-Server project has some interesting new features. First of all: i'm using Google Backends to handle the Javascript scope on the server-side. Backends are a new feature of the Google App Engine 1.5. and allow the usage of long-running processes in the background.
Now i have two servlets - the original JTalk-Servlet for saving the jtalk.js or resetting etc. and second one, the backend servlet for executing smalltalk code on the server and for maintaining a user session.
The main cause for using backends was that the ScriptEngine for executing Javascript was not serializable, so it was necessary to setup the JTalk environment for every server roundtrip.
The call to the backend looks like that:
        BackendService backendsApi = BackendServiceFactory.getBackendService();
        String rhinoscopeURL = "http://" + backendsApi.getBackendAddress("rhinoscope", 0) + "/jtalk_backend";
        System.out.println(("rhinoscopeURL: " + rhinoscopeURL));

        URLFetchService fetchService = URLFetchServiceFactory.getURLFetchService();
        HTTPRequest requestToBackend = new HTTPRequest(new URL(rhinoscopeURL), HTTPMethod.POST);
        requestToBackend.setPayload(("contentString=" + contentString + "&owner=" + owner + "&commandString="+commandString).getBytes());

        HTTPResponse responseFromBackend = fetchService.fetch(requestToBackend);
        byte[] respContent = responseFromBackend.getContent();

        String resultString = new String(respContent);

The full code is available here.

As mentioned in this thread, backends on GAE only work in production-mode by using the appcfg.cmd:
e_1.5.0.r35v201105092302\appengine-java-sdk-1.5.0\bin>appcfg.cmd backends update
 "C:\Documents and Settings\krecher\My Documents\workspace\jtalk-server\war"
Otherwise the backends won't appear in the admin-console of the GAE.
In development mode the existence of a backends.xml is enough for using backends.

Another new feature is the possibility to pass arguments to the RemoteRunner. Without passing arguments from the client to the server that whole thing would be completly useless ...

A call with arguments would look like that:

RemoteRunner new runClass: RemoteTest3 with: #('hack' 'the' 'planet')

The arguments should be an array of strings.

The last new feature ist the usage of a logger in the Javascript-Scope on the server-side.
Here an excerpt from the example class: params do: [ :each | {'logger.fine(each);'} ].
logger is the logger-instance of the servlet.

If you want to use these new features, and you've used the JTalk Server on GAE before, remember to first press the Reset-button and then press "Export & Save JTalk to DB".

I guess the next step will be to implement a binding for the google-datastore-api.