Automatic Refresh of Projects in Eclipse

I am working with the Maven Eclipse Plugin, the Maven Bundle Plugin and the eclipse PDE.

A common activity in this setup is to refresh projects in the workspace, since the Maven bundle plugin generates new MANIFEST.MF files (which I copy via Maven Ant Task), which become “out of sync” for eclipse.

Today I found that it is easy to set up eclipse to automatically refresh the projects in the workspace. The setting is in the Preferences under General / Workspace / “Refresh automatically”.

However, another problem remains for me: the classpath of the projects seems to be corrupted by rebuilding projects with Maven. Therefore, I constantly need to perform “Update Classpath” form the PDE project context menu. It would be great if this could be configured to update automatically as well.

Resources

Eclipse Newslist: Automatic Refresh

Unit Tests in GWT (using Maven and eclipse PDE/OSGi)

One of the strengths of GWT, from my point of view, is that large portions of the code (eg business logic) can be tested with plain old JUnit tests, without the slightest interference from servers, web browsers and other constraints.

However, certain parts of the code must be tested in a richer context including the compiled java script or client/server communication. Luckily, the GWTTestCase provides a powerful tool to automate tests in such rich contexts.

Following a few pointers, of how these GWT unit tests can be setup in an environment using Maven and the eclipse PDE (the tests are not exactly using this technology but should be able to be part of a possible OSGi module).

  • Create a new gwt module (gwt.xml) in a dedicated package (eg gwttests) in the src/test/java folder such as the following. Make this unit inherit the modules, you want to test.

<?xml
version=“1.0”
encoding=“UTF-8”?>

<module
rename-to=‘nxservergwttests’>

    <!– Inherit the core Web Toolkit stuff. –>

    <inherits
name=‘com.google.gwt.user.User’
/>

 

    <!– Other module inherits –>

    <inherits
name=‘nx.servergwt.client.NxGwtClient’></inherits>

    <inherits
name=“com.google.gwt.junit.JUnit”
/>

 

    <!– Specify the app entry point class. –>

    <entry-point
class=‘nx.servergwt.tests.DummyEntryPoint’
/>

 

    <!– Specify the paths for translatable code –>

    <source
path=
/>

    

    <set-property
name=“gwt.suppressNonStaticFinalFieldWarnings”

        value=“true”
/>

 

</module>

  • Create a class in that package following the naming pattern: “GwtTest*.java”, let this class extend com.google.gwt.junit.client.GWTTestCase. Return a module name pointing to your module (gwt.xml file) for gwtModuleName()

public
class GwtTestClientServerCommunication extends GWTTestCase {

 

    @Override

    public String getModuleName() {

        return
“nx.servergwt.tests.NxServerGwtTests”;

    }

    

    public
void testNetworkOperations() {

        Network n = Nx.newNetwork();

        String root = “root”;

        Nx.put().node(root).inNetwork(n);

        Nx.append().node(“a string”).to(root).inNetwork(n);

        
 

                    assertTrue(Nx.check().ifNode(root).hasChild(Nx.instanceOf(String.class)).inNetwork(n));

    }

    

}

  • Now you should be able to run this test using “mvn gwt:test” (but make sure to check for the pitfalls below).

Some possible pitfalls

-No compilation unit found for test-

The GWT compiler might report that the class of the test case could not be found:

[INFO] com.google.gwt.junit.JUnitFatalLaunchException: The test class …’ was not found in module …; no compilation unit for that type was seen

In this case, there might be problem with the module (gwt.xml) file you have defined, for instance you forgot to declare “<source
path=
/>

 

-Need to manually open test case in browser-

When executing gwt:test, the maven gwt plugin (or the gwt compile) might report the following:

[INFO] Please navigate your browser to this URL:

[INFO] http://130.216.XX.XX:54530/&#8230;.JUnit/junit.html?gwt.codesvr=130.216.XX.XX:54526

This can be omitted by configuring the maven gwt plugin to utilize htmlunit to lunch a browser. Add the following to the pom.xml:

<plugin>

    <groupId>org.codehaus.mojo</groupId>

    <artifactId>gwtmavenplugin</artifactId>


    <configuration>

        <htmlunit>IE8</htmlunit>

    </configuration>

    <mode>htmlunit</mode>

