Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Tuesday, May 15, 2018

java.sql.SQLException: Operation not allowed after ResultSet closed

I faced this problem recently. As a part of closing some resources, I was closing resources in the finally block.

  ResultSet resultSet; // class variable

  ...
  ...
  Statement st = null;
  try {
    st = conn.createStatement();
    resultSet = st.getGeneratedKeys();
  } catch (Exception e) {
    throw e;
  } finally {
    try {
      if (st != null) st.close();
    } catch (SQLException e) {
      throw e;
    }
  }

      
As soon as I did this, I started to get the exception when I tried resultSet.hasNext();
java.sql.SQLException: Operation not allowed after ResultSet closed
My initial guess was I might have executed resultSet.close() somewhere. But it was not the case.

Problem

The actual problem is, ResultSet instance also saves underlying Statement. So, when the underlying Statment is closed (as done in the FINALLY block above), ResultSet is also closed. This causes the problem.
JavaDoc has clearly mentioned this.

When a Statement object is closed, its current ResultSet object, if one exists, is also closed.

Solution

So to fix the problem, you obviously cannot close the Statement instance untill you are done with ResultSet. Once you are done with ResultSet, you can close both ResultSet and Statement.






Thursday, May 3, 2018

PowerMockito - Mocking One Static Method and Not Mocking Other in the Same Class

Suppose we have a class,

  public class ClassWithPrivateStaticMethods {
  
   private static String getParam(String paramName) {
      String result = "";

      ...
      ...

      return result;
   }

   private static String getDetail(String contextName) {
      String result = "";

      String temp = getParam(tempParamName);
      ...

      return result;
   }
}

Until today, to mock static method, I had been doing:

  PowerMockito.mockStatic(ClassWithPrivateStaticMethods.class);
  PowerMockito.when(ClassWithPrivateStaticMethods.class, "getParam", Mockito.anyString()).thenReturn("dummy");

This works only when your test executes only this static method getParam().

Problem

PowerMockito.mockStatic() actually mocks all the static method in the class.

So if you have the circumstance where you want to mock one static method, but you want other method to run normally, then this method will not work. Because the other method will also be mocked.

  PowerMockito.mockStatic(ClassWithPrivateStaticMethods.class)
  PowerMockito.when(ClassWithPrivateStaticMethods.class, "getParam", Mockito.anyString()).thenReturn("dummy");
  String result = Whitebox.invokeMethod(ClassWithPrivateStaticMethods.class, "getDetail", Mockito.anyString());

here result will not the result of the execution of the method getDetail() but result of mocked up which is either null or equivalent because we haven't defined mock for the method getDetail

Solution - Partial Mocking

We can solve this by mocking individual static methods by following way:

  PowerMockito.spy(ClassWithPrivateStaticMethods.class);
  PowerMockito.doReturn("dummy").when(ClassWithPrivateStaticMethods.class, "getParam", Mockito.anyString())
  String finalResult = Whitebox.invokeMethod(ClassWithPrivateStaticMethods.class, "getDetail", Mockito.anyString());

Complete Code Demonstration

Following is a complete code demonstration.







Wednesday, April 19, 2017

Generating Pagination Numbers

Very often we need to generate series of numbers for pagination. For small number of pages, all the page numbers can be displayed. However, when there are large number of pages, then we need to display only appropriate page numbers.

Below is a Java Code that can be used to generate the sequence.

It can be easily converted into Javascript function and make necessary changes as required to display in your web site.

public class Pagination {

     public static void main(String []args){
        generatePaginationNumbers(150, 5, 13);
     }
     
     public static void generatePaginationNumbers(int totalItems, int pageSize, int currentPage) {
         int DELTA = 3;
         int SHOW_ALL_SIZE = 10;
         int lastPage = totalItems/pageSize;
         if (totalItems > lastPage * pageSize) {
             lastPage++;
         }
         
         currentPage = currentPage < 1 ? 1 : currentPage;
         if (currentPage > lastPage) {
             currentPage = 1;
         }
         
         if (totalItems < 1) {
             return;
         }
         
         if (currentPage > 1) {
             System.out.print("prev ");
         }
         printPaginationPage(1, currentPage);
         if (totalItems > pageSize) {
             printPaginationPage(2, currentPage);
         } else {
             return;
         }
         
         if (currentPage - DELTA > 3 && lastPage > SHOW_ALL_SIZE) {
             System.out.print(" ... ");
         }
         
         int page = lastPage > SHOW_ALL_SIZE ? currentPage - DELTA : 3;
         page = page <= 2 ? 3 : page;
         int end = currentPage + DELTA;
         end = end >= lastPage - 1 ? lastPage - 2 : end;
         for( ; page <= end; page++) {
             printPaginationPage(page, currentPage);
         }
         
         if (page <= lastPage - 2 && lastPage > SHOW_ALL_SIZE) {
             System.out.print(" ... ");
         }
         
         printPaginationPage(lastPage - 1, currentPage);
         printPaginationPage(lastPage, currentPage);
         
         if (currentPage < lastPage) {
             System.out.print("next");
         }
     }
     
