Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.

Im ersten Tutorial setzen wir ein einfaches GWT-Projekt auf (basierend auf Spring Boot) und richten unsere Entwicklungsumgebung ein. Zum Schluss starten wir unser GWT-Modul per Spring Boot und können unsere erste statische Host-Page im Browser öffnen.

In den folgenden Tutorials wollen wir dann die JWT-Bibliotheken einbinden, Dokumente laden und anzeigen, mit Dokumenten interagieren und viele weitere nützliche Tipps zur Entwicklung von JWT-Anwendungen kennenlernen.

Info
Wir empfehlen den Code bereits vor Durchführung des Tutorials hier herunterzuladen.

Projektstruktur

Wir orientieren uns bei der Organisation unseres Projekts grundsätzlich an der Standardstruktur von Maven und den im GWT-Projekt beschriebenen Best-Practice-Vorgaben, angereichert um typische Spring-Boot Ablageorte. Unsere Verzeichnisstruktur sieht so aus:

Codeblock
languagexml
themeRDark
titleVerzeichnisstruktur
├── pom.xml
├── src/main/java/application.yml     			- Die Spring Boot Konfigurationsdatei
├── pom.xml							- Hier legen wir unsere PackagesDie Projektbeschreibung mit Details zum Build Prozess und Klassen an.
│	└── org/jwt/	 zur Spring Boot Konfiguration
├── src/main/assembly/						- Unser verwendeter package-Name.
│		├── Application.gwt.xmlDie Konfiguration für das Maven Assembly Plugin (MAP) befindet sich in diesem Verzeichnis
│	└── all.xml	 						- Unsere GWTMAP-Modulkonfiguration.		
│		└── client/	 Konfigurationsdatei. Für eine genauere Beschreibung siehe https://bit.ly/3FYB8BN
├── src/main/java/							- UnserHier package,legen dem wir Client-spezifischeunsere Packages und Klassen hinzufügenan.	└── org/jwt/	 						└── ApplicationEntryPoint.java- Unser verwendeter package-Name.
│		├── Application.gwt.xml					- Unsere GWT-EinstiegsklasseModulkonfiguration.		
├── src/main/resources/ 	
└── src/main/webapp/            		- Das entspricht unserem WAR-Verzeichnis. 
    ├── index.html
	└── WEB-INF/	
		└── web.xml         

Details zu den Implementierungen folgen weiter unten.

Vorbereiten der Entwicklungsumgebung

Für Eclipse und IntelliJ IDEA gibt es jeweils nützliche GWT-Plugins, die bei der Entwicklung von GWT-Projekten sehr hilfreich sind. Wir zeigen hier die initiale
client/	 							- Unser package, dem wir Client-spezifische Klassen hinzufügen
│  			└── ApplicationEntryPoint.java		 	- Unsere GWT-Einstiegsklasse.	
│		└── server/								- Hier legen wir Klassen ab, die nur auf Server-Seite benötigt werden. 
│  			└── SpringBootApplication00x.java	- Die Start-Klasse für den Server mit Spring Boot Konfiguration
├── src/main/resources/ 	
└── src/main/webapp/            		- Das entspricht unserem WAR-Verzeichnis. 
    ├── index.html 							- index html, aus der wir ein HTML Element nutzen um den GWT-Code einzuhängen

Details zu den Implementierungen folgen weiter unten.

Vorbereiten der Entwicklungsumgebung

Für Eclipse und IntelliJ IDEA gibt es jeweils nützliche GWT-Plugins, die bei der Entwicklung von GWT-Projekten sehr hilfreich sind. Wir zeigen hier die initiale Einrichtung in beiden Umgebungen.

Eclipse

Erweitern
titleFür die Einrichtung in Eclipse hier erweitern...

Installation des GWT-Plugins

Die einfachste Möglichkeit das GWT-Eclipse-Plugin zu installieren ist über den Eclipse-Marketplace. Hier suchen wir nach GWT und wählen in der Ergebnisliste den Eintrag "GWT Eclipse Plugin" aus.

Info
Eine ausführliche Installationsanleitung des GWT-Eclipse-Plugins befindet sich hier.

Download des aktuellen GWT-SDK

Unter http://www.gwtproject.org/download.html müssen wir noch das aktuelle GWT-SDK herunterladen und lokal ablegen. Das SDK benötigen wir im nächsten Schritt zur Projektkonfiguration.

Konfiguration des Projekts

In den Properties des Projekts aktivieren wir GWT indem wir unter GWT > General Settings den Haken bei Use GWT setzen. Außerdem konfigurieren wir unter Configure SDKs die aktuelle GWT-SDK, die wir im letzten Schritt heruntergeladen haben.

