Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Monday, February 20, 2017

Java Sequence Generator which simulates Oracle DB Sequence Generator

There is a requirement in my recent project, to generate 11 digit long sequence number without any database. Interesting, we are so used to rely on database to generate sequence number. In Java programming world, there isn’t a convenient library to generate sequence number!?

Solution 1: UUID.randomUUID().
UUID is alpha numeric and UUID size is way bigger than 11 digits.

Solution 2: System.currentTimeMillis().
[1] System.currentTimeMillis() generates 13 digits.
[2] If we substring the left most 11 characters, we lose the accuracy.
[3] The sequence is not continuous.
[4] In the very fast machine and fast retrieval, it is possible to obtain repeated value.

Solution 3: System.currentTimeMillis() as init value and +1 subsequently.
In the high volume retrieval, +1 may outrun the speed of time, e.g. 20000 transactions per second. When program restart, the newly System.currentTimeMillis() init value might have been used previously.

Solution 4: Plain and basic +1 counter and save the value in local file. This ensures the uniqueness of sequence number and sequence number will resume when restart the program.
Issue: Too much file write will slow down the program.

Solution 5: Plain and basic +1 counter with cache, similar to Oracle sequence cache. When cache is used up, renew it and save the new cache value in local file.
Issue: When the program or server crashes, local file is not updated and we don’t know where the last sequence number.

Solution 6: Enhanced version 5. When program is restarted, sequence counter will start from previous cache.
Issue: This behavior is the same as Oracle sequence generator. Un-used sequence number is lost when program is restarted.

Solution 7: Enhanced version 6. With the help of Java ShutdownHock, we’ll save current and new cache value in the file. Local file will be updated when
1)Program is properly shutdown, ShutdownHock will store [Current count, current count].
2)When new cache is created, store [Current count, new cache]

So, when program is restarted, it will read the file and compare,
1)If Current count == current count, resume sequence number = Current count.
2)If Current count < new cache, it means program crashed previously. Sequence number will start from new cache + 1.

So far Solution 7 is quite good. It is clean and light-weight.
http://stackoverflow.com/questions/1186387/generating-9-digit-ids-without-database-sequence/42344842#42344842

Interesting observation is,
1) Many people would think until Solution 4, 5, 6 and got stuck.
2) When 1 person is working alone, it is not easy to get out of blind spot.
3) The best solution indeed is not known or given. The best solution is purified from questioning and brain-storming with a team of good colleagues.

Tuesday, November 24, 2015

compile single executable jar file with maven

Reference: http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven

There are 2 ways of doing it.

(1) To include other jars:

  
    
      
        org.apache.maven.plugins
        maven-shade-plugin
        
          
            package
            
              shade
            
          
        
        
          
            
              asia.wirecard.standalone.reconcile.ReconcileGUWID.App
            
          
          ${artifactId}-${version}-with-libs
        
      
    
  

The jar file itself contains all the classpath dependencies:
java -cp Target.jar com.package.target.App or
java -jar Target.jar

(2) To include extracted classes:

  
    
      
        maven-assembly-plugin
        
          
            
              asia.wirecard.standalone.reconcile.ReconcileGUWID.App
            
          
          
            jar-with-dependencies
          
        
        
          
            make-assembly 
            package 
            
              single
            
          
        
      
    
  

The jar file itself is executable:
java -jar Target.jar

Tuesday, August 23, 2011

native2ascii vs ascii2native

In Java, to display Chinese character, we need to convert Chinese word to Unicode format.
e.g. 你好 becomes \u4F60\u597D.

We can use the following command to do conversion:
(Source: http://javaphoon.iteye.com/blog/148403)
native2ascii -encoding gb2312 test_native.properties > test_ascii.properties
native2ascii -reverse -encoding gb2312 test_ascii.properties > test_native2.properties

This is the online conversion tool:
http://code.cside.com/3rdpage/us/javaUnicode/converter.html

Monday, August 30, 2010

How to install GCJ: GNU Compiler for Java?

In Windows world, there is no single GCJ installation.exe that installs GCJ.

GCJ exists inside Cygwin. So we have to install Cygwin. Detailed Step here:
http://www.mcclean-cooper.com/valentino/cygwin_install/

Cygwin contains many components. It is not a good idea to install all and fill up the harddisk. How to decide which one to install?

My feeling is, choose only those components needed.

For example, I am clear that I want to use gcj ( GNU Compiler for Java ). So in the Cygwin-setup Search box, I type in “java” keyword. I choose only Devel/gcc-java.

The good thing is, when I click Next button, all the dependencies will be automatically chosen. Hence only the minimum set of components will be downloaded and installed.

When I am using gcj, along the way I’ll hit additional error, e.g. “cannot find…” missing libraries.

Error Message:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -liconv
collect2: ld returned 1 exit status

Then, I’ll launch Cygwin-setup again to install the missing library.

Keyword to install:
libiconv

Thursday, April 15, 2010

Windows 7 and Java JDK 1.6 Timezone issue

Same piece of Java program running on Windows 7 and JDK 1.6, the date time related routine returns TIME ZONE :Greenwich Mean Time, which is wrong.

Insteads of going into source code level to add in timezome "GMT+8" routine, we can alter the timezone properties at command line level.

java -Duser.timezone="GMT+8" .....
or
java -Duser.timezone="Asia/Singapore" .....


Reference:
http://bugs.sun.com/view_bug.do?bug_id=6456628

Saturday, January 13, 2007

What happens inside JSP/Struct/JSF Redirect?

Let’s use the following servlet to demo a redirect.
public class RedirectServlet extends HttpServlet
{
public void service(HttpServletRequest req,
HttpServletResponse resp)
{
String contextPath = req.getContextPath();
String redirectStr = contextPath +
"/nextpage.jsp?param1=value1";
// Use encodeRedirectURL so that session id can be
// included in browser which doesn't support cookies.
resp.sendRedirect(resp.encodeRedirectURL(redirectStr));
}
}
Then, we use Telnet to access this servlet:
% telnet machine_hostname 8080

Manually enter:
GET /servlet/RedirectServlet HTTP/1.0

You will get the reply:
HTTP1.1 302 Moved Temporarily
Location: http://machine_hostname:8080/webapp/nextpage.jsp?param1=value1
DATE: ...
Server: ...
Connection: ...


What to observe is that,
1) Redirect in fact is a 302 response from webserver.
2) The complete URL and Port are written out fully in the Location.

This is the reason why the internal machine hostname will be shown up in browser, when we login OracleAS EM (Enterprise Manager) or perform a JSP/Struct/JSF Redirect in our web application.

Please check how to let EM and Redirect return URL as expected-ly.