Friday, February 28, 2014

nginx proxypass configuration with X-Forwarded-Host header

I have used and configured apache for proxy pass and proxy pass reverse multiple times with X-Forwarded-Host. I tried configuring same with nginx and it works out to be more customisable and easy one.

    server {
        listen       80;
        server_name  pandurangpatil.com;
        location /myapp {
            proxy_set_header X-Forwarded-Host $host;
            proxy_pass http://localhost:8080/myapp;
        }
        .
        .
        .
    }

MySql JPA toplink Auto increment id generation.

To configure JPA entity to make use of auto increment feature of MySql for primary key generation you can make use of IDENTITY strategy ref below code. 


@Entity 
public class Customer { 

        @Id 
        @GeneratedValue(strategy=GenerationType.IDENTITY) 
        private long id;
        .
        .
        .
        public long getId() {
  return id;
 }
}

But problem with this way of generating ids with MySql and JPA combination is when you persist new entity and try to retrieve id assigned to newly persisted entity using getId() method. You get 0 value, because newly generated id for the record is not set with managed entity for that you need to flush after persisting the entity. 

If you don't specify strategy with GeneratedValue annotation, default value will be GenerationType.AUTO. AUTO strategy means your are asking JPA to select appropriate strategy. In most of the cases it is TABLE strategy. 


@Entity 
public class Customer { 

        @Id 
        @GeneratedValue
        private long id;
        .
        .
        .
        public long getId() {
  return id;
 }
}

One can make use of TABLE strategy directly, this way you have more control over configurations.


@Entity 
public class Customer { 

 @Id
 @GeneratedValue(generator = "idgen")
 @TableGenerator(name = "idgen", table = "ID_GEN", pkColumnName = "ID_NAME", valueColumnName = "ID_VAL", pkColumnValue = "CUST_SEQ", allocationSize = 1, initialValue = 0)
        private long id;
        .
        .
        .
        public long getId() {
  return id;
 }
}


Wednesday, February 26, 2014

Java java.lang.OutOfMemoryError: PermGen space


java.lang.OutOfMemoryError: PermGen space

You get this error that means your JVM is running out of allocated memory for storing class metadata information (class properties, methods annotations etc). This space is not cleaned by Garbage Collected by Garbage collector. When JVM run out of memory for this, it could happen because of multiple reasons, 
  1. One you are dynamically generating classes and those are getting loaded in JVM. 
  2. Second your application is so big and it has more number of dependencies on other third party libraries.  Which in turn deploys huge number of jars.
  3. Third you are deploying multiple modules in the form separate wars (multiple war files) inside your application server. Which results in loading big number of classes in JVM's memory space.
In either of the case to resolve this issue, you have to first try to reduce the number of classes / jars that you are deploying with your application. In some cases I have seen we tend to use multiple frameworks in the same application when single framework can do the job. Generally that happens if we don't keep a tap on what all frameworks getting used in your application and every team member go ahead and add new framework in application. Because he / she has already used it and not willing to explore frame work being used currently in project. If we try, avoid and exclude absolute dependency we can reduce the memory foot print of the application. Which in turn reduces the possibility of getting this errors. I also also see one more reason for this error that is "Maven" which includes dependencies of dependencies some times dependencies which are not needed. This happens without the knowledge to the developer.  And it may become tedious to remove / exclude unwanted dependencies with maven. I don't say it is not possible but it takes some time.

In some cases if you are deploying multiple applications (.war this in context of deploying application on single servlet container). Every application's dependencies will be isolated from each other, and thus it ends up loading some common jars (across the deployed wars) multiple times and in turn ends up consuming more memory. In such cases, one can sort out all common jars across application and deploy them in containers class path directly e.g. inside jetty you can copy those common jar in <jetty home>/lib/ext. As well as remove such common jar from individual war file and then deploy them. Now here there are some challenges as well as some extra efforts and time you need to put in to sort those dependencies. When I talk about challenges, I am talking about situation where there is conflict of versions of dependencies i.e. one app is used lower version of some library and other one is using latest version of the same. In such cases you should keep those dependencies packaged with war only. On extra efforts and time, it depends on you whether you are ready invest your time or money on spending more on hardware. (ok I prepared one utility that will scan all war files, extract common shared jars in one folder and repackage those war files once again excluding common jar files refer)

If you are developing your front end with GWT, then I have seen all GWT libraries remain packaged with WAR file. Here I would like to point out that when you compile your GWT project for deployment, all your GWT client code has been converted to JavaScript. So you no more require those classes to be deployed with your application unless those are being used in backend code as well. And some times it becomes quite tedious to isolate these classes. So I would suggest you to break down you application in three modules, one for pure client side GWT code, one for common code which will be shared across both GWT client side code as well as backend code and third module will be for pure backend side code. In this situation you could exclude the dependency or code from pure GWT module while deployment.

After you try all possibilities and you cannot reduce the memory foot print you can try increasing the allocated permgen memory with following options
  • -XX:PermSize=64M -XX:MaxPermSize=128M Increase memory used for perm gen. Value for these options you need to do trial and error. 
  • You can also try with following options if you are using AOP or dynamically generating the classes.
    • -XX:+CMSClassUnloadingEnabled : Enables garbage collection in permgen 
    • -XX:+CMSClassUnloadingEnabled  Allows garbage collector to remove the classes.  