Image RemovedImage Added


Unter GWT > Web Application konfigurieren wir noch als WAR-Verzeichnis unser webapp-Verzeichnis.

Image RemovedImage Added

IntelliJ IDEA

Erweitern
titleFür die Einrichtung in IntelliJ hier erweitern...

Installation des GWT-Plugins

Initiale Installation von IntelliJ IDEA

Das GWT-Plugin kann unter anderem beim allerersten Start von IntelliJ IDEA konfiguriert werden. Hier kann GWT als eines der Java Frameworks im Customize IntelliJ IDEA Dialogausgewählt werden:

Image RemovedImage Added

Nachträgliche Installation des Plugins

Die zweite Möglichkeit ist die Konfiguration im Menü über File > Settings. Unter Plugins musshier GWT aktiviert werden.

Image RemovedImage Added

Info
Eine ausführliche Installationsanleitung des GWT-Plugins für IntelliJ IDEA findet sich hier.

Download des aktuellen GWT-SDK

Außerdem müssen wir unter http://www.gwtproject.org/download.html das aktuelle GWT-SDK herunterladen und lokal ablegen. Das SDK benötigen wir weiter unten für die Konfiguration der GWT-Module.

Konfiguration des Projekts

In der Regel erkennt IntelliJ IDEA automatisch, dass es sich bei dem Projekt um ein GWT-Projekt handelt und zeigt den Dialog Frameworks Detected. Über Configure können die Projekte dann initial konfiguriert werden:

Image RemovedImage Added


Das GWT-Verzeichnis müssen wir in den Project Settings hinterlegen. Dazu öffnen wir File > Project Structure und wählen Facets, dann GWT und wählen den Reiter Defaults:

Image RemovedImage Added

Folgendes muss eingetragen werden:

  • Path to GWT installation directory
    Hier muss das lokale GWT-Installationsverzeichnis konfiguriert sein.

Die erkannten GWT-Module müssen wir im selben Menü überprüfen. Dazu wechseln wir zu Modules und wählen ein jwt-tutorial-Modul > GWT:

Image RemovedImage Added

Folgendes muss sichergestellt werden:

  • Target Web Facet
    Als Target-Web-Facet muss das bereits vorkonfigurierte Web-Facet ausgewählt sein.
Info
Hat die automatische Erkennung nicht funktioniert, müssen dem Modul beide Facets manuell über Add hinzugefügt werden.


Maven

Erläuterung zum Maven Build

Die für unser Beispiel-Projekt benötigten GWT- Bibliotheken werden über folgende Dependencies eingebundenMaven eingebunden. Im folgenden Kapitel werden einzelne relevante Abschnitte aus der pom.xml näher beschrieben. Am Ende listen wir die komplette Datei für einen Überblick.

Dependencies

Zunächst definieren wir einige Parameter, die in anderen Abschnitten referenziert werden. Hierunter fallen insbesondere die Versionen der zu verwendenden Komponenten:

Codeblock
languagexml
themeRDark
titlepom.xml - dependenciesVersionen
<dependency><properties>
	<!-- General  <groupId>com.google.gwt</groupId>
   <artifactId>gwt-user</artifactId>
   <version>2.8.2</version>
   <scope>provided</scope>
</dependency>
<dependency>
   <groupId>com.google.gwt</groupId>
   <artifactId>gwt-dev</artifactId>
   <version>2.8.2</version>
   <scope>provided</scope>
</dependency>
Da GWT Java 8 voraussetzt müssen wir noch den Compiler entsprechend konfigurieren
project settings -->
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>

	<!-- levigo dependencies -->
	<jwt.version>5.10.52.2</jwt.version>

	<!-- GWT dependencies -->
	<gwt.version>2.9.0</gwt.version>
</properties>


Im DependencyManagement-Block importieren wir die JWT-Starter BOM (Bill of Material). Dadurch erhalten wir die Versionen aller zugehörigen JWT Dependencies und müssen diese nicht separat pflegen.

Codeblock
languagexml
themeRDark
titlepom.xml - compiler-properties
<properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
</properties>

Damit beim Bau unseres Moduls alle benötigten GWT-dependencies im WAR landen, müssen wir das gwt-maven-plugin konfigurieren:

