Wednesday, November 13, 2013

Overloading resolution in Java

Overloading is a very interesting topic in object oriented programming. As I know the what, when, why, and how, one more thing I didn’t know is the rule. Yes, there are rules defined on JVM how should resolved overloading method in JAVA. I got this piece of information when I was reading Programmer’s guide to SCJP. This is what mentions in the book:
The algorithm used by the compiler for the resolution of overloaded methods incorporates the following phases:
  1. It first performs overload resolution without permitting boxing, unboxing, or the use of a varargs call.
  2. If phase (1) fails, it performs overload resolution allowing boxing and unboxing, but excluding the use of a varargs call.
  3. If phase (2) fails, it performs overload resolution combining a varargs call, boxing, and unboxing.
When I first read on this, I never know such rules ever exist. Does this only happen to JAVA or it have been there since object oriented is invented? Anyhow, do not overlook on the rules mention above, there are priority when resolving overloading method. The condition define in first rule will always verify first before second and third rule is verify. If it fails, compiler will move on to the next rule, until it found a match. Consider following situation:
public static void funcA(String str, Object... obj) {    // (1)
 ...
}

public static void funcA(String str, Integer... i) {     // (2)
 ...
}
I have 2 overloading method at above code, if I do this:

funcA(“STRING”, 10, 10);

Compiler resolved the overloading method easily by picking up method (2). Now if I change this:
public static void funcA(String str, int x, Object... obj) {    // (1)
 ...
}

public static void funcA(String str, Integer... i) {            // (2)
 ...
}
This would bring trouble to the compiler as both overloading method could be the best fit, compiler unable to identify the most specific overloading method, thus compiler were force to issue an compile error to me.

Tuesday, November 12, 2013

What is Delegating Constructor in C++?

Ahh... It has been so long I didn’t write any C++ code since 2010. While I was reading C++ article published at IBM’s website, I come across this term which I found very interesting and new to me. Consider following code snippet, all constructors use as a common initializer for its member variable.
class ClsA {
    private:
        int var;
        
    public:
        ClsA() : var(0) {}
        ClsA(int x) : var(x) {}
        
        ...
}
This is what I usually did at old school. Now there is slightly little improvement on the constructor syntax. Remember how the syntax applied when a member variable is initialized by a constructor. The same syntax can be applied to trigger another constructor to perform member variable initialization. This is what the syntax called delegating constructor. Consider:
class ClsA {
    private:
        int var;
        
    public:
        ClsA() : ClsA(123) {}    // (1)
        ClsA(int x) : var(x) {}  // (2)
        
        ...
};
When I do this:

ClsA clsA;

The constructor at (1) will get invoke and further call another constructor at (2) where member variable var get initialize to 123. The constructor at (1) is a delegating constructor, (2) is a target constructor. Somehow programmer still has the flexibility to invoke constructor at (2) directly to perform its initialization. More details on this specification can be found at open-std(dot)org.

Sunday, November 10, 2013

Variation on authentication-manager in Spring Security

During the feasibility study on authentication module, I been thinking to implement BO/DAO pattern. While working on the POC, I keep asking myself: "Is this the right way of doing this?" Without re-implementing the wheel, I search on the WEB to see whether is there any existing framework out there which specialize on authentication? Yes, I found Apache Acegi and Spring Security. Interestingly, there is a rumours about Spring Security is actually origin from Apache Acegi. Anyway what I'm concern is since I'm already using Spring framework at the earlier stage of the development, thus I will continue with the Spring family.

The configuration is pretty straight forward to setup. One thing that caught my attention is the usage of authentication-manager. The code snippet shown below is the typical usage to everyone which is to make a quick POC demo with a static account. In this case the login ID is huahsin and the password is 1234.
 ...
 <authentication-manager alias="authenticationManager">
  
  <authentication-provider>
   <password-encoder hash="plaintext"/>
   <user-service>
    <user authorities="ROLE_USER" name="huahsin" password="1234"/>
   </user-service>
  </authentication-provider>
 </authentication-manager>
In real world, the user account are usually store in a database for later verification. Now code snippet below shows that user-service has been replace by jdbc-user-service. Notice that users-by-username-query is responsible for retrieving the user name whereas authorities-by-username-query is the sub-query of previous query that retrieve the user role.
 ...
 <authentication-manager alias="authenticationManager">
  ...
  <authentication-provider>
   <jdbc-user-service authorities-by-username-query="select users.username, authority.authority as authority from users, authority where users.username = ? and users.username = authority.username" data-source-ref="dataSource" users-by-username-query="select username, password, 'true' as enabled from users where username=?"/>
  </authentication-provider>
 </authentication-manager>
This is the initial idea from me but somehow there are still objection on it as I have expose the risk on the SQL code is being published to the other developers. This is very subjective to some company. But in mine company there is IT governance look after us. They are very concern on this and they don't like any sensitive data being retrieved easily. Thus I have to move this into Java code like this:
package org.huahsin.security;

public class AuthServiceProvider implements AuthenticationProvider {

