Any experienced developer tends to reuse existing components and organize 
his own code to allow reusability in future whenever it is possible. 
Division of labor further encourages a group of developers to physically 
split a big project into modules and work independently on each part. I 
think T.Broyer's multi-module project archetype for Maven introduces a 
great platform enabling these features and making versioning task look 
effortless.

However I personally start to have issues with the last part, when it comes 
to the release. Specifically, should I aggregate the build artifacts into 
one *gwt-user.jar* kind of unit? I know it's a broad topic, and there're 
multiple angles to look at this problem, one of which says "it's not Maven 
way" (though I start to doubt that I applied "Maven way" concept in the 
appropriate contex). Therefore I want to hear your advice regarding this 
matter and avoid reinventing the wheel. If there's a sample project already 
configured to do the similar task with grace, then I guess a link to github 
will be sufficient.

Imagine you're developing *gwt-user*. Inside *com\google\gwt\user* folder 
you'll find *client *direcotry and a bunch of *<module>.gwt.xml* files such 
as *User.gwt.xml, UI.gwt.xml, TextBox.gwt.xml.* The latter contains a bunch 
of deferred binding instructions, e.g.:

  <!-- IE has a completely different TextBox implementation -->
  <replace-with class="com.google.gwt.user.client.ui.impl.TextBoxImplIE8">
    <when-type-is class="com.google.gwt.user.client.ui.impl.TextBoxImpl"/>
    <when-property-is name="user.agent" value="ie8"/>
  </replace-with>

*User* inherits *UI *and *UI *inherits *TextBox*. But then we also have a 
subfolder *datepicker *with *DatePicker.gwt.xml* and it's own *client*
 directory.

So my view on this is that you don't wanna ship *datepicker.jar* to your 
clients, but instead combine the components from all related projects and 
modules into one library.

--------------------------------------------------------------------------------------------------------------------------------

Further in the text I'm gonna present my hack to multi-module archetype 
build configuration based on *maven-shade-plugin*, so let's get into 
details.

There were three strong candidates to do this job: *maven-jar-plugin, *
*maven-assembly-plugin* and *maven-shade-plugin*. However the latter was 
specifically made for:
- This plugin provides the capability to package the artifact in an 
*uber-jar*, including its dependencies and to shade - i.e. rename - the 
packages of some of the dependencies.
- The Shade Plugin has a single goal: *shade:shade *is bound to the *package 
*phase and is used to create a shaded jar.

In multi-module structure of my *sandbox *project I have two *gwt-lib* packaged 
modules *my-client-lib* and *my-client-lib-a*. The task is to gather their 
build artifacts inside one jar. My solution was to create a subsidiary 
*module* *sandbox-gwt* (though it could as well be another *project*) with 
the same groupId as *my-client-lib** and to include only such artifacts in 
the uber-jar. Making it this way automates the task of naming by exploiting 
${project.groupId} and ${project.version} properties.

*pom.xml* of *sandbox-gwt *module*:*

<project xmlns="http://maven.apache.org/POM/4.0.0";
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
 <modelVersion>4.0.0</modelVersion>
 <parent>
   <groupId>com.example.project</groupId>
   <artifactId>sandbox</artifactId>
   <version>0.0.1-SNAPSHOT</version>
 </parent>
 <groupId>net.coolcode.gwt</groupId>
 <artifactId>sandbox-gwt</artifactId>

 <dependencies>
   <dependency>
     <groupId>${project.groupId}</groupId>
     <artifactId>my-client-lib</artifactId>
     <version>${project.version}</version>
   </dependency>
   <dependency>
     <groupId>${project.groupId}</groupId>
     <artifactId>my-client-lib-a</artifactId>
     <version>${project.version}</version>
   </dependency>
 </dependencies>

 <build>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-shade-plugin</artifactId>
       <version>3.1.1</version>
       <configuration>
         <artifactSet>
           <includes>
             <include>${project.groupId}</include>
           </includes>
         </artifactSet>
         <createDependencyReducedPom>true</createDependencyReducedPom>
       </configuration>
       <executions>
         <execution>
           <phase>package</phase>
           <goals>
             <goal>shade</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
   </plugins>
 </build>
</project>

*artifactSet* - Artifacts to include/exclude from the final artifact. 
Artifacts are denoted by composite identifiers of the general form 
*groupId:artifactId:type:classifier*.

But there's a set of techniques mentioned in different sources, which might 
do the task better?! Those include the use of:
- *<profiles>*
- *<executions>*
- *BOM* parent to manage dependencies better. I think it also helps to keep 
versioning clean.

--------------------------------------------------------------------------------------------------------------------------------

I also noticed, that *gwt-maven-plugin* can generate some code in <
*actual-module-name>.gwt.xml*, such as adding

<inherits name="com.google.gwt.core.Core"/>

In the context of a large uber-jar such as *gwt-user.jar* if it could 
establish the crossreferencing between modules based only on Maven 
dependencies, that would be interesting. E.g. to put 

<inherits name="net.coolcode.gwt.mvp.MyCoolCodeAppA" />

inside *MyCoolCodeApp.gwt.xml*, if *my-client-lib* depends on 
*my-client-lib-a*.

--------------------------------------------------------------------------------------------------------------------------------

Lastly I'm curious, in a context of development of *gwt-user* project it 
seems that due to an unconventional for GWT applications module structure (
*src/main/module.gwt.xml* not *src/main/package/MyModule.gwt.xml)* if we 
want to strictly follow the archetype's idiom, we must have one module per 
one *<module>.gwt.xml*, e.g. *TextBox.gwt.xml*. I'm not sure what I'm 
trying to ask, but is it the way? And since we manually manage <source path=
"client" /> in *module.gwt.xml*, is it so evil to put *server-lib* artifacts 
in the same uber-jar? 

--------------------------------------------------------------------------------------------------------------------------------
*p.s. It actually began to get into my habit to revisit this archetype once 
in a while, and then find myself seriously confused shortly after ^^.*

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

Reply via email to