<build>
Codeblock
languagexml
themeRDark
titlepom.xml - gwt-maven-plugin
collapsetrue
dependency management
<dependencyManagement>
    <dependencies>
        <!-- Let's import the Jadice Webtoolkit bill of material. JWT dependency
            versions will be managed via this BOM. -->
        <dependency>
 <plugins>  			<!-- Configure the gwt-clean-plugin to generate a deployable war -->
 <groupId>com.levigo.jadice.webtoolkit</groupId>
           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>gwt-maven-plugin< <artifactId>webtoolkit-spring-boot-bom</artifactId>
                <version>${gwtjwt.version}</version>
            <scope>import</scope>
   <executions>         <type>pom</type>
        </dependency>
  <execution>                         <goals>
                            <goal>resources</goal>
          </dependencies>
</dependencyManagement>


Anschließend definieren wir die benötigten Abhängigkeiten für das Projekt. Dabei müssen wir keine Versionen angeben, da diese aus der BOM ermittelt werden:

Codeblock
languagexml
themeRDark
titlepom.xml - dependencies
<dependencies>
	<!-- Dependency versions are managed by parent / imported BOMs -->

	<!-- JWT via Spring-Boot Starter -->
	<dependency>
		<groupId>com.levigo.jadice.webtoolkit</groupId>
		<artifactId>webtoolkit-spring-boot-starter</artifactId>
	</dependency>
	
	<!-- Required for SuperDev mode -->
	<dependency>
		<groupId>com.levigo.jadice.webtoolkit</groupId>
		<artifactId>webtoolkit-spring-boot-devmode</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
	</dependency>
</dependencies>

Weitere Informationen zur Verwendung der BOM finden Sie unter Maven BOM im webtoolkit.

Build-Prozess

Für den Build-Lauf, dessen Ziel die Erstellung einer ausführbaren jar-Datei ist, benötigen wir einige Plugins. Diese erläutern wir in den folgenden Absätzen.

Erweitern
titlepom.xml - Build-Prozess

Maven Assembly Plugin - Dieses Plugin verwenden wir, um unsere Web-Ressourcen in den Standard Ordner für Web-Ressourcen von Spring Boot zu kopieren:

Codeblock
languagexml
themeRDark
titlepom.xml - assembly plugin
<!-- We use the assembly plugin to copy the index.html to the 'public' folder -->
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-assembly-plugin</artifactId>
	<version>3.1.0</version>
	<executions>
		<execution>
			<id>assemble</id>
			<phase>package</phase>
			<goals>
				<goal>single</goal>
			</goals>
			<configuration>
				<descriptors>
					<descriptor>src/main/assembly/all.xml</descriptor>
				</descriptors>
				<appendAssemblyId>false</appendAssemblyId>
			</configuration>
		</execution>
	</executions>
</plugin>

In der Datei src/main/assembly/all.xml definieren wir, welche Dateien vom Maven Assembly Plugin kopiert werden sollen. Wir wollen hier die Web-Ressourcen aus "src/main/webapp" in den "public"-Ordner kopieren (dies ist der Standard Ordner für Web-Ressourcen von Spring-Boot):

Codeblock
languagexml
themeRDark
titleall.xml
<assembly
        xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

    <id>all</id>

    <formats>
        <format>dir</format>
        <format>jar</format>
    </formats>

    <includeBaseDirectory>false</includeBaseDirectory>

    <fileSets>
    	<!-- Copy web resources to 'public' folder (the default folder for web-resources from spring boot) -->
        <fileSet>
            <directory>src/main/webapp</directory>
            <outputDirectory>public</outputDirectory>
            <includes>
                <include>imageviewer/**</include>
                <include>**/*.html</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${project.build.directory}/classes</directory>
            <outputDirectory></outputDirectory>
            <filtered>false</filtered>
        </fileSet>
    </fileSets>
</assembly> 


Spring Boot Maven Plugin: Dieses Plugin sorgt dafür, dass beim Maven-Build eine ausführbare jar-Datei mit allen benötigten Abhängigkeiten entsteht:

Codeblock
languagexml
themeRDark
titlepom.xml - spring boot maven plugin
<!-- Use spring boot maven plugin to create an executable JAR with all 
				dependencies -->
<plugin>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-maven-plugin</artifactId>
	<version>2.2.13.RELEASE</version>
	<executions>
		<execution>
			<goals>
				<goal>repackage</goal>
			</goals>
		</execution>
	</executions>
</plugin>


GWT Maven Plugin: Mit diesem Plugin werden die clientseitigen Java-Quellen nach Javascript compiliert:

Codeblock
languagexml
themeRDark
titlepom.xml - gwt maven plugin
<!-- We use the gwt maven plugin to compile the client side javascript 
				files from java sources -->
