Tuesday, May 29, 2012

Some Errors / Solutions down the way

appengine-web.xml does not contain a <threadsafe> element
Error
SEVERE: Received exception processing C:\Users\CA-DT\Documents\Eclipse Projects\loyaltycard\war\WEB-INF/appengine-web.xml
com.google.apphosting.utils.config.AppEngineConfigException: appengine-web.xml does not contain a <threadsafe> element.
See http://code.google.com/appengine/docs/java/config/appconfig.html#Using_Concurrent_Requests for more information.
You probably want to enable concurrent requests.

Description
http://code.google.com/appengine/docs/java/config/appconfig.html#Using_Concurrent_Requests

Solution
Add <threadsafe>true</threadsafe> to your war/WEB-INF/appengine-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">

    <application></application>
    <version>1</version>
    <threadsafe>true</threadsafe>


WARNING: failed _ah_ServeBlobFilter: java.lang.ClassCastException
Error 
WARNING: failed _ah_ServeBlobFilter: java.lang.ClassCastException: com.google.appengine.tools.development.ApiProxyLocalImpl cannot be cast to com.google.appengine.tools.development.ApiProxyLocal

Description
  • appengine-api-labs 
  • appengine-api-stubs 
  • appengine-testing

The above mentioned files shouldn't be in the war/WEB-INF/lib directory. They are only thought as test libraries needed during Unit tests. 

Solution
  • Delete the files from the classpath.
  • Put the files in to another location such as c:\GWTTestLibs.
  • Add the files to the classpath as External Jars

The App Engine SDK 'C:\<workspace path>\<project name>\war' on the project's build path is not valid
Error
The App Engine SDK 'C:\<workspace path>\<project name>\war' on the project's build path is not valid

Description
There is a problem in the latest GAE plugin which prevents this from working. If you get an error like "The App Engine SDK 'C:\<workspace path>\<project name>\war' on the project's build path is not valid" proceed with following solution below.

Solution
  1. Open preferences -> Google -> App Engine and select the sdk version again
  2. Open preference -> Java Build Path -> Export Order. Change the Export order so that the App Engine SDK is ABOVE the "Web App Libraries" classpath container.

Implementing Jersey (JAX-RS) in to a GWT application

Goal
I want to build my GWT project using a Jersey (JAX-RS) backend to decouple the Client from the Server and to allow different kind of Clients (developed in all kind of languages) to connect to my application

This tutorial is based on Eclipse as it is the only client supported by GWT currently. I have read that there can be difficulties using Maven. Hence these instructions are following the manual (official) way how to add third party server side libraries.

Create a new GWTP Project
First thing you have to do is to create a new GWTP (GWT-Platform) project. Don't tick the creation of sample code.

Add Jersey (and dependent) Libraries
The following libraries have to be downloaded and added to the war/WEB-INF/lib directory:
It is important to take the same Versions for the jersey-core, jersey-server and jersey-json JARs. Otherwise you can get errors during execution.

Add Libraries to the Classpath
  • Right click on to the application in Eclipse
  • Choose Properties
  • Choose Java Build Path
  • Choose Libraries
  • Click on to Add Jar 
  • Select all the Jar files from above (jersey-core, jersey-server, jersey-json and asm)
  • Click Ok to add them to the build path

Create a new Resources Java Package
  • Right click on to the src folder within Eclipse
  • Choose New -> Package
  • Insert your Package name: com.yourcompany.yourapp.resources

Add necessary lines to web.xml
You need to add some lines to web.xml. You need to initialize some Jersey related stuff but what is especially important that you add the package path and the url-pattern.

When starting your GWT application in it's default configuration you should be able to execute a servlet over the path http://127.0.0.1:8888/api/<Resource>.

web.xml
    <!--
        The below lines are implementing Jersey (JAX-RS) in to the GWT application.
     -->
     <servlet>
        <servlet-name>Jersey</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
            <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
        </init-param>       
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>com.yourcompany.yourapp.resources</param-value>
        </init-param>        
    </servlet>
   
    <servlet-mapping>
        <servlet-name>Jersey</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

Create a Hello Resource
Right click on to the package com.yourcompany.yourapp.resources
Choose New -> Class
Name your Class HelloResource.java

HelloResource.java
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class HelloResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHello() {
        return "Hello Jersey";
    }
}

Once finished you should be able to run the application as Webapplication.
Right click on to your application
Choose Run As -> Google Web Application

Please note that the default URL will not work as there haven't been any GWT Presenters implemented. But you should now be able to open following URL: http://127.0.0.1:8888/api/hello.