Showing posts with label Eclipse. Show all posts
Showing posts with label Eclipse. Show all posts

Friday, November 9, 2012

EclipseLink logging with Arquillian in Eclipse

I have been doing some experimentation with Arquillian for testing my refactored J2EE application in embedded glassfish. I really like it so far, but I ran into an issue where me test-persistence.xml file use did not see to provide anything more than SERVERE level logging from eclipselink. I had tried setting the property
<property name="eclipselink.logging.logger" value="DefaultLogger"/>

to no avail. I also set this value to JavaLogger without results. I finally stumbled across an answer while looking into changing the embedded glassfish http port - and that is to use the following value:

<property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.DefaultSessionLog"/>

This allows me to see the SQL statements (assuming your set the other log values) in both Eclipse and through the maven command line test execution.

Sunday, March 1, 2009

GWT and Google App Engine - How to develop!

So I have developed an application in GWT using the GXT library which is currently connecting to a Restful WebService through Tomcat and using JPA to access my MySQL Database. I recently had a disk failure on this system, and so have become acutely aware of the possibility at some point I might want to have my application hosted.

I was looking at the Google App Engine, and wanted to experiment with it. The problem is, there are blogs talking about putting your GWT application onto a GAE app, but how do you develop the app on your local box and communicate with either a local or remote GAE application? You can develop the GAE in eclipse and run it locally, but there is currently no way to embed GAE apps in your hosted mode browser for GWT. As well, by default the GWT app sandbox does not allow you connect to a site outside of the site hosting the GWT app. My requirements were simple:
  1. Develop a GAE application in Eclipse and run the server locally.
  2. Continue to develop my GWT Application in eclipse connecting to my existing server.
  3. Be able to connect my GWT Application to a GAE application, with the intent to later deploy it on that application (therefore request url should remain the same).
  4. (Optionally) - "replace" a web-service running on my server with a GAE application service.

The way to do this, is to insert a redirect filter in the embedded tomcat run within the GWTShell to send any requests matching a particular syntax to the GAE application. This actually worked surprisingly well. The filter I am using was one I found after a quick search, I came across the HttpRedirectFilter. This didn't take much at all to configure and voila I am off to the races. The general strategy here, is you can use this redirect filter to forward requests to the GAE application while in development. Upon compilation of your GWT application you can bundle it with the GAE application (see Configuring Eclipse on Windows to Use With Google App Engine) and deploy this to Google. In my case, I can still have features hosted locally and as I convert a Restful Resource to GAE I can use the Redirect Filter to redirect the request to GAE. Once everything is converted, I can stop supporting my Jersey-based application and use the pure GAE app. At this point, I am purely in the evaluation stage of GAE, but it was a non-starter if I was not going to be able to concurrently develop a GWT and GAE applications together. This method gives me this ability to experiment with this. As well, you could concievably use this technique to develop a pure GAE application, by just providing the redirect filter in your web.xml configuration.

As an example of the redirectfilter.xml I am using, I configured a new fictious resource testpy to be redirected to my helloworld GAE application on port 9998 on my local machine. Since I had to read the source code provided in the HttpRequestFilter to get this to work, I figured I would show what my file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE redirect-filter PUBLIC "-//zlatkovic.com//DTD RedirectFilter 2.0//EN" "http://www.zlatkovic.com/dtd/redirect-filter-2.0.dtd">
<redirect-filter>

 <redirect match="/StampWeb/resources/testpy$" target="http://localhost:9998/helloworld" remote-address="127.0.0.1/255.0.0.0"/>
 
</redirect-filter>