<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>gwt-maven-plugin</artifactId>
	<version>${gwt.version}</version>
	<executions>
		<execution>
			<goals>
				<goal>resources</goal>
				<goal>compile</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<failOnError>true</failOnError>
		<inplace>true</inplace>
	</configuration>
</plugin>


Wir verwenden das Maven Clean Plugin, um temporäre GWT-Dateien aufzuräumen:

Codeblock
languagexml
themeRDark
titlepom.xml - maven clean plugin
<!-- On clean, also delete the temporary /src/main/gwt-unit-cache folder 
				which is created by the gwt compiler -->
<plugin>
	<artifactId>maven-clean-plugin</artifactId>
	<version>2.4.1</version>
	<executions>
		<execution>
			<phase>clean</phase>
			<goals>
				<goal>clean</goal>
			</goals>
			<configuration>  
				<filesets>
                	<fileset>
	                  <directory>src/main/gwt-unitCache</directory>
    	              <includes>
        	            <include>**</include>
            	      </includes>
                	  <followSymlinks>false</followSymlinks>
	                </fileset>
    	            <fileset>
        	          <directory>.springboot-gwt-devmode</directory>
            	      <includes>
                	    <include>**</include>
	                  </includes>
    	              <followSymlinks>false</followSymlinks>
        	        </fileset>
              </filesets>    
			</configuration>
		</execution>
	</executions>
</plugin>


Eclipse-Benutzer erhalten unter Umständen eine Meldung in der IDE: "Plugin execution not covered by lifecycle configuration". Um diese Meldung zu umgehen, verwenden wir folgenden Block:

Codeblock
languagexml
themeRDark
<!-- This section is only needed for Eclipse users to get rid of the errors 
			in the POM regarding 'plugin execution not covered by lifecycle configuration' 
			which is thrown by the M2E Plugin for no sensible reason. 
			
			When not using the Eclipse IDE, this section can be ignored -->
<pluginManagement>
	<plugins>
		<plugin>
			<groupId>org.eclipse.m2e</groupId>
			<artifactId>lifecycle-mapping</artifactId>
			<version>1.0.0</version>
			<configuration>
				<lifecycleMappingMetadata>
					<pluginExecutions>
						<pluginExecution>
							<pluginExecutionFilter>
								<groupId>org.codehaus.mojo</groupId>
								<artifactId>gwt-maven-plugin</artifactId>
								<versionRange>[2.4.0,)</versionRange>
								<goals>
									<goal>resources</goal>
									<goal>compile</goal>
									<goal>i18n</goal>
									<goal>generateAsync</goal>
								</goals>
							</pluginExecutionFilter>
							<action>
								<execute />
							</action>
						</pluginExecution>
						<pluginExecution>
							<pluginExecutionFilter>
								<groupId>org.apache.maven.plugins</groupId>
								<artifactId>maven-war-plugin</artifactId>
								<versionRange>[2.1.1,)</versionRange>
								<goals>
									<goal>exploded</goal>
								</goals>
							</pluginExecutionFilter>
							<action>
								<execute />
							</action>
						</pluginExecution>
					</pluginExecutions>
				</lifecycleMappingMetadata>
			</configuration>
		</plugin>
	</plugins>
</pluginManagement>


komplette pom.xml

