Saturday, March 29, 2014

Run eclipse on remote ubuntu 13.10 server using x11

To run eclipse from on remote ubuntu 13.10 server using x11 on local machine. 

Requirement.
I am assuming Jdk and eclipse is already installed. 

In addition to that you need to install few libraries on remote server. Run following command to install those libraries on remote server.


  $ sudo apt-get install libgtk2.0-0:i386 libxxf86vm1:i386 libsm6:i386 lib32stdc++6 libxtst6

Once above libraries are install open another terminal and connect remote server through ssh with -X option


#From local machine
$ ssh <username>@<remote machine ip> -X

Now you can start the eclipse from this ssh session


#From local machine
$ cd <to location where eclipse is installed>
$ ./eclipse


Friday, March 28, 2014

UBUNTU 13.4 LD_LIBRARY_PATH is not set from /etc/environment

For some reason LD_LIBRARY_PATH value is not getting set through /etc/environment. All other variables are getting initialized properly when it is been set through /etc/environment. After searching for the solution I came to know after UBUNTU 9.04 release you are not able to set LD_LIBRARY_PATH from "$HOME/.profile, /etc/profile, nor /etc/environment" refer documentation https://help.ubuntu.com/community/EnvironmentVariables#List_of_common_environment_variables

Run following command and restart the machine to workaround the issue.

echo STARTUP=\"/usr/bin/env LD_LIBRARY_PATH=\${LD_LIBRARY_PATH} \${STARTUP}\" | sudo tee /etc/X11/Xsession.d/90preserve_ld_library_path

For more details refer comment #17 at this bug report https://bugs.launchpad.net/ubuntu/+source/xorg/+bug/366728. as well as refer https://bugs.launchpad.net/ubuntu/+source/xorg/+bug/380360




Thursday, March 27, 2014

Install ZeroMQ on ubuntu with Java Binding

First install all required tools to build zeromq library
sudo apt-get install libtool autoconf automake uuid-dev build-essential pkg-config

Once you have required tools install download zeromq source code and make a build


 #Download latest zermoq source code http://zeromq.org/area:download   
 #I tried it with zeromq-3.2.4.tar.gz (http://download.zeromq.org/zeromq-3.2.4.tar.gz)   
 $ zeromq-3.2.4.tar.gz  
 $ tar -zxvf zeromq-3.2.4.tar.gz  
 $ cd zeromq-3.2.4  
 $ ./configure  
 $ make  
 $ sudo make install  
 $ cd ../  

This will install zeromq libraries at location "/usr/local/lib" you may like to set this path with "LD_LIBRARY_PATH" so that the libraries will be used at the time of execution. If you are setting LD_LIBRARY_PATH from .profile, or /etc/environment then you will it is not getting set refer.

Generate Java binding refer official documentation for more details
http://zeromq.org/bindings:java
 $ git clone https://github.com/zeromq/jzmq.git  
 $ cd jzmq  
 $ ./autogen.sh  
 $ ./configure  
 $ make  
 $ sudo make install

At the end you will find zmq.jar generated at location /usr/local/share/java/zmq.jar


Updated Note : 

With latest version of available you may get following error

checking for sodium... no
configure: error: Package requirements (libsodium) were not met:
No package 'libsodium' found

You may not require this package, so install it with it to do that run configuration with following option


./configure --without-libsodium




Install Eclipse Maven plugin and import maven project

With new versions of Eclipse old m2e plugins have become absolute now you need to install eclipse plugins from eclipse market place. Follow below steps to install m2e plugins along with required GWT plugins. I have tried below steps with Eclipse (Kepler)


  • Install GWT eclipse plugin Help -> "Eclipse Marketplace". Search with string "GWT" install "Google Plugin for eclipse 4.3".
  • Install maven plugin open "Eclipse Marketplace" and search for "m2e-wtp" look for "Maven Integration for Eclipse WTP Juno (1.0.1)" and install it
  • Other maven integration plugins open "Eclipse marketplace" and search for "m2e" look for "APT M2E Connector" and "GWT M2E Connector" install both the plugins.


