Tuesday, January 3, 2012

IzPack - A simple tutorial to create a JAVA based Installer

Hi friends, hereunder is the easy steps for creating the java installer (executable jars) using the IzPack.

Where to get IzPack

Download the IzPack distribution from http://get.izpack.org/izpack/4.3.5.
Prerequisite for IzPack is that you should have java installed in your host and path should be set to java/bin folder.

How to Install

If the native platform is windows, open the cmd client and type the following command for installation:
cd <download dir>
java -jar <downloaded IzPack jar>

If the native platform is linux, open the terminal and first navigate to download dir and launch the command for installing the IzPack.
cd <download dir>
java -jar <downloaded IzPack jar>

Follow the steps of installer it will install the IzPack on your host.

How to Use

IzPack having following component:
  1. install.xml : Used as a controller for all the installation process.
  2. userInputSpec.xml : Used for creating the installer panels.
  3. antActionSpec.xml : Used for calling different ant files based on the installation flow.
  4. RegistrySpec.xml : Used for registering the installed product to windows registry.
  5. ShortCutSpec.xml : Used for creating application shortcuts in program menu.
Sample Example

Assume you have a build file say build.xml which is responsible to create a war file for your deployment, you want to create a database in mysql and for that you have createdb.xml file. Now you need to create a installer which check the java version first, call the build.xml for creating your application war, copy your war to tomcat server and create database in mysql for you application along with automated uninstaller and program application registry for your application. Following code is a sample for doing these with help of IzPack :

Assumption

  1. build.xml : Build file for your project gives the final deploy-able application war.
  2. copyWar.xml: ant file having copyWar target which is responsible to copy the war file to selected server webapps directory.
  3. createDB.xml: ant file having createMySQLDB target which is having sql task to execute your database creation sql and needed the connector jar.
Steps for Creating Installer

Create a directory called MyInstaller inside your project say WatchEyeUI and follow these steps:
Project Structure for IzPack Installer



Step1: Configuring the install.xml

Create one xml file say install.xml and add the content like as:




    
        WatchEyeInstaller
        04012012
        
            
        
        http://www.mycompany.com
        1.6
    

    
  
  
    

    
        
    

    
    
    
    

    
        
    
 
  
 
 
        
    
    
        
    

    
        
        
        
            
        
    

    
    
        
        
        
        
        
        
               
    

    
        
        
        
    

    
    
        
        
        
        
             
        
        
        
        
        
    

    
 
        
            The set of base files.
            
            
            
        
        
            
        
       
           
        
        
           
        
    


Step2: Configuring the userInputSpec.xml

Create one xml file say userInputSpec.xml and add the content like as for creating the panel for taking the db parameter and server location:

       
            
               
            
            
            
               
            
                
                
            
               
            
                
                
            
               
            
                
                
            
               
            
                
                
                
                    
              
               
            
            
            
               
            
                
                
                                                                                                                                                                                                                   
Step3: Configuring the antActionSpec.xml

 
  
        
   
  
 
 
  
   
   
   
  
 
 
  
   
   
   
   
   
   
  
    

   Step4: Configuring the RegistrySpec.xml
     
           
  
  
   
   
   
   
       
   
        
  
  
  
    
             
  
 

  Step5: Configuring the ShortCutSpecSpec.xml
 
 
  
  
  
  
  
  
  
  
 
    Step6: Compiling the installer       Go to the bin directory of IzPack installation by following command:             cd C:\Program Files\IzPack\bin Use compile command to make the MyApplication.jar executable.Assume Project is in C:\WatchEye folder.
     compile C:\WatchEye\WatchEyeUI\installer\data\install.xml -b C:\WatchEye\WatchEyeUI\installer\data\ -o MyApplication.jar
It will create MyApplication.jar as executable. To launch the installer double click on your jar or type command java -jar MyApplication.jar for launching your installer.
References:
As per the request hereunder the sample createDB.xml file.
 
      
       
       
       
       
       
       
  
   
    
        
  
  
  
   
   
  
  
   
   
  
  
   
    
   
  
 
Sample: DBConnectionValidator class
package com.izforge.izpack.util;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.SQLException;
import com.izforge.izpack.installer.AutomatedInstallData;
import com.izforge.izpack.installer.DataValidator;

