Skip to content

Commit

Permalink
Add a simple maven archetype for a multi-module project with servlets (
Browse files Browse the repository at this point in the history
…#114)

This provides a working example of a good way to build a real project, 
with minimal configuration. There is a shared project which runs its 
own test, but is also included by both client and server, and a client 
test that confirms the behavior of the shared code.

Fixes #66
  • Loading branch information
niloc132 authored Feb 17, 2022
1 parent ecdeb90 commit 45be16e
Show file tree
Hide file tree
Showing 37 changed files with 768 additions and 80 deletions.
29 changes: 11 additions & 18 deletions j2cl-archetypes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,14 @@ mvn org.apache.maven.plugins:maven-dependency-plugin:get \

# `simple-project`

This project is a simple html page, with a css file, and a single Java class. It is not a good example
of how to set up a client/server project, but serves only to show how to make very simple standalone
samples.

After creating this, you'll need two consoles to start it. First, run `mvn jetty:run` in one window -
you'll know it is working when it reports "Started Jetty Server". In the other console window, run
`mvn j2cl:watch`, and wait for `Build Complete: ready for browser refresh`. With both running, open
`http://localhost:8080/` in a browser to see the app. Refresh the page in the browser after editing
any source file (and seeing the "Build Complete" message in the j2cl:watch log).

To deploy a sample to a servlet container, use `mvn verify` to build a war, then copy it from the
`target/` directory to the webapps directory of the servlet container. Alternatively, just run
`mvn jetty:run` without also running the watch command, the j2cl output will be replaced automatically
with JS compiled for production.

To reiterate, this is _not_ a suggested way to develop a real project, but is only intended for a quick
sample to get the basic idea of how the plugin functions, and to quickly experiment with J2CL and the
Closure Compiler in Maven.
This project is a simple html page, with a css file, and a single Java class. It is _not_ a good
example of how to set up a client/server project, but serves only to show how to make very simple
standalone samples.

# `j2cl-servlet-project`

Creates two Java modules, one for the server, and one for the client. The server module uses Jakarta
servlets to host some http static content and offer some services, and the client module provides a
simple J2cl-based browser application that is served from, and connects to that server for more content.
The parent pom is configured to make it easy to add either shared or client-only modules to the project,
and still get a good debugging experience from the browser.
14 changes: 14 additions & 0 deletions j2cl-archetypes/j2cl-servlet-project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# `j2cl-servlet-project`

Creates two Java modules, one for the server, and one for the client. The server module uses Jakarta
servlets to host some http static content and offer some services, and the client module provides a
simple J2cl-based browser application that is served from, and connects to that server for more content.
The parent pom is configured to make it easy to add either shared or client-only modules to the project,
and still get a good debugging experience from the browser.

After creating this, you'll need two consoles to start it. First, run `mvn jetty:run -pl *-server -am -Denv=dev`
in one window - you'll know it is working when it reports "Started Jetty Server". In the other
console window, run `mvn j2cl:watch`, and wait for `Build Complete: ready for browser refresh`. With
both running, open `http://localhost:8080/` in a browser to see the app. Refresh the page in the
browser after editing any source file (and seeing the "Build Complete" message in the j2cl:watch log).

27 changes: 27 additions & 0 deletions j2cl-archetypes/j2cl-servlet-project/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<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.vertispan.j2cl</groupId>
<artifactId>j2cl-maven-archetypes</artifactId>
<version>0.19-SNAPSHOT</version>
</parent>
<artifactId>j2cl-servlet-project</artifactId>
<packaging>maven-archetype</packaging>

<name>J2CL+Servlet Project</name>
<description>Example reactor project with Jakarta Servlets</description>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="J2cl+Servlet Maven Project Archetype">
<requiredProperties>
<requiredProperty key="module" />
</requiredProperties>
<modules>
<module id="${rootArtifactId}-client" dir="__rootArtifactId__-client" name="${rootArtifactId}-client">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
<include>**/*.native.js</include>
</includes>
</fileSet>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/test/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-shared" dir="__rootArtifactId__-shared" name="${rootArtifactId}-shared">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/test/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
</fileSets>
</module>
<module id="${rootArtifactId}-server" dir="__rootArtifactId__-server" name="${rootArtifactId}-server">
<fileSets>
<fileSet filtered="true" packaged="true" encoding="UTF-8">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
<fileSet filtered="true" encoding="UTF-8">
<directory>src/main/webapp</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.html</include>
<include>**/*.css</include>
</includes>
</fileSet>
<fileSet encoding="UTF-8">
<directory>src/main/jettyconf</directory>
<includes>
<include>**/*.xml</include>
</includes>
</fileSet>
</fileSets>
</module>
</modules>
</archetype-descriptor>
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>\${groupId}</groupId>
<artifactId>\${rootArtifactId}</artifactId>
<version>\${version}</version>
</parent>

<artifactId>\${artifactId}</artifactId>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>\${project.groupId}</groupId>
<artifactId>\${rootArtifactId}-shared</artifactId>
<version>\${project.version}</version>
</dependency>

<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-dom</artifactId>
</dependency>
<dependency>
<groupId>com.google.elemental2</groupId>
<artifactId>elemental2-core</artifactId>
</dependency>
<dependency>
<groupId>com.google.jsinterop</groupId>
<artifactId>jsinterop-annotations</artifactId>
</dependency>


<dependency>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>junit-annotations</artifactId>
<version>\${j2cl.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>gwttestcase-emul</artifactId>
<version>\${j2cl.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>gwttestcase-emul</artifactId>
<version>\${j2cl.version}</version>
<classifier>sources</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>junit-emul</artifactId>
<version>\${j2cl.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>junit-emul</artifactId>
<version>\${j2cl.version}</version>
<classifier>sources</classifier>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Disable surefire if it causes problems for your client project -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M4</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>

<plugin>
<groupId>com.vertispan.j2cl</groupId>
<artifactId>j2cl-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
<execution>
<id>js-tests</id>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- force ADVANCED for tests to compile out class keyword, so htmlunit can run tests -->
<compilationLevel>ADVANCED</compilationLevel>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package ${package}.client;

import ${package}.shared.SharedType;

import elemental2.dom.DomGlobal;
import elemental2.dom.HTMLButtonElement;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.Response;
import elemental2.promise.Promise;
import jsinterop.base.Js;

public class ${module} {

public void onModuleLoad() {
HTMLDivElement wrapper = (HTMLDivElement) DomGlobal.document.createElement("div");
wrapper.classList.add("wrapper");

HTMLButtonElement btn = (HTMLButtonElement) DomGlobal.document.createElement("button");
btn.classList.add("myButton");
btn.textContent = SharedType.sayHello("HTML");

btn.addEventListener("click", evt -> {
goGetData(btn);
});

wrapper.appendChild(btn);

DomGlobal.document.body.appendChild(wrapper);
}

private void goGetData(HTMLButtonElement button) {
DomGlobal.fetch("/hello.json?name=J2cl")
.then(Response::json)
.then(json -> {
String string = Js.asPropertyMap(json).getAsAny("response").asString();
button.textContent = string;
return Promise.resolve(json);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Defer this command, since this will be folded into the entrypoint js impl,
// and if it runs right away, will not have its dependencies resolved yet (at least while
// running in BUNDLE or BUNDLE_JAR).
setTimeout(function(){
// Call the java "constructor" method, `new` will only work if it is a @JsType, or maybe
// once optimized. Without this, in BUNDLE mode, `new` doesn't include the clinit, so
// static imports haven't been resolved yet.
var ep = ${module}.$create__();
// Invoke onModuleLoad to start the app.
ep.m_onModuleLoad__()
}, 0);

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package ${package}.shared;

import org.junit.Assert;
import org.junit.Test;
import com.google.j2cl.junit.apt.J2clTestInput;


/**
* Represents some type that could be shared between client and server.
*/
@J2clTestInput(SharedTypeTest.class)
public class SharedTypeTest {
@Test
public void sayHello() {
Assert.assertEquals("Hello, Foo!", SharedType.sayHello("Foo"));
}
}
Loading

0 comments on commit 45be16e

Please sign in to comment.