With above plugins installed before importing  your maven project. I tend to make sure I use same maven installation and configuration that I use for command line maven build. When you install m2e eclipse plugin for maven it comes with default maven installation. To change your maven installation to same as that of command line maven. Follow below steps.


  • Open Window - > Preferences "Preferences" window will be open.
  • Expand "Maven" label on left side panel.
  • Select "Installations" on right hand side panel you will see "embedded" maven installation selected.
  • Click on "Add" button directory window will be prompted.  Select home folder of your maven installation and click "Ok".
  • With addition of your installed maven installation. Make sure check mark is marked on your installed maven installation and then click on "OK" 
To import your maven project inside eclipse follow below steps.
Note: Before importing your eclipse projects make sure you make a complete build from command prompt.

  • Select "File - > Import" 
  • Expand "Maven" and select "Existing Maven Projects" and click on "Next".
  • Click on "Browse" button on next screen folder explorer will appear.
  • Select your project's parent folder which contains the pom.xml. 
  • Next follow next screens as next screens varies based on maven plugins used in your project. Sometimes it may take some time, but be patient and allow eclipse to complete it (in some cases where you are using maven plugin in your pom.xml m2e will try to locate respective eclipse plugin to achieve same task from eclipse. If it fails to find one it will try to locate in eclipse market place and if it is there user will be prompted to install the same). 

Sunday, March 23, 2014

gwt youtube player

Created GWT wrapper over YouTube Iframe player api refer

Usage

Inherit GWT module <inherits name="open.pandurang.gwt.youtube.YouTube" />
Before you start using YouTube iframe library one need to load them first, so as to load the library first you need make call to YouTubePlayer.loadYouTubeIframeApi();. This will ensure library is loaded, you can register to recieve event when library is loaded completely by using ApiReadyEventHandler for more details on the same refer YouTube documentation's geting started section. This ApiReadyEvent is equivalent to onYouTubeIframeAPIReady javascript callback.

