2015-12-31

Power up your node.js REST API


Building micro services can be very exciting. The ease and speed of creating them using node.js has changed the way devs think. From requirement analysis to continuous integration, micro services can be developed within weeks and operate quite impressively.
Using node.js you can create very robust apps with asynchronous calls by design. Still though there are some times where you may add up a little more in that and make your application even stronger and harder to collapse on tough situations like an unpredictable request that destroys the process or too much concurrent requests or maybe a dos attack from a hacker.
With this post I want to present some node modules that will help you overcome problems like these.

Module 1) cluster. This module comes in handy when you want to overcome memory limitations and processing power when using a single process app. Apart from that, will give you the ability to respawn dead node processes (like pm2 does).
Useful links:
http://www.sitepoint.com/how-to-create-a-node-js-cluster-for-speeding-up-your-apps/
https://nodejs.org/api/cluster.html

Module 2) express.  It is one of the best modules for creating HTTP endpoints. Some people prefer other modules like restify – and this is quite ok. Just use the one you think it fits more to you. Just keep in mind that in terms of speed express might be the best one.

Module 3) ddos. This module will give you some basic dos protection against malicious users. Probably you will never need it but again why risking it? Note though that ddos module will only protect you against simple dos attacks. If you also want protection against ddos attacks you will need something more. Personally, I believe that this is the work of the load balancer. Those that using Haproxy read this: http://blog.haproxy.com/2012/02/27/use-a-load-balancer-as-a-first-row-of-defense-against-ddos/ .
Useful links:
https://github.com/rook2pawn/node-ddos

Module 4) toobusy-js. This is one of the many implementations of the original toobusy module. What it does? When receiving an http request instead of trying to execute it, it first checks the load of the process. If the process is overburdened it returns a 503 response telling that the server is busy at the moment. So instead of having too many failures with timeouts you will return on some requests service unavailable fast and serve the rest normally.
Useful links:
https://www.npmjs.com/package/toobusy-js
https://hacks.mozilla.org/2013/01/building-a-node-js-server-that-wont-melt-a-node-js-holiday-season-part-5/

Module 5) bunyan. Yes it is a logger but who can live without a logger. Just be very cautious with production environments to only log what is necessary. Also bunyan’s log rotation using cluster is buggy so you should better avoid it. You should anyway let the operating system do the job with logrotate.

For your convenience I have created a github repo here with a template project which uses all the previous modules. Feel free to clone it and use it as your as a skeleton for your new project
Have fun!

Useful links:

https://github.com/mdagis/api-template



2015-10-29

Install Node.js on EC2 Linux AMI



Recently I wanted to install  node.js on ec2 linux machine and to my surprise this task turned to be a little more tedious than I thought it would be. The reason for that is mainly because there are many ways to do it each of them with their pros and cons. The only alternative that I found easier to follow was to run the command: "sudo yum install nodejs npm --enablerepo=epel" . Unfortunately the epel repository has a very old version of node so I had to stick with a better option.

In this topic I am going to cover the option to download the binaries and just add the node directory to path.

The steps:

1. Go to https://nodejs.org/dist/ and select the version of node.js that you want. Normally you will need the latest. When I did the installation i used https://nodejs.org/dist/v4.2.1/node-v4.2.1-linux-x64.tar.gz .

2. After selecting the url that you want go to your machine and create a folder to have your node installation (be sure that the owner of the folder is ec2-user, if not change it with chown). In my case I created /opt/ . Then download your package with the command: wget https://nodejs.org/dist/v4.2.1/node-v4.2.1-linux-x64.tar.gz

3. Uncompress the file with command: tar -xvzf node-v4.2.1-linux-x64.tar.gz  and then navigate to created folder. In my case it was node-v4.2.1-linux-x64

4. The last step now is to add the node bin directory to path. To do so just create a new file in /etc/profile.d/node.sh . Edit the file and add the line: pathmunge /opt/node-v4.2.1-linux-x64/bin/ . Save the file and then run: source /etc/profile to refresh profile and you are ready.


This should normally be enough to have your node installation up and running.

2015-09-20

How to survive from Node.js and JavaScript callbacks




