Compile multiple modules in one project

105 views
Skip to first unread message

Neil Aggarwal

unread,
Dec 28, 2024, 11:25:00 AM12/28/24
to google-we...@googlegroups.com
I am trying to follow this example:
https://groups.google.com/g/google-web-toolkit/c/sjh6AGfeCKQ/m/Dp2fNL6HAQA
J

So, I put this into my pom.xml:
<build>
<plugins>
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.1.0</version>
<extensions>true</extensions>
<executions>
<execution>
<id>DiagonalSlitherlink</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<failOnError>true</failOnError>
<logLevel>INFO</logLevel>
</configuration>
</execution>
<execution>
<id>DiagonalSlitherlink2</id>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<failOnError>true</failOnError>
<logLevel>INFO</logLevel>

<moduleName>com._3dmathpuzzles.gwt.DiagonalSlitherlink2</moduleName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

But I get this error from Maven:

[INFO] Scanning for projects...
[INFO]
[INFO] -----------------< com.3dmathpuzzles:3DMathPuzzlesWeb
>-----------------
[INFO] Building 3DMathPuzzlesWeb 2.1.0
[INFO] from pom.xml
[INFO] --------------------------------[ war
]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ 3DMathPuzzlesWeb ---
[INFO] Deleting C:\OneDrive\Dev\3DMathPuzzlesWeb\target
[INFO]
[INFO] --- resources:3.3.0:resources (default-resources) @
3DMathPuzzlesWeb ---
[INFO] Copying 0 resource
[INFO] Copying 52 resources
[INFO]
[INFO] --- compiler:3.10.1:compile (default-compile) @ 3DMathPuzzlesWeb
---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 65 source files to
C:\OneDrive\Dev\3DMathPuzzlesWeb\target\classes
[INFO]
[INFO] --- gwt:1.1.0:compile (default-cli) @ 3DMathPuzzlesWeb ---
[INFO]
------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO]
------------------------------------------------------------------------
[INFO] Total time: 4.939 s
[INFO] Finished at: 2024-12-28T10:24:00-06:00
[INFO]
------------------------------------------------------------------------
[ERROR] Failed to execute goal
net.ltgt.gwt.maven:gwt-maven-plugin:1.1.0:compile (default-cli) on project
3DMathPuzzlesWeb: The parameters 'moduleName' for goal
net.ltgt.gwt.maven:gwt-maven-plugin:1.1.0:compile are missing or invalid
-> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the
-e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions,
please read the following articles:
[ERROR] [Help 1]
http://cwiki.apache.org/confluence/display/MAVEN/PluginParameterException


Thank you,
Neil

--
Neil Aggarwal, (972) 834-1565, http://www.propfinancing.com
We offer 30 year loans on single family houses!

Colin Alworth

unread,
Dec 28, 2024, 11:35:01 AM12/28/24
to GWT Users
Note that you've defined more than one gwt:compile execution into a single maven module. The maven plugin you're using is capable of this, but not really designed for it - please consider splitting into multiple maven modules (1:1 with the gwt modules they seek to compile).

Only one of your <execution>s defines <moduleName>, and the error is letting you know that at least one execution doesn't define a moduleName.

As it happens, you have three executions as your project is configured: DiagonalSlitherlink, DiagonalSlitherlink2, and "default-cli" the default execution. All three are required to have a moduleName to be able to run. 

I believe that dropping the "gwt-app" packaging will opt you out of the default wiring that the plugin assumes, and get rid of default-cli, but you also may have some additional setup to do to make the project work once you've removed all the default wiring.

What are you trying to achieve with this?

Neil Aggarwal

unread,
Dec 28, 2024, 11:45:10 AM12/28/24
to google-we...@googlegroups.com

> Only one of your <execution>s defines <moduleName>, and the error is letting you know that

> at least one execution doesn't define a moduleName.

 

Oops. I was editing the file and accidentally deleted that. I fixed it, but I am still getting
the error.

 

> What are you trying to achieve with this?

 

I am trying to create a war file which has two GWT endpoints in it.

I would like to access them by these URLs:

 

https://dev.3dmathpuzzles.com/3dmp/DiagonalSlitherlink.html

 

and

 

https://dev.3dmathpuzzles.com/3dmp/DiagonalSlitherlink2.html

Colin Alworth

unread,
Dec 28, 2024, 11:58:19 AM12/28/24
to GWT Users
I can't see what you've edited to fix it - do you now have three entries for <moduleName>? Or did you remove gwt-app as the packaging?

There are many ways to achieve what you're after, depending on what tradeoffs you want. The simplest option in terms of build configuration and fastest option in terms of compilation is to keep a single module, and edit the EntryPoint to test the URL of the page that loaded, and delegate accordingly to two different "sub entrypoints". Odds are very high that this will reduce downloaded code size if users often will load both pages with the same browser cache, since there will likely be a fair amount of shared code between the two pages.

