Monday, October 16, 2017

Quick reference guide for CompletionStage


Java 8 introduced a built-in promise interface, CompletionStage<T>.

Which give the developer power of asynchronous programming.
Let me brief it up for the quick reference. 

Methods

Every method in CompetionStage has three variants:
1)  method(callback) runs its callback synchronously,
2) methodAsync(callback) runs the callback asynchronously on the common ForkJoinPool, 
3) methodAsync(callback, executor) runs the callback asynchronously on the specified executor.

Example: thenApply(), thenApplyAsync(callback) & thenApplyAsync(callback, executor)
  • The then() method is represented by a number of methods, depending on whether the callback consumes the value and/or returns a new value.
    • thenAccept() consumes the value and returns void. 
    • thenApply() consumes the value and returns a different value. 
    • thenCompose() consumes the value and returns a new promise. 
    • thenRun() consumes nothing and returns nothing (it accepts a simple Runnable).
  • To handle errors, call exceptionally(), or handle() to run a callback whether the stage was resolved or rejected.
  • The Deferred object is CompletableFuture<T>, which implements CompletionStage (and is in fact the only built-in implementation), and adds mutator methods to resolve, reject, or cancel the promise.
  • Promise creation helpers are CompletableFuture.allOf()CompletableFuture.anyOf(), and CompletableFuture.completedFuture().
  • CompletionStage also has binary versions of all() and any() as instance methods. Call stage1.{accept|applyTo|runAfter}Either(stage2, callback) (parallel to the standard then() variants listed above) to add a then() callback to whichever promise completes first. Call stage1.{thenAccept|runAfter}Both() to add a then() callback to both promises together.
  • You run code on a background thread in a Java Executor and get a promise of the result by calling CompletableFuture.runAsync() (returns a promise of void) or CompletableFuture.supplyAsync() (returns a promise of a value).

Monday, December 14, 2015

Some MAVEN BUILD Challenges

Today let's go through some of the learnings from maven build failure
Challenge 1)
testSet failed: java.lang.IllegalArgumentException: Language not supported in this application: Lang(en,IN) not in Lang.availables(), took 6.537 sec
[error] at play.mvc.Http$Context.setTransientLang(Http.java:238)
Solution
Make sure OS locale is correct one.
For example in Ubuntu localce can modify by editing the below file
/etc/default/locale

Challenge 2)
phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory
Solution
phantomjs say no dependencies but it require fontconfig. Install this missing dependencies by using below command
sudo apt-get install libfontconfig

Challenge 3)
DockerException: Can't obtain ID from build output stream.
Solution
Normally due to network fluctuations it may happens, please retry and see.
Another cause of error is low memory availability for maven, we can set heap memory for maven as below ( would give it 2Gb of heap)
  • set MAVEN_OPTS=-Xmx2048m 
OS Memory leak may also lead unavailability of enough memory, In ubuntu noticed that after running dockers, memory are not released properly, please use below command to verify, in case if available memory is less we may need to consider rebooting of ubuntu as well.
free -m
NOTE: While retry always use the flag -rf, --resume-from
          Resume reactor from specified project
example: mvn <goals> -rf :redis-poc

Challenge 4)
Some of the sanity test cases fails and stuck to proceed with build, and don't want waste time on low priority fixes?
Solution
We can skip test cases by defining the property in pom.xml, say skipITs like below under the corresponding plugin.


<plugin>
  <executions>
    <execution>
        ....
        ....
        <configuration>
            <skip>${skipITs}</skip>
            <executable>.....

And use below build option.
mvn <goals> -DskipTests
example: mvn clean install -DskipTests=true
NOTE:Please do with extra caution, as we don't want to skip any major failures. 

Friday, November 6, 2015

java.lang.NoClassDefFoundError vs ClassNotFoundException

There is common missunderstanding between java.lang.NoClassDefFoundError & java.lang.ClassNotFoundException


Both seems to be same and most of us consider both as due to required class file not available in the class path.

If so, certainly java no need both, then why java have both?

If we look closely we can easily find a quick difference.

Yes! As we guessed one is Error & other one is Exception.

So what? What else?

Let me brief with below code.

Just try below code; it will be interesting to understand behavior of both scenarios.

public class ClassDefExceptionTest {
       static {
              ClassDefExceptionTest.init();
       }
       public ClassDefExceptionTest(){
             
       }
       private static void init(){
              //
              //Some useful code
              //
              throw new RuntimeException("Sorry you can't create this object");
       }
      
}