Many people coming from Java ecosystem to Node.js (like I did) are facing problems to adjust with the new platform philosophy since the basic principles of JavaScript itself are way different from the other well-known Object Oriented Languages.

Personally I think the biggest problem that I had was to understand the nature of functions in JavaScript and subsequently the way callbacks behave.

The truth is the first time I read about them I thought that I understood them. Unfortunately understanding them was not enough because all those years of experience turned into a barrier for me.

I will try to present the conceptual problem that I had in the beginning and also what I did in order to overcome it.


THE PROBLEM


Let’s say that you want to make a simple program that does 3 steps.

Step1. It reads a file.

Step 2. It accepts a prompt from console with username and password.

Step 3. It sends an email connecting to the mail server using the given credentials and having as a body the file contents read from step 1.


Normally with a conventional OO language you would create 3 functions each one doing one step and call them all three from the body of a third with the order 1, 2, 3.

Most programming languages are doing things synchronously by default which means that step 2 will be executed after 1 and 3 after 2.

This is a sample of something we could do in Java. For the sake of the example please ignore the static and the lack of OO architecture.

public static void main(String[] args) {
        readfile();
        getCredentials();
        sendMail();
}

    public static void readfile(){}

    public static void getCredentials(){}

    public static void sendMail(){}


Unfortunately (and fortunately) the following work flow would not work in Node.js. When your code reaches the step 2 the result of step 1 will not be ready and on step 3 the result of step 2 will not be ready either. The reason is that most modules of node.js work asynchronously and that requires a more delicate approach.


THE SOLUTION


As a matter of fact there are 3 solutions.

A) Using callbacks properly

B) Using nested callbacks

C) Using Promises.

I will skip solution B and C because B is not a decent solution since the readability of the code would be terrible and C because it is a different topic.

I will try to focus on solution (A).


As we saw on the previous code we had 3 functions doing the work and one more calling those 3 with a sequence.

In Node.js you will only need the fourth function to trigger the Step 1 and passing as a parameter the function that knows what to do after Step 1 ends.

Note that the fourth function - let’s call it trigger function – will not do anything more than calling step 1. The callback function 1 will be responsible to acquire the result of step 1 and trigger step 2 passing a new callback to step 2. Call back function 2 will be called by step 2 after finishing and that will call step 3.


Here is a diagram showing the procedure:



Here is some ample code:


function trigger(){
    readfile(callBack1);
}

function callBack1(){
    getCredentials(callBack2);
}

function callBack2(){
    sendMail();
}

// Step 1

function readfile(nextStep) {
    fs.readfile(path, function (error, text) {
        nextStep();
    });
}

// Step 2

function getCredentials(nextStep) {
    prompt.getCredentials(value, function (error, result) {
        nextStep();
    });
}

// Step 3

function sendMail() {
    transporter.sendMail(mailOptions, function (error, info) {
        //done
    });
}

2015-06-02

Implement Simple Websocket with Node.js



It's been almost two months since I wrote anything in here and before moving forward in topics I will try to add something more with the web socket technology.

As I have written in the last topic here I 'd like to present a very simple way to create Websocket server. This was implemented with Java EE7.

This time I wanted to try to use Node.js and to my surprise things got much easier.

The only thing I had to do (apart from installing Node.js) was to install the module ws with the command:

npm install ws


That's it! Now the following code is a sample of doing the whole thing:


... and in case you haven't read the previous post here is the html5 client to test it:

2015-04-05

JavaEE7 Websocket Example


In this tutorial I will try to present a very easy way to create a minimal Websocket Application using Java EE7.

The specific web application will have a working  Websocket Server deployable on every Java EE7 container plus a basic HTML5 page that will act as a client just to test your work.

Let's get started then. The first thing that you will have to do is to create a web application. I used Netbeans IDE but you can do exactly the same thing using your IDE of preference or even just using maven and a text editor.

For those that use Netbeans go to -> New Project -> Maven -> Web Application. Give a name to your application and Select Java EE 7 Web.

The whole Websocket server will consist of 4 classes, the Message Class, the Encoder Class, the Decoder Class and the ServerEndpoint Class.

Here is the sample code for all 4 classes plus the HTML client:



2015-03-29