If there is little to no overlap between the pages, that at least suggests that there will be minimal caching benefits in splitting the modules. In that case, both to avoid overlap and to easily use gwt-app packaging to give you the configuration you want, the next best option is to have three pom files - a parent, and two children, where each child has its own src/main/module.gwt.xml and its own src/main/java full of sources. This has the advantage of using configuration and features of maven that you already understand. Note that if both modules share some library code, a shared cache can still be beneficial.

Last main option is to continue as you're doing - make sure you've removed gwt-app as the packaging, and explicitly control the goal wiring in all ways. 

Technically, the GWT compiler can take more than one module as input, so you don't need to invoke the compiler twice in a single module as you're doing - but as I mentioned the gwt-maven-plugin is intended to encourage a 1:1 mapping from maven module to gwt module. If you want to invoke the compiler only once to save some build time, you could set up an exec:java goal that directly calls the compiler with a handwritten argument list. I would strongly encourage one of the two earlier options.

Neil Aggarwal

unread,
Dec 28, 2024, 12:10:58 PM12/28/24
to google-we...@googlegroups.com

> I can't see what you've edited to fix it - do you now have three entries for <moduleName>? Or did you remove gwt-app as the packaging?

 

I am attaching my full pom.xml file.

pom.xml

Neil Aggarwal

unread,
Dec 28, 2024, 12:20:45 PM12/28/24
to google-we...@googlegroups.com

> did you remove gwt-app as the packaging?

 

I want the project packaged into a single war file which I upload
to my server.

 

I am not knowledgeable enough about Maven and GWT to understand
most of your emails but I am working through them.

Neil Aggarwal

unread,
Dec 28, 2024, 1:01:35 PM12/28/24
to google-we...@googlegroups.com

I was able to get it working by setting the goals in my run configuration to:

clean compile gwt:compile@DiagonalSlitherlink gwt:compile@DiagonalSlitherlink2 war:war

Colin Alworth

unread,
Dec 28, 2024, 1:48:55 PM12/28/24
to GWT Users
If you're asking my advice, add a switch/case to your entrypoint based on window.location.pathname, and keep a single entrypoint - will pay off for caching, for compile time, for encouraging code reuse, will produce a single war in a simple `mvn verify` command.

If you want to use the @execution syntax that's fine, but it is definitely not going to be familiar to other developers, and makes it more complex to do things like run tests, etc. The conventions exist because Maven tries to view all kinds of project through the same lens. It does tend to make inventing your own project structure tricky - the other thread you linked has advice on using Gradle or the like if you do want to build your own graph of tasks to perform.

Producing a single war from multiple maven modules is straightforward - make a "webapp" project with packaging=war, and depend on each of the other wars. See https://maven.apache.org/plugins/maven-war-plugin/overlays.html for a discussion of this.

Neil Aggarwal

unread,
Dec 28, 2024, 2:01:13 PM12/28/24
to google-we...@googlegroups.com

> If you're asking my advice, add a switch/case to your entrypoint based on window.location.pathname,

> and keep a single entrypoint

 

I am not sure that will work.  Different puzzles might have completely different layouts.

For example, I am designing my Diagonal Slitherlink puzzle to be completely contained
in the GWT UI, but I am envisioning the TripleCross puzzles to have the clues in the HTML
below the UI.

 

> Producing a single war from multiple maven modules is straightforward

 

I will look into that.

Colin Alworth

unread,
Dec 28, 2024, 2:19:14 PM12/28/24
to GWT Users

I am not sure that will work.  Different puzzles might have completely different layouts.

For example, I am designing my Diagonal Slitherlink puzzle to be completely contained
in the GWT UI, but I am envisioning the TripleCross puzzles to have the clues in the HTML
below the UI.


I cannot think of how that would influence this - if each HTML page has its own layout as you already have it, but all load "games/games.nocache.js", and the entrypoint there tests the name of the HTML page that loaded it to decide what to do next, the rest of the code and module could be shared. If the layout instead were in the entrypoint code, then the "branches" of the switch case would initialize the layout based on which page it was on. Either way, not an impediment to this strategy.

Neil Aggarwal

unread,
Dec 28, 2024, 2:22:34 PM12/28/24
to google-we...@googlegroups.com

> if each HTML page has its own layout as you already have it, but all load "games/games.nocache.js", and

> the entrypoint there tests the name of the HTML page that loaded it to decide what to do next, the rest of the

> code and module could be shared

 

Maybe you are right.  I am going to test it.

Neil Aggarwal

unread,
Dec 28, 2024, 3:31:33 PM12/28/24
to google-we...@googlegroups.com

> if each HTML page has its own layout as you already have it, but all load "games/games.nocache.js",

> and the entrypoint there tests the name of the HTML page that loaded it to decide what to do next,

> the rest of the code and module could be shared.

 

You are correct.  I tried it and it is working.  Thanks for the advice!

Reply all
Reply to author
Forward
0 new messages