Wednesday, July 25, 2012

Let's Get into the Hygienic Habit of Code Refactoring!

It is motivated by Code smells

Code Smells

1. Duplicate Code

The following are some of the ways in which two code sequences can be duplicates of each other:
  • character-for-character identical
  • character-for-character identical with white space characters and comments being ignored
  • token-for-token identical
  • token-for-token identical with occasional variation (i.e., insertion/deletion/modification of tokens)
  • functionally identica

    There are a number of reasons why duplicate code may be created, including:

  • Copy and paste programming, in which a section of code is copied "because it works". In most cases this operation involves slight modifications in the cloned code such as renaming variables or inserting/deleting code.
  • Functionality that is very similar to that in another part of a program is required and a developer independently writes code that is very similar to what exists elsewhere.
  • Plagiarism, where code is simply copied without permission or attribution

Code duplication is generally considered a mark of poor or lazy programming style. Good coding style is generally associated with code reuse. It may be slightly faster to develop by duplicating code, because the developer need not concern himself with how the code is already used or how it may be used in the future. The difficulty is that original development is only a small fraction of a product's life cycle, and with code duplication the maintenance costs are much higher. Some of the specific problems include:
  • Code bulk affects comprehension: Code duplication frequently creates long, repeated sections of code that differ in only a few lines or characters. The length of such routines can make it difficult to quickly understand them. This is in contrast to the "best practice" of code decomposition.
  • Purpose masking: The repetition of largely identical code sections can conceal how they differ from one another, and therefore, what the specific purpose of each code section is. Often, the only difference is in a parameter value. The best practice in such cases is a reusable subroutine.
  • Update anomalies: Duplicate code contradicts a fundamental principle of database theory that applies here: Avoid redundancy. Non-observance incurs update anomalies, which increase maintenance costs, in that any modification to a redundant piece of code must be made for each duplicate separately. At best, coding and testing time are multiplied by the number of duplications. At worst, some locations may be missed, and for example bugs thought to be fixed may persist in duplicated locations for months or years. The best practice here is a code library.
  • File size: Unless external lossless compression is applied, the file will take up more space on the computer.
  •  
  • Consider the following code snippet for calculating the average of an array of integers
  • extern int array1[];
    extern int array2[];
     
    int sum1 = 0;
    int sum2 = 0;
    int average1 = 0;
    int average2 = 0;
     
    for (int i = 0; i < 4; i++)
    {
       sum1 += array1[i];
    }
    average1 = sum1/4;
     
    for (int i = 0; i < 4; i++)
    {
       sum2 += array2[i];
    }
    average2 = sum2/4;
    
    The two loops can be rewritten as the single function:
    int calcAverage (int* Array_of_4)
    {
       int sum = 0;
       for (int i = 0; i < 4; i++)
       {
           sum += Array_of_4[i];
       }
       return sum/4;
    }
    
    Using the above function will give source code that has no loop duplication:
    extern int array1[];
    extern int array2[];
     
    int average1 = calcAverage(array1);
    int average2 = calcAverage(array2);
    
     
A number of different algorithms have been proposed to detect duplicate code. For example:
2. Long Method/Function/Procedure that has grown too large
3. Large class: a class that has grown too large. See God object.
          
In object-oriented programming, a god object is an object that knows too much or does too much. The god object is an example of an anti-pattern.
The basic idea behind object-oriented programming is that a big problem is broken down into several smaller problems (a divide and conquer strategy) and solutions are created for each of them. Once the small problems have been solved, the big problem as a whole has been solved. Therefore there is only one object about which an object needs to know everything: itself. Likewise, there is only one set of problems an object needs to solve: its own.
God object–based code does not follow this approach. Instead, most of a program's overall functionality is coded into a single "all-knowing" object, which maintains most of the information about the entire program and provides most of the methods for manipulating this data. Because this object holds so much data and requires so many methods, its role in the program becomes god-like (all-encompassing). Instead of program objects communicating amongst themselves directly, the other objects within the program rely on the god object for most of their information and interaction. Since the god object is referenced by so much of the other code, maintenance becomes more difficult than it would in a more evenly divided programming design.
A god object is the object-oriented analogue of failing to use subroutines in procedural programming languages, or of using far too many global variables to store state information.
While creating a god object is typically considered bad programming practice, this technique is occasionally used for tight programming environments (such as microcontrollers), where the slight performance increase and centralization of control is more important than maintainability and programming elegance

4. Too many parameters: a long list of parameters in a procedure or function make readability and      code quality worse.
5.  Feature envy: a class that uses methods of another class excessively.

A classic smell is a method that seems more interested in a class other than the one it actually is in. The most common focus of the envy is the data. We’ve lost count of the times we’ve seen a method that invokes half-a-dozen getting methods on another object to calculate some value. Fortunately the cure is obvious, the method clearly wants to be elsewhere, so you use Move Method to get it there. Sometimes only part of the method suffers from envy; in that case use Extract Method on the jealous bit and Move Method to give it a dream home.

Of course not all cases are cut-and-dried. Often a method uses features of several classes, so which one should it live with? The heuristic we use is to determine which class has most of the data and put the method with that data. This step is often made easier if Extract Method is used to break the method into pieces that go into different places.

for tomorrow!!
 http://sourcemaking.com/refactoring/move-method
A method is, or will be, using or used by more features of another class than the class on which it is defined.

Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether.
graphics/07fig01.gif

Motivation


Moving methods is the bread and butter of refactoring. I move methods when classes have too much behavior or when classes are collaborating too much and are too highly coupled. By moving methods around, I can make the classes simpler and they end up being a more crisp implementation of a set of responsibilities.

I usually look through the methods on a class to find a method that seems to reference another object more than the object it lives on. A good time to do this is after I have moved some fields. Once I see a likely method to move, I take a look at the methods that call it, the methods it calls, and any redefining methods in the hierarchy. I assess whether to go ahead on the basis of the object with which the method seems to have more interaction.

It’s not always an easy decision to make. If I am not sure whether to move a method, I go on to look at other methods. Moving other methods often makes the decision easier. Sometimes the decision still is hard to make. Actually it is then no big deal. If it is difficult to make the decision, it probably does not matter that much. Then I choose according to instinct; after all, I can always change it again later.