RESTful API testing tools comparison





Tool name Description Testing CI integration Total
SOAP UI 3 2 3 3
REST-assured 5 1 2 3
Postman 3 2 5 4
frisby.js 5 4 2 4
RAML 1 4 5 4
Runscope Radar 3 3 5 3
Dredd 1 3 2 2



Read the analysis here

... or read all 6 chapters here

2015-03-12

HTML Barcode Scanner















Have you ever tried to type in a long number on your cell phone or simply enter the number of your membership card into a web application?

This might be a time consuming and error prone task which can be avoided by using barcodes.
This is nothing new. Many solutions exist for reading barcodes with a regular camera, like zxing, but they require a native platform such as Android or iOS.

Building your own application in two different platforms its not the easiest thing to do because it requires a lot of effort to develop and maintain in parallel. Of course there are cross platform mobile SDKs that give you the flexibility - and some of them are quite exciting like Phonegap/Cordova.

The problem is that you will need to learn and invest on a new API which might lead to unfortunate results.

If let's say you have build and invest a lot of know-how and source code in a technology that will not evolve, then your company will be exposed to a big risk.

If we had to gather up all the requirements needed in order to build an application that uses the device camera to scan barcodes, we would probably come up with the following aspects:

- It must be able to use the mobile's/tablet's camera to scan barcodes quickly enough.

- It must be developed in one platform (at least the 95% of it) in order to avoid duplicate work and maintenance.

- It must be developed with a widely approved technology that minimizes the possibility to be discontinued or having everlasting bugs.

After thoroughly examining the related technologies and the requirements that I had, I concluded on 2 different solutions and each of them had it's own strengths and weaknesses.


Solution A. Pure HTML5.

This is a very promising solution since it is all implemented in HTML. The HTML5 specification gives to the developer a very powerful toolset that can even gain access to the device camera. Hopefully there are people that have took advantage of it and have already implemented a javascript library that actually does the work.

The best implementation I have come across so far is made by Christoph Oberhofer and it is named quaggaJS. The specific library although it feels a bit immature  works quite impressive on specific devices and browsers. Those that are interested may have a look on http://serratus.github.io/quaggaJS/ which is the original web site. You can also read a nice article in Mozilla about it here

https://hacks.mozilla.org/2014/12/quaggajs-building-a-barcode-scanner-for-the-web/ .


After testing it for a while on android I realized that it still has some issues important enough to be a barrier for production environment.
Some of them are:

- It fails to use camera's autofocus on some browsers. On Android I managed to make it work in Firefox but I had no luck with chrome.

-  It's a bit slow on scan. The main requirement of the project is to make it easier to scan than typing. If it takes more time to scan the people will prefer to type.


Solution B. HTML & Native app hybrid.

This solution is a bit hard to grasp the first time you hear about but it makes sense after a while. The basic idea is to write the whole application business logic in pure HTML and leave only the scanning part for the native app. Then in order to activate the scan ability of you phone you can click a link of a URL. The specific url is hooked by a native android/ios application where it's only scope is to scan and return the value to the caller.

If you don't know how to open a native app from browser in android you can read here whereas  those that want to do in ios should read here.

The tricky part here is returning the scanned value back to browser since there is an obvious isolation between them. Unfortunately the cookies cannot help you since the native application's cookies cannot be accessed by the caller browser. So what is left?

The solution that I though was to have browser open the app and at the same time passing a unique token code. Then, after the native app scans the barcode it will make an http post to a web service passing as parameter the token and the value scanned. After that, the mobile app will close automatically and return focus to the caller browser. At the same time the browser should poll the same web service and actual ask it if there is available any value with the specific token.

Here is a diagram describing the process flow.







With this technique, when the value arrives from the mobile app to the web service, the web application will learn about it and display on GUI.

You might think that this is too complicated but we have actually managed to implement a full operational proof of concept with a colleague of mine in a few hours.

Here is a commercial app that more or less does the same.

 



2015-03-10

Enable CORS v2 Spring Boot



