Code reuse in GWT from common Java projects

351 views
Skip to first unread message

Marius Grama

unread,
Nov 15, 2012, 4:00:40 AM11/15/12
to google-we...@googlegroups.com
On the GWT project on which I am working we have dependencies to some common utility methods from libraries that are to be used by other modules for their business logic in order to avoid code redundancy.
e.g. : the logic used for calculating a gross price based on a set of given parameters (netto price, tax, promotion type) is used on the GWT client side for displaying the cost information as well as on the webservice side before persisting the data.

This is the reason why we are currently defining several common libraries (along with their dependencies - e.g. : hibernate) as a dependency for our web application.

One idea I have in mind to avoid the unnecessary dependencies in the web application is that during the building process all the utility classes from the common libraries that are neded in the GWT application could be copied in another project (e.g. : my-gwt-application-utilities), and  in this way the GWT application to have only this project as dependency. Downside is that the  same code would exist in two places, upside would be that the unnecessary dependencies problem would be solved.

Projects with their dependencies before this operation :
SERVICE SIDE
- mycompany.services.utilities (java utility project)
    - jasper       
- mycompany.services (webservice project - contains among other generic cost calculation methods)
    - mycompany.service.utilities
    - hibernate
    - ...
- mycompany.services.gen (webservice stubs projects)
CLIENT SIDE 
- mycompany.mygwtapp (gwt application communicating over SOAP/REST with mycompany.services)
     - mycompany.services
     - mycompany.services.gen
     - jasper
     - hibernate
     - ....

If there would be the artificial gwt project created to contain the common classes the project structure would look like this:
SERVICE SIDE
mycompany.services.utilities (java utility project)
    - jasper       
mycompany.services (webservice project - contains among other generic cost calculation methods)
    - mycompany.service.utilities
    - hibernate
    - ...
mycompany.services.gen (webservice stubs projects)
CLIENT SIDE 
- mycompany.mygwtapp.utilities (contains the utility classes needed by mycompany.mygwtapp project copied during the build process from mycompany.service.utilities and mycompany.services projects)
mycompany.mygwtapp (gwt application communicating over SOAP/REST with mycompany.services)
     - mycompany.mygwtapp.utilities
     - ....


This is one  (maybe naive) approach on which I've been thinking to tackle this issue.
Can anybody provide me some feedback on how they've tackled with this issue (putting the utility classes in separate projects to be used by the business logic and GWT wouldn't necessarily work in my case)?

Thad

unread,
Nov 15, 2012, 10:30:53 AM11/15/12
to google-we...@googlegroups.com
I think I've a similar situation which I managed to solve without duplicating code.

I've a large number of classes representing various database tables in a server app. These classes are used by a variety of applications--some command line, some JSP, some GWT, etc. The developement directory is organize like so

  javadev/
    database/
      build.xml
      src/
      com/
        /corp
          /database
             *.java
    lib/
    server/
    servlet-utils/
    utils/
    project-a/
    project-b/
    project-gwt/
      lib/
      database-gwt/
        build.xml
        src/
          com/
            corp/
            client/
              MyDb.java 
            MyDatabase.gwt.xml
            MyDb.gwt.xml
        war/
          ...
      client-app/
        build.xml
        src/
        war/

The javadev/database directory builds a JAR file used by the server and different projects. All classes implement java.io.Serializable and use only GWT serializable data types (Date, not Calendar).

The javadev/project-gwt/database-gwt builds a JAR file with both *.class and *.java files.

The MyDatabase.gwt.xml looks like
  <module>
    <inherits name="com.google.gwt.core.Core"/>
   <source path="database"/>
  </module>

The MyDb.gwt.xml looks like
  <module rename-to='mydb'>
    <inherits name='com.google.gwt.user.User'/>
    <inherits name='com.corp.MyDatabase' />
    <entry-point class='com.corp.client.MyDb'/>
  </module>

The MyDb.java is nothing more than an entry point to serve as a target for compiling the module:

  package com.corp.client;
  import com.google.gwt.core.client.EntryPoint;

  public class MyDb implements EntryPoint {

    public void onModuleLoad() {
      // no op
    }
  }

After that, it's matter of arranging ant targets (through depends attributes) such that javadev/project-gwt/database-gwt/build.xml calls javadev/database/build.xml, then calling targets for javac, gwtc, and jar. The jar target collects the *.java, *.class, and *.gwt.xml files:

  <target name="jar" depends="javac" 
        description="Package up the project as a jar">
    <jar destfile="mydb-gwt.jar">
      <fileset dir="war/WEB-INF/classes">
        <include name="**/*.class"/>
      </fileset>
      <fileset dir="src">
        <include name="**"/>
      </fileset>
      <fileset dir="../../database/classes">
        <include name="**/*.class"/>
      </fileset>
      <fileset dir="../../database/src">
        <include name="**"/>
      </fileset>
    </jar>
  </target>