My web.xml configuration look like the following (Note: I am currenly filtering everything, but you could easily configure it just for the resources that are on the GAE application):

   <filter>
        <filter-name>HttpRedirectFilter</filter-name>
        <filter-class>com.zlatkovic.servlet.RedirectFilter</filter-class>
        <init-param>
         <param-name>configFile</param-name>
         <param-value>/WEB-INF/redirectfilter.xml</param-value>
        </init-param>
        <init-param>
         <param-name>reloadConfig</param-name>
         <param-value>true</param-value>
        </init-param>
        <init-param>
         <param-name>logRedirects</param-name>
         <param-value>true</param-value>
        </init-param>
   </filter>
   <filter-mapping>
     <filter-name>HttpRedirectFilter</filter-name>
     <url-pattern>/*</url-pattern>
   </filter-mapping>

Friday, October 3, 2008

Deploying RestEasy in Tomcat 6.0

Since I was successful deploying Jersey to Tomcat 6.0, I decided to check out RestEasy from JBoss. One issue I ran into with Jersey was it's inability to XML serialize a collection of objects. This is bug ID is 18, and it is fixed for the 1.0 release (however a beta of this does not appear to be available yet), but I decided to see if RestEasy (a non-reference implementation) has the same issue.

UPDATE I have discovered from some testing that neither XML nor JSON is currently supported as a return type for a Collection/List of items. An issue has been filed for RestEasy for JSON (RESTEASY-134) with an RC1 delivery, however I did not see one for XML.

Here are the steps I used to get this working:

  1. Download RestEasy from the JBoss website: http://www.jboss.org/resteasy/
  2. Follow the steps 2 to 4 of my previous blog Deploying Jersey in Tomcat 6.0
  3. Download and create a Eclipse library for JavaAssist. Include this in your WEB project (or provide the javaassist.jar for Tomcat)
  4. Create a new RestEasy library in eclipse which contains the content of the rest easy installation lib location. You can probably skip a few of the jars if you do not need all the functionality (such as jyaml.jar and possibly mail.jar)
  5. Modify your web.xml for your project to include the following (this comes right from the sample web.xml in the rest easy install):

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>TestWeb</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <!-- set this if you map the Resteasy servlet to something other than /* <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/resteasy</param-value> </context-param> --> <!-- if you are using Spring, Seam or EJB as your component model, remove the ResourceMethodSecurityInterceptor --> <context-param> <param-name>resteasy.resource.method-interceptors</param-name> <param-value> org.jboss.resteasy.core.ResourceMethodSecurityInterceptor </param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
  6. Start your tomcat in Eclipse and you should be good to go!

Thursday, October 2, 2008

Deploying Jersey in Tomcat 6.0

Jersey is a reference implementation for the JAX-RS (JSR-311) for building RESTful Web services. It is nearing approval with the JSR committees. While there are many wikis and articles in using Jersey with Netbeans (downloading the Netbeans 6.1 EE package includes everything you need for JSR-311), there was very little information on using Tomcat 6.0 with Jersey. After piecing together several blogs, I was able to get a simple resource working in Tomcat using JSR-311.

The following are the steps I used to get this working:

  1. Download and unjar the Jersey distribution (I used 0.8) from https://jersey.dev.java.net/ to a location on your system (lets call it JERSEY_HOME for this article).
  2. Download and install the Java-WS distribution (I used 2.1) from https://jax-ws.dev.java.net/. (lets call it JAXWS_HOME for this article).
  3. Rama Pulavarthi wrote a blog (in fact the key for me) in configuring tomcat to reference the Jersey distribution jars. To summarize, in TOMCAT_HOME/conf/catalina.properties modify the shared.loader property entry to point to your JAXWS_HOME/lib/*.jar. Mine looks like this:

    shared.loader=C:/dev/jaxws-ri/lib/*.jar
  4. Create a new Dynamic Web Project in Eclipse using Tomcat 6.0 as the application server.
  5. Create a new library in which you add the following JARs:
    1. JERSEY_HOME/lib/asm-3.1.jar
    2. JERSEY_HOME/lib/jersey.jar
    3. JERSEY_HOME/lib/jsr311-api.jar
  6. Next modify the web.xml to include the adaptor for jersey. Most of the Blogs refer to a different class than what appears in 0.8 I am not certain which is the right class, only the following works for me (and the documented one is not available throught the downloads!):

    <servlet> <servlet-name>ServletAdaptor</servlet-name> <servlet-class>com.sun.jersey.impl.container.servlet.ServletAdaptor</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ServletAdaptor</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config>
  7. If you start Tomcat, you will see the following error:

    com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.

    This error is due to not providing any root RESTful resources.

  8. Create a new class and include the following:

    import javax.ws.rs.GET; import javax.ws.rs.ProduceMime; import javax.ws.rs.Path; @Path("/test") public class TestResource { @GET @ProduceMime("text/html") public String getMessage( ) { return "hello"; } }
  9. Start and test the application with the following url:

    http://localhost:8080/appName/resources/test

    and you should see a hello in your web-browser.

Sunday, July 27, 2008

Automatically recording Create/Update Timestamps with JPA

Now that I am using Bugzilla to track various bugs and enhancements for my projects, I finally got around to addressing this issue of "Provide the ability to record the create/update timestamp." for my stamp objects. This seems simple enough, and most database applications record this information, however by default this is not something that is automated by the JPA frameworks (unlike the Primary Key with the @Id annotation). Let us first examine the ways we could accomplish this:
  1. Provide a database trigger to try and insert the timestamps automatically.
  2. Manually set them (or have each persistent service set them) before performing a persist() operation with an EntityManager.
  3. Use aspects to dynamically insert the timestamp.
  4. Provide an EntityListener which automatically sets the creation/modification timestamp at persist time
  5. .

Obviously the first solution is very database specific and is not really tied to the JPA code. The second solution is likely to be error prone and easily missed. The final solution is the best way to handle his. Daniel Pfeifer provides an excellent walkthrough of this technique in his blog here. I have a few comments on this. First off, the concept of an entity listener, does not follow the normal "implement this interface" convention. An entity listener is any POJO class which contains one or more methods in the format:
public void someMethod( Object obj )


It should be noted that there are javax.persistence annotations for each of the JPA lifecycle states. In the case of create timestamps, annotating a method with @PrePersist will allow it to be used to provide the creation timestamp. For the modify timestamp, annotating a method with @PreUpdate will call this method on persisting an entity which was previously persisted. The entity listener can be registered either in the orm.xml file (as described by Daniel Pfeifer) or one the Entity class itself using the annotation @EntityListeners( class ... ). Personally I prefer this technique as it allows me to programatically tie a class with its behavior (such as storing timestamps on create/update) without having an external configuration. Using an external configuration in several modules, and unit tests quickly becomes muttled in that you forget to update the file under test etc. It also increases the developer's awareness of this association, and to be candid, it is unlikely that I really want to swap out the persistence timestamp handling at package time with a different solution. Since the annotation is applied to an abstract @MappedSuperClass annotated class, any implementing classes will automatically inherit this behavior. I might change my stance on this approach in the future, but at least for this this seems to be the right way to approach this.

Subversion/Bugzilla and Eclipse

I wanted to try and get my newly installed Bugzilla system configured to work with eclipse and subversion. I wanted to be able to reference my Bug IDs on subversion check-in and be able to navigate to them in Eclipse. Mark Phippard did a fantastic job discussing this in his blog here.

Since I was connecting to a bugzilla database which I am allowing anonymous view access to, the bugtraq:url property I used was http://<hostname>/bugzilla/show_bug.cgi?id=%BUGID%. Doing so, meant that when I check in my files and provide a Bug ID, the subversion history will have a record of it, which will be provided as a link to the information page of the bug in eclipse. Pretty neat stuff!

Sunday, July 13, 2008

HSQLDB/EclipseLink Bug Filed

Well I got around to filing the uniqueness column constraint issue for HSQLDB and EclipseLink. The Bug ID is: 240618.

Saturday, July 12, 2008

EclipseLink - Initial Impressions

As was suggested by Doug Clarke, I took a look at EclipseLink. I was actually caught a little off guard on the whole subject, as with the birth of my daughter I had pretty much gone under a rock for the past few months. EclipseLink is yet another JPA provider, but there are some interesting aspects to it:
  • It was chosen by Sun Microsystems to serve as the reference implementation for Java Persistence 2.0.
  • The JPA development community has essentially switched from TopLink JPA right over to EclipseLink.
  • EclipseLink is bringing further capabilities with support for MOXy (JAXB), SDO and OSGI to name a few.

There are several good articles on the tool itself from the EclipseLink home page.

I downloaded the most recent release from the Eclipse website, and set about setting up my applications to use it. Generally speaking, I had tried to make only API calls to the javax.persistence APIs, thus I had very little package dependency changes. Since EclipseLink is based off TopLink virtually all the classes from TopLink appear in EclipseLink under a different naming convention. Basically oracle.toplink.essentials became org.eclipse.persistence. Since I have a nice level of unit testing around my services, I was able to quickly identify the places that were failing. In particular, I had some Query Hints that I was applying if the provider was the TopLink provider. I had to replicate this functionality for EclipseLink code paths (fortunately it was only in a few places). I think the biggest impact was on the Upgrade Tooling in which the SQLSchemaUpdateUtility had package dependencies on TopLink Essentials. Instead I roled this into a StatementExecutor interface/implementation and used reflection to call the APIs. Similarly, I did something similar for EclipseLink if I detected it as the persistence provider.

One observation I have noticed is that EclipseLink takes significantly longer to "initialize" than TopLink Essentials. This is most noticeable with the Unit Tests and HSQLDB, where the execution time is approximately ~ 5.0 seconds different. I brought up my JavaSE application in Netbeans 6.1 using the Profiler, and there is a significant time lag building and initializing the EntityManagerFactory. I am not convinced yet that there isn't a setting I am missing which is causing this lag. For example, launching my JavaSE application (which will query to see if there are any upgrades needed, query for all collections and countries, display the Swing UI etc.), almost 56% of the total startup time was spent in the deploy() method of the EntityManagerSetupImpl.

EclipseLink provides a nice compact javax.persistence_1.0.0.jar file which represents all of the J2EE javax.persistence classes required to compile. This is great for application development, and means you can provide your JPA provider at runtime (along with the persistence.xml configuration). Of course, this assumes you are using non-compile dependencies for things like QueryHints etc.

The documentation for EclipseLink seems a little disorganized, but overall there is a lot of information available through the EclipseLink Wiki User Guide.

I am looking forward to using some of the query features (such as fetches for foreign key objects) and it will take some time to really take advantage of the broader features being offered.

Monday, June 9, 2008

The Tale of Two Tomcats

The other night I was baffled as to why I could get my Linux server running with Tomcat properly doing BASIC authentication, whereas my desktop development environment would not authenticate through Eclipse to the same URI. Well it turns out, that when you have a web project in Eclipse, while the Tomcat binaries are run from your tomcat install, it uses a separate "set" of configuration files when run in Eclipse. Therefore, my tomcat-users.xml that existed in my tomcat installation location was being completely ignored in favor of the Eclipse configuration file. Once I discovered this, I was able to quickly get BASIC authentication to work (which is fine for testing purposes). Below is an example of how this shows up in the Eclipse Package Explorer:


Thursday, May 1, 2008

Eclipse, Toplink, JPA and a Lost Evening

So I decided to put together a simple web-application using the dynamic web project in Eclipse. However, my recent workspace had become rather "corrupted" and so I had created a new one named "eclipse 3.3" (under my common \dev\workspace area). To my dismay, I simply could not get my web-application which was working in my old workspace to work. The crazy thing about this, is I know my persistence.xml and project was setup correct. The Tomcat log was producing the following:
INFO: The configured persistenceUnitName is: MileageTracker
[TopLink Config]: 2008.05.01 10:23:15.703--ServerSession(2165595)--Thread(Thread[main,5,main])--The alias name for the entity class [class org.javad.mileage.model.Vehicle] is being defaulted to: Vehicle.
javax.persistence.PersistenceException: No Persistence provider for EntityManager named MileageTracker: The following providers:
oracle.toplink.essentials.PersistenceProvider
oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider
Returned null to createEntityManagerFactory.

at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:154)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
... 
Now what is curious about this, is Toplink was found, and it determined some information about my EntityBean. I spent a lot of time trying to discover what was wrong here, checking my other projects from the previous workspace etc. It turns out the problem was an Eclipse bug in which you have workspaces with spaces (" ") it will fail to find the Entity Manager Factory. The reference bug ID is 210280 Sufficit to say, this cost me a few hours of productivity.....

Tuesday, April 29, 2008

GWT and JPA with Servlets

I am doing some investigation of GWT and in writing an application, I wanted to integrate the servlet end of my application with a JPA services oriented architecture (either through the servlet itself, or a standalone JPA service). I have written a few JPA applications and there are several things I like about JPA:

  • There is a nice model(bean)/service view of the world.
  • Defining your persistence behavior on your JavaBeans "feels" right.
  • Takes care of all the ugly connection/pooling stuff for you.
  • You do not need to be a service "guru" (personally I prefer the business layer and presentation layer) to get a working application with persistent storage.

While there are certainly disadvantages with JPA, I wanted to leverage my JPA knowledge, tools and services with a GWT application using RPC-Servlets. The nice thing about using RPC-Servlets is you can code your servlet in a very DSL like manner. (I was going to look into REST and Restlets but decided GWT was enough to learn for now). Getting JPA and RPC-Servlets proved rather difficult at first, and I almost abandoned the approach in favor of a pure servlet "service" approach delivering JSON or XML objects and then using HTTPRequests to get the responses from GWT.

My first attempt was to try and stick my servlet(s) that referenced my JPA services outside of the GWT client packages and then try and run these within the hosted tomcat within GWT. This proved problematic since GWT/tomcat bundles an earlier version of the xerces library which is not compatible with the persistence.xml xsi schema. (I also wasn't very convinced this would work anways since I am not sure if the imbedded tomcat runs with a 1.4-compliant JDK or not (thus preventing JPA annotations)). So I needed another approach. I had read that GWT hosted browser could run without the Tomcat imbedded, hence allowing you to work and debug within the hosted browser, but use a standard OOTB tomcat service. This appealed to me alot, since I can easily setup a dynamic web project in eclipse to host my servlet/service and I can work in the natural hosted browser of GWT. After a little tweaking I got this to work in eclipse and so far, while not as clean as a pure GWT hosted-mode environment I am able to do everything I need to do.

Application Description

I am going to write an application which allows me to store user profiles (website profiles, not Windows profiles) in a database with encrypted passwords. If you are like me, after signing up for a few sites, you can never remember you user ids and passwords. The application will be called ProfileManager and it will be written in GWT as a web-application, using JPA to access the database through a ProfileService.

GWT Application Setup

I created an eclipse project for my GWT application using the projectCreator and applicationCreator scripts provided by GWT with the -eclipse flag. This provides you with the basic scaffolding necessary for the creation of a GWT application. For the purposes of this blog, the package path of my module is org.javad.profile.gwt.ProfileManager. Executing the ProfileManager.launch script launches the GWT toolkit development shell and my application. I am not going to go into more details here as these procedures are well documented in text and websites.

Step 1: Create the Service Interface

My service interface under the package org.javad.profile.gwt.client.rpc. The interface has to extend the google interface RemoteService. For simplicity this interface defines only a single method getAll( ) that looks like the following:


package org.javad.profile.gwt.client.rpc;

import java.util.List;
import com.google.gwt.user.client.rpc.RemoteService;


public interface RPCProfileService extends RemoteService {
   public List getAll( );
}
As more functionality is added, I will add the signatures to the service interface. Along with the interface, I need an Asynchronous interface which is defined in the same package:

package org.javad.profile.gwt.client.rpc;
import com.google.gwt.user.client.rpc.AsyncCallback;

public interface RPCProfileServiceAsync {
   public void getAll( AsyncCallback callback );
}

Step 2: Create your Serializable Bean

Since JPA uses annotations, we unfortunately have to translate the JPA POJO to a GWT DAO. One product you might want to look at is HiberObjects. For this project, I created a simplified model of my JPA POJO called "ProfileBean" under org.javad.profile.gwt.client.model. Since this overview does not use the ProfileBean directly, I am not going to say any more on it, other than you'd need it for a full GWT Application.

Step 3: Create an Externalized JAR

In order to implement the service interface (and retrieve ProfileBean objects) you need to bundle these into an external JAR to associate to your web project. Within eclipse you can do this with the File->Export ...->JAR File functionality. This JAR forms the externalized view of our service which we'll need to implement within the web project.

Step 4: Modify the .launch Script

When you create your project, the GWT toolkit created a ProfileManager.launch script which you can use to launch your application. The problem is, this launch script will launch the Toolkit Development shell with an imbedded Tomcat, will attempt to connect on port 8888 (default for GWT toolkit) and will not include a web-application root name, which if you are deploying with web project will be needed.

The GWTShell command can take some arguments which we'll use to adjust this. Editing the ProfileManager.launch shell, you need to change the value of the stringAttribute " org.eclipse.jdt.launching.PROGRAM_ARGUMENTS"

  1. First, we need to tell the shell not to launch an imbedded Tomcat. This is done by specifiying the -noserver option.
  2. The port needs to be specified. In my case, my Tomcat is running on port 8080 which can be defined by specifying the -port 8080 option.
  3. Finally, we need to change the application which is launched by the application script by prepending the web-application name in front of the module's HTML file.

An example of this line from my ProfileManager.launch script looks like the following:

<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noserver -port 8080 -out www Profiles/org.javad.profile.gwt.ProfileManager/ProfileManager.html"/>

Now executing the script will open the Toolkit Shell an attempt to execute the GWT application with the correct port number and web-application name. A tomcat instance will not be started by the Toolkit Shell. The navigator window of course will not be able to connect to your application (since we have not hooked it up yet) so your window should look something like this:

Step 5: Make a call to the Service

Before we go on to the servlet project, it'll be helpful to know that we have the connection to the service working within GWT when the servlet is ready. To test this, I modified the the onModuleLoad( ) method of the application to simply dispatch a call to the RPC service. Obviously if you are going to use a DAO/Controller pattern this would be abstracted, but this is simply a test to know you are on the right path.


   ...
   RPCProfileServiceAsync service = (RPCProfileServiceAsync)GWT.create(RPCProfileService.class);
   ServiceDefTarget endpoint = (ServiceDefTarget) service;
   String moduleRelativeURL = GWT.getModuleBaseURL() + "servlet/ProfileServlet";
   endpoint.setServiceEntryPoint(moduleRelativeURL);
   AsyncCallback callback = new AsyncCallback() {
      public void onSuccess(Object result) {
         System.out.println("in callback");
      }
      public void onFailure(Throwable caught) {
         caught.printStackTrace();
      }
   };
   service.getAll(callback);

If we were to launch the application now, it would fail since there would be no response from the service. However when we complete the next section, we should see to "in callback" message shown in the console of the GWTShell.

Servlet Project For the servlet project, I am using Eclipse Europa with the WTP 2.0. This includes Dali, which allows you to easy define you JPA POJOs using the built in editor. Step 1: Create the Project Create the project within Eclipse using the "File->New->Project..." and selecting the dynamic web project under the Web project types. Enter a project name (this will be the default web-application name) so for mine I chose "Profiles". For the Project Facets step, make sure you choose the "Java Persistence" facet. This will allow you to manage your JPA objects.

Step 2: Add the GWT RPC library When we exported the RPC library from our GWT project (see Step 3 above) we created the contract that the servlet needs obey. We now need to import this JAR into the web project as a references library. After adding it as a referenced library, we also need to ensure that it is copied to the server deployment location. This is done by selecting the Properties of our project and selecting the necessary JARs under the J2EE Module Dependency option. I also included the TopLink JPA, MySQL (connector library) and gwt-servlet.jar as can be seen from the image below:

Step 3: Create your RPC Servlet

To implement our servlet, I created a class GWTProfileServlet which extends the RemoteServiceServlet and implements our RPCProfileService. This is located in the org.javad.profile.servlet package under the src variant of my web project.


package org.javad.profile.servlet;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.javad.profile.gwt.client.rpc.RPCProfileService;
import org.javad.profile.model.Profile;
import org.javad.profile.service.ProfileService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;


public class GWTProfileServlet extends RemoteServiceServlet implements RPCProfileService {
   @Override
   public List getAll() {
      ProfileService service = ProfileService.getInstance();
      Collection profiles = service.getAll();
      System.out.println("debug: got all profiles" + profiles);
      return new ArrayList();
   }
}

In the example above, I make a call to the ProfileService which is a JPA Enabled service for managing profile objects from the datastore. You could also add your JPA persistence code directly to the servlet here. I am also printing out a debug message just to show that I am getting the output in the servlet.

Step 4: Create the servlet mapping

Since we want the GWTProfileServlet to be mapped under the GWT Application, in the web.xml for the web project, you need to define the servlet-mapping that includes the GWT Module name. So for our application, the servlet path was appended to the module path, making a url-pattern name as follows:


<servlet>
<description></description>
<display-name>RPCProfileServlet</display-name>
<servlet-name>RPCProfileServlet</servlet-name>
<servlet-class>org.javad.profile.servlet.GWTProfileServlet</servlet-class></servlet>
<servlet-mapping>
   <servlet-name>RPCProfileServlet</servlet-name>
   <url-pattern>/org.javad.profile.gwt.ProfileManager/servlet/ProfileServlet</url-pattern>
</servlet-mapping>

Step 5: Copy over the base GWT Application

In order for the web application to properly server the GWT Application to the imbedded browser we need to provide some files to the Tomcat.

First compile the GWT Application that you wrote in the first section above using the ProfileManager-compile.cmd through the External Tools in Eclipse.

Create a folder under the www-root named "org.javad.profile.gwt.ProfileManager". In this folder copy the following files from the www-root folder from your GWT Project:

   ProfileManager.html
   org.javad.profile.gwt.ProfileManager.nocache.js
   hosted.html
   gwt.js
Now you should be able to start your application server, and launch the GWT Toolkit browser and debug the application (both the servlet and the GWT application) using the eclipse debugger.

Monday, April 28, 2008

Failed Servers in Eclipse

I was trying out the Dali plugin for Eclipse and trying to create a persistence class within a dynamic web project, but I couldn't get my Apache/Tomcat 6.0 server to start within Eclipse. It would appear that I was running into the Eclipse Bug 117611 reported here. The resolution? Remove the server from my eclipse configuration and recreate it. This did the trick and I was able to synchronize the web application.