public class TestFun {
       public static void main(String a[]){
              ClassDefExceptionTest test = null;
              try{
               test = new ClassDefExceptionTest();
              }catch(Throwable e){
                    
                     e.printStackTrace();
              }
              
              try{
                      test = new ClassDefExceptionTest();
                      
              }catch(Throwable e){
                           e.printStackTrace();
              }
               

              try{
                 Class ctest = Class.forName("fhd.practise.ClassDefExceptionTest");
                 System.out.println("loaded successfully.."+ctest.getSimpleName());

                 ClassDefExceptionTest tobj = (ClassDefExceptionTest)ctest.newInstance();
                 System.out.println("Instance created successfully..");
              }catch(Throwable e){
                           e.printStackTrace();
              }
                  
         
     try{
              Class ctest = Class.forName("fhd.practise.ClassNoWhereAvailable");
           }catch(Throwable e){
                     e.printStackTrace();
                        }
  
       }
}



Any guess on output?

No yet guessed? Then please test above code and see :-)


java.lang.NoClassDefFoundError in web application most often developers get treat this error wrongly, as root cause java.lang.ExceptionInInitializerError generated long back and may scrolled up in the log. So developer assume particular class not reachable and waste time running behind it, we can’t blame developers just googlers, Since Googling mislead us as below.

NoClassDefFoundError means that the class is present in the classpath at Compile time, but it doesn't exist in the classpath at Runtime.

This is true in some scenario but not always.

NoClassDefFoundError can occur for multiple reasons like

•             ClassNotFoundException -- .class not found for that referenced class irrespective of whether it is available at compile time or not (i.e base/child class).
•             ExceptionInInitializerError -- Class file located, but Exception raised while initializing static variables or static blocks
•             ClassLoaders also may cause such error, which is basically ClassNotFoundException, in this scenario class may present in classpath but attempt to load from different ClassLoader

In a nut shell, when we face java.lang.NoClassDefFoundError follow the below 3 steps.


1.   Identify rout cause of such error by just scrolling above the logs and verify root cause is java.lang.ExceptionInInitializerError OR java.lang.ClassNotFoundException
Some scenario it is not possible to find none of the above as the server may start long back and logs got rotated from the system or it will be tedious task to go through tens of log files.

2.     Then next approach is locate the candidate class from the class path, if not available in anywhere in the class path then solution is simple, get required class or jar and add it to the class path :-)
Most of us wonder if particular class is available in the class path, what is wrong………….

Nothing!

Simply pay attention on static block/variable of particular class, definitely something wrong will be going on static block/variable 

3.     If above couldn’t help, Issue related will be with ClassLoader, which is basically ClassNotFoundException, in this scenario class may present in classpath but attempt to load from different ClassLoader. Which is also simple to fix but we should have clear idea about classloaders, let me explain it in the another blog 

Thursday, November 20, 2014

Extra space (blanks padded) with data

Most of us experience blank padded with data, when we deal with database, experienced developer will look the data type is varchar or not and it's size defined as per the requirement and fix the issue quickly.

Let me share another experience with extra padded space that may occur even when we carefully select the data type.

We deployed tested code in production, but it got failing since there is extra space in the value when we retrieve from the oracle database table. Same code work fine in SIT environment,

So debugging was found to be easy as it is environmental issue.

We verify the column type in both environment, surprisingly both are char(2).

Then what will be the issue?
why it works fine in SIT not in production, Although we define data type char of size 2, we are getting data as "01    " instead of  "01"

When we dig into deep we realize that even though both are char(2) there is difference in both environment, 

In production it was CHAR(2 CHAR) but in SIT it is CHAR(2 BYTE)

root cause is When neither BYTE nor CHAR is specified, the setting of NLS_LENGTH_SEMANTICS at the time of column creation determines which is used.

so we alter the table column data type and it got working fine :-)

Tuesday, January 21, 2014

Character encoding issue with MySQL

ِAfter a long time, let me share my debugging challenges.

I was troubling with below error for long hours!

 org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '????????????????' at line 1)
   at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
   at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
   at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)

What is going wrong?  ...........

One thing I am sure is, it should be character encoding issue as we can see  '????????????????' instead of exact query.

I am wondering that I don't have such short query in my place, moreover this Exception trows immediately try to connect database.

To support my assumption at a glance, I gone through the stack-trace, so root cause was as below, which clearly point that issue is related with character set.