Now project-gwt's *.gwt.xml file includes <inherits name='com.corp.MyDatabase' /> and all is good.

I hope this helps.

Marius Grama

unread,
Nov 15, 2012, 10:48:10 AM11/15/12
to google-we...@googlegroups.com
Hi Thad,
thanks for the feedback.

do you also work with maven?

In your IDE, when you have to edit a common javadev class (which is used in GWT as well) do you have to rebuild the library (through the ant task exposed above) in order to have the GWT project knowing about  it - because the GWT project knows only about mydb-gwt.jar dependency?

Thad

unread,
Nov 15, 2012, 11:11:14 AM11/15/12
to google-we...@googlegroups.com
(answers inline)


On Thursday, November 15, 2012 10:48:10 AM UTC-5, Marius Grama wrote:
Hi Thad,
thanks for the feedback.

do you also work with maven?

No. (1) I've have had dismal record in getting even GWT's samples that use maven to build. They often just WON'T BUILD; (2) there is management opposition to using maven since we'd be dependent on outside repositories (we SVN all 3rd party libraries so we know what we deal with between builds), and (3) we're a small shop and haven't the cycles for our own maven repository of 3rd party libraries.

In your IDE, when you have to edit a common javadev class (which is used in GWT as well) do you have to rebuild the library (through the ant task exposed above) in order to have the GWT project knowing about  it - because the GWT project knows only about mydb-gwt.jar dependency?

Yes. I use Eclipse. It might be possible to set something up, but I haven't hit on it (ditto for the other directories out there which generate jar's used only server-side). This has not been a big issue. The core of the database and other directories were written a long while ago, years before I started messing with GWT (and that was over 6 years ago!). These classes are fairly fixed with only the very occasional addition, say, when some new feature is added to our server API. All test and production builds are made from the command line where ant handles keeping the build order straight.

joerg.h...@googlemail.com

unread,
Nov 15, 2012, 12:01:29 PM11/15/12
to google-we...@googlegroups.com
Hi Marius,

we are also doing maven and have a simple and consistent setup for GWT projects:

+myproject
|
+-+myproject-component1
|  |
|  +-+myproject-component1-shared
|  |
|  +-+myproject-component1-client
|  |
|  +-+myproject-component1-server
|
...
+-+myproject-componentN
   |
   +-+myproject-componentN-shared
   |
   +-+myproject-componentN-client
   |
   +-+myproject-componentN-server
 
As far as I know this is the most common and suggested layout for a modularized GWT application.

Marius Grama

unread,
Nov 15, 2012, 12:33:05 PM11/15/12
to google-we...@googlegroups.com
Hi Joerg, 

my situation is similar to what Thad is having.
We are using code, that exists in projects that contain generic business logic functionality (used by different modules - not only gwt web ones), and among this functionality there are some utility classes that i need in GWT.
 I am searching a solution for avoiding code duplication.

I am not sure that the solution that you imply fits for the situation that I have.

Regards,
Marius.

Abraham Lin

unread,
Nov 15, 2012, 1:11:37 PM11/15/12
to google-we...@googlegroups.com
I think that Joerg's proposal is exactly what you're looking for, though what may not be immediately obvious is how the various components relate to one another. The basic idea is that myproject-componentN-client depends on myproject-componentN-shared and that myproject-componentN-server depends on myproject-componentN-shared as well. For multiple components (number them #1 and #2), you may also have myproject-component2-client depend on myproject-component1-client, myproject-component2-shared depend on myproject-component1-shared, and myproject-component2-server depend on myproject-component1-server.

Having multiple "server" modules for a given component is straightforward as well - just have them all depend on the "shared" module.

-Abraham

joerg.h...@googlemail.com

unread,
Nov 16, 2012, 10:41:13 AM11/16/12
to google-we...@googlegroups.com
Hi Marius,

in that case I also have a hint for you:

I have retro-fitted my own OSS lib for GWT.
The lib is here:

I added another module/lib that contains the GWT related config and portation code:

Here you can find all required magic to make this work:

Hope it helps.

Regards
  Jörg

Marius Grama

unread,
Nov 19, 2012, 3:45:14 AM11/19/12
to google-we...@googlegroups.com
Hi Jörg,

I had a look over the sample project that you've referenced and, from what I see so far, I am using a similar solution with yours.

The mmm-util-gwt project depends on mmm-util-core project.
The mmm-util-core project depends on spring, hibernate, etc. libraries.

My gwt project also depends on utility projects which are used for the business logic also by other modules.
What I am trying to avoid is to package (via maven) all these business logic libraries, that are actually not needed, within the gwt web application.

regards,
Marius.
Reply all
Reply to author
Forward
0 new messages