Tomcat 7 onwards set additional JAVA_OPTS options

To set JAVA_OPTS options which you want to set additionally while running the tomcat should be set inside set <tomcat home>/bin$setenv.sh if this file is not present then create one and set variable JAVA_OPTS="-Dsomething $JAVA_OPTS". If you have to set some variables while only starting the tomcat then you need to set those variables to CATALINA_OPTS rather than JAVA_OPTS. 

Friday, February 21, 2014

Jersey REST retrieve List of custom object

It took me while to understand how one require to  retrieve generic object from ClientResponse.

I had an array of objects in Json format as a response of an REST api, which I was trying to deserialize it into List<CustomObject> refer.

	ClientResponse rsp = webresource.path(id.toString()).type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
	List<CustomObject> list = rsp.getEntity(new GenericType<List<CustomObject>>(CustomObject.class));


But I kept on getting following Error:

Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of test.CustomObject out of START_ARRAY token
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@3488b1e6; line: 1, column: 1]
	at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)


Issue got solved with following way


	ClientResponse rsp = webresource.path(id.toString()).type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
	List<CustomObject> list = rsp.getEntity(new GenericType<List<CustomObject>>(){});


Tuesday, February 18, 2014

Install nginx on OS-X


One need to have gcc installed for that you need to install xcode along with command line tools. To install the same one can refer to this link for xcode 5.0.1.

Nginx requires PCRE – Perl Compatible Regular Expressions to build, I used PCRE version 8.33

Install PCRE

$ mkdir source
$ cd source
$ curl -OL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz
$ tar -zxvf pcre-8.33.tar.gz 
$ cd pcre-8.33/
$ ./configure
$ make
$ sudo make install

Install nginx

Here I am considering stable version for installation.


$ cd ..
$ curl -OL http://nginx.org/download/nginx-1.4.4.tar.gz
$ tar -zxvf nginx-1.4.4.tar.gz
$ cd nginx-1.4.4
$ ./configure --with-http_ssl_module --with-pcre=../pcre-8.33
# When you are done with ./configure command you will see below output at the end you might want to keep this information copied some where for future reference.
$ make
$ sudo make install


Output--


nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"



Start / Stop nginx

# Start
$ sudo /usr/local/nginx/sbin/nginx 

# Stop
$ sudo /usr/local/nginx/sbin/nginx -s stop

For more details on command line help refer (http://wiki.nginx.org/CommandLine)

you can make your life easier to access ngnix from anywhere by adding nginx path (/usr/local/nginx/sbin) into PATH environment variable inside ~/.profile file.

Sunday, February 16, 2014

Set default submit button on a page with GWT

I found few ways to set default submit button on page with GWT. 

1. Add key press handler for all form fields check for enter button and take action. You can add common key press handler for all form fields. This way you are not adding multiple handler for each form field. (I am assuming you understand what is ui handler and how it works.)

 @UiHandler({ "txtCompanyName", "txtcontactName", "txtEmail" })
 public void onKeyPress(KeyPressEvent event) {
  if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
   // TODO: Take your action.
  }
 }

2.  Enclose all your form fields inside com.google.gwt.user.client.ui.FocusPanel and handle key press event on this focus panel.
 @UiField
 FocusPanel mainPanel;
        .
        .
        .
 @UiHandler("mainPanel")
 public void allkyePressHandler(KeyPressEvent event) {
  if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
   // TODO: Take your action.
  }
 }

3. Add page wide native event handler and intercept each event, check if it is enter button and take your action.


 Event.addNativePreviewHandler(new NativePreviewHandler() {

  @Override
  public void onPreviewNativeEvent(NativePreviewEvent event) {
   if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
    // TODO: Take your action.
   }
  }
 });


Wednesday, February 12, 2014

Set environment variable which is inherited inside eclipse workspace

Ubuntu : Set required environment variable inside /etc/environment and restart the machine. This will set environment variable which can be inherited inside eclipse workspace.  Above method will set the environment variable for all the users.  To set environment variable for individual user set the required variable inside <user home>/.profile file. While doing so please make sure you use "export" keyword before variable which is required if those variables are expected to be passed on to subprocess. You need to make use of "export" keyword while setting those variables from inside ".bashrc". 

Note: There is some issue to set LD_LIBRARY_PATH through /etc/environment refer for workaround.

MAC OSX (tested on maverick): Set required environment variable inside /etc/launchd.conf (setenv PROJECT_HOME <Project home location) and restart the machine. 

Sunday, February 9, 2014

Remove cookie.



To remove cookie from server one need to set its expiry time to current time.

e.g. J2EE container one can remove the cookie in following way

HttpServletResponse response = (HttpServletResponse) servletResponse;
Cookie cookie = new Cookie("cookie-key", "");
.... set all the other attributes same as that of existing cookie, like path and domain.  
cookie.setMaxAge(0);
response.addCookie(cookie);

setting max age of cookie to '0' I am setting its expiry to current machine time.

JavaScript

document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT";

For more details refer