Caused by: java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '????????????????' at line 1
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1600)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1695)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:3020)
   at com.mysql.jdbc.Connection.configureClientCharacterSet(Connection.java:2343)
   at com.mysql.jdbc.Connection.initializePropsFromServer(Connection.java:3748)
   at com.mysql.jdbc.Connection.createNewIO(Connection.java:2585)
   at com.mysql.jdbc.Connection.<init>(Connection.java:1485)
   at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)


Is it due to character set encoding at Java side or MySQL?

Is it due to wrong mysql jdbc driver version?

I was using mysql-connector-java-3.1.14.jar So I upgrade to correct driver mysql-connector-java-5.1.9.jar. But this couldn't help us.

It is reproducible, so we need to do Reduction & Deduction,

Let us try character encoding at java, Its seem fine as we can see default character encoding is utf-8 and java process even the Arabic string as expected.

So we reduce the problem as only possible area is MySQL.
What next? of course we should experiment various options.

let us find the default character set of MySQL and how we should define various character set in MySQL.

Ohh! it is simple MySQL has configuration file my.cnf, mostly it will locate in /etc for Linux system.

What we need to add OR modify in it?

Just add OR modify below property as below.

character_set_server=utf8
collation_server=utf8_general_ci

We made the necessary changes. 

What next ? off-course restart the MySQL, we did so. Don't forget to do so :-) as it was another learning from my Experience.

Wow That worked well!.

Again learning here is take the big picture of the problem
"Exception was in Java but the fix was in MySQL configuration, If we have only concentrate fix on Java Side then it will be another Killing Bug!"







Thursday, January 10, 2013

Quick guide for Migration of Commons HttpClient 3.x to HttpComponents HttpClient 4.x




As I agreed in the previous blog post for the migration guide of Commons HttpClient 3.x to HttpComponents HttpClient 4.x. Even I also took time to migrate, let me put my effort here so that someone can reap from it.

HttpComponents HttpClient is a HTTP/1.1 compliant HTTP agent implementation based on HttpCore. It also provides reusable components for client-side authentication, HTTP state management, and HTTP connection management. HttpComponents Client is a successor of and replacement for Commons HttpClient 3.x. Users of Commons HttpClient are strongly encouraged to upgrade.

Below table is the quick reference for the migration.


Commons HttpClient 3.x
HttpComponents HttpClient 4.x
import
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient. MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient. UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
HttpClient 
HttpClient client = new HttpClient(connectionManager);
DefaultHttpClient client = new DefaultHttpClient();



proxy configuration
client.getHostConfiguration().setProxy( proxyHost, proxyPort);
client.getState().setAuthenticationPreemptive( true);
Credentials cred = new  UsernamePasswordCredentials( proxyUser, proxyPassword);
client.getState().setProxyCredentials( AuthScope.ANY_HOST, proxyHost, cred)
client.getCredentialsProvider(). setCredentials(
 new AuthScope(proxyHost, proxyPort),
 new UsernamePasswordCredentials( proxyUser, proxyPassword));
HttpHost proxy = new HttpHost(proxyHost proxyPort);
client.getParams().setParameter( ConnRoutePNames.DEFAULT_PROXY, proxy);






POST
PostMethod post = new PostMethod();
post.setPath(url.getFile());
HttpPost post = new HttpPost(url.getFile());



POST Header
post.setRequestHeader(key, (String) headers.get(key));
post.addHeader(key, (String) headers.get(key));



POST Body
post.setRequestBody(message);
StringEntity messageEntity = new StringEntity( message,
 ContentType.create("text/plain", "UTF-8"));
      post.setEntity(messageEntity);



Execute POSt
client.executeMethod(post);
HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
HttpResponse httpResponse = client.execute(targetHost, post);



Response Header
Header[] rspHeaders = post.getResponseHeaders();
Header[] rspHeaders = httpResponse.getAllHeaders();



Response Body
String responseMsg = post.getResponseBodyAsString()
StringBuffer buffer = new StringBuffer();
      BufferedReader reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent()));
String dataLine = null;
while((dataLine = reader.readLine()) != null){
            buffer.append(dataLine);
}
String responseMsg =    buffer.toString();



GET
GetMethod getMethod = new GetMethod();
getMethod.setPath(url.getFile());
HttpGet httpGet = new HttpGet(url.getFile());



GET Header
getMethod.setRequestHeader(key, value);
httpGet.addHeader(key, value);



Execute GET
client.executeMethod(getMethod);
HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol());
HttpResponse httpResponse = client.execute( targetHost, httpGet);