Codeblock
languagexml
themeRDark
titlepom.xml - komplett
collapsetrue
<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">

  <groupId>org.jwt</groupId>
  <artifactId>jwt-tutorial-000</artifactId>
  <version>5.10.52.2</version>

  <description>Getting Started - jadice web toolkit</description>
  <url>https://levigo.de/info/x/cwGABQ</url>

  <modelVersion>4.0.0</modelVersion>

  <properties>
    <!-- General project settings -->
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>

    <!-- levigo dependencies -->
    <jwt.version>5.10.52.2</jwt.version>

    <!-- GWT dependencies -->
    <gwt.version>2.9.0</gwt.version>
  </properties>

  <dependencies>
    <!-- Dependency versions are managed by parent / imported BOMs -->

    <!-- JWT via Spring-Boot Starter -->
    <dependency>
      <groupId>com.levigo.jadice.webtoolkit</groupId>
      <artifactId>webtoolkit-spring-boot-starter</artifactId>
    </dependency>

    <!-- Required for debugging purposes (GWT SuperDev mode). Consider removing those in production -->
    <dependency>
      <groupId>com.levigo.jadice.webtoolkit</groupId>
      <artifactId>webtoolkit-spring-boot-devmode</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-devtools</artifactId>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <!-- Let's import the jadice web toolkit bill of material. JWT dependency
        versions will be managed via this BOM. -->
      <dependency>
        <groupId>com.levigo.jadice.webtoolkit</groupId>
        <artifactId>webtoolkit-spring-boot-bom</artifactId>
        <version>${jwt.version}</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <!-- We use the assembly plugin to copy the index.html to the 'public'
        folder -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.1.0</version>
        <executions>
          <execution>
            <id>assemble</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
            <configuration>
              <descriptors>
                <descriptor>src/main/assembly/all.xml</descriptor>
              </descriptors>
              <appendAssemblyId>false</appendAssemblyId>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <!-- Use spring boot maven plugin to create an executable JAR with all
        dependencies -->
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>2.2.13.RELEASE</version>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <!-- We use the gwt maven plugin to compile the client side javascript
        files from java sources -->
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <goal>compile</goal><artifactId>gwt-maven-plugin</artifactId>
        <version>${gwt.version}</version>
        <executions>
          <execution>
 <goal>test</goal>           <goals>
             < <goal>resources</goals>goal>
              <goal>compile</goal>
     </execution>       </goals>
          </executions>execution>
        </executions>
        <configuration>
          <failOnError>true</failOnError>
          <failOnError>true<<inplace>true</failOnError>inplace>
        </configuration>
      </plugin>

   <inplace>true</inplace>
           <!-- On clean, also delete the temporary /src/main/gwt-unit-cache folder
       </configuration>   which is created by the gwt compiler -->
  </plugin>    <plugin>
    </plugins>
</build>

Beim Aufruf von Maven clean soll generierter Code und temporäre GWT-Dateien korrekt aufgeräumt werden. Dazu konfigurieren wir das Maven-Clean-Plugin. Hier müssen wir auch darauf achten, dass die index.html und die web.xml davon ausgenommen werden. Im Laufe der Entwicklung ist es wahrscheinlich, dass wir diese Liste ergänzen müssen:

Codeblock
languagexml
themeRDark
titlepom.xml - maven-clean-plugin
collapsetrue
    <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-clean-plugin</artifactId>
        <version>2.4.1</version>
        <executions>
          <plugins><execution>
             <!-- Configure the maven-clean-plugin to delete GWT-temp files at cleanup -->
 <phase>clean</phase>
            <goals>
          <plugin>    <goal>clean</goal>
            <artifactId>maven-clean-plugin</artifactId></goals>
            <configuration>
              <filesets>
                <fileset>
         <version>3.1.0</version>         <directory>src/main/gwt-unitCache</directory>
       <executions>           <includes>
         <execution>           <include>**</include>
             <phase>clean</phase>     </includes>
                  <followSymlinks>false</followSymlinks>
<goals>                </fileset>
            <goal>clean</goal>    <fileset>
                  <directory>.springboot-gwt-devmode</directory>
 </goals>                 <includes>
       <configuration>             <include>**</include>
               <filesets>   </includes>
                  <followSymlinks>false</followSymlinks>
          <fileset>      </fileset>
              </filesets>
            </configuration>
  <directory>src/main</directory>        </execution>
        </executions>
      </plugin>
    </plugins>

    <!-- This <includes>section is only needed for Eclipse users to get rid of the errors
      in the POM regarding 'plugin execution not covered by lifecycle configuration'
      which is thrown by  <include>**</include>
    the M2E Plugin for no sensible reason.

      When not using the Eclipse IDE, this section can be ignored -->
    <pluginManagement>
      <plugins>
</includes>        <plugin>
           <groupId>org.eclipse.m2e</groupId>
          <artifactId>lifecycle-mapping</artifactId>
     <excludes>     <version>1.0.0</version>
          <configuration>
            <lifecycleMappingMetadata>
           <exclude>java/**</exclude>   <pluginExecutions>
                <pluginExecution>
                  <pluginExecutionFilter>
 <exclude>resources/**</exclude>                   <groupId>org.codehaus.mojo</groupId>
                     <exclude>**/index.html</exclude><artifactId>gwt-maven-plugin</artifactId>
                    <versionRange>[2.4.0,)</versionRange>
                   <exclude>**/web.xml</exclude> <goals>
                      <goal>resources</goal>
                 <exclude>**/.gitignore</exclude>     <goal>compile</goal>
                      <goal>i18n</goal>
        </excludes>              <goal>generateAsync</goal>
                    </fileset>goals>
                  </pluginExecutionFilter>
            </filesets>      <action>
                  </configuration>  <execute/>
                  </execution>action>
                </executions>pluginExecution>
                <pluginExecution>
   </plugin>