Mechanics


  • Examine all features used by the source method that are defined on the source class. Consider whether they also should be moved.
    If a feature is used only by the method you are about to move, you might as well move it, too. If the feature is used by other methods, consider moving them as well. Sometimes it is easier to move a clutch of methods than to move them one at a time.
  • Check the sub- and superclasses of the source class for other declarations of the method.
    If there are any other declarations, you may not be able to make the move, unless the polymorphism can also be expressed on the target.
  • Declare the method in the target class.
    You may choose to use a different name, one that makes more sense in the target class.
  • Copy the code from the source method to the target. Adjust the method to make it work in its new home.
    If the method uses its source, you need to determine how to reference the source object from the target method. If there is no mechanism in the target class, pass the source object reference to the new method as a parameter. If the method includes exception handlers, decide which class should logically handle the exception. If the source class should be responsible, leave the handlers behind.
  • Compile the target class.
  • Determine how to reference the correct target object from the source.
    There may be an existing field or method that will give you the target. If not, see whether you can easily create a method that will do so. Failing that, you need to create a new field in the source that can store the target. This may be a permanent change, but you can also make it temporarily until you have refactored enough to remove it.
  • Turn the source method into a delegating method.
  • Compile and test.
  • Decide whether to remove the source method or retain it as a delegating method.
    Leaving the source as a delegating method is easier if you have many references.
  • If you remove the source method, replace all the references with references to the target method.
    You can compile and test after changing each reference, although it is usually easier to change all references with one search and replace.
  • Compile and test.

Example


An account class illustrates this refactoring:

 class Account...
   double overdraftCharge() {
       if (_type.isPremium()) {
           double result = 10;
           if (_daysOverdrawn > 7) result += (_daysOverdrawn - 7) * 0.85;
           return result;
       }
       else return _daysOverdrawn * 1.75;
   }
 
   double bankCharge() {
       double result = 4.5;
       if (_daysOverdrawn > 0) result += overdraftCharge();
       return result;
   }
   private AccountType _type;
   private int _daysOverdrawn;

Let’s imagine that there are going to be several new account types, each of which has its own rule for calculating the overdraft charge. So I want to move the overdraft charge method over to the account type.

The first step is to look at the features that the overdraftCharge method uses and consider whether it is worth moving a batch of methods together. In this case I need the _daysOverdrawn field to remain on the account class, because that will vary with individual accounts.

Next I copy the method body over to the account type and get it to fit.

 class AccountType...
   double overdraftCharge(int daysOverdrawn) {
       if (isPremium()) {
           double result = 10;
           if (daysOverdrawn > 7) result += (daysOverdrawn - 7) * 0.85;
           return result;
       }
       else return daysOverdrawn * 1.75;
   }

In this case fitting means removing the _type from uses of features of the account type, and doing something about the features of account that I still need. When I need to use a feature of the source class I can do one of four things: (1) move this feature to the target class as well, (2) create or use a reference from the target class to the source, (3) pass the 0source object as a parameter to the method, (4) if the feature is a variable, pass it in as a parameter.

In this case I passed the variable as a parameter.

Once the method fits and compiles in the target class, I can replace the source method body with a simple delegation:

 class Account...
   double overdraftCharge() {
       return _type.overdraftCharge(_daysOverdrawn);
   }

At this point I can compile and test.

I can leave things like this, or I can remove the method in the source class. To remove the method I need to find all callers of the method and redirect them to call the method in account type:

 class Account...
   double bankCharge() {
       double result = 4.5;
       if (_daysOverdrawn > 0) result += _type.overdraftCharge(_daysOverdrawn);
       return result;
   }

Once I’ve replaced all the callers, I can remove the method declaration in account. I can compile and test after each removal, or do them in a batch. If the method isn’t private, I need to look for other classes that use this method. In a strongly typed language, the compilation after removal of the source declaration finds anything I missed.

In this case the method referred only to a single field, so I could just pass this field in as a variable. If the method called another method on the account, I wouldn’t have been able to do that. In those cases I need to pass in the source object:

 class AccountType...
   double overdraftCharge(Account account) {
       if (isPremium()) {
           double result = 10;
           if (account.getDaysOverdrawn() > 7)
              result += (account.getDaysOverdrawn() - 7) * 0.85;
           return result;
       }
       else return account.getDaysOverdrawn() * 1.75;
   }

I also pass in the source object if I need several features of the class, although if there are too many, further refactoring is needed. Typically I need to decompose and move some pieces back.


 http://sourcemaking.com/refactoring/extract-method



6.   Inappropriate intimacy: a class that has dependencies on implementation details of another class.

Sometimes classes become far too intimate and spend too much time delving in each others’private parts. We may not be prudes when it comes to people, but we think our classes should follow strict, puritan rules.

Overintimate classes need to be broken up as lovers were in ancient days. Use Move Method and Move Field to separate the pieces to reduce the intimacy. See whether you can arrange a Change Bidirectional Association to Unidirectional. If the classes do have common interests, use Extract Class to put the commonality in a safe place and make honest classes of them. Or use Hide Delegate to let another class act as go-between.

Inheritance often can lead to overintimacy. Subclasses are always going to know more about their parents than their parents would like them to know. If it’s time to leave home, apply Replace Delegation with Inheritance.


7.   Refused bequest: a class that overrides a method of a base class in such a way that the contract of the base class is not honored by the derived class. See Liskov substitution principle.

All the time we design a program module and we create some class hierarchies. Then we extend some classes creating some derived classes.
We must make sure that the new derived classes just extend without replacing the functionality of old classes. Otherwise the new classes can produce undesired effects when they are used in existing program modules.
Likov's Substitution Principle states that if a program module is using a Base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module.

Intent

Derived types must be completely substitutable for their base types.

Example

Below is the classic example for which the Likov's Substitution Principle is violated. In the example 2 classes are used: Rectangle and Square. Let's assume that the Rectangle object is used somewhere in the application. We extend the application and add the Square class. The square class is returned by a factory pattern, based on some conditions and we don't know the exact what type of object will be returned. But we know it's a Rectangle. We get the rectangle object, set the width to 5 and height to 10 and get the area. For a rectangle with width 5 and height 10 the area should be 50. Instead the result will be 100
// Violation of Likov's Substitution Principle
class Rectangle
{
 protected int m_width;
 protected int m_height;

 public void setWidth(int width){
  m_width = width;
 }

 public void setHeight(int height){
  m_height = height;
 }


 public int getWidth(){
  return m_width;
 }

 public int getHeight(){
  return m_height;
 }

 public int getArea(){
  return m_width * m_height;
 } 
}

class Square extends Rectangle 
{
 public void setWidth(int width){
  m_width = width;
  m_height = width;
 }

 public void setHeight(int height){
  m_width = height;
  m_height = height;
 }

}

class LspTest
{
 private static Rectangle getNewRectangle()
 {
  // it can be an object returned by some factory ... 
  return new Square();
 }

 public static void main (String args[])
 {
  Rectangle r = LspTest.getNewRectangle();
        
  r.setWidth(5);
  r.setHeight(10);
  // user knows that r it's a rectangle. 
  // It assumes that he's able to set the width and height as for the base class

  System.out.println(r.getArea());
  // now he's surprised to see that the area is 100 instead of 50.
 }
}


This principle is just an extension of the Open Close Principle and it means that we must make sure that new derived classes are extending the base classes without changing their behavior.

Immutable Objects example