 private User user;
 
 private Role role;

 @Override
 public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  
  String name = authentication.getName();
  String password = authentication.getCredentials().toString();
  
  /*
   * assuming there is an DAO object retrieving the particular user information
   * from table and the information is store inside User entity.
   */
  
  if( user.getUsername().equals(name) && user.getPassword().equals(password) ) {
   List<grantedauthority> grantedAuths = new ArrayList<grantedauthority>();
   grantedAuths.add(new SwitchUserGrantedAuthority(role.getRole(), authentication));
   Authentication auth = new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
   
   return auth;
  }
  else {
   return null;
  }
 }

 @Override
 public boolean supports(Class authentication) {
  
  return authentication.equals(UsernamePasswordAuthenticationToken.class);
 }

}

And trigger this bean from Spring like this way:
 ...
   <authentication-manager alias="authenticationManager">
  
      <authentication-provider ref="authServiceProvider"/>
   </authentication-manager>

   <beans:bean class="org.huahsin.security.AuthServiceProvider" id="authServiceProvider"/>
   ...
Notice that the code above is extending the AuthenticationProvider class, this shows the general usage during authentication process as it provide wider flexibility on identifying a user. There is always an alternate solution that could allow me to authenticate a user, which is by extending the UserDetailsService. This class has an override method, loadUserByUsername() which will retrieve the specific user during the authentication process. As shown in the code snippet below:
@Service("authServiceProvider")
public class AuthServiceProvider implements UserDetailsService {

 private User user;
 
 private Role role;

 @Override
 public UserDetails loadUserByUsername(String username)
   throws UsernameNotFoundException, DataAccessException {
  
  /*
   * assuming there is an DAO object retrieving the particular user information
   * from table and the information is store inside User entity.
   */
  
  return new org.springframework.security.core.userdetails.User(user.getUsername(), 
      user.getPassword(),
      true,
      true,
      true,
      true,
      role.getRole());
 }
}
Since this class is extending UserDetailsService, there is a slightly difference when trigger this bean from Spring, now the bean is register with user-service-ref.
 ...
 <authentication-manager alias="authenticationManager">
  <authentication-provider user-service-ref="authServiceProvider"/>
 </authentication-manager>
Usually the user's credential store in database are encrypted, says SHA512, then I just need to mention the encryption algorithm used in Spring like this:
 ...
 <authentication-manager alias="authenticationManager">
  <authentication-provider ref="daoAuthenticationProvider"/>
 </authentication-manager>

 <beans:bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider" id="daoAuthenticationProvider">
  <beans:property name="userDetailsService" ref="authServiceProvider"/>
  <beans:property name="passwordEncoder" ref="passwordEncoder"/>
 </beans:bean>

 <beans:bean class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" id="passwordEncoder">
  <beans:constructor-arg index="0" value="512"/>
 </beans:bean>
Spring very kind for me, there is no single piece of Java code on user's password encryption, it is all handle automatically.

Tuesday, November 5, 2013

AnnotationException No identifier specified for entity

Sometimes a foolish mistake could drag me few hours to resolve although it is simple. At one time I was rushing to commit my code. But what a surprise is that I got this error throw out during unit test and I don't know what is really happening?
Caused by: org.hibernate.AnnotationException: No identifier specified for entity: org.huahsin.Rocket.Entity
 at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:243)
 at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:663)
 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3406)
 at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3360)
 at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1334)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1724)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1775)
 at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:251)
 at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:372)
 at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:357)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
 ... 14 more
I spent few hours on this searching and I found a silly mistake happened in my datasource-spring.xml:
 ...
 ...
 <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
  <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
  <property name="dataSource" ref="dataSource"/>
  <property name="packagesToScan" value="org.huahsin.Rocket.*"/>
 </bean>
packagesToScan is expecting a value of package name. org.huahsin.Rocket is a valid package name whereas org.huahsin.Rocket.* is not. I'm old. My eyes wasn't as good as when I was young. My eyes couldn't spot the tiny little star.

QuerySyntaxException: Entity is not mapped [from Entity]

Few days ago I was encountering this weird error in my program. This is my first time seeing this error and really nice to meet this error.
org.hibernate.hql.ast.QuerySyntaxException: Entity is not mapped [from Entity]
 at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:180)
 at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:111)
 at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:93)
 at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:327)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3441)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3325)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:733)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:584)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
 at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:244)
 at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:256)
 at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:187)
 at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:138)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
 at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
 at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:124)
 at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
 at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
 at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1770)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:345)
...
What does this error means? I have this nonsense error struggling me for few hours. I am sure the entity mapping is doing so well in Hibernate, and there is noting wrong with the entity class. After few hours searching, I found out this error was cause by auto-import=”false” as shown in the snapshot below.

<hibernate-mapping package="org.huahsin" auto-import="false">

According to the documentation, I got this:
auto-import (optional - defaults to true): specifies whether we can use unqualified class names of classes in this mapping in the query language.
Let's digest what this message trying to tell. If I got an Entity class declare as below:
    package org.huahsin;

    public class Entity {
    }
    ...