// 3. This function creates an <iframe> (and YouTube player)
//    after the API code downloads.
   var player;
   function onYouTubeIframeAPIReady(){}


      YouTubePlayer.addApiReadyHandler(new ApiReadyEventHandler() {

            public void onApiReady(ApiReadyEvent event) {
              // Action you want take after api is loaded.
            }
      }

Note: Please make sure you load iframe library well in advance before using YouTube Player.
    public void onModuleLoad() {
        YouTubePlayer.loadYouTubeIframeApi();
        YouTubePlayer.addApiReadyHandler(new ApiReadyEventHandler() {

            public void onApiReady(ApiReadyEvent event) {
                PlayerConfiguration config = (PlayerConfiguration) PlayerConfiguration.createObject();
                config.setVideoId("M7lc1UVf-VE");
                config.setHeight("562.5");
                config.setWidth("1000");
                final YouTubePlayer player = new YouTubePlayer(config);
                player.addPlayerReadyHandler(new PlayerReadyEventHandler() {

                    public void onPlayerReady(PlayerReadyEvent event) {
                        GWT.log("First player is ready.");
                        GWT.log("First player state -> " + player.getPlayer().getPlayerState());
                    }
                });
                player.addStateChangedHandler(new StateChangeEventHandler() {

                    public void onStateChange(StateChangeEvent event) {
                        GWT.log("First player state changed => " + event.getPlayerEvent().getData());
                    }
                });
                RootPanel.get().add(player);
                Button btn = new Button("Stop");
                btn.addClickHandler(new ClickHandler() {

                    public void onClick(ClickEvent event) {
                        player.getPlayer().stopVideo();
                        GWT.log("First player state -> " + player.getPlayer().getPlayerState());
                    }
                });
                RootPanel.get().add(btn);
                config = (PlayerConfiguration) PlayerConfiguration.createObject();
                config.setVideoId("4biVZcgCn9A");
                PlayerVariables playerVars = (PlayerVariables) PlayerVariables.createObject();

                playerVars.setControls(0);
                playerVars.setRel(0);
                playerVars.setShowInfo(0);
                playerVars.setShowInfo(0);
                config.setPlayerVars(playerVars);
                final YouTubePlayer player1 = new YouTubePlayer(config);
                RootPanel.get().add(player1);

                Button btnCue = new Button("Cue");
                btnCue.addClickHandler(new ClickHandler() {

                    public void onClick(ClickEvent event) {
                        JsArrayString list = (JsArrayString) JsArrayString.createArray();
                        list.push("tQIBhsDlTxU");
                        list.push("4jGFreAGRI4");
                        player1.getPlayer().cuePlaylist(list);
                    }
                });
                RootPanel.get().add(btnCue);

            }
        });
    }

Fore more details refer test sample project

Maven Dependency
        <dependency>
            <groupId>open.pandurang.gwt</groupId>
            <artifactId>gwt-youtube-player</artifactId>
            <version>0.1</version>
            <scope>provided</scope>
        </dependency>

Maven Repository
   <repositories>
      <repository>
         <id>Pandurang repo</id>
         <url>https://github.com/pandurangpatil/pandurang-mvn-repo/raw/master/releases</url>
      </repository>
   </repositories>






Friday, March 21, 2014

GIMP Add border and shadow to a layer

To Add border to layer follow below steps


  1. Select the layer then use menu "Layer -> Transparency -> Alpha to Selection.
  2. "Select -> Border" Border Selection window will appear. Enter the size of border you want to show.
  3. "Layer -> Transparency -> Intersect with selection"
  4. "Edit -> Fill with FG/BG Color" You need to select required color from FG / BG color panel.
  5. "Select -> None"
With above steps you will be added border to your layer.

To add shadow to layer

  1. Select the layer 
  2. "Select -> All"
  3. "Filters -> Light And Shadows -> Drop Shadows"
  4. Window will appear select / add required values and click on "OK"



Tuesday, March 18, 2014

Call GWT Java Code from JavaScript

It is very easy to call javascript from GWT java code by making use of JSNI. But calling GWT java code from external java script of JSNI is little tricky and it becomes more complicate when you have to call instance method of a GWT java class. For more detail refer GWT official document (refer)

Call static class method from JavaScript

GWTCode.java


package open.pandurang.client.view;

/**
 * @author Pandurang Patil 18-Mar-2014
 * 
 */
public class GWTCode {

 public static String hello(String name) {
  return "Hello " + name + "!";
 }

 public static native void exportMethod() /*-{
  $wnd.gwtcode_hello = function(name) {
   return @open.pandurang.client.view.GWTCode::hello(Ljava/lang/String;)(name);
  };
 }-*/;
}

At line 15 we are exposing this GWTCode.hello method and assign it to window.gwtcode_hello. Please note there are two "( )" brackets, first one will declare parameter types and second will take actual parameters. Don't worry if you are using eclipse when you press CTRL + SPACE after method name it will populate corresponding type. Now from java script code you can call window.gwtcode_hello("<name>") method. 

NOTE: If method don't take any argument then line no 15 will look like "return @open.pandurang.client.view.GWTCode::hello()();"

Entry Point class 
Sample.java



package open.pandurang.client.view;

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

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class samples implements EntryPoint {

 public void onModuleLoad() {

  GWTCode.exportMethod();
 }

}

at line no 12 you will see we are calling exportMethod to export the GWTCode Hello method.

html code
sample.html


<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Samples and trials</title>
<script type="text/javascript" language="javascript" src="sample/sample.nocache.js"></script>
</head>
<script type="text/javascript" language="javascript">
 function jsGwtCallTest() {
  var msg = window.gwtcode_hello("Pandurang");
  alert(msg);
 }
</script>
</head>
<body>
    <!-- OPTIONAL: include this if you want history support -->
    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position: absolute; width: 0; height: 0; border: 0"></iframe>
    <!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
    <noscript>
        <div
            style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
            Your web browser must have JavaScript enabled in order for this application to display correctly.</div>
    </noscript>
    <button onclick="jsGwtCallTest();">test</button>
</body>
</html>


we are calling this method on event of button click. You will not see any issues here but if you are calling this method from other .js file on some events like on page load or something. You need to make sure gwt entry point has been executed and exported the method.

Saturday, March 15, 2014

Monday, March 10, 2014

Check Cron executed or not.

Many a times it happens we schedule some cron job to get executed, we do check as well whether command gets executed properly or not. And even though we tried the command some times your cron fail to execute.  There are two possibilities either cron is not configured properly or some how command is failed. Now in this case how do we check if cron is getting executed or not. Does it gets logged some where when is last cron executed? Yes it does get logged in syslog you can run following command to check cron entries
$ grep CRON /var/log/syslog
Mar 10 08:00:01 staging01 CRON[23609]: (root) CMD (my-command)
Mar 10 08:00:01 staging01 CRON[23608]: (CRON) info (No MTA installed, discarding output)
Mar 10 08:10:01 staging01 CRON[23611]: (root) CMD (my-command)
Mar 10 08:10:01 staging01 CRON[23610]: (CRON) info (No MTA installed, discarding output)
Mar 10 08:17:01 staging01 CRON[23613]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Mar 10 08:20:01 staging01 CRON[23616]: (root) CMD (my-command)
Mar 10 08:20:01 staging01 CRON[23615]: (CRON) info (No MTA installed, discarding output)
Mar 10 08:30:01 staging01 CRON[23618]: (root) CMD (my-command)
Mar 10 08:30:01 staging01 CRON[23617]: (CRON) info (No MTA installed, discarding output)
Mar 10 08:40:01 staging01 CRON[23620]: (root) CMD (my-command)
Mar 10 08:40:01 staging01 CRON[23619]: (CRON) info (No MTA installed, discarding output)
Mar 10 08:50:01 staging01 CRON[23698]: (root) CMD (my-command)


Sunday, March 9, 2014

Setup firewall with UFW on ubuntu

It is very easy to setup firewall using UFW on ubuntu server 

First you need to check if you have UFW installed on your machine. If it is installed you can check the status of the same using 
$ sudo ufw status
Status: inactive

In case it is installed but not enabled. If it is not installed then it will throw command not found error. If it is active then it will show out put similar like below output.
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere

If it is not installed then you can install it 
$ sudo apt-get install ufw

This will install ufw. Now when you will check the status it will be inactive. Before you activate the same you need to set the rules.  Depending on your requirement, you can set default policy for incoming as well as outgoing connections. If default policy for incoming is "deny" then all incoming connections are by default denied the access. Except on those ports which are made open. If you set default policy to be "allow" then all incoming connections will be allowed except on those ports for which rule has been added to deny the connections. Same is true for outgoing connections. Ideally we should set default policy to be "deny" for all incoming connections and default policy to be "allow" for all out going connections.

Set default policy for incoming connections
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

Set default policy for outgoing connections
$ sudo ufw default allow outgoing
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

Now you before you enable the UFW you have to add rules to allow connections on specific port. Most importantly allow connections on SSH port, if you are doing all this on remote machine, over SSH. Don't enable it before you make sure you have added rule to allow connections over SSH port.

add rules to allow connections
$ sudo ufw allow ssh
or 
$ sudo ufw allow 22/tcp

Similarly you can allow other connections over port 80 and if required 443 as well
$ sudo ufw allow www
$ sudo ufw allow 443/tcp

you can add deny rule like 
$ sudo ufw deny 80/tcp

Delete any rule like
$ sudo ufw delete allow www

Once you have all rule set (Make sure you have added rule to allow ssh connection). Now you can enable ufw to act as firewall
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere

You can disable it like
$ sudo ufw disable




Saturday, March 8, 2014

download Oracle JDK / JRE from console / command prompt

Many a times we have to download JDK / JRE on remote machine through console. In most of the cases we tend to download it on our desktop and then upload it to the remote machine through SCP as the download link from Oracle website are not directly accessible. You need to first accept the agreement so that you get the download link. The link is not usable to download it using wget. It seems oracle site look at a cookie value which marks given download request as user's acceptance of agreement.  And that cookie is 

Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F

Now you can download it using wget by passing this cookie with required download link as follows

wget --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F" http://download.oracle.com/otn-pub/java/jdk/7u51-b13/jdk-7u51-linux-x64.tar.gz

Thursday, March 6, 2014

GWT access style defined inside .ui.xml within corresponding .java file

Some times you may want to access styles defined inside your Sample.ui.xml file which you want to access / use from within Sample.java widget class. You can do that by defining an interface which extends from com.google.gwt.resources.client.CssResource and declaring method with name matching exactly that of required style class name that you have declared inside ui.xml. Refer below code.


Sample.ui.xml contents


<src path>/com/pandurang/client/ui/Sample.ui.xml

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
   .
   .
   .
   <ui:style type="com.pandurang.client.ui.Sample.MyStyle">
 .domain {
  margin: 0 auto;
  width: 730px;
 }
  
 .editImg {
  cursor: pointer;
  float: left;
  margin-left: 181px;
 }
   </ui:style>
    <g:HTMLPanel>
        <div>
            <div class="{style.domain}">
                   <!-- Contents.... -->
            </div>
        </div>
    </g:HTMLPanel>
</ui:UiBinder>

You need to connect <ui:style> tag with corresponding CssResource interface by using "type" attribute of <ui.style> tag as shown above.

Sample.java contents


<src path>/com/pandurang/client/ui/Sample.java

package com.agnie.useradmin.main.client.ui;

import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.core.client.GWT;

public class Sample extends Composite {

        interface MyUiBinder extends UiBinder<Widget, Sample> {
 }

 private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

 interface MyStyle extends CssResource {
  String domain();
                String editImg();
 }

 @UiField
 MyStyle      style;

        public Sample(){
             initWidget(uiBinder.createAndBindUi(this));
        }
}

If you look at above code, we have defined MyStyle interface and declared methods with name matching to that of css class names. And instance of MyStyle will be injected by using @UiField annotation. In your java code you can make use of style variable to access the styles defined inside ui.xml.

configure nginx to redirect user from HTTP to HTTPS

When you are going to sever all requests over SSL then in some cases you need to only serve requests over SSL. While doing that you may have to disable port 80 so that all the requests will be only served through SSL. But in that case if user hits your url with http, user will see page not found error. Instead you can enable your port 80 and redirect all requests to https url with following configuration.



     server {
        listen      80;
        server_name www.yourdomain.com;
        return 301 https://www.yourdomain.com$request_uri;
    }


Adding "$request_uri" will make sure it will keep requested url as is as per requested. Other wise even if you hit the url like http://www.yourdomain.com/company/about.html still it will be redirected to https://www.yourdomain.com

Configure Nginx for SSL

You need to have private key and CA signed certificate (to test you may generate your own Self signed certificate) to configure your nginx to serve request over SSL. Add following lines into your nginx.conf file and make required changes to point ssl_certificate to location of your certificate in this configuration it is "server.crt" (if you copy your .crt and .key file into "<nginx home>/conf" folder . In that case you can specify only file name other wise you need to specify absolute path of a file). Change ssl_certificate_key to point your key file.

Restart nginx server and hit https url https://yourdomain.com. ( If you have installed self signed certificate you will see Untrusted Exception. You can safely continue with it.) 


    # HTTPS server
    #
    server {
        listen       443;
        server_name  yourdomain.com;

        ssl                  on;
        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }


Generate self signed SSL certificate

Follow below steps to generate self signed certificate:

1. You need to first generate your own private key.
$ openssl genrsa -des3 -out server.key 1024

Generating RSA private key, 1024 bit long modulus
.......................++++++
.......++++++
e is 65537 (0x10001)
Enter pass phrase for server.key:
Verifying - Enter pass phrase for server.key:

With above command it will generate private key, while doing that it will ask you to enter pass phrase which will make this private key useful who knows this pass phrase. This will generate the private server key "server.key".

2. Then you need to generate Certificate Signing Request.


$ openssl req -new -key server.key -out server.csr

Enter pass phrase for server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Maharashtra
Locality Name (eg, city) []:Pune
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Pandurang Patil Pvt. Ltd.
Organizational Unit Name (eg, section) []:Pune
Common Name (e.g. server FQDN or YOUR name) []:www.pandurangpatil.com    
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Here you need to enter required details, you can refer above request output. You may chose to skip last to questions. This step will generate the certificate signing request server.csr. 

3. To self sign the certificate we need to create signing certificate as well (that is your own CA certificate). For that you need to first create private key for CA.


$ openssl genrsa -des3 -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
.......................++++++
.......++++++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:

This private key pass phrase will be required to be used while signing the Certificate Signing Request.

4. Now we have to generate CA certificate


$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Maharashtra
Locality Name (eg, city) []:Pune
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Pandurang Patil CA
Organizational Unit Name (eg, section) []:Pune
Common Name (e.g. server FQDN or YOUR name) []:www.pandurangpatil.com
Email Address []:[email protected]

5. Now we have to sign .csr request that we have generated in step 2. For that we need to provide .conf file through which utility will take required inputs. Somebody has created this nice script which will automate next steps to sign .csr request. You can download this .sh file on your machine, I am assuming it will be saved on sign.sh at the same location from where you are executing above commands. Make this sign.sh executable.


$ ./sign.sh server.csr

CA signing: server.csr -> server.crt:
Using configuration from ca.config
Enter pass phrase for ./ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'IN'
stateOrProvinceName   :PRINTABLE:'Maharashtra'
localityName          :PRINTABLE:'Pune'
organizationName      :PRINTABLE:'Pandurang Patil Pvt.Ltd.'
organizationalUnitName:PRINTABLE:'Pune'
commonName            :PRINTABLE:'www.pandurangpatil.com'
emailAddress          :IA5STRING:'[email protected]'
Certificate is to be certified until Mar  6 09:52:59 2015 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
CA verifying: server.crt <-> CA cert
server.crt: OK

While signing you need to enter pass phrase for ca.key and confirm the details. This step will generate "server.crt". This way you have your private key "server.key" and self signed certificate "sever.crt" generated.

Wednesday, March 5, 2014

Configure nginx to server multiple domains / subdomains

With nginx it is quite easy to configure multiple domains or subdomains to be served from single server. Refer following configuration for the same.

    server {
        server_name first.pandurangpatil.com;
        root /var/www/first;
    }

    server {
        server_name second.pandurangpatil.com;
        root /var/www/second;
    }

    server {
        server_name someother.com;
        root /var/www/other;
    }



Monday, March 3, 2014

compare more than two war files and repackage them excluding common jars

Some times you need to deploy more than one war files under same servlet container. In those war files there might have some common jars across them, which you want to deploy directly to servlet containers class path. So that container won't load those jars separately in the context of each war application. Which in turn will reduce the utilisation of permgen memory space. Following code snippet will help you to compare more than two war files, extract common shared libraries inside separate folder and repackage those wars excluding common jar files. This will generate two folders "shared" and "repackaged" inside given path where you have kept war files. "shared" folder will contain all extracted shared jar files and "repackaged" folder contains all war repackaged excluding shared jar files. 


import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;

/**
 * @author Pandurang Patil 02-Mar-2014
 * 
 */
public class RepackProcessor {

 private String    source;

 private Boolean    verbose    = false;

 private static final String sharedLocateion  = "shared";
 private static final String outPutLocation  = "repackaged";
 private Set<String>   commonLibs   = new HashSet<String>();
 private Set<String>   allLibs    = new HashSet<String>();
 private Set<String>   commonCopiedLibs = new HashSet<String>();

 public void process() throws Exception {
  File f = new File(source);
  if (f.isDirectory()) {
   File[] files = f.listFiles(new FileFilter() {

    public boolean accept(File pathname) {
     if (pathname.isFile() && pathname.getName().endsWith(".war")) {
      return true;
     }
     return false;
    }
   });
   if (files == null || files.length < 2) {
    System.out.println("You need to have at least have two war files in your source directory");
    return;
   }
   System.out.println("Scanning existing war files...");
   for (File file : files) {
    scan(file);
   }
   System.out.println("Scan complete...");

   if (commonLibs.size() == 0) {
    System.out.println("There are no common libraries found, so there is no need to repackage the wars, you can use them as is");
   } else {
    java.io.File mainDir = new java.io.File(source + java.io.File.separator + sharedLocateion);
    mainDir.mkdir();
    mainDir = new java.io.File(source + java.io.File.separator + outPutLocation);
    mainDir.mkdir();
    System.out.println("Repackaging...");
    for (File file : files) {
     repackage(file);
    }
   }
  } else {
   System.out.println("You need to specify directory which contains all war files that needs to be repackaged.");
  }
 }

 /**
  * Repackage war files by excluding common jar files.
  * 
  * @param warFile
  * @throws IOException
  */
 public void repackage(File warFile) throws IOException {
  FileOutputStream fos = new FileOutputStream(new File(source + java.io.File.separator + outPutLocation + java.io.File.separator + warFile.getName()));
  System.out.print("\nRepackaging war =>" + warFile.getName());
  JarOutputStream target = new JarOutputStream(fos);
  JarFile war = new JarFile(warFile);
  Enumeration<JarEntry> files = war.entries();
  while (files.hasMoreElements()) {
   java.util.jar.JarEntry file = files.nextElement();
   extractAndAdd(war, file, target);
  }
  System.out.println();
  target.close();
  war.close();
 }

 /**
  * Scan war file contents to identify shared libraries.
  * 
  * @param warFile
  * @throws Exception
  */
 public void scan(File warFile) throws Exception {
  JarFile war = new JarFile(warFile);
  Enumeration<JarEntry> files = war.entries();
  while (files.hasMoreElements()) {
   JarEntry file = files.nextElement();
   String fileName = file.getName();
   if (!file.isDirectory() && fileName.startsWith("WEB-INF/lib/") && fileName.endsWith(".jar")) {
    // file is jar file.
    if (!commonLibs.contains(fileName)) {
     if (allLibs.contains(fileName)) {
      // If given file is there in all libs that means it been added while scanning previous war file.
      // That means its common file between two wars.
      commonLibs.add(fileName);
     } else {
      // other wise add it in all libs list.
      allLibs.add(fileName);
     }
    }
   }
  }
  war.close();
 }

 /**
  * Extract given file from source war file and add it to destination war file. While doing that it will exclude
  * common jar files and copy to shared folder.
  * 
  * @param sourceWarFile
  *            Source war file.
  * @param source
  *            source file from source war file.
  * @param target
  *            Target war file output stream.
  * @throws IOException
  */
 private void extractAndAdd(JarFile sourceWarFile, JarEntry source, JarOutputStream target) throws IOException {
  String fileName = source.getName();
  if (!source.isDirectory() && commonLibs.contains(fileName)) {
   if (commonCopiedLibs.contains(fileName)) {
    return;
   } else {
    if (verbose)
     System.out.println("copying to shared Lib => " + fileName);
    else
     System.out.print(" .");
    java.io.File newFile = new java.io.File(this.source + java.io.File.separator + sharedLocateion + java.io.File.separator
      + fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length()));
    java.io.InputStream is = sourceWarFile.getInputStream(source); // get the input stream
    java.io.FileOutputStream fos = new java.io.FileOutputStream(newFile);
    while (is.available() > 0) { // write contents of 'is' to 'fos'
     fos.write(is.read());
    }
    fos.close();
    is.close();
    commonCopiedLibs.add(fileName);
   }
  } else {
   if (verbose)
    System.out.println("adding to war =>" + fileName);
   else
    System.out.print(" .");
   target.putNextEntry(source);
   if (!source.isDirectory()) {

    java.io.InputStream is = sourceWarFile.getInputStream(source); // get the input stream
    while (is.available() > 0) { // write contents of 'is' to 'target war'
     target.write(is.read());
    }
   }
   target.closeEntry();
  }
 }

 public static void main(String[] args) throws Exception {
  RepackProcessor rp = new RepackProcessor();
  // Copy all war files at one location and provide absolute path to the location which contains all those war
  // files.
  rp.source = "<location of folder where all war files are placed.";
  rp.process();
 }
}