Now the tests should run without the need to open a browser manually (see Gwt Maven Plugin Parameters Mode)

 

-Access to junit.framework in eclipse PDE-

Eclipse PDE might report that: “Access restriction: The method assertTrue(boolean) from the type Assert is not accessible due to restriction on required library”

This can mitigated by adding the following dependency:

     <dependency>


<groupId>junit</groupId>


<artifactId>junit</artifactId>


<version>3.8.2</version>


<scope>test</scope>


</dependency>

As well as the following imported package in the configuration of the maven bnd plugin:

org.junit,

com.google.gwt.junit.client,

junit.framework,

After rebuilding the project with “mvn eclipse:clean clean package eclipse:eclipse -Declipse.pde -Declipse.useProjectReferences=false install” and refreshing the files in eclipse, the access restriction error should disappear.

 

-Calls to server Servlets result in 404 errors-

Some calls per RPC to Servlets on the server might result in 404 errors. In your original project, the Servlets could just be declared in the web.xml configuration. In order for Servlets to work in the GWT unit test, they must be declared in the gwt module definition (and here it is sensible to define them in the module you want to test rather than the ‘test’ module).

<servlet path=’/yourservletforrpc’ class=’com.yourpackage.Servlet’></servlet>

 

Resources

Gwt Maven Plugin Parameters Mode (set this to htmlunit)

Maven Gwt Plugin User Guide: Testing

GWT Developer’s Guide: JUnit Testing

 

GWT deRPC to be Deprecated

Direct evaluate Remote Procedure Calls (deRPCs) in GWT seem to be promising approach to transfer objects from server to browser. Rather than encoding objects into a stream of text in a legacy format, deRPC sends objects as JavaScript statements from server to client.

However, after some time of working with it, two important reasons surfaced not to adopt this technology.

-1- deRPC does not work very well

I had a number of issues in using deRPC:

  • While my test application ran fine in the hosted mode, I was not able to get it working deployed as a WAR onto tomcat and jetty. Debugging with Firebug reveals that the messages send from client to server are identical in hosted mode/deployed but the response send from the server was no JavaScript code in hosted mode (but only in deployed mode – which then was not read correctly by the server). I might of course have configured the whole project incorrectly, but I spent hours on the problem and did not get it fixed.
  • The JavaScript generated by the server, which was sent over the wire (when the application was deployed in a servlet container), seemed to be very verbose.

-2- GWT deRPC is about to be depreacted by the Google GWT team

“DeRPC was created to help with large object graph serialization; however, DeRPC (NOT GWT-RPC) will likely be deprecated eventually in favor of RequestFactory.” (David Chandler on Google Groups)

Serializing Immutable Objects in GWT

Immutable objects are an easy yet powerful way to leverage some of the advantages of functional programming languages when writing plain old java. Such immutable objects declare all their attributes as final and are therewith protected from unforeseen state changes and side-effects. However, unfortunately the GWT RPC mechanism has problems in dealing with immutable objects. In particular, GWT RPC does not consider final attributes in serialization and deserialization of objects.

What GWT does support:

What GWT does not support:

Final fields will be treated as transient fields (and therewith omitted during serialization). GWT compiler will report for instance “[WARN] Field ‘public final java.lang.String name’ will not be serialized because it is final”.

GWT compiler will report: “[Type] is not default instantiable (it must have a zero-argument constructor or no constructors at all) and has no custom serializer” or “[Type] has no available instantiable subtypes”

What can be done:

-0- Try Direct Eval RPC ?

There is a newer version of the RPC mechanism called Direct-Eval RPC (or short deRPC). This mechanism (besides bringing improvements in the client-side deserialization performance) is supposed to allow serializing final fields. However, using GWT 2.1.0 and the gwt-maven-plugin version 2.1.1-SNAPSHOT, final fields would still be ignored during serialization and deserialization. Moreover, the mechanism would still require a no argument constructor. Most sensible immutable objects require a constructor with arguments (to initialize the final fields).

-1- Add ‘dummy’ constructors to your classes:

Take all possible precautions that this constructor is not used in any other place in your code: (1) Declare as private, (2) Declare as Deprecated (which it will hopefully be if GWT serialization mechanism evolves), (3) add warning Java doc.