     public static void printPaginationPage(int page, int current) {
         if (page == current) {
             System.out.print("[" + page + "] ");
         } else {
             System.out.print(page + " ");
         }
     }
}


Sample Inputs and Outputs


generatePaginationNumbers(150, 5, 13);
Output: prev 1 2  ... 10 11 12 [13] 14 15 16  ... 29 30 next

generatePaginationNumbers(150, 5, 28);
Output: prev 1 2  ... 25 26 27 [28] 29 30 next

generatePaginationNumbers(150, 5, 2);
Output: prev 1 [2] 3 4 5  ... 29 30 next

generatePaginationNumbers(150, 5, 1);
Output: [1] 2 3 4  ... 29 30 next

generatePaginationNumbers(150, 5, 30);
Output: prev 1 2  ... 27 28 29 [30]








Sunday, January 29, 2017

Harry Potter Audio

Are you the fan of Harry Potter?

Do you want to listen to audios of Harry Potter Series?

Here are two easy options for you

1. DOWNLOAD JAR file (This is to be run with Java 8 Update 121 or above)



2. DOWNLOAD APK file to run in your Android Device









Tuesday, January 24, 2017

Too Many Redirect with SSL in NGINX and Jetty Server

Recently I faced a very nasty problem.

I am using Nginx as my web server and Java Web Application as App Server hosted in Jetty.

I was required to host all the pages using SSL i.e. HTTPS. I enabled Nginx to handle the HTTPS requests at the port 443. Nginx did handle the https requests however Jetty server received all the HTTPS requests as HTTP. There I had the logic to redirect all HTTP to HTTPS. So I fell into the problem that it was redirecting again and again, therefore causing Too Many Redirect error.

I had to spent a lot of time and finally I found the error and hence solution.

While the problem was HTTPS scheme was getting lost at load balancer. This could be solved using the following snippet into the web.xml


  <context-param>
    <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
    <param-value>/</param-value>
  </context-param>

  <filter>
    <filter-name>XForwardedFilter</filter-name>
    <filter-class>fr.xebia.servlet.filter.XForwardedFilter</filter-class>
    <init-param>
      <param-name>protocolHeader</param-name>
      <param-value>x-forwarded-proto</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>XForwardedFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>








Sunday, January 19, 2014

Date-Time as Directory in JAVA

There are times when you want to create directory structure as per the date and time.

For example if it is 2012 Jan 17 and time 10:38:22, then you have the requirement to create directory structure as
/2012/01/17/10/38/22

Of course it is possible to create the structure by manually extracting each components i.e year, month, day, etc from the object Date (methods to extract year, month, etc in Date object are now Deprecated) and Calendar (preferred to Date).

However recently I came with a method that easily formats the Calendar Object to represent as String in required format.


Examples:
  • Printing in the format YYYY/MM/DD

System.out.format(%tY/%tm/%td", c, c, c);


  • Printing in the format YYYY/MM/DD/HH/mm/SS

System.out.format("%tY/%tm/%td/%tl/%tM/%tS%n", c, c, c, c, c, c);

SEPARATING TOKEN CHARACTERS ( Like / , - ,  : ,  etc ) can be changed easily:
  • To Print as YYYY-MM-DD-HH:mm:SS

System.out.format("%tY-%tm-%td-%tl:%tM:%tS%n", c, c, c, c, c, c);

Formatting Options Available



      // %tY = Year
      // %ty = Year in 2 digit format
      // %tB = Month name
      // %tm = Month in 2 digits format
      // %td = Day of the month in format (02)
      // %te = Day of the month in format (2)
      // %tD = Date in format (02/02/1980)
      // %tl = Hours in 12 hour format
      // %tM = Minutes 00... 59
      // %tS = Seconds 00... 59
      // %tp = am/pm time


For saving the output into a variable instead of Printing directly


In the previous example the PrintStream has been delegated to system output stream (System.out). If however it is required to save the output to a variable, the PrintStream can be delegated to different stream so as to save to a variable. One of the method is by using ByteArrayOutputStream.

Example:

new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
ps.format("%tY/%tm/%td/%tl/%tM/%tS%n", c, c, c, c, c, c);
String content = baos.toString();


Here the output String is saved to the variable content.

Other Methods:

Apart from the method explained above, there are also other method to achieve this. One of the method is by using SimpleDateFormat. Its more simple to use this.

Example:

String strdate = null;
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
strdate = sdf.format(c.getTime());

According to the requirement, the format String can be provided as argument to SimpleDateFormat() constructor.