Using REST web services directly from a web page using javascript/jquery/angularjs is one of the hot issues these days. My guess is that many people (like me) have bugged a bit, trying to find out how to make it work using Spring Boot Rest Web Services.
The obstacle that stands between you and the solution has a name and this is CORS.
On my previous post here, I have some short explanation of what it is and how to overcome it in Java EE environment.
On Spring Boot we will need to do almost the same thing except from the fact that instead of changing a web.xml, we will add a configuration class that does more or less the same thing.

How to start then?  First follow this guide in order to create a REST web service with CORS enabled. Yeah that's right. Spring.io will give you a great step by step guide how to do it. The problem is though that if it happens to also want to have some basic security there, then the CORS will break again. So, after completing the previous guide open you pom.xml and add the following dependency:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>


This will add some basic http authentication with a user named "user" and a random password that will be created each time you start your app (something like: Using default security password: 8f608422-3faf-4f94-b60a-67ebd966af10).

Now, the trick is to add the following class:



This will do 2 things.
1) Add a user admin will password 1111 on group USER.
2) Enable OPTIONS request to be called without basic http authentication.

That's it. you are done!

2015-03-08

Enable CORS on JavaEE Web Application



Let's say that you have created a REST API in your Java EE WEB Application and you want to use it in HTML pages through AngularJS, jQuery or even plain JS. If you were newb (like I was), you would expect that this is going to work out of the box (as is) since your API has already been used in many cross platform clients without any problem.

Unfortunately though, for Murphy's sake, this is not the case. Due to Same-origin policy  http requests that are made in browsers must be done with a very specific way in order to work when the caller (web site) is on different domain than the web service (REST API).

In order to make it work, the caller must perform CORS  HTTP request to the WEB service and the web service subsequently must be modified in order to support CORS requests.

When I first came across to that problem I thought that this would be a-half-an-hour-problem but it wasn't. I had to spend a full day on this (thankfully on weekend) until the problem was completely "solved and working" on every modern browser.

For your web services, to support CORS requests you must deal with 2 problems.

1) CORS HEADERS

The first problem is about adding some additional HTTP headers (CORS) in your HTTP responses. This is relatively easy to find since googling about CORS almost everyone will tell about this. The new CORS headers will "tell" the caller if you support CORS requests and some other things like from which origin or which headers you accept as valid.
For example the header with value "Access-Control-Allow-Origin" expects the valid caller domain names. If the caller site is on domain mydomain.com, then the value of that header should be "http://mydomain.com". Alternatively in order to indicate that callers from any domain can access your resource you may just use the value "*".

If your application requires authentication (which was my case), the header "Access-Control-Allow-Headers" should also include the value "Authorization".

2)  Preflighted requests

The second one is about Preflighted requests. This was very tricky and hard to find since I only saw that happen on Firefox and Chrome - which in my opinion are the most important browsers out there. These two browsers first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send.  Cross-site requests are preflighted like this since they may have implications to user data.  In particular, a request is preflighted if:

- It uses methods other than GET, HEAD or POST.  Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
- It sets custom headers in the request.


SOLUTION

In order to overcome both of the problems you must change your web.xml file and also create a custom class that implements javax.servlet.Filter interface.

This is what I had to do in order to overcome Problem 1:





As you can see I created a Filter Class that accepts from web.xml one parameter which is the permitted origin and I used * as a value. The specific filter will intercept all of your application responses and add the custom CORS headers.

To overcome Problem 2 you will also need to modify your web.xml and in your security-constraint tag under web-resource-collection add all the HTTP method except OPTIONS. This will remove your current security from OPTIONS requests and actually make preflight requests feasible.
Here is a sample of what I did in our API:





As you can seeI have exluded OPTIONS request from authentication filter. If you don't do that your requests will always get a 401 error although the security on client is set correctly.

Here is the JavaScript code that I used to call one om Web services:


2015-03-01

Openshift! Create free account and deploy your Java app in less than 5 minutes




On a previous blog entry here, I analyzed the steps to create a basic Java RESTful app in less than 5 minutes. Most probably after creating a RESTful app you will need to put it on cloud in order to be accessible for clients to use. In case that your app is not going to have too much load it is ok to use one of the free PaaS services that exists out there.