public class DBConnectionValidator implements DataValidator {  
 private String dbType="";
 private String cause="";
 @Override  
 public boolean getDefaultAnswer() {  
  return true;  
 }  

 @Override  
 public String getErrorMessageId() {  
  return "Can not connect to "+ dbType+" database." + cause;  
 }  

 @Override  
 public String getWarningMessageId() {  
  return "OPS-101";  
 }  

 @Override  
 public Status validateData(AutomatedInstallData arg) {  
  Connection connection = null;  
  try
  {
   URL urls [] = {};
   JarFileLoader cl = new JarFileLoader (urls);
   cl.addFile (arg.getVariable("jarFile.loc"));
   dbType=arg.getVariable("databasetype");
   java.sql.Driver driver=null;
   java.util.Properties props=null;

   System.out.println(arg.getVariable("jarFile.loc"));

   if(dbType.equalsIgnoreCase("MySQL")){
    Class cls = cl.loadClass ("com.mysql.jdbc.Driver");
    driver = (java.sql.Driver)cls.newInstance(); 
    props = new java.util.Properties();
    props.put("user", arg.getVariable("user"));
    props.put("password", arg.getVariable("password"));
    connection = driver.connect("jdbc:mysql://"+arg.getVariable("dbhostname")+":"+arg.getVariable("portno")+"/", props);
   }else if(dbType.equalsIgnoreCase("MS SQL Server")){
    Class cls = cl.loadClass ("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    driver = (java.sql.Driver)cls.newInstance(); 
    props = new java.util.Properties();
    props.put("user", arg.getVariable("user"));
    props.put("password", arg.getVariable("password"));
    // The replacement in the following is done to discard the % with \ while creating the connection URL with named instance.
    connection = driver.connect("jdbc:sqlserver://"+arg.getVariable("dbhostname").replace('%', '\\')+":"+arg.getVariable("portno"),props);
   }else if(dbType.equalsIgnoreCase("ORACLE")){
    Class cls = cl.loadClass ("oracle.jdbc.driver.OracleDriver");
    driver = (java.sql.Driver)cls.newInstance(); 
    props = new java.util.Properties();
    props.put("user", arg.getVariable("user"));
    props.put("password", arg.getVariable("password"));
    connection = driver.connect("jdbc:oracle:thin:@"+arg.getVariable("dbhostname")+":"+arg.getVariable("portno")+":"+arg.getVariable("instanceName"),props);
   }
  }
  catch (ClassNotFoundException e) {  
   e.printStackTrace();
   cause = "\nCause: Connector Jar is not valid for selected database!";
   if(dbType.equalsIgnoreCase("MySQL"))
    cause = cause + "\n\nYou can dowload the Connector Jar for MySQL form:\nhttp://dev.mysql.com/downloads/connector/j/5.0.html";
   else if (dbType.equalsIgnoreCase("MS SQL Server"))
    cause = cause + "\n\nYou can dowload the Connector Jar for MS SQL Server form:\nhttp://www.microsoft.com/download/en/details.aspx?displaylang=en&id=21599";
   else if (dbType.equalsIgnoreCase("ORACLE"))
    cause = cause + "\n\nYou can dowload the Connector Jar for Oracle form:\nhttp://www.oracle.com/technetwork/database/enterprise-edition/jdbc-10201-088211.html";
   cause = cause +"\n\nAfter selecting proper Connector Jar, proceed with the installation.";
   
   return Status.ERROR;  
  } catch (SQLException e) {  
   e.printStackTrace();
   cause = "\nCause: Invalid connection parameter(s) OR the database service is not started!";
   return Status.ERROR;  
  } catch (MalformedURLException e) {
   e.printStackTrace();
   return Status.ERROR;  
  } catch (InstantiationException e) {
   e.printStackTrace();
   return Status.ERROR;  
  } catch (IllegalAccessException e) {
   return Status.ERROR;  
  } finally {  
   if (connection != null) {  
    try {  
     connection.close();  
    } catch (SQLException e) {  
     return Status.ERROR;  
    }  
   }  
  }  
  return Status.OK;  
 }

 public static class JarFileLoader extends URLClassLoader
 {
  public JarFileLoader (URL[] urls)
  {
   super (new URL[]{});
  }

  public void addFile (String path) throws MalformedURLException
  {
   String urlPath = "jar:file:///" + path + "!/";
   addURL (new URL (urlPath));
  }
 }  
}