Monday, 14 September 2009

Making GWT urls pretty

We've been working on an GWT application for sometime. The url always ended up as

http://server/context/package.name.Application/index.jsp

This is quite ugly. After a little searching, I managed to find this post. The post itself suggests one fix, but in the comments the following tip was outlined.

"Yeah, alternatively you can use the rename-to attribute to pushing the FooModule.gwt.xml down to the root directory."

So expanding that a little, edit the Application.gwt.xml file, adding an attribute to the module token. My entry ended up as 

<module rename-to="gwtFcg">

This changed the application url to the following, which is much prettier

http://server/context/gwtMyName/index.jsp

Thursday, 3 September 2009

Using JMeter with GWT

I have tried to use JMeter to load test a GWT application. I recorded the script, but when I replayed it, all the GWT calls failed. I couldn't find much to help on the internet. Eventually I came up with the following solution

  1. Create a top level thread group. 
  2. Create a child simple controller and add samplers to fetch all the GWT files
  3. Create a second child simple controller. To this add a HTTP Header Manager. In this, add an entry for "Content-Type" with a value of "text/x-gwt-rpc; charset=utf-8". To this controller add all the GWT rpc calls
  4. For any further http traffic calls, add more simple controllers to contain the samplers
The header manager ensures that all http samplers at that level, send the given headers. In this case is corrects the content type for all GWT RPC calls, allowing them to work. You still need to split GWT RPC calls from "normal" http traffic by keeping each in their own controller.

With that done, the jmeter script worked as required. Now I just have to fix the application code ;-)

Update: if you record the interactions, some client posts may contain thestring \\. Java tries to interpret this, so you will have to update this to be \\\\. I found this easiest to do by saving the jmeter script, opening a test editor and then using search/replace

Moving from GWT v1.5.2 to v1.6 or v1.7

I recently tried to move from GWT v1.5.2 to v1.7. To do this, I followed the steps outlined in the release notes. However I hit a snag when trying to run in hosted mode. The hosted mode kept complaining that the web.xml couldn't be found. The message indicated that it was looking for the file in 'war\WEB-INF\web.xml'.

We use maven for our build process, and to make GWT and maven play nicely, you need to use the undocumented switch -war. So the arguments for the hosted mode become

-noserver -war src/main/webapp -startupUrl http://localhost:8087/app

Wednesday, 2 September 2009

Oracle XE Concurrent Connection Problem

I was hitting a problem with an application connecting to an oracle XE database. Over intermittant periods of time, the application would be unable to connect to the database anymore, throwing the following exception.

ORA-12519: TNS:no appropriate service handler found 

Issuing the following command

lsnrctl services

Showed other stuff and the following important line

Service "xe" has 1 instance(s).
  Instance "xe", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:688 refused:0 state:blocked
         LOCAL SERVER

I googled around a lot, and the best answer I could come up with was on an Oracle forum. It essentially said that the oracle process tells the listener how many connections are available, and then every now and again it tells the listener when connections have been closed. So the problem will manifest itself if a lot of connections are opened before the database tells the listener about the closures. By default in Oracle XE, 40 connections are allowed, which after accounting for background processes leaves 19 client connections.

So the solutions that I could come up with

1) Not use Oracle - moving to MySQL should remove  this problem, but may introduce others ;-)
2) The real fix would be to stop the client from creating too many connections via a connection pool. Depending on the application, this may or may not be possible
3) A quick fix to mask the problem would be to alter the number of allowed processes via issuing the following command as sysdba, and the restarting the database and listener

ALTER SYSTEM SET PROCESSES=150 SCOPE=SPFILE