Friday, February 22, 2019

Spring Boot with GWT using gradle build

Today I am going to write an interesting concept, which will be quite useful to quickly start and deploy a  big project without worrying about any javascript complexities.

It is well accepted that Spring Boot is very popular backend framework and I have to say, it is not quite supportive for front-end development. For that we have to use frontend development system using Javascript, because Javascript is the only option. And the communication to the server using Javascript makes less maintainable code. Also, using GWT, we write both server and client side program using a single programming language Java, which makes it a very scalabale and maintaible project. That's my experience because I use a framework called echo(echo.nextapp.com) which is quite stable and very very maintainable.

Lets begin implementing Spring boot with GWT. It seems a bit complicated, have a patience because end result is very interesting.

I am using eclipse IDE for development. So, I assume you have already installed it including JDK(1.8 is preferrable). Please be sure the installed gradle version is greater or equal to 4.0 for SpringBoot to work.

Step 1: Project Creation

Now create a new gradle project from eclipse IDE or using gradle command.

gradle init --type java-library


and just import created project into eclipse. This is the basic project project. We have modify this project.


Step 2: Configuration

We carry out build configuration in build.gradle file. It is recommended to remove all the contents and use the following content:
//build.gradle
buildscript{
repositories{
mavenCentral()
}
dependencies{
classpath 'org.wisepersist:gwt-gradle-plugin:1.0.6'
}
}

plugins{
//Required for springboot
id 'java'
id 'org.springframework.boot' version '2.1.3.RELEASE'
}
apply plugin: 'gwt'
apply plugin: 'io.spring.dependency-management'

sourceCompatibility =1.8
targetCompatibility=1.8
def GWT_VERSION='2.8.2' //latest version

repositories{
  jcenter()
}

//not needed (if you use default values). The following values
// are default values, so not necessary.
sourceSets{
main.java.srcDir "src/main/java"
main.resources.srcDir "src/main/resources"
test.java.srcDir "src/test/java"
test.resources.srcDir "src/test/resources"
}

dependencies{
//Just add this 4 libraries for gwt
compileOnly("com.google.gwt:gwt-user:${GWT_VERSION}")
    compileOnly("com.google.gwt:gwt-dev:${GWT_VERSION}")
    compileOnly('org.fusesource.restygwt:restygwt:2.2.3')
    compile('javax.ws.rs:javax.ws.rs-api:2.1.1')
    
    //Spring libraries
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-jetty')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    compile('org.springframework.boot:spring-boot-starter-web'){
      exclude module: 'spring-boot-starter-tomcat'    
    }      
}
 //gwt configuration
 gwt{
     gwtVersion=GWT_VERSION
     modules 'com.kpaudel.frontend.SpringBootGwt'
     maxHeapSize="1024M"
 }


//package
task copyGWTCode(type:Copy){
  //from compileGwt.outputs
  from file("${buildDir}/gwt/out")
  into file("${buildDir}/resources/main/static")
 }

 copyGWTCode.dependsOn compileGwt

 bootJar{
  dependsOn copyGWTCode
  doLast{
  mkdir "${buildDir}/target"
  setDestinationDir(file("${buildDir}/target"))
  copy()
  }

 } 

Step 3: Create a GWT module

It is important step. Here we provide the path of the module definition file. This file defines all GWT related information.  There can be multiple modules,  which should be first define in build.gradle file(in gwt block) above. In packaging system, suppose we create a package called

com.kpaudel.com.frontend

Then module information file is located in the package(the file extension of module file name is always *.gwt.xml). We create a module definition file name with the following contents:

   

So, we create two packages, one for client and one for shared.

com.kpaudel.frontend.client This package for client only files
com.kpaudel.frontend.shared This package for shared files(both client and server)

Like we defined entry point class in module definition file above, we create a Java File as entry point:
Here is a very simple example:

//SpringBootGwt.java
package com.kpaudel.frontend.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

public class SpringBootGwt implements EntryPoint {

@Override
public void onModuleLoad() {
RootPanel.get().add(new Label("Hello World"));
}
}

Step 4: Compilation

What we did so far can convert our java files into javascript file using the following gradle script in the project root path.

./gradlew compileGwt

The compiled javascript files are located in build/gwt/out/frontend folder. The folder name frontend comes from the module name defined in the module definition file.

Step 5: Server Stuffs

Now, we can do server stuffs now. Because we are backed up by very powerful spring framework, so we can do whatever we want using this technology.

Step 6: Packaging

Packing stuffs into a bundle jar is a bit complicated in the sense that we have to include some scripts in build.gradle file. Please have a look at the last lines of build.gradle file.

No comments:

Post a Comment