A classic example of an immutable object is an instance of the Java String class.
String s = "ABC";
s.toLowerCase();
The method toLowerCase() will not change the data "ABC" that s contains. Instead, a new String object is instantiated and given the data "abc" during its construction. A reference to this String object is returned by the toLowerCase() method. To make the String s contain the data "abc", a different approach is needed.
s = s.toLowerCase();
Now the String s references a new String object that contains "abc". There is nothing in the syntax of the declaration of the class String that enforces it as immutable; rather, none of the String class's methods ever affect the data that a String object contains, thus making it immutable.
By default, fields and local variables are mutable. They can be made immutable using the final keyword.
int i = 42;
i = 43; // OK
 
final int j = 42;
j = 43; // does not compile


8.  Lazy class / Freeloader: a class that does too little.

A superclass and subclass are not very different.

Merge them together.
graphics/11fig10.gif

Motivation


If you have been working for a while with a class hierarchy, it can easily become too tangled for its own good. Refactoring the hierarchy often involves pushing methods and fields up and down the hierarchy. After you’ve done this you can well find you have a subclass that isn’t adding any value, so you need to merge the classes together.

Mechanics


  • Choose which class is going to be removed: the superclass or the subclasses.
  • Use Pull Up Field and Pull Up Method or Push Down Method and Push Down Field to move all the behavior and data of the removed class to the class with which it is being merged.
  • Compile and test with each move.
  • Adjust references to the class that will be removed to use the merged class. This will affect variable declarations, parameter types, and constructors.
  • Remove the empty class.
  • Compile and test.


9.  Contrived complexity: forced usage of overly complicated design patterns where simpler design would suffice.
10.  Excessively long identifiers: in particular, the use of naming conventions to provide disambiguation that should be implicit in the software architecture
11.  Excessively short identifiers: the name of a variable should reflect its function unless it's obvious.
12.  Excessive use of literals: these should be coded as named constants, to improve readability and to avoid programming errors. Additionally, literals can and should be externalized into resource files/scripts where possible, to facilitate localization of software if it is intended to be deployed in different regions.
13.  Ubercallback: a callback that is trying to do everything
The following code in C demonstrates the use of callbacks to display two numbers.
#include <stdio.h>
#include <stdlib.h>
 
/* The calling function takes a single callback as a parameter. */
void PrintTwoNumbers(int (*numberSource)(void)) {
    printf("%d and %d\n", numberSource(), numberSource());
}
 
/* A possible callback */
int overNineThousand(void) {
    return (rand() % 1000) + 9001;
}
 
/* Another possible callback. */
int meaningOfLife(void) {
    return 42;
}
 
/* Here we call PrintTwoNumbers() with three different callbacks. */
int main(void) {
    PrintTwoNumbers(&rand);
    PrintTwoNumbers(&overNineThousand);
    PrintTwoNumbers(&meaningOfLife);
    return 0;
}
This should provide output similar to:
 125185 and 89188225
 9084 and 9441
 42 and 42
Note how this is different from simply passing the output of the callback function to the calling function, PrintTwoNumbers() - rather than printing the same value twice, the PrintTwoNumbers calls the callback as many times as it requires. This is one of the two main advantages of callbacks.

14.  Anti-pattern