There are quite a few of them helping developers to bootstrap their projects.
Openshift (https://www.openshift.com/), Google Cloud Platform (https://cloud.google.com/appengine/docs) and Cloud Foundry are some of them.
The scope of this tutorial is to analyze the steps creating account and deploy your Java project in Openshift.

To begin with it, you should navigate to https://www.openshift.com/ and click on Signup for free. After filling in your info you will receive an email to validate your mail account. Click on the link to validate login to Openshift.

The first thing it will ask you to do is to add an application and this is done in 3 steps.

Step1. Choose a type of application.
Select Do it Yourself.

Step2. Configure the application.
On field "Public URL" you will need to provide the application name and a domain name. The app name and the domain name will be on the final URL of your app so if you give"myapp" as app name and "mydomain" as domain name then you app's url will be http://myapp-mydomain.rhcloud.com/ .
On field  "Source Code" you should provide your Github's URL of your project see here for more info. Hit create application.

Step3. Next Steps.
Click on "Continue to the application overview page."

Now that your application is created you will need to create an RSA key to connect with SSH. Click on settings and add your RSA key. If you don't have any you can read this guide  that will help you create one.

Next, click on Applications and select your app. Click on "Want to log in to your application?".
This will expand some text that have a code to connect with SHH. Copy the code and use it to connect (in case that you have Windows you can use putty).

Assuming that you have managed so far to login you should run the following command to navigate to you data folder:
cd $OPENSHIFT_DATA_DIR

Then run the following command:
echo -e  "<settings>\n   <localRepository>$OPENSHIFT_DATA_DIR</localRepository>\n</settings>\n" > settings.xml 
This commands will setup maven local repository on a folder that is actually writable.

Then run the following to change folder to your repository:
 cd $OPENSHIFT_REPO_DIR

and to build your project:
mvn install -s $OPENSHIFT_DATA_DIR/settings.xml 

Finally you  run the following to actually run the project:
java -jar target/*.jar --server.port=${OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP}


That's it you are done. You can now navigate to http://myapp-mydomain.rhcloud.com/  and see the results.

2015-02-28

Dropwizard, a Java framework for high-performance, RESTful web services


Dropwizard straddles the line between being a library and a framework. Its goal is to provide performant, reliable implementations of everything a production-ready web application needs. Because this functionality is extracted into a reusable library, your application remains lean and focused, reducing both time-to-market and maintenance burdens.
read more here ..

Maven: The Complete Reference



Learning Maven can be a daunting and frustrating task. While there are a number of references for Maven online, there is no single, well-written narrative for introducing Maven that can serve as both an authoritative reference and an introduction. Sonatype maintains two books focused on Maven: an example-driven introduction to Maven,
read more here ...

2015-02-26

Create Java Hypermedia REST Web Services Tutorial (HATEOAS)








Here is a very nice tutorial in spring.io explaining how to create Hypermedia REST Web Services (HATEOAS)  in Java.

For those those that don't know what HATEOAS is here is a short description:

HATEOAS is a REST application architecture in which the application's  REST API is not fixed. Instead the available business operations are provided by the same web service and may vary upon state.

For example instead of writing a web service for a car dealer that buy and sell cars, you may write a  HATEOAS service in which when the car dealer is called (probably through a GET request) the response includes the link of the sell and buy operations. In that way when the car dealer is out of money the response will omit the link for buy. On a classic web service the buy link would be always available and an error handling inside the buy service should check if the car dealer has enough money or not.

You can read more here.

Interesting reads:

https://spring.io/guides/gs/rest-hateoas/
https://spring.io/understanding/HATEOAS
projects.spring.io/spring-data-rest/


2015-02-22

Create a one jar REST web service in JAVA for less than 5 minutes










More than a decade after its introduction, REST has become one of the most important technologies for Web applications. Its importance is likely to continue growing quickly as all technologies move towards an API orientation. This simple tutorial will help you build in less than 5 minutes a REST web services implementation using JAVA.


 
Tools that I used:

- Netbeans
- Maven (Contained in Netbeans)
- Spring boot (Auto downloaded by Maven)

Step 1. Create a new project.

Open Netbeans and select New project -> Maven -> Java Application.
Give to your project a decent name, path, package name and hit finish.
This should create for you an empty maven project.
In case you want to skip Netbeans for project creation, navigate to maven and run :
mvn archetype:generate -DgroupId=my.package -DartifactId=myProjectName -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false


Step 2. Add spring boot.

Spring boot will actually do the whole job here. It will attach to your project Apache Tomcat and do all the dirty work behind the scenes.
The spring boot package that you need is spring-boot-starter-web. You can add it to your project either from NetBeans by right clicking the dependencies folder and then selecting add dependency or just open your pom.xml and add:
<dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

            <version>1.1.9.RELEASE</version>

        </dependency>
</dependencies>

Note: You don’t have to use the same version (1.1.9.RELEASE). I used this because it was the last one.

After adding spring boot, navigate to it’s website (http://projects.spring.io/spring-boot/) and you will see there a nice sample Java class named SampleController. As you can see the specific Class declares a simple REST web service that listens on port 8080 on localhost/ .
Copy it as it is into your project and modify it writing the following:

import org.springframework.boot.*;

import org.springframework.boot.autoconfigure.*;

import org.springframework.http.MediaType;

import org.springframework.stereotype.*;

import org.springframework.web.bind.annotation.*;



@Controller

@EnableAutoConfiguration

public class SampleController {



    @RequestMapping(value = "/",

            method = RequestMethod.GET,

            produces = MediaType.APPLICATION_JSON_VALUE)

    @ResponseBody

    Person home() {

        Person p = new Person();

        p.setFirstName("Agis");

        p.setLastName("Kefalinos");

        return p;

    }

   

    @RequestMapping(value = "/who",

            method = RequestMethod.POST,

            produces = MediaType.TEXT_PLAIN_VALUE,

            consumes = MediaType.APPLICATION_JSON_VALUE)

    @ResponseBody

    String who(@RequestBody Person p, @RequestParam(value = "action", required = false) String action) {

        return action + " " + p.getFirstName();

    }



    public static void main(String[] args) throws Exception {

        SpringApplication.run(SampleController.class, args);

    }

}


Also Add the following helper Class:


public class Person {

   

    private String firstName;

    private String lastName;



    public String getFirstName() {

        return firstName;

    }



    public void setFirstName(String firstName) {

        this.firstName = firstName;

    }



    public String getLastName() {

        return lastName;

    }



    public void setLastName(String lastName) {

        this.lastName = lastName;

    }   
}


This will actually add to your project the following:

- A REST GET method that listens at localhost:8080/ and returns a Person POJO as JSON like: {"firstName":"Agis","lastName":"Kefalinos"}

- A REST POST method that listens at localhost:8080/who that consumes a Person POJO and uses an optional query parameter named action . The response of that WS is the concatenation of the query parameter plus the first name of the POSO Person.
Now that we finished with a typical business logic we can actually run our project and see the results.


Step 3. Create a runnable single Jar.

If we run it inside Netbeans it will run without any problem and do the trick. The problem will come if we try to run it from command like “java –jar myproject.jar”.
Doing so we will have 2 problems:

1) The jar does not know which method is the MAIN and we have to provide it to maven. To do it just add to pom.xml under plugins:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>my.package.SampleController</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

Note: Replace my.package.SampleController with your main’s full Class name.

2) The second problem is that the spring boot is not at your class path so the jar as it is will not run. An interesting way to bypass this problem is to build your app having all other dependencies included into your jar. Of course that will increase the size of you jar but sometimes this is the way to go. To do it you will need to add to pom.xml under plugins the following:

            <plugin>
                <groupId>org.dstovall</groupId>
                <artifactId>onejar-maven-plugin</artifactId>
                <version>1.4.4</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>one-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Also add to your pom.xml under project the following:

    <pluginRepositories>
        <pluginRepository>
            <id>onejar-maven-plugin.googlecode.com</id>
            <url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
        </pluginRepository>
    </pluginRepositories>

Rebuild your project and you will notice that apart from your myproject.jar another jar is created named myproject.one-jar.jar. This jar will contain all the needed libraries for your project to run. 

Open your console and hit “java –jar myproject.jar”. Then open your favorite browser and navigate to http://localhost:8080/

That’s it, you are set!

Sample source code here: https://github.com/mdagis/SpringBootTest

Popular Posts