/* #gwtdummyconstrstart */

    /**

     * Non-argument constructor required for GWT RPC serialization.<br/>

     * <em>DO NOT CALL this constructor manually.</em>

     */

    @SuppressWarnings(“unused”)

    @Deprecated

    private Person() {

    }

    /* #gwdummytconstrend */

 

-2- Remove the final modifier from all fields in classes, which need to be serialized

Here again, it might be a good idea to somehow make the omitted final modifiers easily replaceable (in hope that future versions of gwt will support immutable objects).

    /* #gwtnofinal */ private String name;

 

Hints

deRPC is supposed to support the serialization of classes with non-final fields. However, the compile still issues warnings for all these fields (for good reasons as the final fields were still ignored in my case). It is possible to suppress these warnings by adding the following element to the Gwt module definition (gwt.xml) (see Issue 2862):

<set-property name=”gwt.suppressNonStaticFinalFieldWarnings” value=”true” />

Resources

Direct Evalable RPC GWT Wiki

GWT Docs Communicate with a Server

GWT Docs Direct-Eval RPC (deRPC)

 

GWT Warning “Non-canonical source package”

The Problem

Sometimes you might want to include classes from a package in your gwt module, which are not in a sub-package of the package in which you have defined the Gwt module (MyModule.gwt.xml).

For instance, you might have the following directory structure:

/client/ClientService.java

/browser/BrowserEntryPoint.java

/browser/MyModule.gwt.xml

The first natural option would be to define a source dependency in the Gwt module (gwt.xml) as follows:

<source path=’../client’ />

However, when compiling the module, a “Non-canonical source package” warning is issued. Furthermore, the class in the client package will not be recognized by the Gwt compiler.

The Solution

One clean (but not necessary straightforward) solution is to define a new Gwt module in the client package, and link this in your original module. The directory structure would change to:

/client/ClientService.java

/client/ClientModule.gwt.xml

/browser/BrowserEntryPoint.java

/browser/MyModule.gwt.xml

The following dependency would have to be added to MyModule.gwt.xml:

<inherits name=’client.ClientModule’></inherits>

Resources

GWT Google Group – Source-Source

 

GXT Images are not displayed

The Problem

When developing an GWT application using Ext Gwt (GXT), various images are not displayed when opening the deployed .html file of your GWT project.

These images may include:

  • borders of panels
  • backgrounds of panels
  • icons displayed when dragging and dropping components

A panel, for instance, might look as follows:

(for me, when running the application in GWT hosted mode – using the Maven GWT plugin mvn:run the images are displayed. They are only missing in the compiled deployment version)

The Solution

In my case, the problem was caused by wrong paths for images in the Gxt css file (gxt-all.css). These were expecting the images in a folder relative to the .css files parent folder (../):

Therefore, the css file had to be moved to a child folder of the generated .html file (or the webapp directory):

/webapp/[your gwt module].html

/webapp/css/gxt-all.css

/webapp/images (à the images required for GXT)

Also, the path to the css file in your .html template needs to be changed to something like: css/gxt-all.css instrad of gxt-all.css.

After reloading the html file, the components should be displayed correctly:

 

GXT TreeGrid Selection Event/Listener

In the evolution of the Ext GWT (GXT) framework, there seemed to have been some change as to how selection events of trees/tree grids can be intercepted. In release 2.2.1, the following approach works:

treeGrid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<ModelData>() {

            @Override

            public void selectionChanged(SelectionChangedEvent<ModelData> se) {

                GWT.log(“selection changed from getSelectionModel”);

            }

        });

The following approaches do not work:

store.addListener(Events.SelectionChange, new SelectionChangedListener<TreeModel>() {

            @Override

            public void selectionChanged(SelectionChangedEvent<TreeModel> se) {

                GWT.log(“selection changed”);    

            }

        });

        

        treeGrid.addListener(Events.SelectionChange, new SelectionChangedListener<TreeModel>() {

            @Override

            public void selectionChanged(SelectionChangedEvent<TreeModel> se) {

                GWT.log(“selection changed”);    

            }    

        });

Resources:

TreeBinder JavaDoc – TreeBinder seems to be deprecated, use selection model instead.