It wouldn’t cause any error if this class is going to make a query like this way:

List<Entity> entityList = session.createQuery("from Entity").list();

This is due to the reason Hibernate use unqualified class name (when auto-import is missing in the Hibernate configuration). Since I have it explicitly set to false, meaning I’m require to put the fully qualified class name when making the query. Thus the correct syntax making this query should be following way:

List<Entity> entityList = session.createQuery("from org.huahsin.Entity").list();

Upgrade from Hibernate to Spring with HibernateDaoSupport

There is a program has already implementing Hibernate as its natural implementation when retrieving data from database. At the very first glance on the code, it’s very clean. Code snippet below is the main function of the program, this function hold an instance of BookDao.
 public static void main(String args[]) {

  BookDao bookDao = new BookDao();
  
  List< book > bookList = bookDao.readAll();
  
  if( bookList == null ) {
   System.out.println("No book records found");
  }
 }
The BookDao has a readAll() that retrieve the data from database and return the book list back to the main function.
public class BookDao {
 public List< book > readAll() {
  
  List< book > bookList = null;
  Session session = SessionManager.getSessionFactory().getCurrentSession();
  session.beginTransaction();
  bookList = session.createQuery("from Book").list();

  return bookList;
 }
 ...
 ...
}
This is the Hibernate mapping of the book entity. It is pretty straight forward.

 
  
   
  
  
  
  
  
 

Well, not much nonsense in this program. In one day, there is a requirement to integrate this DAO with Spring framework. Things start to get complicated, in the same time more code to write.

Step 1 – I need to have a data source bean configure in Spring. Pump in all the required information into this bean to bridge my program and my desire database, in my case is MYSQL.
 
  
  
  
  
 
Step 2 – I need to have a sessionFactory bean configure in Spring because the DAO will need this bean to initialize the session in Spring. Port over the data source declares in Step 1 to tell which connection that this session will hold.
 
  
   
  
  
  
   
    org.hibernate.dialect.MySQLInnoDBDialect
    org.hibernate.hql.ast.ASTQueryTranslatorFactory
    100
    false
    auto
    thread
    false
    false
    true
    true
   
  
  
  
   
    Book.hbm.xml
   
  
 
Step 3 - Revamp BookDao to extends HibernateDaoSupport. Note on the remark at (1), the session is came from the sessionFactory declare in step 2. Also take note that I’m no longer call beginTransaction() in order to execute the query.
public class BookDao extends HibernateDaoSupport {
 
 public List< Book > readAll() {
  List< Book > bookList = null;
  Session session = getSession();    // (1)
  bookList = session.createQuery("from org.huahsin.Book").list();
  
  return bookList;
 }
 ...
 ...
}
Step 4 – Inject the sessionFactory bean into DAO. This is to tell DAO which session and connection will be use to communicate to database.
 
  
 
Take note that if the sessionFactory is not injects into DAO in this step, when this BookDao bean is first load. Following error would be seen immediately.
Caused by: java.lang.IllegalArgumentException: 'sessionFactory' or 'hibernateTemplate' is required
 at org.springframework.orm.hibernate3.support.HibernateDaoSupport.checkDaoConfig(HibernateDaoSupport.java:118)
 at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1479)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1419)
 ... 12 more
Last but not least, the hibernate.cfg.xml may throw away since it is not needed anymore. This is all about the work need to be done when migrate to Spring’s HibernateDaoSupport.

Wednesday, October 30, 2013

Setup Derby from scratch

The very first step after Derby is install is to create a database. In order to create a database, I must have a command prompt ready. And then decide where am I going to put my database. Assume I'll create the database in this path /home/derby/ (if derby folder doesn't exists, created one), make sure the current directory is showing /home/derby when pwd command is issued. After this, I am going to launch Derby ij tool to create the database. Try either one of the following command to launch that tool:

  1. java -jar $DERBY_HOME/lib/derbyrun.jar ij
  2. $DERBY_HOME/bin/ij

This is very important, this tool must be launch where the database is going to create. If the database create under /home/the_database directory, make sure the current directory is locate at the_database, no elsewhere. Otherwise an error message say Unable to establish connection will shown.

Now issue this command to create a database > connect 'jdbc:derby:thedb;create=true', a new folder named thedb will be created under the /home/derby directory. Usually a database will come with user authentication to ensure the data are secure. Unfortunately Derby set this configuration to false by default. To enabled user authentication, make sure derby.properties is exists in Derby installation path. If not, create it. The content should look like below. Replace username with your prefer user ID, and password with your desire password.

derby.connection.requireAuthentication=true
derby.user.username=password

To connect the database, use this command > connect 'jdbc:derby:DB_name;user=username;password=password'; Alternately, it can also be connect in this way > connect 'jdbc:derby:DB_name' user='username' password='password'; Since I am setting up the Derby for R&D on my local PC, and I have no intention to do serious work, thus I am keeping the authentication as simple as possible.