Object-oriented design

  • Anemic Domain Model: The use of the domain model without any business logic. The domain model's objects cannot guarantee their correctness at any moment, because their validation and mutation logic is placed somewhere outside (most likely in multiple places).
  • BaseBean: Inheriting functionality from a utility class rather than delegating to it, For example, an order is not a vector, although an order may contain a vector of line items.A class should not inherit from another class simply because the parent class contains functionality needed in the subclass. Instead, delegation (has-a relationship) should be used to obtain the business logic or data structure that is required.In technical terms, this case warrants composition over inheritance
  • Call super: Requiring subclasses to call a superclass's overridden method

    Example

    Suppose there is a class for generating a report about the inventory of a video rental store. Each particular store has a different way of tabulating the videos currently available, but the algorithm for generating the final report is the same for all stores. A framework that uses the call super anti-pattern may provide the following abstract class (in C#):
    abstract class ReportGenerator {
        public virtual Report CreateReport() {
            // Generate the general report object
            // ...
            return new Report(...);
        }
    }
    
    A user of the class is expected to implement a subclass like this:
    class ConcreteReportGenerator : ReportGenerator {
        public override Report CreateReport() {
            // Tabulate data in the store-specific way
            // ...
     
            // Design of this class requires the parent CreateReport() function to be called at the 
            // end of the overridden function. But note this line could easily be left out, or the
            // returned report could be further modified after the call, violating the class design
            // and possibly also the company-wide report format.
            return base.CreateReport();
        }
    }
    
    A preferable interface looks like this:
    abstract class ReportGenerator {
        public Report CreateReport() {
            Tabulate();
     
            // Generate the general report object
            // ...
            return new Report(...);
        }
     
        protected abstract void Tabulate();
    }
    
    An implementation would override this class like this:
    class ConcreteReportGenerator : ReportGenerator {
        protected override void Tabulate() {
            // Tabulate data in the store-specific way
            // ...
        }
    }
    
  • Circle-ellipse problem: Subtyping variable-types on the basis of value-subtypes

    Challenge the premise of the problem

    While at first glance it may seem obvious that a Circle is-an Ellipse, consider the following alternate representation of essentially the same problem, stated in terms of Java code.
    class Person
    {
      void walkNorth( int meters ) {...}   // No failure or exception allowed
      void walkEast( int meters ) {...}    // No failure or exception allowed
    }
    
    Now, a prisoner is obviously a person. So we could logically create a sub-class:
    class Prisoner extends Person
    {
      void walkNorth( int meters ) {...}   // No failure or exception allowed
      void walkEast( int meters ) {...}    // No failure or exception allowed
    }
    
    Just as obviously, this leads us into trouble, since a prisoner is not free to move an arbitrary distance in any direction, yet the contract of the Person class states that a Person can.
    So, in fact, the class Person could better be named FreePerson. If that were the case, then the idea that class Prisoner extends FreePerson is clearly wrong.
    By analogy, then, a Circle, is not an Ellipse, because it lacks the same degrees of freedom as an Ellipse.
    This strongly suggests that inheritance should never be used when the sub-class restricts the freedom implicit in the base class, but should only be used when the sub-class adds extra detail to the concept represented by the base class as in 'Monkey' is-a 'Animal'.
  • Circular dependency: Introducing unnecessary direct or indirect mutual dependencies between objects or software modules

    Circular dependencies can cause many unwanted effects in software programs. Most problematic from a software design point of view is the tight coupling of the mutually dependent modules which reduces or makes impossible the separate re-use of a single module.
    Circular dependencies can cause a domino effect when a small local change in one module spreads into other modules and has unwanted global effects (program errors, compile errors). Circular dependencies can also result in infinite recursions or other unexpected failures.
    Circular dependencies may also cause memory leaks by preventing certain very primitive automatic garbage collectors (those that use reference counting) from deallocating unused objects.
    In very large software designs, software engineers may lose the context and inadvertently introduce circular dependencies. There are tools to analyze software and find unwanted circular dependencies[1][2].
    Circular dependencies are often introduced by inexperienced programmers who need to implement some kind of callback functionality. Experienced programmers avoid such unnecessary circular dependencies by applying design patterns like the observer pattern.
    Implementation of circular dependencies in C/C++ can be a bit tricky, because any class or structure definition must be placed above its usage in the same file. A circular dependency between classes A and B will thus both require the definition of A to be placed above B, and the definition of B to be placed above A, which of course is impossible. A forward declaration trick is therefore needed to accomplish this.
    The following example illustrates how this is done.

     a.h:
#ifndef A_H
#define A_H
 
class B;        //forward declaration
 
class A {
public:
        B* b;
};
#endif //A_H 
 
 b.h:
 
#ifndef B_H
#define B_H
 
class A;        //forward declaration
 
class B {
public:
        A* a;
};
#endif //B_H 
 
 main.cpp:
 
#include "a.h"
#include "b.h"
 
int main() {
        A a;
        B b;
        a.b = &b;
        b.a = &a;
}
Note that although a name (e.g. A) can be declared multiple times, such as in forward declarations, it can only be defined once (the One Definition Rule).

  • Constant interface: Using interfaces to define constants

    Example

    public interface Constants {
     
            public static final double PI = 3.14159;
            public static final double PLANCK_CONSTANT = 6.62606896e-34;
    }
     
     
    public class Calculations implements Constants {
     
            public double getReducedPlanckConstant() {
                    return PLANCK_CONSTANT / (2 * PI);
            }
    }
    

    Alternatives

    Many of the pitfalls of the anti-pattern can be avoided by converting the constants interface to a proper class with no instances:
    public final class Constants {
     
            private Constants() {
                    // restrict instantiation
            }
     
            public static final double PI = 3.14159;
            public static final double PLANCK_CONSTANT = 6.62606896e-34;
    }
    
    This still leaves the original intent of the pattern mostly un-addressed (i.e. there is no syntax for accessing the constants unqualified). However, since Java 5, consider using static import[2] to achieve the same goal:
    import static Constants.PLANCK_CONSTANT;
    import static Constants.PI;
     
    public class Calculations {
     
            public double getReducedPlanckConstant() {
                    return PLANCK_CONSTANT / (2 * PI);
            }
    }
    
  • God object: Concentrating too many functions in a single part of the design (class)
    In object-oriented programming, a god object is an object that knows too much or does too much. The god object is an example of an anti-pattern.
    The basic idea behind object-oriented programming is that a big problem is broken down into several smaller problems (a divide and conquer strategy) and solutions are created for each of them. Once the small problems have been solved, the big problem as a whole has been solved. Therefore there is only one object about which an object needs to know everything: itself. Likewise, there is only one set of problems an object needs to solve: its own.
    God object–based code does not follow this approach. Instead, most of a program's overall functionality is coded into a single "all-knowing" object, which maintains most of the information about the entire program and provides most of the methods for manipulating this data. Because this object holds so much data and requires so many methods, its role in the program becomes god-like (all-encompassing). Instead of program objects communicating amongst themselves directly, the other objects within the program rely on the god object for most of their information and interaction. Since the god object is referenced by so much of the other code, maintenance becomes more difficult than it would in a more evenly divided programming design.
    A god object is the object-oriented analogue of failing to use subroutines in procedural programming languages, or of using far too many global variables to store state information.
    While creating a god object is typically considered bad programming practice, this technique is occasionally used for tight programming environments (such as microcontrollers), where the slight performance increase and centralization of control is more important than maintainability and programming elegance
  • Object cesspool: Reusing objects whose state does not conform to the (possibly implicit) contract for re-use
    When writing an object pool, the programmer has to be careful to make sure the state of the objects returned to the pool is reset back to a sensible state for the next use of the object. If this is not observed, the object will often be in some state that was unexpected by the client program and may cause the client program to fail. The pool is responsible for resetting the objects, not the clients. Object pools full of objects with dangerously stale state are sometimes called object cesspools and regarded as an anti-pattern.
    The presence of stale state is not always an issue; it becomes dangerous when the presence of stale state causes the object to behave differently. For example, an object that represents authentication details may break if the "successfully authenticated" flag is not reset before it is passed out, since it will indicate that a user is correctly authenticated (possibly as someone else) when they haven't yet attempted to authenticate. However, it will work just fine if you fail to reset some value only used for debugging, such as the identity of the last authentication server used.
    Inadequate resetting of objects may also cause an information leak. If an object contains confidential data (e.g. a user's credit card numbers) that isn't cleared before the object is passed to a new client, a malicious or buggy client may disclose the data to an unauthorized party.
    If the pool is used by multiple threads, it may need means to prevent parallel threads from grabbing and trying to reuse the same object in parallel. This is not necessary if the pooled objects are immutable or otherwise thread-safe.
  • Object orgy: Failing to properly encapsulate objects permitting unrestricted access to their internals

    Absence of data encapsulation. The data members may be public (or might as well be because they are exposed to the world through getters and setters), or the objects may hold references to each other. In any case the objects do more tweaking of the other objects data than their own, with ensuing confusion about who did what to whom when.
    Have you ever attempted to disassemble a mechanical stopwatch? While most aren't too bad, many share one interesting trait: upon removing the back cover, tiny springs, gears, cogs, plates, shafts, sprockets, ratchets and dozens of unidentifiable pieces literally fly out. This sensation of hopelessness is matched only by a programmer assigned to make changes to a program designed to work exactly one way and to never be changed. Building anew is far more likely than ever picking the pieces up "off the floor"
  • Poltergeists: Objects whose sole purpose is to pass information to another object

    The consequences of an object orgy are essentially a loss of the benefits of encapsulation:

        Unrestricted access makes it hard for the reader to reason about the behaviour of an object. This is because direct access to its internal state means any other part of the system can manipulate it, increasing the amount of code to be examined, and opening the door to future abuse.
        As a consequence of the difficulty of reasoning, design by contract is effectively impossible.
        If much code takes advantage of the lack of encapsulation, the result is a scarcely maintainable maze of interactions, commonly known as a rat's nest or spaghetti code.
        The original design is obscured by the excessively broad interfaces to objects.
        The broad interfaces make it harder to re-implement a class without disturbing the rest of the system. This is especially hard when the clients of the class are developed by a different team or organisation.
  • Sequential coupling: A class that requires its methods to be called in a particular order
    Methods whose name starts with Init, Begin, Start, etc. may indicate the existence of sequential coupling.Using a car as an analogy, if the user steps on the gas without first starting the engine, the car does not crash, fail, or throw an exception - it simply fails to accelerate.Sequential coupling can be refactored with the Template method pattern to overcome the problems posed by the usage of this anti-pattern.[1]
  • Yo-yo problem: A structure (e.g., of inheritance) that is hard to understand due to excessive fragmentation
    In computer science, the yo-yo problem is an anti-pattern that occurs when a programmer has to read and understand a program whose inheritance graph is so long and complicated that the programmer has to keep flipping between many different class definitions in order to follow the control flow of the program. It often happens in object-oriented programming. The term comes from comparing the bouncing attention of the programmer to the up-down movement of a toy yo-yo.

Programming

  • Accidental complexity: Introducing unnecessary complexity into a solution
    Accidental complexity is complexity that arises in computer programs or their development process which is non-essential to the problem to be solved. While essential complexity is inherent and unavoidable, accidental complexity is caused by the approach chosen to solve the problem.[1]
    While sometimes accidental complexity can be due to mistakes such as ineffective planning, or low priority placed on a project, some accidental complexity always occurs as the side effect of solving any problem. For example, the complexity caused by out of memory errors is an accidental complexity to most programs that occurs because one decided to use a computer to solve the problem.
  • Action at a distance: Unexpected interaction between widely separated parts of a system
    Action at a distance is an anti-pattern (a recognized common error) in which behavior in one part of a program varies wildly based on difficult or impossible to identify operations in another part of the program. The way to avoid the problems associated with action at a distance are a proper design which avoids global variables and alters data in a controlled and local manner, or usage of a pure functional programming style with referential transparency.
    Bugs due to "action at a distance" may arise because a program component is doing something at the wrong time, or affecting something it should not. It is very difficult, however, to track down which component is responsible. Side effects from innocent actions can put the program in an unknown state, so local data is not necessarily local. The solution in this particular scenario is to define which components should be interacting with which others. A proper design that accurately defines the interface between parts of a program, and that avoids shared states, can largely eliminate problems caused by action at a distance.

    This example, from the Perl programming language, demonstrates an especially serious case of action at a distance:
    Array indices normally begin at 0 because the value of $[ is normally 0; if you set $[ to 1, then arrays start at 1, which makes Fortran programmers happy, and so we see examples like this in the perl(3) man page:
    foreach $num ($[ .. $#entry) {
      print "  $num\t'",$entry[$num],"'\n";
    }
    
    And of course you could set $[ to 17 to have arrays start at some random number such as 17 or 4 instead of at 0 or 1. This was a great way to sabotage module authors.
    Fortunately, sanity prevailed. These features are now recognized to have been mistakes. The perl5-porters mailing list now has a catchphrase for such features: they're called "action at a distance". The principle is that a declaration in one part of the program shouldn't drastically and invisibly alter the behavior of some other part of the program.
    Proper object oriented programming involves design principles that avoid action at a distance. The Law of Demeter states that an object should only interact with other objects near itself. Should action in a distant part of the system be required then it should be implemented by propagating a message. Proper design severely limits occurrences of action at a distance, contributing to maintainable programs. Pressure to create an object orgy results from poor interface design, perhaps taking the form of a God object, not implementing true objects, or failing to heed the Law of Demeter.

    referential transparency:
    As an example, let's use two functions, one which is referentially opaque, and the other which is referentially transparent:
     globalValue = 0;
    
     integer function rq(integer x)
     begin
       globalValue = globalValue + 1;
       return x + globalValue;
     end
    
     integer function rt(integer x)
     begin
       return x + 1;
     end
    
    The function rt is referentially transparent, which means that rt(x) = rt(y) if x = y. For instance, rt(6) = 6 + 1 = 7, rt(4) = 4 + 1 = 5, and so on. However, we can't say any such thing for rq because it uses a global variable which it modifies
  • Blind faith: Lack of checking of (a) the correctness of a bug fix or (b) the result of a subroutine
    In computer programming blind faith (also known as blind programming or blind coding) is a situation whereby a programmer develops a solution or fixes a computer bug and deploys it without ever testing their creation. The programmer in this situation has blind faith in their own abilities.
    Another form of blind faith is when a programmer calls a subroutine without checking the result. E.g.: A programmer calls a subroutine to save user-data on the hard disk without checking whether the operation was successful or not. In this case the programmer has blind faith in the subroutine always performing what the programmer intends to accomplish.
    Blind faith is an example of an Anti-pattern. Other common names for blind faith include "God oriented programming" and "divine orientation".
  • Boat anchor: Retaining a part of a system that no longer has any use

    The term boat anchor is also used in software development to refer to an unused piece of code[2] that is left in a system's code base, typically for the reason "In case we need it later".
    CodeCmmt002.svg
    This is an example of an anti-pattern and therefore can cause many problems for people attempting to maintain the program that contains the obsolete code. The key problem comes from the fact that programmers will have a hard time differentiating between obsolete code which doesn't do anything and working code which does. For example, a programmer may be looking into a bug with the program's input handling system, so they search through the code looking for code that links into the input handling API. Obviously if the programmer comes across obsolete input handling code they may well start editing and debugging it, wasting valuable time before they realise that the code that they're working with is never executed and therefore not part of the problem they're trying to solve. Other problems include longer compile times and the risk that programmers may accidentally link working code into the defunct code, inadvertently resurrecting it. The correct solution for dealing with boat anchors in source code is to remove them from the code base and to place them in a separate location so that they can be referred to if necessary, but will not be compiled or be mistaken as "working" code. (For example deleting them, knowing they are stored in the projects's source control)
  • Busy waiting: Consuming CPU while waiting for something to happen, usually by repeated checking instead of messaging
    In software engineering, busy-waiting or spinning is a technique in which a process repeatedly checks to see if a condition is true, such as whether keyboard input is available, or if a lock is available. Spinning can also be used to generate an arbitrary time delay, a technique that was necessary on systems that lacked a method of waiting a specific length of time. On modern computers with widely differing processor speeds, spinning as a time delay technique often produces unpredictable results unless code is implemented to determine how quickly the processor can execute a "do nothing" loop.
    The following C code examples illustrate two threads that share a global integer i. The first thread uses busy-waiting to check for a change in the value of i:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <stdlib.h>
     
    volatile int i = 0; /* i is global, so it is visible to all functions.
                           It's also marked volatile, because it
                           may change in a way which is not predictable by the compiler,
                           here from a different thread. */
     
    /* f1 uses a spinlock to wait for i to change from 0. */
    static void *f1(void *p)
    {
        while (i==0) {
            /* do nothing - just keep checking over and over */
        } 
        printf("i's value has changed to %d.\n", i);
        return NULL;
    }
     
    static void *f2(void *p)
    {
        sleep(60);   /* sleep for 60 seconds */
        i = 99;
        printf("t2 has changed the value of i to %d.\n", i);
        return NULL;
    }
     
    int main()
    {
        int rc;
        pthread_t t1, t2;
     
        rc = pthread_create(&t1, NULL, f1, NULL);
        if (rc != 0) {
            fprintf(stderr,"pthread f1 failed\n");
            return EXIT_FAILURE;
        }
     
        rc = pthread_create(&t2, NULL, f2, NULL);
        if (rc != 0) {
            fprintf(stderr,"pthread f2 failed\n");
            return EXIT_FAILURE;
        }
     
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
        puts("All pthreads finished.");
        return 0;
    }
    
    Most operating systems and threading libraries provide a variety of system calls that will block the process on an event, such as lock acquisition, timer changes, I/O availability or signals. Using such calls generally produces the simplest, most efficient, fair, and race-free result. A single call checks, informs the scheduler of the event it is waiting for, inserts a memory barrier where applicable, and may perform a requested I/O operation before returning. Other processes can use the CPU while the caller is blocked. The scheduler is given the information needed to implement priority inheritance or other mechanisms to avoid starvation.
    In low-level programming, busy-waits may actually be desirable. It may not be desirable or practical to implement interrupt-driven processing for every hardware device, particularly those that are seldom accessed. Sometimes it is necessary to write some sort of control data to hardware and then fetch device status resulting from the write operation, status that may not become valid until a number of machine cycles have elapsed following the write. The programmer could call an operating system delay function, but doing so may consume more time than would be expended in spinning for a few clock cycles waiting for the device to return its status.


  • Caching failure: Forgetting to reset an error flag when an error has been corrected
  • Cargo cult programming: Using patterns and methods without understanding why
  • Coding by exception: Adding new code to handle each special case as it is recognized
  • Error hiding: Catching an error message before it can be shown to the user and either showing nothing or showing a meaningless message
  • Hard code: Embedding assumptions about the environment of a system in its implementation
  • Lava flow: Retaining undesirable (redundant or low-quality) code because removing it is too expensive or has unpredictable consequences[5][6]
  • Loop-switch sequence: Encoding a set of sequential steps using a switch within a loop statement
  • Magic numbers: Including unexplained numbers in algorithms
  • Magic strings: Including literal strings in code, for comparisons, as event types etc.
  • Repeating yourself: Writing code which contains repetitive patterns and substrings over again; avoid with once and only once (abstraction principle)
  • Soft code: Storing business logic in configuration files rather than source code[7]
  • Spaghetti code: Programs whose structure is barely comprehensible, especially because of misuse of code structures
  • Shotgun surgery: Developer adds features to an application codebase which span a multiplicity of implementors or implementations in a single change.






















Thursday, July 5, 2012

Java > Create a JAR file

http://viralpatel.net/blogs/create-jar-file-in-java-eclipse/

 

 

Create a JAR file

?
1
2
3
jar cf JAR_FILE_NAME FILE_NAMES_OR_DIRECTORY_NAME
e.g.
jar cf MyApp1.jar C:\JavaProject\MyApp

View contents of a JAR file

?
1
2
3
jar tf JAR_FILE_NAME
e.g.
jar tf MyApp1.jar

View contents with detail of a JAR file

?
1
2
3
jar tvf JAR_FILE_NAME
e.g.
jar tvf MyApp1.jar
Note that we have used v (verbose) option to see the detail of JAR.

Extract content of JAR file

?
1
2
3
jar xf JAR_FILE_NAME
e.g.
jar xf MyApp1.jar

Extract specific file from JAR file

?
1
2
3
jar xf JAR_FILE_NAME FILE_NAME(S)_FROM_JAR_FILE
e.g.
jar xf MyApp1.jar Test1.class

Update a JAR file

?
1
2
3
jar uf JAR_FILE_NAME FILE_NAMES_FROM_JAR_FILE
e.g.
jar uf MyApp1.jar Test1.class

Executing a JAR file

?
1
2
3
java -jar JAR_FILE_NAME
e.g.
java -jar MyApp.jar

Create an executable JAR file

In order to create an executable JAR, one of the classes that we include in our JAR must be a main class.
Create a text file called MANIFEST.MF using any text editor and copy following content in it.
?
1
2
Manifest-Version: 1.0
Main-Class: MyMainClass
Where MyMainClass is the name of the class that contents main method. Also note that you have to specify fully qualified class name here.
Use following command to create an executable JAR file.
?
1
jar cvfm MyApp.jar MANIFEST.MF FILE_NAMES_OR_DIRECTORY_NAME

JAR file using Eclipse IDE

Creating JAR file using Eclipse IDE is pretty much easy. Follow the simple steps.
Right click on your project, which you want to create a JAR file of. And select Export from the context menu.

Select JAR file from Java folder and click Next.

Provide the Destination path and click on Finish to create the JAR.

Make Exe in java

http://www.excelsior-usa.com/articles/java-to-exe.html


"How do I make an .EXE file from my Java application?", "Need help converting jar to exe", "Is it possible to create a Windows executable using Java?" --- these and similar questions are among the most popular topics on Java developer forums. Should you start such a topic today, you are likely to encounter the following three types of replies:
  • "You cannot"
  • "You should not, because that would kill the very purpose of Java"
  • "You can do that with third party software X and Y"
The truth is that there exist two completely different approaches to the creation of native executables from Java applications, addressing different sets of problems. Moreover, under certain conditions some of those problems may be solved without making an EXE. So the most correct way to reply to such a post would be a request for more information, namely what is the goal of conversion to EXE. And the most frequent answer would be

Simplify Java Application Deployment

Java compiles to platform-independent bytecode (.class files), which is not directly supported by PC hardware. So a Java program needs a Java Runtime Environment (JRE) to run, which would either interpret the bytecode instructions or compile them to native code on the fly. This in turn means that the author of that program has to ensure somehow that the proper version of the JRE is installed on an end user system.
In a general case you may not expect that your end users will know what a JRE is, how to check its version, and how to download and install it. This is especially true for consumer applications, such as games or multimedia. And those who already have a JRE installed may not like the idea about installing a different version, because it may break their existing Java applications and favorite applets.
Then, even if you can make sure the right version of the JRE is properly installed on enduser systems, which is quite possible in a classroom or enterprise environment, the command line required to launch your Java application can be quite long:
    java -Xmx200m -cp whatever.jar -Dsome.property MyApp
Yes, you may put that line into a batch file and call it runme.bat, but it looks so much easier to give your program to a friend, teacher or colleague as a single file that can be run by a double-click. Or, even better, enable it to be installed and uninstalled in a native manner without affecting other applications.
So it comes as no surprise that the primary motivation for seeking a way to convert a Java application into an EXE file is to make its deployment and use simpler and safer for an average user, that is, a Windows user. What surprises newbie Java developers is that the JDK does not offer such functionality. Before J2SE 1.4, all you could make with JDK tools were

Executable Jars

Pros
No need to use any third-party tools
Single distribution for all Java-enabled platforms
Cons
Application will not start on systems that do not have a JRE (properly) installed
Application will not work if it uses APIs absent in the default JRE
Need to teach users that .JAR files are clickable
Resources
The Java Archive (JAR) File Format
Tools
One-JAR
Autojar
Fat Jar
Java Launcher
You can make your Java application runnable via a double-click by packaging it into a so called executable jar. You do that by specifying the main class of your application, any extra jar files it may require and so on in the jar's manifest file
    Main-Class: MyAppMain
    Class-Path: mylib.jar
Then you use the jar utility from the Java SDK to package your classes and resource files, specifying the m option and the name of your manifest file:
    jar cvfm MyApp.jar MyApp.mf *.class *.gif
This will result in the creation of MyApp.jar. Now, if you type
    java -jar MyApp.jar
the Java launcher will read the manifest from MyApp.jar and invoke the main method from the class MyAppMain. Moreover, if you double-click that jar file on a system that has JRE installed, the java launcher will be invoked automatically.
Note: As of J2SE 5.0, jar files are associated with the javaw launcher on Windows, which does not open a console on startup. If your application needs a console, write a batch file which would start it using the java launcher.
If your application consists of more than one jar file, there is an open source tool called One-JAR that claims to correctly repackage multiple jars into one.
The major problem with executable jars is compatibility. The default JRE may be of an older version than is required by your application or may not have the necessary Java Optional Packages (previously known as Standard Extensions) installed. For instance, if your app uses the java.nio package introduced in Java 2 version 1.4, it will not work on JRE 1.3.x. Similarly, if it uses JavaMail 1.3, and the default JRE has JavaMail 1.2 or JavaMail is not present at all, the double-clicked jar will not run.
Fortunately, Sun has created a Java application deployment technology that eliminates this compatibility problem and adds some nice features. It is part of the Java 2 platform since version 1.4 and is called

Java Web Start

Pros
Available for all major desktop platforms
Single distribution for all JWS-enabled platforms
Code-signing and sandboxing
Versioning and incremental updates
Automatic installation of JREs and optional packages
Use of third-party tools is optional
Cons
Internet connectivity required if JWS, JRE, and/or an Optional Package is not present on the system
Support for jnlp MIME type required on both Web server and browser
Limited desktop integration capabilities
Resources
JWS Technology Home
Deploying Software with JNLP and Java™ Web Start
Java Web Start
(Roedy Green's Java Glossary)
Lopica - All Things Web Start
Tools
Xito Application Manager
Automatic JNLP Generator DeployDirector
Java Web Start (JWS) and the underlying Java Network Launch Protocol (JNLP) enable Java application delivery from a standard Web server. The end user initiates application installation by clicking on an URL. If the Java Web Start engine is not present on the system, the user is prompted to download and install it. Once Java Web Start is in place, clicking on the same URL will initiate the application download and installation procedures. It may involve download and installation of the required version of the JRE and Optional Packages. Upon their successful completion, the application is launched. The application will be cached on the user's system so next time the user clicks on the same URL, the JWS engine will launch the local copy of the application from the cache, if it detects that the computer is offline or the application was not updated on the Web site.
Another important feature of JWS is its ability to run your application in a sandbox - a restricted container based on Java security architecture. But, unlike an applet, your application can gain access to local system resources like the filesystem, printer and system clipboard using the JNLP API even if it comes from an untrusted environment, after prompting the user for confirmation.
Java Web Start is available for Windows, Linux, and Solaris, and is part of MacOS X since v10.1. There are also third-party implementations of the JNLP protocol, some of them also include tools that assist you in the creation and maintenance of JNLP packages.
That was the bright side. Now, what is not so good about JNLP? First off, for seamless operation both the browser and the Web server that hosts the JNLP-enabled application must support application/x-java-jnlp-file MIME type. Some hosting providers do not support it. Moreover, versioning and incremental updates require additional support from the Web server, which has to be implemented using servlets, cgi-bin scripts, etc.
On the client side, a major browser would be configured to recognize the above MIME type during installation of the JWS engine, but users of less popular browsers, such as Opera, may have to do that manually.
JNLP-enabling an application may involve minor changes in its code and (re)packaging it into a set of jar files.
Before J2SE 5.0, JWS had very little to offer in terms of desktop integration - all it could do was create a desktop icon and/or a Start Menu entry for the application. On Windows, the application will not show up in Add/Remove Programs, so end users would have to run the Java Web Start application manager in order to remove your application.
Finally, JWS user interface needs much polishing. As of J2SE 5.0, users still complain about ugly windows with incomprehensible messages.
To sum it up, JWS can be a viable option in a controlled environment, such as corporate intranet, but it is not ready for the consumer market, where you may be better off using

Custom Java Launchers And Wrappers

Pros
JRE version check
JRE download or bundling
Unique process name and icon
No end-user training
Cons
Platform specific
Desktop integration capabilities absent or very limited
Resources
JNI 6.0 Specification, FAQ, & Downloads
Java Native Interface: Programmer's Guide and Specification (book, HTML, and PDF)
Tools
Commercial:
Free:
JSmooth
Launch4j
jstart32
exeJ
Java Launcher
Janel
jstart
Roxes Ant Tasks Orangevolt
Marner Java Launcher
When a Java program is invoked using one of the methods discussed above (batch file, executable jar, or Java Web Start/JNLP), the operating system runs a Java launcher from the JRE. The Windows version of the JRE has separate launchers for command-line and GUI apps, called java.exe and javaw.exe respectively.
As a result, all running Java applications have the same Taskbar/Alt-Tab icons and appear in the Windows Task Manager as either java.exe or javaw.exe. If you have two or more Java apps running, you have no means to distinguish between multiple instances of the standard Java launcher in the Task Manager.
In fact, those launchers are just small native programs that load the Java Virtual Machine from a DLL/shared library and then feed your program to that JVM using the Invocation API. That API is part of the Java Native Interface (JNI), so it is standardized, and it is also very simple. This makes it relatively easy to write your own launcher with a unique name and icon. What it has to do is find a suitable JRE on the end user's system (unless you bundle the JRE with your application), load and initialize the JVM, and run your application on it.
If you do not have the right tools, skills, or time to develop a custom launcher for your Java application, there are quite a few third-party Java launcher generators listed in the Tools section of the frame. Some of them provide additional features such as instant splash screen, stdout and stderr redirection, and so on, the most notable being wrapping.
A Java wrapper is essentially a custom Java launcher that is also a self-extracting archive containing all the application's classes, jars and auxiliary files. The wrapper unpacks those files on startup and removes on termination. This way, your application is distributed as a single executable.
A wrapper normally looks up the JRE upon startup. If the JRE is not present or its version does not match the application's compatibility requirements, some wrappers may install the JRE (if you have included it when wrapping your application) and/or download and install the required version of the JRE.
The most sophisticated wrappers may also setup file associations and create shortcuts on first run. But if you need something more complex, such as support for automatic updates or uniform cross-platform deployment, have a look at

Java-Aware Setup Authoring Tools

Pros
Complete desktop integration
Can be platform-specific or cross-platform
Localization support
Flexibility
Cons
Requires third-party tools which may be too pricey and/or complex
Resources
AppDeploy.com
Tools
Commercial:
Free:
IzPack
jelude (NSIS script)
If all you need is install a private copy of the JRE alongside your application and create shortcuts that run your application on that JRE, you may use any setup generator. However, using a Java-aware tool may give you the following benefits:
  • Install-time JRE detection and download
  • Generation of native launchers
  • User-editable JVM parameter files
  • Redirection of stderr and stdout for saving logs and exception stack traces.
  • Registration of Java applications as Windows services and Unix daemons
This category is the most diversified in terms of tool pricing and functionality. The differences are explained below by example.
Windows-centric tools, such as Advanced Installer for Java enable you to build MSI (Windows Installer) packages.
Multi-platform tools can generate native installers for multiple platforms - Windows, Linux, Mac OS X, as well as RPMs and tarballs. install4j is one such tool.
There exist also Java-based setup authoring tools enabling you to create cross-platform installations, Those installations are essentially executable jars with platform-specific logic selected at run time. InstallAnywhere is perhaps the most well known tool of this type, but if its pricing is beyond your budget, consider the open source IzPack.
Finally, there is One Tool to Rule Them All - InstallShield, which can create both Windows desktop (MSI) and cross-platform installations, plus server and mobile ones, for any type of application and for a multitude of platforms. And yes, it does support JRE lookup and bundling, native launchers, and so on.
For straightforward installations, however, InstallShield is an overkill. Also note that InstallAnywhere and InstallShield are aimed at the enterprise developer and are priced accordingly.
All the above solutions do not change the fundamental principle mentioned in the first section of this article. Whether you make an executable jar or create a sophisticated installer, your Java program is still deployed as platform-independent bytecode. In the early days of Java, the only way to execute a Java program on a common PC hardware was to interpret that bytecode. Today, any decent J2SE implementation contains a Just-In-Time (JIT) compiler that compiles frequently executed methods to native code. So it sounds quite natural to take one step further and compile the entire application down to native code before it is deployed. Such tools exist and they are called

Retrying Operations in Java

There are many cases in which you may wish to retry an operation a certain number of times. Examples are database failures, network communication failures or file IO problems.
Approach 1
This is the traditional approach and involves a counter and a loop.
final int numberOfRetries = 5 ;
final long timeToWait = 1000 ;
 
for (int i=0; i<numberOfRetries; i++) {
 //perform the operation
 try {
  Naming.lookup("rmi://localhost:2106/MyApp");
  break;
 }
 catch (Exception e) {
  logger.error("Retrying...",e);
  try {
   Thread.sleep(timeToWait);
  }
  catch (InterruptedException i) {
  }
 }
}
Approach 2
In this approach, we hide the retry counter in a separate class called RetryStrategy and call it like this:
public class RetryStrategy
{
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;
 
 private int numberOfRetries; //total number of tries
 private int numberOfTriesLeft; //number left
 private long timeToWait; //wait interval
 
 public RetryStrategy()
 {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME);
 }
 
 public RetryStrategy(int numberOfRetries, long timeToWait)
 {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
 }
 
 /**
  * @return true if there are tries left
  */
 public boolean shouldRetry()
 {
  return numberOfTriesLeft > 0;
 }
 
 /**
  * This method should be called if a try fails.
  *
  * @throws RetryException if there are no more tries left
  */
 public void errorOccured() throws RetryException
 {
  numberOfTriesLeft --;
  if (!shouldRetry())
  {
   throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + getTimeToWait() +
     "ms interval");
  }
  waitUntilNextTry();
 }
 
 /**
  * @return time period between retries
  */
 public long getTimeToWait()
 {
  return timeToWait ;
 }
 
 /**
  * Sleeps for the duration of the defined interval
  */
 private void waitUntilNextTry()
 {
  try
  {
   Thread.sleep(getTimeToWait());
  }
  catch (InterruptedException ignored) {}
 }
 
 public static void main(String[] args) {
  RetryStrategy retry = new RetryStrategy();
  while (retry.shouldRetry()) {
   try {
    Naming.lookup("rmi://localhost:2106/MyApp");
    break;
   }
   catch (Exception e) {
    try {
     retry.errorOccured();
    }
    catch (RetryException e1) {
     e.printStackTrace();
    }
   }
  }
 }
}
Approach 3
Approach 2, although cleaner, hasn't really reduced the number of lines of code we have to write. In the next approach, we hide the retry loop and all logic in a separate class called RetriableTask. We make the operation that we are going to retry Callable and wrap it in a RetriableTask which then handles all the retrying for us, behind-the-scenes:
public class RetriableTask<T> implements Callable<T> {
 
 private Callable<T> task;
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;
 
 private int numberOfRetries; // total number of tries
 private int numberOfTriesLeft; // number left
 private long timeToWait; // wait interval
 
 public RetriableTask(Callable<T> task) {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME, task);
 }
 
 public RetriableTask(int numberOfRetries, long timeToWait,
                      Callable<T> task) {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
  this.task = task;
 }
 
 public T call() throws Exception {
  while (true) {
   try {
    return task.call();
   }
   catch (InterruptedException e) {
    throw e;
   }
   catch (CancellationException e) {
    throw e;
   }
   catch (Exception e) {
    numberOfTriesLeft--;
    if (numberOfTriesLeft == 0) {
     throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + timeToWait +
     "ms interval", e);
    }
    Thread.sleep(timeToWait);
   }
  }
 }
 
 public static void main(String[] args) {
  Callable<Remote> task = new Callable<Remote>() {
   public Remote call() throws Exception {
    String url="rmi://localhost:2106/MyApp";
    return (Remote) Naming.lookup(url);
   }
  };
 
  RetriableTask<Remote> r = new RetriableTask<Remote>(task);
  try {
   r.call();
  }
  catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Wednesday, July 4, 2012

PHP - Log error

In PHP language checking the logs and checking error is sometimes became difficult.
PHP is offer inbuild solution to log all errors to a log fiie.
First I will tell about creating the normal error log file.
Open your pho.ini file and modify the following line.
error_log = /var/log/php-error.log
Make sure display_errors set to Off (no errors to end users)
display_errors = Off
This is normal way to check the php error log.
But if you want to check where is script is dying or you want to debug.
Then use trigger_error() function. Personaly I love to use this function for logging the php errors.
Using this function you can specify the custom error messages as per your script requirement.
<?php
$test = ture;
if ($test == true) {
trigger_error("A custom error has been triggered");
}
?>
When you run this file and check the php error log file or you can check httpd/apache error log file.
you will got following error message.
Notice: A custom error has been triggered
in C:\webfolder\test.php on line 5