Unsere vollständige pom.xml enthält natürlich noch weitere Informationen, wie z. B. die Artefakt-Beschreibung:

Codeblock
languagexml
themeRDark
titlepom.xml - vollständig
collapsetrue
<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">

	<groupId>org.jwt</groupId>
	<artifactId>jwt-tutorial-000</artifactId>
	<version>5.8.2.0</version>

	<description>Getting Started - jadice web toolkit</description>
	<url>https://levigo.de/info/x/cwGABQ</url>
	
	<modelVersion>4.0.0</modelVersion>
	<packaging>war</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>

		<!-- GWT -->
		<gwt.version>2.8.2</gwt.version>
	</properties>

	<dependencies>
		<!-- General GWT dependencies -->
		<dependency>
			<groupId>com.google.gwt</groupId>
			<artifactId>gwt-user</artifactId>
			<version>${gwt.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.google.gwt</groupId>
			<artifactId>gwt-dev</artifactId>
			<version>${gwt.version}</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>


	<build>
		<plugins>

			<!-- Configure the gwt-clean-plugin to generate a deployable war -->
			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>gwt-maven-plugin</artifactId>
				<version>${gwt.version}</version>
				<executions>
					<execution>
						<goals>
							<goal>resources</goal>
							<goal>compile</goal>
							<goal>test</goal>
						</goals>
					</execution>
				</executions>
				<configuration>
					<failOnError>true</failOnError>
					<inplace>true</inplace>
				</configuration>
			</plugin>

			<!-- Configure the maven-clean-plugin to delete GWT-temp files at cleanup -->
			<plugin>
				<artifactId>maven-clean-plugin</artifactId>
				<version>3.1.0</version>
				<executions>
					<execution>
						<phase>clean</phase>
						<goals>
							<goal>clean</goal>
						</goals>
						<configuration>
							<filesets>
								<fileset>
									<directory>src/main</directory>
									<includes>
										<include>**</include>
									</includes>
									<excludes>
										<exclude>java/**</exclude>
										<exclude>resources/**</exclude>
										<exclude>**/index.html</exclude>
										<exclude>**/web.xml</exclude>
										<exclude>**/.gitignore</exclude>
									</excludes>
								</fileset>
							</filesets>
						</configuration>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>               <pluginExecutionFilter>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <versionRange>[2.1.1,)</versionRange>
                    <goals>
                      <goal>exploded</goal>
                    </goals>
                  </pluginExecutionFilter>
                  <action>
                    <execute/>
                  </action>
                </pluginExecution>
              </pluginExecutions>
            </lifecycleMappingMetadata>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>


Die Application.yml

Die Application.yml wird von Spring verwendet, um Konfigurationsparameter zu setzen. Hier im Beispiel geben wir nur einen Parameter an, um den Port des Servers festzulegen:

Codeblock
server:
  port: 8080


Die Application.yml ist Bestandteil des Spring-Standardmechanismus zum Laden von externer Konfiguration. Neben einfachen Schlüssel-Wert-Paaren für Spring-Komponenten können darin auch eigene applikationsspezifische Einstellungen abgelegt werden.

Weitere Informationen hierzu können in der Spring-Dokumentation gefunden werden.


Modulkonfiguration (gwt.xml)

Damit der GWT-Compiler weiß, welcher Code nach JavaScript übersetzt werden soll, benötigen wir eine Modulkonfiguration. Wir legen dazu eine Konfigurationsdatei mit der Endung gwt.xml in das Package unserer Wahl. In unserem Beispiel nennen wir die Konfiguration Application.gwt.xml und nutzen das Package org.jwt:

Codeblock
languagexml
themeRDark
titlesrc/main/java/org/jwt/Application.gwt.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.8.0//EN" "http://www.gwtproject.org/doctype/2.8.2/gwt-module.dtd">
<module rename-to="imageviewer">
    <inherits name="com.google.gwt.user.User" />
	<inherits name="com.google.gwt.user.theme.chrome.Chrome" />

    <!-- The locale configuration. -->
    <extend-property name="locale" values="de,en" />
    <set-property name="locale" value="de,en" />
    <set-property-fallback name="locale" value="en" />

 	<!-- Define all subpackages which sources are used in the client. In our case: org.jwt.client -->
    <source path="client" />

    <!-- The entry-point of the application -->
    <entry-point class="org.jwt.client.ApplicationEntryPoint" />
</module>


Die Konfiguration kurz erläutert:

  • module
    Wir geben unserer GWT-Anwendung den Namen imageviewer. Der generierte JavaScript-Code erhält diesen Namen: imageviewer/imageviewer.nocache.js
  • extend-property
    Hier konfigurieren wir unsere verfügbaren Lokalisierungs-Dateien. Die JWT-Module bieten Standard-Lokalisierungen für de (deutsch) und en (englisch). Natürlich können auch eigene Lokalisierungen ergänzt werden, vgl. http://www.gwtproject.org/doc/latest/DevGuideI18nLocale.html.
  • set-property-fallback
    Unsere Standard-Lokalisierung stellen wir auf en.
  • inherits
    Hierwerden die GWT-Module angegeben, die wir erweitern wollen.
  • source
    Unter source sind alle Subpackages definiert, die auf Client-Seite vorliegen müssen und entsprechend nach JavaScript kompiliert werden sollen. Das Package wird relativ zur gwt.xml angegeben. Der GWT-Compiler übersetzt in unserem Beispiel also alles im Package org.jwt.client. Alle Klassen die nicht unterhalb eines so definierten Source-Packages liegen, sind nicht im Client verfügbar und führen zur Laufzeit zu Fehlern.
  • entry-point
    Zuletzt teilen wir dem GWT-Compiler über den ApplicationEntryPoint mit, welche Klasse den Einstiegspunkt unserer Anwendung darstellt. Diese wird beim Client-seitigen Aufruf der Applikation, also beim Laden der JavaScript-Datei, ausgeführt. In unserem Beispiel nennen wir unsere Einstiegspunkt-Klasse, die wir im nächsten Schritt erstellen, org.jwt.client.ApplicationEntryPoint.

EntryPoint

Wir erstellen nun den in der gwt.xml konfigurierten EntryPoint:

Codeblock
languagejava
themeRDark
titleorg.jwt.client.ApplicationEntryPoint.java
package org.jwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;

/**
 * This is the applications {@link EntryPoint} as defined in the "Application.gwt.xml".
 */
public class ApplicationEntryPoint implements EntryPoint {
    @Override
    public void onModuleLoad() {
        GWT.log("jwt tutorial loaded");
    }
}

Unsere Anwendung gibt bisher nur die Meldung "jwt tutorial loaded" in der Browserkonsole aus. Wir binden noch keine Benutzeroberflächen-Elemente ein.

Deployment Descriptor: web.xml

Wie für jede Webanwendung benötigen wir einen Deploymentdeskriptor, der unsere Anwendung dem zugrundeliegenden Servletcontainer bekannt macht. Dazu legen wir im WEB-INF-Verzeichnis die Datei web.xml an:

Codeblock
languagexml
themeRDark
titleweb.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee" 
		 xmlns:web="http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
		 version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee">
	
	<display-name>jwt-tutorial-000</display-name>

 </web-app>user.client.Window;

/**
 * This is the applications {@link EntryPoint} as defined in the
 * "Application.gwt.xml".
 */
public class ApplicationEntryPoint implements EntryPoint {

	@Override
	public void onModuleLoad() {
		Window.alert("jwt tutorial loaded");
	}
}

Unsere Anwendung gibt bisher nur die Meldung "jwt tutorial loaded" als Popup-Window aus und wir greifen noch nicht auf jadice web toolkit Funktionalitäten zu. Einzig GWT und Spring Boot werden dadurch wirklich verwendet.

Deployment Descriptor: web.xml

Durch Spring Boot werden ServletContaine via Annotationen registriert und nicht mehr über die web.xml. Für eine Migration siehe z.B. hier: https://www.baeldung.com/spring-boot-dispatcherservlet-web-xml

Host-Page: index.html

Jede GWT-Anwendung wird in eine HTML-Seite, die sogenannte Host-Page, eingebettet. Unsere index.html legen wir ins webapp-Verzeichnis. Wir binden den generierten JavaScript-Code, wie jedes andere JavaScript auch, über das script-Element ein.

Codeblock
languagexml
themeRDark
titleindex.html
<!doctype html>
<html>
<head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8">
   <title>tutorial 0</title>
   <script src="imageviewer/imageviewer.nocache.js" type="text/javascript"></script>
</head>

<body style="margin: 0; padding: 0/html; charset=UTF-8">
   JWT Tutorial 000. GWT-Projekt erfolgreich gestartet. 
</body>
</html>

Start der Anwendung

Zum Anstarten unserer Applikation müssen wir für die Entwicklungsumgebungen wieder einige Besonderheiten beachten:

Eclipse

Erweitern
titleFür den Start aus Eclipse hier erweitern...

Bevor wir die Anwendung starten, müssen wir sicherstellen, dass die Anwendung korrekt kompiliert wurde. Das können wir z.B. über Maven > Update Maven Project oder einen Maven compile erreichen.

Die Anwendung können wir nun starten indem wir auf dem Projekt Run As > GWT Development Mode with Jetty aufrufen. Beim ersten Start fragt Eclipse erneut nach dem WAR-Verzeichnis. Hier geben wir wieder unser webapp-Verzeichnis an:

Image Removed

Sobald das Projekt erfolgreich kompiliert wurde, wird im Tab Development Mode die URL http://127.0.0.1:8888/index.html angezeigt. Wir können diese Seite dann im Browser unserer Wahl anzeigen.

IntelliJ IDEA

<title>tutorial 0</title>
   <script src="imageviewer/imageviewer.nocache.js" type="text/javascript"></script>
</head>

<body style="margin: 0; padding: 0">
   JWT Tutorial 000. GWT-Projekt erfolgreich gestartet. 
</body>
</html>

Start der Anwendung

Aus der IDE

Der Start des Servers erfolgt, indem wir die Klasse "MySpringBootApplication" ausführen - diese beinhaltet die main()-Methode und startet die Spring Boot Applikation.

Erweitern
titleFür den Start aus IntelliJ hier erweitern...

Zum Starten der Anwendung müssen wir eine neue Run Configuration erstellen. Dazu wählen wir im Menü Run > Edit-Configuration, um die Run/Debug Configurations zu öffnen. Nun fügen wir über Add New Configuration eine neueGWT  Spring Boot Configuration hinzu:

Image RemovedImage Added


Die neue Konfiguration müssen wir nun auf unser Projekt anpassen:

Image Removed

  • Module
    Wir wählen unser Module GWT-Modul jwt-tutorial-000 aus.
  • VMoptions
    GWT-Applikationen benötigen in der Regel mehr Speicher als die standardmäßig ausgewählten 512MB. Wir setzen den Wert deshalb über -Xmx1024m auf 1024MB.
  • Working directory
    Hier wählen wir unser webapp-Verzeichnis aus.
  • Start page
    Hier sollte nach des Auswahl des Moduls bereits unsere index.html ausgewählt sein.

Die Konfiguration kann nun im Menü unter Run > Run zum Starten der Applikation verwendet werden. Sobald das Projekt erfolgreich kompiliert wurde, wird der konfigurierte Browser automatisch geöffnet (vgl. Run Configuration > Open in browser)Image Added

  • Main class
    Hier sollte nach des Auswahl des Moduls bereits unsere SpringBootApplication000 ausgewählt sein.
  • classpath
    Wir wählen unser Modul jwt-tutorial-spring-boot-000 aus.
  • Working directory
    Hier wählen wir unser jwt-tutorial-spring-boot-000-Verzeichnis aus.


Die Konfiguration kann nun im Menü unter Run > Run zum Starten der Applikation verwendet werden.

Via executable Jar

Hierfür führen wir einen Maven-Build auf das Projekt aus. Als Ergebnis erhalten wir im target Folder ein einziges ausführbares Jar-File. Dieses starten wir auf der Kommandozeile mittels des Befehls "java -jar <filename>.jar"

Aufruf im Browser

Zugriff per Browser erfolgt dann über den Link http://localhost:8080

Zusammenfassung

In diesem Tutorial haben wir das Tutorial 2 der klassischen Tutorial-Reihe nach Spring Boot portiert. Funktional ist das Ergebnis identisch zum klassischen Tutorial. Der Unterschied besteht darin, dass die gesamte Anwendung inklusive des zugehörigen Application Servers in ein einziges Jar-File verpackt ist.

Dieses Packaging eignet sich gut, um es in ein Docker Image zu verpacken und anschließend in einer Cloud Infrastruktur zu betreiben. Das Erstellen eines solchen Docker Images beschreiben wir im folgenden Tutorial.




Zusammenfassung

In diesem Tutorial haben wir unser initiales GWT-Projekt erstellt. Wir haben die grundlegenden Konzepte von GWT kennengelernt, wie den EntryPoint und die gwt.xml. Außerdem haben wir unsere Entwicklungsumgebung konfiguriert, um mit dem passenden GWT-Plugin unsere Applikation starten zu können.

Das Ergebnis ist eine noch sehr statische Seite, die im Erfolgsfall einen Text ohne Fehlermeldung ausgibt. In der Browserkonsole sehen wir außerdem die Ausgabe "jwt tutorial loaded".

Image RemovedImage Added

...