Wednesday, 13 March 2013

unsupported version 0x1. If possible, set the switch to use one of the versions [3]

This error is thrown by ryu-manager when your controller application is using current OpenFlow specification version, but the bridge doesn't. To demonstrate this, let assume you're using mininet switch on current version of Open vSwitch. You then assume this should be enough to assign flow targeted for current OpenFlow versions, but to your surprise Ryu complains.

The solution to this is pretty simple:
While mininet is still running open a new terminal and type:
ovs-vsctl show
This should show result synonymous to that shown below;
root@sdn-0l:~# ovs-vsctl show
e7fd4eea-afe3-4f9f-977c-86330374e7a5
    Bridge "s1"
        Controller "ptcp:6634"
        Controller "tcp:10.100.1.61:6633"
            is_connected: true
        fail_mode: secure
        Port "s1-eth1"
            Interface "s1-eth1"
        Port "s1"
            Interface "s1"
                type: internal
        Port "s1-eth2"
            Interface "s1-eth2"
As you can see the bridge value is "s1" in my case. Now run below to instruct the bridge to support current version protocols.
ovs-vsctl set bridge s1 protocols=OpenFlow10,OpenFlow12,OpenFlow13

Friday, 18 May 2012

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function

So who is the culprit?! I tell you who it is, you are getting below exception;
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'chmod':
The specified procedure could not be found.

 at com.sun.jna.Function.<init>(Function.java:129)
 at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:250)
 at com.sun.jna.Library$Handler.invoke(Library.java:191)
 at $Proxy0.chmod(Unknown Source)

because the native function mentioned in your exception is not found in your native library, Or your native functions are not exposed outside the premiss of your library.

To inspect your native library, for example if you have done something similar to previous post, for windows enviroment I recommed downloading Dependency Walker or .*nix users using gdb core to inspect the output library.

If you cannot see the mentioned function, chances are you compiled your native library as shown in previous post or as shown below;
gcc -o native.dll native.c
Solution
Use the -shared flag to resolve this. Now compile your library like this;
gcc -shared -mno-cygwin -Wall -o native.dll native.c
remove -mno-cygwin -Wall if you are not using cygwin on windows. Now go grab a cuppa coffee and see your natives in action. And oh, don't forget to move the library to your classpath.

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library

Again let me dive straight in to catch this culprit. So! how did it happen? You have a method call which uses or wants to use JNA to perform some native system calls. You then fired your call only to be greeted with:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'c': 
The specified module could not be found.

 at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:145)
 at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:188)
 at com.sun.jna.Library$Handler.<init>(Library.java:123)
 at com.sun.jna.Native.loadLibrary(Native.java:255)
 at com.sun.jna.Native.loadLibrary(Native.java:241)
WTH is this you asked yourself?! well I have to be honest, this is just the beginning. Let me demostrate this with a simple JNA call to illustrate where this exception came from. Let us assume below is your native functions you want to invoke. Again I will make an assumption that, your native code was compiled on windows enviroment using perhaps Cygwin gcc command.
//File Name: native.c

#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>

#ifdef _WIN32
#   include <io.h>

typedef signed int md_t;

int fchmod(const char * path, md_t mode)
{
 return (_chmod(path, (mode==777 ? _S_IWRITE : _S_IREAD )));
}

#else
int fchmod(const char * path, md_t mode)
{
 return(chmod(path, mode));
}

#endif
int main(int argv, char ** argvs)
{
  return 0;
}
Here again let us assume this is your Java application from which you want to call the native functions:
import com.sun.jna.Library;
import com.sun.jna.Native;

public class demoJNA
{
  public interface Natives extends Library
  {
    public int fchmod(String path, int mode);
  }

  public static void main(String[] args)
  {
    Natives posix = (Natives) Native.loadLibrary("c", Natives.class);
    posix.fchmod("c:\\somefile.txt", 777);
  }
}
Out of patience you compiled your java application, executed it and hence the exception. Ok stop here! lets revisit your application, first notice the call;
Native.loadLibrary("c", Natives.class); 
is "c" the library output name given when you compiled your native code? Let say I compile the native code above like this;
gcc -o native.dll native.c
the call then should look like this;
Natives posix = (Natives) Native.loadLibrary("native", Natives.class);
One more thing, Is the ouput library file located at your classpath? if not then please do move it there, because it from there JNA will be looking when the call Native.loadLibrary is fired.

Monday, 14 May 2012

Controlling method recursion to avoid StackOverflowError - Java RMI call as Example

There are times that you want the flexibility of your method to be able to recurse itself when an exception occurs to re-attempt without recursing too deeply. This could possibly be a call to remote Socket or RMI which has been restarted, and therefore the stub or the connector object instance needs re-allocating or other. I have opted to use an RMI call as an example due to reasons which will be clear pretty shortly. Say you are allocating and using RMI connection stub via singleton instance as shown bellow;
public class Foo
{
 private RemoteStub stub;
 public RemoteStub getRemoteConnection()
 {
  if(stub==null)
  {
    try
    {
     this.stub= ((RemoteStub) Naming.lookup(...));
    }
    catch (Exception e)
    {
      e.printStackTrace(System.out);
    }
  }
  return stub;
 }
}
Chances are when the remote server instance is restarted, your stub object will not re-allocate itself to hold the new instance. And hence an attempt to make remote calls will yeild the exception below;
java.rmi.ConnectException: Connection refused to host: 192.168.0.1; nested exception is: 
    java.net.ConnectException: Connection timed out: connect
A quick and easy way to fix this issue is to have your connection stub builder method ignore null check or simply no singleton instance for your remote calls, which means every remote call will have the connection stub re-allocated and returned. As said, this is quick and easy, but doesn't come cheap neither. And so, this is the reason why I have decided to use this example as an insight into controlling method recursion, to make it pretty easy to follow through.

An alternative and yet effective approach is to extend your connection stub builder method to re-allocate on demand. This way when above exception occurs you can recurse your method to re-attempt once and ignore. The assumption here is that if you do re-attempt and fails again, there is a high chance remote server is down or something is preventing you from connecting. Now, let us go ahead and expand on getRemoteConnection() method and introduce the techiques for re-attempting the call.
public class Foo
{
 private RemoteStub stub;
 private AtomicBoolean reconnect;
 
 public Foo()
 {
  reconnect= new AtomicBoolean(false);
 }

 public RemoteStub getRemoteConnection()
 {
  //Extended the builder to handle on demand
  if(stub==null || reconnect.get())
  {
    try
    {
     this.stub= ((RemoteStub) Naming.lookup(...));
     reconnect.set(false);
    }
    catch (Exception e)
    {
      e.printStackTrace(System.out);
    }
  }
  return stub;
 }

 protected void reconnect()
 {
  reconnect.set(true);
 }
}
As you can see above, we have expanded on the remote stub builder method to handle on demand call to re-allocate the remote stub object. This gives us the flexibility in our calling method to fire reconnect() whenever we re-attempt. One issue we have not raised so far is the fact that, there is a high chance re-attempt via recursion will fail subsequently due to assumption made above. Here we are likely to enter into deep recursion and hence StackOverflowError.
  public class FooCaller extends Foo
  {
    private static final CharSequence failedConnect = "Connection refused";
    public void callRemoteMethod()
    {
      try
      {
        int status = getRemoteConnection().doSomething();
        System.out.println("Remote call - " + (status > -1 ? "Succeeded" : "Failed"));
      }
      catch (RemoteException e)
      {
        if (e.getMessage().contains(failedConnect))
        {
         // re-attempt
         reconnect();
         callRemoteMethod();
        }
      }
    }
  }
To control this we will use a token object and a simple stack handler, which does ensure recursions are detached straight after first re-attempt call, to avoid StackOverflowError. See below for extended version of FooCaller class with method handler for issuing attempt token and generic handler method for handling re-attempt calls to avoid code verbosity.
/**
 Re-Attempt Token
*/
public class ReAttemptToken
{
  public long lastAttempted = System.currentTimeMillis();
  public String method;

  public ReAttemptToken(String method)
  {
    this.method = method;
  }
}
.. simple stack object to control the life span of ReAttemptToken held for a specific method recurse;
/**
 * Simple stack object for holding recursive method recall to avoid {@link StackOverflowError}.
 * 
 * @author Bright Dadson
 * 
 */
@SuppressWarnings("serial")
public class ReAttemptStack extends ArrayList<ReAttemptToken>
{
  /**
   * Creates an empty Stack.
   */
  public ReAttemptStack()
  {
  }

  /**
   * Pushes an item onto the top of this stack. This has exactly the same effect as: 
* *
   * add(item)
   * 
* *
* * @param item the item to be pushed onto this stack. * @return the item argument. * @see java.util.ArrayList#add */ public ReAttemptToken push(ReAttemptToken item) { add(item); return item; } /** * Tests if this stack is empty. * * @return true if and only if this stack contains no items; false otherwise. */ public boolean empty() { return size() == 0; } /** * Locate and return items in this stack. * * @param o the desired {@link ReAttemptToken}. * @return found object else null */ public synchronized ReAttemptToken locate(ReAttemptToken o) { int i = this.searchToken(o.method); return (i >= 0) ? get(i) : null; } /** * Scan this stack to search for token with method same as passed argument * * @param method - token method * @return index of the token within this stack */ public int searchToken(String method) { for (int i = 0; i < size(); i++) { if (get(i).method.equals(method)) return i; } return -1; } }
.. and finally a new extended version of FooCaller with stack control handlers;
 public class FooCaller extends Foo
 {
    private long reAttemptTTL = 3 * 1000;
    private ReAttemptStack stack;
    private static final CharSequence failedConnect = "Connection refused";

    private FooCaller()
    {
      stack = new ReAttemptStack();
    }

    /**
     * Typical remote call
     * 
     */
    public void callRemoteMethod()
    {
      try
      {
        int status = getRemoteConnection().doSomething();
        System.out.println("Remote call - " + (status > -1 ? "Succeeded" : "Failed"));
      }
      catch (RemoteException e)
      {
        if (e.getMessage().contains(failedConnect))
        {
          try
          {
            ReAttemptToken token = getReAttemptToken("callRemoteMethod");
            reAttemptRemoteCall(this.getClass().getMethod("callRemoteMethod"), new Object[] {}, token);
          }
          catch (Exception ex)
          {}
        }else e.printStackTrace();
      }
    }

    /**
     * This method issues token to calling functions. If the token is not expired and hence still exist, the method returns the same token from the
     * stack for usage.
     * 
     * @param method
     * @return
     */
    private ReAttemptToken getReAttemptToken(String method)
    {
      int tokenIndex;
      if ((tokenIndex = stack.searchToken(method)) > -1)
      {
        return stack.get(tokenIndex);
      }
      return (new ReAttemptToken(method));
    }

    /**
     * Using the method we can retry remote reconnection, obtain a fresh connection stub and re-invoke the failed method. In the aid of re-attempt
     * token passing control, we can avoid indefinite recurssion from occuring when we re-invoke. Each token is expired every 3secs to enable recall.
     * @param methodToRecurse
     * @param params
     * @param token
     */
    private void reAttemptRemoteCall(Method methodToRecurse, Object[] params, ReAttemptToken token)
    {
      try
      {
        long now = System.currentTimeMillis();
        boolean attempt = false;
        if (stack.locate(token) == null)
        {
          stack.push(token);
          attempt = true;
        }
        else if ((stack.locate(token) != null) && now > (reAttemptTTL + token.lastAttempted))
        {
          stack.remove(token);
          stack.push(getReAttemptToken(token.method));
          attempt = true;
        }
        if (attempt)
        {
          System.err.println("Re-Attempting failed remote call **");
          reconnect();
          methodToRecurse.invoke(this, params);
        }
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
    }
  }
Disclaimer
The code and technique adopted in this post has only been written to demonstrate how to control StackOverFlowError from occuring in method calls which require recursion, to re-attempt situations where an exceptions is possible to occur due to anticipated reasons. Also note that, the approach adopted here is not required for all situations.

Drop a comment if you've spotted a bug, known enhancement possible to extend the technique or any relevant comment which is helpful to other readers.

Friday, 11 May 2012

Waiting on a Thread without blocking Java Swing EDT

Event dispatching threads are used as background thread to avoid blocking queues, or simply to avoid components from freezing while performing multi-tasking. JTabbedPane is a brilliant component to demostrate typical blocking EDT issues. Assume you have JTable on two panels placed on JTabbedPane, the first panel make adaptor call to remote server to pull collection of rows to render in the table and the second does pretty much the same thing.

Without EDT, there is a great posibility that while the first panel is building its table model with data fetched from remote server, the second tab will be blocked(freeze) to prevent access. One typical solution to this culprit is to use EventQueue.invokeLater(Runnable) method. But for a long running method, this option is not viable as it is only appropriate for simple application threads that needs to update the GUI.

A more viable approach to enable you wait on a Thread while performing a long running routine is using the worker design pattern. SwingWorker enables you perform a long running task without blocking EDT. To demostrate this, let assume this business scenario, we have a system which performs several concurrent executions. We want a button ActionEvent to call a delegated shutdown method, which will await on all the threads to complete before asking the JVM to bring the system to halt.

This request can be achieved in several ways, but because we do not want our waiting thread to block Swing EDT, we will first place the delegate call to shutdown in EventQueue.invokeLater(Runnable) and then use worker pattern to handle the long waiting thread as shown below.

» Assume this is our JButton action listner event
    closeButton.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        EventQueue.invokeLater(new Runnable()
        {
          public void run()
          {
            shutDown();
          }
        });
      }
    });
» Assume this is our delegated shutdown method
 public void shutDown()
 {
    try
     {
      closeButton.setEnabled(false);//disable the button to avoid futher clicks
      ShutdownWorker task = new ShutdownWorker();
      task.execute();
    }
    catch (Exception e)
    {
      // just force it
      System.exit(0);
    }
  }
» SwingWorker handler class
  class ShutdownWorker extends SwingWorker<Void, Void>
  {
    public Void doInBackground() throws Exception
    {
       System.out.println("halting system");
       performSomeLongAwaitCall();

      return null;
    }

    public void done()
    {
      // shutdown
      System.gc();
      System.exit(0);
    }
    
    private void performSomeLongAwaitCall()
    {
      try
      {
       while(some condition is not true)
       {
         //TODO: perform the thread shutdown or 
         //await on all the threads to shutdown gracefully
         [...]
         Thread.sleep(2000);
       }
      }
      catch (InterruptedException ignore)
      {}
    }
  }
Adopting this approach for tasks that takes longer to complete is much effective for Swing UI applications. As you have seen above, we used a class which extends SwingWorker, implemented its abstract method doInBackground to handle the long awaiting call to shutting down the application to avoid blocking other events dispatched from userbility.

The approach gives the user the flexibility to perform several tasks and also add power to your application. Because this post is targeted to non-blocking Swing EDT, I will not dive more deeper into SwingWorker itself here. But surely there is more to it than just using it for controlling blocking threads. I will leave the rest to you to explore - but do hope this post has help you in some way to adapt an approach for handling Swing Event dispatching design pattern.

Disclaimer
The code above has only been written to demonstrate how to avoid waiting threads blocking Swing EDT, but not a complete working program.

Wednesday, 4 April 2012

Convert currency using Google API calculator and Java

So why do I propose this option against the numerous converter apis out there on the web? For me the answer is pretty simple, I can't think of any API out there which stands virtually at par with google on various matching grounds. Free, Robust, 247uptime for critical systems and over all easy to use. Google currency calculator like most of its apis like Dojo, Ext Core, jQuery etc. are used both by google developement team and developers all over. These apis are accessible so long as the google project is alive.

Although I will not stick my neck on it and say it is "mission-critical", which I believe it is, I can only say - if you dont trust the google conversion api on the grounds of critical usage, then you're going to find it difficult to arrive on a specific api for your currency conversion, unless you are looking to subscribe for one which the providers can stick their neck on and say it is "mission-critical". To demonstrate how easy and quick it is, I opted to use Core Java to create a simple currency converter util to interract with the api.


A request to convert say 12GBP to USD, simply translates to:
http://www.google.com/ig/calculator?h1=en&q=12gbp=?usd
With a typical standard Jason result as shown below:
{lhs: "12 British pounds",rhs: "19.0188 U.S. dollars",error: "",icc: true}

This makes it pretty straight forward, all we need now is an enumumeration class to hold all the various currency codes, and helper functions relevant for a specific convertion. Took time to compile this to support various currencies your application is possible to support.
/**Currency and code used mostly for conversion and other purposes
 * 
 * @author Bright Dadson
 *
 */
public enum Currency
{
  UAE_Dirham("AED", "UAE Dirham"),
  Afghanistan_Afghani("AFA", "Afghanistan Afghani"),
  Albanian_Lek("ALL", "Albanian Lek"),
  Neth_Antilles_Guilder("ANG", "Neth Antilles Guilder"),
  Argentine_Peso("ARS", "Argentine Peso"),
  Australian_Dollar("AUD", "Australian Dollar"),
  Aruba_Florin("AWG", "Aruba Florin"),
  Barbados_Dollar("BBD", "Barbados Dollar"),
  Bangladesh_Taka("BDT", "Bangladesh Taka"),
  Bahraini_Dinar("BHD", "Bahraini Dinar"),
  Burundi_Franc("BIF", "Burundi Franc"),
  Bermuda_Dollar("BMD", "Bermuda Dollar"),
  Brunei_Dollar("BND", "Brunei Dollar"),
  Bolivian_Boliviano("BOB", "Bolivian Boliviano"),
  Brazilian_Real("BRL", "Brazilian Real"),
  Bahamian_Dollar("BSD", "Bahamian Dollar"),
  Bhutan_Ngultrum("BTN", "Bhutan Ngultrum"),
  Botswana_Pula("BWP", "Botswana Pula"),
  Belize_Dollar("BZD", "Belize Dollar"),
  Canadian_Dollar("CAD", "Canadian Dollar"),
  Swiss_Franc("CHF", "Swiss Franc"),
  Chilean_Peso("CLP", "Chilean Peso"),
  Chinese_Yuan("CNY", "Chinese Yuan"),
  Colombian_Peso("COP", "Colombian Peso"),
  Costa_Rica_Colon("CRC", "Costa Rica Colon"),
  Cuban_Peso("CUP", "Cuban Peso"),
  Cape_Verde_Escudo("CVE", "Cape Verde Escudo"),
  Cyprus_Pound("CYP", "Cyprus Pound"),
  Czech_Koruna("CZK", "Czech Koruna"),
  Dijibouti_Franc("DJF", "Dijibouti Franc"),
  Danish_Krone("DKK", "Danish Krone"),
  Dominican_Peso("DOP", "Dominican Peso"),
  Algerian_Dinar("DZD", "Algerian Dinar"),
  Estonian_Kroon("EEK", "Estonian Kroon"),
  Egyptian_Pound("EGP", "Egyptian Pound"),
  Ethiopian_Birr("ETB", "Ethiopian Birr"),
  Euro("EUR", "Euro"),
  Falkland_Islands_Pound("FKP", "Falkland Islands Pound"),
  British_Pound("GBP", "British Pound"),
  Ghanian_Cedi("GHC", "Ghanian Cedi"),
  Gibraltar_Pound("GIP", "Gibraltar Pound"),
  Gambian_Dalasi("GMD", "Gambian Dalasi"),
  Guinea_Franc("GNF", "Guinea Franc"),
  Guatemala_Quetzal("GTQ", "Guatemala Quetzal"),
  Guyana_Dollar("GYD", "Guyana Dollar"),
  Hong_Kong_Dollar("HKD", "Hong Kong Dollar"),
  Honduras_Lempira("HNL", "Honduras Lempira"),
  Croatian_Kuna("HRK", "Croatian Kuna"),
  Haiti_Gourde("HTG", "Haiti Gourde"),
  Hungarian_Forint("HUF", "Hungarian Forint"),
  Indonesian_Rupiah("IDR", "Indonesian Rupiah"),
  Israeli_Shekel("ILS", "Israeli Shekel"),
  Indian_Rupee("INR", "Indian Rupee"),
  Iraqi_Dinar("IQD", "Iraqi Dinar"),
  Iceland_Krona("ISK", "Iceland Krona"),
  Jamaican_Dollar("JMD", "Jamaican Dollar"),
  Jordanian_Dinar("JOD", "Jordanian Dinar"),
  Japanese_Yen("JPY", "Japanese Yen"),
  Kenyan_Shilling("KES", "Kenyan Shilling"),
  Cambodia_Riel("KHR", "Cambodia Riel"),
  Comoros_Franc("KMF", "Comoros Franc"),
  North_Korean_Won("KPW", "North Korean Won"),
  Korean_Won("KRW", "Korean Won"),
  Kuwaiti_Dinar("KWD", "Kuwaiti Dinar"),
  Cayman_Islands_Dollar("KYD", "Cayman Islands Dollar"),
  Kazakhstan_Tenge("KZT", "Kazakhstan Tenge"),
  Lao_Kip("LAK", "Lao Kip"),
  Lebanese_Pound("LBP", "Lebanese Pound"),
  Sri_Lanka_Rupee("LKR", "Sri Lanka Rupee"),
  Liberian_Dollar("LRD", "Liberian Dollar"),
  Lesotho_Loti("LSL", "Lesotho Loti"),
  Lithuanian_Lita("LTL", "Lithuanian Lita"),
  Latvian_Lat("LVL", "Latvian Lat"),
  Libyan_Dinar("LYD", "Libyan Dinar"),
  Moroccan_Dirham("MAD", "Moroccan Dirham"),
  Moldovan_Leu("MDL", "Moldovan Leu"),
  Malagasy_Franc("MGF", "Malagasy Franc"),
  Macedonian_Denar("MKD", "Macedonian Denar"),
  Myanmar_Kyat("MMK", "Myanmar Kyat"),
  Mongolian_Tugrik("MNT", "Mongolian Tugrik"),
  Macau_Pataca("MOP", "Macau Pataca"),
  Mauritania_Ougulya("MRO", "Mauritania Ougulya"),
  Maltese_Lira("MTL", "Maltese Lira"),
  Mauritius_Rupee("MUR", "Mauritius Rupee"),
  Maldives_Rufiyaa("MVR", "Maldives Rufiyaa"),
  Malawi_Kwacha("MWK", "Malawi Kwacha"),
  Mexican_Peso("MXN", "Mexican Peso"),
  Malaysian_Ringgit("MYR", "Malaysian Ringgit"),
  Mozambique_Metical("MZM", "Mozambique Metical"),
  Namibian_Dollar("NAD", "Namibian Dollar"),
  Nigerian_Naira("NGN", "Nigerian Naira"),
  Nicaragua_Cordoba("NIO", "Nicaragua Cordoba"),
  Norwegian_Krone("NOK", "Norwegian Krone"),
  Nepalese_Rupee("NPR", "Nepalese Rupee"),
  New_Zealand_Dollar("NZD", "New Zealand Dollar"),
  Omani_Rial("OMR", "Omani Rial"),
  Panama_Balboa("PAB", "Panama Balboa"),
  Peruvian_Nuevo_Sol("PEN", "Peruvian Nuevo Sol"),
  Papua_New_Guinea_Kina("PGK", "Papua New Guinea Kina"),
  Philippine_Peso("PHP", "Philippine Peso"),
  Pakistani_Rupee("PKR", "Pakistani Rupee"),
  Polish_Zloty("PLN", "Polish Zloty"),
  Paraguayan_Guarani("PYG", "Paraguayan Guarani"),
  Qatar_Rial("QAR", "Qatar Rial"),
  Romanian_Leu("ROL", "Romanian Leu"),
  Russian_Rouble("RUB", "Russian Rouble"),
  Saudi_Arabian_Riyal("SAR", "Saudi Arabian Riyal"),
  Solomon_Islands_Dollar("SBD", "Solomon Islands Dollar"),
  Seychelles_Rupee("SCR", "Seychelles Rupee"),
  Sudanese_Dinar("SDD", "Sudanese Dinar"),
  Swedish_Krona("SEK", "Swedish Krona"),
  Singapore_Dollar("SGD", "Singapore Dollar"),
  St_Helena_Pound("SHP", "St Helena Pound"),
  Slovenian_Tolar("SIT", "Slovenian Tolar"),
  Slovak_Koruna("SKK", "Slovak Koruna"),
  Sierra_Leone_Leone("SLL", "Sierra Leone Leone"),
  Somali_Shilling("SOS", "Somali Shilling"),
  Surinam_Guilder("SRG", "Surinam Guilder"),
  Sao_Tome_Dobra("STD", "Sao Tome Dobra"),
  El_Salvador_Colon("SVC", "El Salvador Colon"),
  Syrian_Pound("SYP", "Syrian Pound"),
  Swaziland_Lilageni("SZL", "Swaziland Lilageni"),
  Thai_Baht("THB", "Thai Baht"),
  Tunisian_Dinar("TND", "Tunisian Dinar"),
  Tonga_Pa_anga("TOP", "Tonga Pa'anga"),
  Turkish_Lira("TRL", "Turkish Lira"),
  Turkey_Lira("TRY", "Turkey Lira"),
  Trinidad_And_Tobago_Dollar("TTD", "Trinidad And Tobago Dollar"),
  Taiwan_Dollar("TWD", "Taiwan Dollar"),
  Tanzanian_Shilling("TZS", "Tanzanian Shilling"),
  Ukraine_Hryvnia("UAH", "Ukraine Hryvnia"),
  Ugandan_Shilling("UGX", "Ugandan Shilling"),
  US_Dollar("USD", "US Dollar"),
  Uruguayan_New_Peso("UYU", "Uruguayan New Peso"),
  Venezuelan_Bolivar("VEB", "Venezuelan Bolivar"),
  Vietnam_Dong("VND", "Vietnam Dong"),
  Vanuatu_Vatu("VUV", "Vanuatu Vatu"),
  Samoa_Tala("WST", "Samoa Tala"),
  CFA_Franc_BEAC("XAF", "CFA Franc (BEAC)"),
  Silver_Ounces("XAG", "Silver Ounces"),
  Gold_Ounces("XAU", "Gold Ounces"),
  East_Caribbean_Dollar("XCD", "East Caribbean Dollar"),
  CFA_Franc_BCEAO("XOF", "CFA Franc (BCEAO)"),
  Palladium_Ounces("XPD", "Palladium Ounces"),
  Pacific_Franc("XPF", "Pacific Franc"),
  Platinum_Ounces("XPT", "Platinum Ounces"),
  Yemen_Riyal("YER", "Yemen Riyal"),
  Yugoslav_Dinar("YUM", "Yugoslav Dinar"),
  South_African_Rand("ZAR", "South African Rand"),
  Zambian_Kwacha("ZMK", "Zambian Kwacha"),
  Zimbabwe_Dollar("ZWD", "Zimbabwe Dollar");

  private final String currencyCode;
  private final String currencyFullName;
  private static final Mapa<String, String> currencyLookup = new HashMap<String, String>();

  static
  {
    for (Currency currencyEnum : EnumSet.allOf(Currency.class))
    {
      currencyLookup.put(currencyEnum.getCurrencyCode(), currencyEnum.getCurrencyCodeFullName());
    }
  }
  
  private Currency(String currencyCode, String currencyFullName)
  {
    this.currencyCode = currencyCode;
    this.currencyFullName = currencyFullName;
  }

  public String getCurrencyCode()
  {
    return this.currencyCode;
  }

  public String getCurrencyCodeFullName()
  {
    return currencyFullName;
  }
  
  /**Using the currency code as an argument, fetch and return associated full name
   * 
   * @param currencyCode - The Currency Code of which you want to retrieve its full reference name.
   */
  public static String getCurrencyCodeFullName(String currencyCode)
  {
    if(currencyLookup.containsKey(currencyCode))
    {
      return currencyLookup.get(currencyCode);
    }
    return null;
  }

  /***Checks and return currency code*/
  public static String getCurrency(String currencyCode)
  {
    if(currencyLookup.containsKey(currencyCode))
    {
      return currencyCode;
    }
    return null;
  }

}
We have all the required currency codes available, what we now need is the converter handler which will accept currency code for both the currency to convert from and the final currency to convert to.

Calling getConvertedValue(..) passing in the amount, currency code to convert to and from, will build and submit a query against google api, retrieve the result and extract the converted value.

We could have happily done this with Jason dependency to our project to perform the extraction. Yet if you're like me who prefer to keep things lightweight and free from overlayered dependencies, then core classic java URL and string manipulations will surely do the simple tasks.
/**
 * Using this class, we convert currencies to its foreign exchange. This class uses google calculator to perform the conversion process
 * @author Bright Dadson
 */
public final class Converter
{
  private static final String error = "error:";
  private static final String noErrorFound = "\"\"";
  private static final String regExp = "-?\\d+(.\\d+)?";

  private int valueToConvert;
  private String convertFrom, convertTo;

  public Converter()
  {}

  /**
   * Convert submitted value from and to the submitted conversion codes.
   * 
   * @param valueToConvert - Amount to convert
   * @param convertFrom - Currency code to convert from
   * @param convertTo - Currency code to convert to
   * @return
   */
  public double getConvertedValue(int valueToConvert, String convertFrom, String convertTo)
  {
    try
    {
      this.valueToConvert = valueToConvert;
      this.convertFrom = convertFrom;
      this.convertTo = convertTo;
      String convertedValue = extractConvertedValue(convert());
      if (convertedValue != null && isNumeric(convertedValue))
      {
        BigDecimal roundVal = new BigDecimal(convertedValue);
        roundVal.round(new MathContext(2, RoundingMode.HALF_UP));
        return roundVal.doubleValue();
      }
    }
    catch (Exception ex)
    {
      ex.printStackTrace(System.out);
    }
    return 0d;
  }

  /**Connect to Google api using http GET request to perform the currency conversion**/
  private String convert()
  {
    try
    {
      String code = String.valueOf("/ig/calculator?h1=en&q=" + valueToConvert + "" + convertFrom + "=?" + convertTo);
      URL converterUrl = new URL("http://www.google.com" + code);
      URLConnection urlConnection = converterUrl.openConnection();

      InputStream inputStream = urlConnection.getInputStream();
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

      String conversionResult = bufferedReader.readLine();
      bufferedReader.close();
      inputStream.close();
      urlConnection = null;

      return conversionResult;
    }
    catch (Exception e)
    {
      e.printStackTrace(System.out);
    }
    return null;
  }

  /**If error is found within the response string, throw runtime exception to report, else parse the result for extraction**/
  private String extractConvertedValue(String convertedResult) throws Exception
  {
    String[] convertedResStrings = convertedResult.split(",");
    for (int i = 0; i < convertedResStrings.length; i++)
    {
      if ((convertedResStrings[i].contains(error)) && convertedResStrings[i].split(" ")[1].equals(noErrorFound))
      {
        String convertedValue = extract(convertedResStrings[i - 1]);
        if (!(convertedValue.isEmpty()))
        {
          return convertedValue;
        }
      }
      else if ((convertedResStrings[i].contains(error)) && !convertedResStrings[i].split(" ")[1].equals(noErrorFound))
      {
        throw new RuntimeException("Error occured while converting amount: "+convertedResStrings[i].split(" ")[1]);
      }
    }
    return null;
  }

  private String extract(String str)
  {
    StringBuffer sBuffer = new StringBuffer();
    Pattern p = Pattern.compile(regExp);
    Matcher m = p.matcher(str);
    if (m.find())
    {
      sBuffer.append(m.group());
    }
    return sBuffer.toString();
  }

  private boolean isNumeric(String str)
  {
    return str.matches(regExp);
  }

}


Example usage
  public static void main(String[] args)
  {
   Converter converter = new Converter();
   //Convert 12GBP to USD and print the result to console
   System.out.println(converter.getConvertedValue(12, Currency.British_Pound.getCurrencyCode(),
                       Currency.US_Dollar.getCurrencyCode()));
  }
As you can see, it is pretty straight forward and free from injected dependencies. If you have read from the top to the bottom of this post - chances are you have already fired your IDE and started playing with this. Do let me know of any enchancement, suggestions or if this directed you on the right selective path.

Friday, 2 March 2012

soapUI request exception - An error was discovered processing the <wsse:Security> header

You've created a soapUI project which connects and fire request to Spring based CXF web service endpoint. Let me make it clear at this stage that, you will have to have access to the endpoint source and Spring context beans to be able to resolve this issue. In your Spring context bean, you have defined WSS4JInInterceptor security interceptor to your endpoint, which requires that, all SOAP requests hold a header with security credentials accepted for access grant. Below shows a typical security interceptor defintion for CXF endpoint:

  
    
      
        
          
            
            
            
              
            
          
        
      
    
  
You decided to test your endpoint calls with soapUI, and so you fired a typical call like:

   
   
   
      
         echo hello world
      
   

..then to your surprise the response message:

   
      
         ns1:InvalidSecurity
         An error was discovered processing the <wsse:Security> header
      
   

And so you became curious, started digging for clues, tailed your server logs. And there it was:
org.apache.cxf.phase.PhaseInterceptorChain Interceptor for {http://mypackage/}Service 
has thrown exception, unwinding noworg.apache.cxf.binding.soap.SoapFault: An error was 
discovered processing the

...

Caused by: org.apache.ws.security.WSSecurityException: 
An error was discovered processing the  header at 
org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.checkActions
(WSS4JInInterceptor.java:331) at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor
.handleMessage(WSS4JInInterceptor.java:287)
 ... 23 more
SOLUTION:
Add wsse:Security header data required by the interceptor to resolve your call. Your request should now look something like this:

   
    
      
      admin
      culprit
     
    
   

   
      
         echo hello world
      
   

Hope this helps!

Wednesday, 29 February 2012

Deploy to Tomcat instance on Eclipse - Steps for Maven enabled projects.

A while ago I was looking for an approach to enable Maven deploy Java web Applications to Tomcat server installed on my eclipse IDE. Did some googling around and did not find anything relevant to my search, and so came up with this approach.
  1. Expand Servers directory as shown in your projects package view
  2. Create a new dir = instances
  3. Open Server view from -> Window -> Show Percpective -> Servers
  4. Double click on the server instance to view its config overview.
  5. On Configuration path: point it to "Servers/tc-6.0.32-config"

  6. From "Server Locations" select the radio button, select "Use custom location"
  7. Server path: point it to "Servers\tc-6.0.32-config\instances"
    Note: Your final config overview should look something like this:
























  8. Now lets save it and ask Maven to generate the target output to our instances directory created above.
  9. Ctrl + S to save the changes.
  10. In your POM file add this line:
          
            org.apache.maven.plugins
            maven-war-plugin
            ${war.plugin.version}
            
              
                ../Server/ts-6.0.32/instance/webapps/name_of_project_for_easy_identification
              
           [..] 
           
          
    
  11. Right click your Maven project select Run As -> build or alternatively execute:
      clean install -X -Dmaven.test.skip.exec=true
    
  12. Select your Servers directory and refresh. Maven will push build files to both targets and your instances/webapps location described above.
  13. Finally Start your server and job done.
Hope it helps you.

Monday, 27 February 2012

/usr/bin/ld: cannot find -lltdl collect2: ld returned 1 exit status make: *** [libphp5.la] Error 1

This culprit emits error to indicates your build ./configure options require additional library file to be installed before PHP can proceed successfully with the build process. The solution described here assumes you're building the sources to install or re-installing PHP manually. Your ./configure option either looks or have options similar to the one shown below:
./configure --enable-embed --enable-maintainer-zts --disable-short-tags --enable-pcntl --with-tsrm-pthreads --with-mysqli --with-mysql --with-
pdo-mysql --with-zlib --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-bcmath --enable-calendar --enable-exif --enable-ftp --with-gd 
--enable-gd-native-ttf --enable-gd-jis-conv --with-iconv-dir --with-gettext --with-imap --with-imap-ssl --with-ldap --with-ldap-sasl --enable-
mbstring --with-mcrypt --with-mhash --enable-soap --enable-sockets --enable-wddx --with-xmlrpc --with-xsl --enable-zip --with-kerberos --with-tidy 
--with-curl --with-curlwrappers

SOLUTION.
First lets take a look at the error again.
/usr/bin/ld: cannot find -lltdl 
collect2: ld returned 1 exit status make: *** [libphp5.la] Error 1
The portion we are interested is cannot find -lltdl, this tells us the header file libltdl.so cannot be found. To resolve this:
  • Install the header file via
    apt-get install libtool
  • If you're configuring for MySQL, install libdbd-mysql
    apt-get install libdbd-mysql
  • Run
    make clean
    ./configure -- with your additonal configure options
    make
    make install
    
If you do have any other error related to your additional configure options, see here for resolutions. Good luck.

Friday, 24 February 2012

Can't locate package Exporter for @PHP::Interpreter::ISA

The last time I caught a culprit was a while ago, and so when I saw this exception, did not hessitate to post the solution right away to fill in the gap. I was performing sys_log analysis this afternoon with Perl and decided to use PHP::Interpreter module to connect to POD for data persistence. ..fired first line syntax to PHP::Interpreter:
my $php_ = PHP::Interpreter->new;
then suddenly, Gotcha! the culprit below.
Can't locate package Exporter for @PHP::Interpreter::ISA at /usr/local/lib/perl/5.10.1/PHP/Interpreter.pm line 35.
Can't locate package Exporter for @PHP::Interpreter::ISA at /usr/lib/perl/5.10/DynaLoader.pm line 193.
Although I have to be honest, it still does the interpretation, I thought! gotta shut this up before future issues. And so got my eyes peeled and poked through the Interpreter.pm module for clues.

Solution
The solution was pretty simple if not obvious at first hand. Add below line of syntax to the Interpreter.pm module.
use Exporter "import";
right after the the line of syntax
require DynaLoader;
Perl's Exporter module allows modules to "export" identifiers (i.e., variable and subroutine names) into the calling program's namespace. See Exporter for more infomation on importing modules to perl function namespace.

Wednesday, 28 September 2011

Concurrent Request chaining.

This is not going to be another definition of what multi-threading or concurrent process execution is, but to findout if you've been another culprit of concurrent request chaining. So what is Concurrent Request Chaining? a simple and perhaps most basic defintion is HTTP GET/POST. The protocol provides a mechanism to accept and process multiple requests via the same session using chaining. As you would appreciate, there are several techniques and built-in objects and types to employ in a multi-threading execution enviroment, to allow a single thread at a time into a particular section of request block thus allowing protection to example variables(make it thread safe) or data from being corrupted by simultaneous modifications from different request coming from the same session.

Although these multi-threaded objects and types provides the answer to the scenario described above, they are not the answer to all business rules. And hence do require proper usage to attain the correct locking for specific instances.

Let's take this business rule for example: A deposit function should be synchronized, if calls to the function are coming from the same account number. This rule is similar to the underlying HTTP request chain explained above.

Noticed there are several approaches to this rule, but how do you provide a robust solution to this, using the concurrent objects and types provided by your JDK? I suppose you've started to think through dozens of possible canditate solutions already. Does each approach work well for the scenario, is the approach lightweight enough?

A classic solution to this will be to join the threads, which if not done properly open doors for dreadful resource issues. Another solution to this will be to use the java.util.concurrent.locks.ReentrantLock and java.util.HashMap to hold a queue of objects to process. This approach gives you the flexibility to lock each process for a specific period before reentrant.
  private Map<Long, ReentrantLock> queue= new HashMap<Long, ReentrantLock>();
  public void AccountDeposit(Long accountNumber)
  {
    addWork(accountNumber);

    ReentrantLock lock = queue.get(accountNumber);
    try
    {
      if (lock.tryLock(1, TimeUnit.MINUTES))
      {
        // Perform Deposit Routine
      }
    }
    catch (InterruptedException e)
    {
      //do some clean up
    }
    finally
    {
      lock.unlock();
    }
  }

  private void addWork(Long accountNumber)
  {
    if (!queue.keySet().contains(accountNumber))
    {
      queue.put(accountNumber, new ReentrantLock());
    }
  }
But if you look closely, the above technique is avoiding adding same Account Number to the queue. If I were you, I will correct this so the queue can hold duplicate customer account numbers to avoid potential deposit calls from been ignored. Here again I will ask you to take very close look, is this approach robust enough? will this be able to handle various data source requests without any potential resource issues in the near future?

Another solution is to manage the pool of threads. This gives you a more flexible way of asking a thread to hold a queue of specific Account Number. Put the deposit and its member objects in a separate instance worker thread, this makes the member objects local to a specific execution unit. Let's take below worker class as an example.
public class DepositHandlerThread extends Thread
{
  public long busyStartTime;
  public static final int MAX_SIZE = 10;
  public final AtomicInteger idUnderProcess = new AtomicInteger();
  private final BlockingQueue<DepositToken> queue = new ArrayBlockingQueue<DepositToken>(MAX_SIZE);

  public static class DepositToken
  {
    private int clientId;

    public DepositToken(int clientId)
    {
      this.clientId = clientId;
    }
  }

  public DepositHandlerThread()
  {
  }

  public void run()
  {
    DepositToken token;
    try
    {
      while ((token =queue.take()) != null)
      {
        // perform the deposit routine
        idUnderProcess.set(token.clientId);
        doDeposit(token);

        if (!queue.isEmpty())
        {
          busyStartTime = 0;
        }
      }
    }
    catch (InterruptedException e)
    {}

  }

  public void doDeposit(DepositToken tokekn)
  {
    /** Some routine here to perform deposit with Token holding client id **/
  }

  public void addWork(DepositToken token)
  {
    try
    {
      busyStartTime = System.currentTimeMillis();
      queue.put(token);
    }
    catch (InterruptedException e)
    {
      throw new AssertionError(e);
    }
  }
}
It accepts and process requests as and when they arrive. Within the controller class which accepts/fetch and process the Deposit Request, you can then manage a pool of worker threads by assigning tasks to avoid same Account Number request executed by seperate threads. This ensures that, a worker currently dealing with a subjected Account Number, has the pile which does not overlaps the execution process, using thread-safe non-blocking FIFO queue. See below example:

Controller class:

  class DepositHandler extends Thread
  {
    int tc;
    private DepositHandlerThread threadPool[];

    public DepositHandler()
    {
      // start pool
      tc = 3;
      threadPool = new DepositHandlerThread[tc];
      for (int i = 0; i < tc; i++)
      {
        threadPool[i] = new DepositHandlerThread();
        threadPool[i].start();
      }
      Thread.yield();
    }

    public void run()
    {
    
    while(/**You have data available from or at some data source**/)
     {
      // I will simulate the situation with a static value
      final Long accountNumber= 123343460;
      boolean taskAssigned = false;

      // Control the pool of threads
      for (int i = 0; i < tc; i++)
      {
        // Check to make sure a live thread is currently working with
        // the ID in hand and if so add the new task to its pile.
        if ((threadPool[i].busyStartTime != 0) && (threadPool[i].isAlive()) && threadPool[i].accountNoUnderProcess .get() == accountNumber)
        {
          // add the new client AccountNumber to queue
          threadPool[i].addWork(new DepositToken(accountNumber));
          taskAssigned = true;
          break;
        }
      }

      if (!taskAssigned)
      {
        int c = 0;
        do
        {
          if (threadPool[c].busyStartTime == 0)
          {
            if (threadPool[c].isAlive())
            {
              // Add works to idle thread
              threadPool[c].addWork(new DepositToken(accountNumber));
              break;
            }
          }
          c++;
        }
        while (c < tc);
      }
     }
    }
  }
The approach exhibited above is transparent, avoid overlaps and future proven, to say the least, it does not force any excessive locking on the process and therefore provide a lightweight thread management process to handle the scenario at hand.

Disclaimer
The code above has not been tested, it has been written to demonstrate request chaining.

Tuesday, 28 June 2011

Capitalise First Letters of String (Useful for Name Conversion)

There are several java utils which can walkthrough words and turn first characters to upper cases - yet if you're like me looking to implement something pretty simple but powerful and also can be easily customized in various ways, then DIY sounds like the way forward.

Below example is something more simple for beginners to start with.

public final class MyUtils
{
  /**
   * Capitalize the First characters of passed Name. If the Name passed are separated by whitespaces, dots, hyphen or apostrophe, the first
   * characters will be capitalized. Example:
   * 

* The name passed = bright dadson.code-nathan o'brian, NameCapitalize(..) will change it to Bright Dadson.Code-Nathan O'Brian *

* @param string * @return */ public static String mameCapitalize(String string) { if (!(string == null)) { char[] replacer = string.toCharArray(); for (int i = 0; i < replacer.length; ++i) { if (((i > -1) && (i == 0)) && Character.isLetter(string.charAt(i))) replacer[i] = Character.toUpperCase(string.charAt(i)); else if ((Character.isWhitespace(string.charAt(i))) || (string.charAt(i) == '-') || (string.charAt(i) == '.' || (string.charAt(i) == '\''))) { if ((i == (replacer.length - 1)) && !Character.isLetter(string.charAt((replacer.length - 1)))) break; if (!(Character.isUpperCase(replacer[(i + 1)]))) { replacer[(i + 1)] = Character.toUpperCase(replacer[(i + 1)]); } } } return String.copyValueOf((replacer)); } return null; } /**To use the util capitalize - something like this**/ public static void main(String... args) { System.out.println(MyUtil.NameCapitalize("bright dadson.code-nathan o'brian")); } }
You are simply creating a pointer in the memory locations to which you modify the address values to upper cases.

Wednesday, 9 June 2010

JavaMail, Commons Mail or Spring Mail - Which does the job?

I thought since the previous culprit focuses on e-mail, it would be essential if I hit the nail on the head with choosing the right API for your e-mail function. For a starter, building e-mail function can be a little fustrating task.

If you are like most developers, you delve in JavaMail API thinking that is it, you have found a boiler plate code which does the job. You then go ahead to customize it to suite your enviroment, finally deployed it to realise your pain has just began.

Take for for instance below JavaMail API generic code:

Email Interface
  public interface EmailEngine
  {
    public void MailTransport(String from, String to, String cc, String subject,
     String message, String doc, String bcc) throws Exception;
  }

Actual Implementation
 public class EmailEngineImpl implements EmailEngine

    public final void MailTransport(String from, String to, String cc, String subject,
     String message, String doc, String bcc)
    {
      Properties props = new Properties();
      props.put(PropsFactory.PropsLookup("mail.host.props"), 
               PropsFactory.PropsLookup("mail.host"));
      Session session = Session.getInstance(props);
      try
      {
        Message msg = new MimeMessage(session);
        MimeMultipart mpRoot = new MimeMultipart();
        MimeMultipart mpAl = new MimeMultipart("alternative");
        MimeBodyPart content = new MimeBodyPart();

        msg.setSubject(subject);
        msg.setSentDate(Today.getDate());
        msg.setFrom(new InternetAddress(from));
        msg.setRecipients(Message.RecipientType.TO, getAddress(to));

        if (cc != null)
        {
          msg.setRecipients(Message.RecipientType.CC, getAddress(cc));
        }
        if (!(bcc == null))
        {
          msg.setRecipients(Message.RecipientType.BCC, getAddress(bcc));
        }
        
        if (doc != null)
        {
          MimeBodyPart p1 = new MimeBodyPart();
          Resource file = new ClassPathResource(doc);
          FileDataSource fds = new FileDataSource(file.getFile())
          {
            public String getContentType()
            {
              return "application/octet-stream";
            }
          };

          p1.setDataHandler(new DataHandler(fds));
          p1.setFileName(fds.getName());
          mpRoot.addBodyPart(p1);
        }
        MimeBodyPart p2 = new MimeBodyPart();
        p2.setText(message);
        mpAl.addBodyPart(p2);

        content.setContent(mpAl);
        mpRoot.addBodyPart(content);

        msg.setContent(mpRoot);
        msg.saveChanges();

        Transport.send(msg);
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
  }
Everything looks fine except you deploy it to realise, Some Email clients typically outlook will work fine but little issues with others. And so you dig around to uncover you'll have to follow the MimeMultiPart structure, WHAP!

You have little time to waste therefore decided to try native Spring Email API. Bravo! Take time to read the API document, did you see the line which says:


Warning regarding multipart mails: Simple MIME messages that just contain HTML text but no inline elements or attachments will work on more or less any email client that is capable of HTML rendering. However, inline elements and attachments are still a major compatibility issue between email clients: It's virtually impossible to get inline elements and attachments working across Microsoft Outlook, Lotus Notes and Mac Mail. Consider choosing a specific multipart mode for your needs: The javadoc on the MULTIPART_MODE constants contains more detailed information.

You avoid the warning and implement Spring Generic Email API as shown below, perhaps tweaking static MULTIPART_MODE to see if it does support various multi email clients. WGL!
NB. Inject org.springframework.mail.javamail.JavaMailSender

  public final void MailTransport(String from, String to, String cc, 
   String subject, String content, String doc, String bcc)
  {
    try
    {
      MimeMessage message = mailSender.createMimeMessage();
      // use the true flag to indicate you need a multipart message
      MimeMessageHelper helper = new MimeMessageHelper(message, true);
      helper.setFrom(from);
      helper.setTo(getAddress(to));
      helper.setSubject(subject.toString());

      if (!(cc == null))
      {
        helper.setCc(getAddress(cc));
      }
      if (!(bcc == null))
      {
        helper.setBcc(getAddress(bcc));
      }

      if (!(doc == null))
      {
        Resource file = new ClassPathResource(doc);
        helper.addAttachment(file.getFilename(), file);
      }

      helper.setText(content);
      mailSender.send(message);
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }

If you do have luck with either Generic JavaMail or Spring implementation, I suppose your first reaction will be, why bother trying Apache Commons Email! You want MHO, go ahead and try it. It saves time and does the job. Well each of these API has it flaws, but TMHO Apache Commons Email ticks most boxes. Get the dependency or the jar file onto your classpath and try this;


  public class EmailEngineImpl implements EmailEngine
  {
    public final void MailTransport(String from, String to, String cc, String subject, String message, String doc, String bcc)
    {
      // Create Multi-Part document
      MultiPartEmail email = new MultiPartEmail();
      try
      {
        if (!(doc == null))
        {
          // Create the attachment
          EmailAttachment attachment = new EmailAttachment();
          Resource file = new ClassPathResource(doc);
          
          attachment.setURL(file.getURL());
          attachment.setDisposition(EmailAttachment.ATTACHMENT);
          attachment.setName(file.getFilename());

          // add the attachment
          email.attach(attachment);
        }

        // Set Mail server location
        email.setHostName(PropsFactory.PropsLookup("mail.host"));
        email.setTo(getAddress(to));
        email.setFrom(from);

        if (!(cc == null))
        {
          email.setCc(getAddress(cc));
        }

        if (!(bcc == null))
        {
          email.setBcc(getAddress(bcc));
        }
        email.setSubject(subject);
        email.setMsg(message);

        // Send message
        email.send();
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }
  }
I did try these and realised, most little issues like multi client and attachment was dealt with. Like I said this is my opinion let me know what you think. And oh if you wondering WTF is the method getAddress(..), see below:

Implementation for Apache Commons
  private Collection getAddress(String arg)
  {
    Collection address = new ArrayList();
    try
    {
      ArrayList ccArray = new ArrayList();
      StringTokenizer st = new StringTokenizer(arg, ",");
      while (st.hasMoreTokens())
      {
        ccArray.add(new InternetAddress(st.nextToken()));
      }

      for (int i = 0; i < ccArray.size(); i++)
      {
        address.add(ccArray.get(i));
      }

    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    return address;
  }
Implementation for JavaMail or Spring
 private InternetAddress[] getAddress(String arg)
  {
    InternetAddress[] address = null;
    try
    {
      ArrayList ccArray = new ArrayList();
      StringTokenizer st = new StringTokenizer(arg, ",");

      while (st.hasMoreTokens())
      {
        ccArray.add(new InternetAddress(st.nextToken()));
      }

      int size = ccArray.size();
      address = new InternetAddress[size];
      for (int i = 0; i < size; i++)
      {
        address[i] = new InternetAddress(ccArray.get(i).toString());
      }

    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    return address;
  }

Drop me a comment to let me know what you think.

Monday, 7 June 2010

Commons mail, JavaMail or Spring Mail with Maven2 and servlet container dependency issue.

If you are working on Spring Web project with Axis2, Axiom or Apache CXF 2 dependency, unless the application do not have concerns with e-mail confirmation/notification functionality. Else you are likely to run into this culprit.
How do you know you've got this issue? You execute a test application from your IDE to see if an e-mail will be sent, to your surprise everything works perfect. But when you deploy the application to either Tomcat, Jboss or Glassfish server, the message is sent with header and footer details as part of the mesage body. The massage body typically resembles below;
------=_Part_0_25002283.1275298567928
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello Mark Doe,

This message is found as a culprit.

Regards,

Joe Blahh

------=_Part_0_25002283.1275298567928

Also if you are attaching documents to this email message, the attachment is sent with base64 encode as part of the message body. Typical attachment message will look like this;

------=_Part_0_25002283.1275298567928
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello Mark Doe,

This message is found as a culprit.

Regards,

Joe Blahh

------=_Part_0_25002283.1275298567928
Content-Type: application/pdf; name="file.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; 
filename="file.pdf"
Content-Description: Some attachment

JVBERi0xLjQNJeLjz9MNCjYzIDAgb2JqDTw8L0xpbmVhcml6ZWQgMS9MIDMxMzE4Mi9PIDY1L0Ug
Mjg2NjY5L04gMS9UIDMxMTgwMi9IIFsgMjgzNiAzNzZdPj4NZW5kb2JqDSAgICAgICAgICAgICAg
DQp4cmVmDQo2MyAxMjcNCjAwMDAwMDAwMTYgMDAwMDAgbg0KMDAwMDAwMzM4MCAwMDAwMCBuDQow
MDAwMDAzNTIzIDAwMDAwIG4NCjAwMDAwMDQzMDcgMDAwMDAgbg0KMDAwMDAwNTEwOSAwMDAwMCBu
DQowMDAwMDA2Mjc5IDAwMDAwIG4NCjAwMDAwMDY0MTAgMDAwMDAgbg0KMDAwMDAwNjU0NiAwMDAw
MCBuDQowMDAwMDA3OTY3IDAwMDAwIG4NCjAwMDAwMDkwMjMgMDAwMDAgbg0KMDAwMDAwOTk0OSAw
MDAwMCBuDQowMDAwMDExMDAwIDAwMDAwIG4NCjAwMDAwMTIwNTkgMDAwMDAgbg0KMDAwMDAxMjky
MCAwMDAwMCBuDQowMDAwMDEyOTU0IDAwMDAwIG4NCjAwMDAwMTI5ODIgMDAwMDAgbg0KMDAwMDAx
.......
CnN0YXJ0eHJlZg0KMTE2DQolJUVPRg0K
------=_Part_0_25002283.1275298567928--

If you've run into this culprit, don't worry too much. Go grab a cuppa coffee, and while you're relaxed look through your Maven dependency to see if you have geronimo-javamail_1.4_spec-1.2 along with geronimo-activation_1.1_spec, because your project build will rely on these. You can do this by issuing below Maven2 commands;
mvn dependency:tree
Optionally, the output parameter can be specified to divert the output to a file:
mvn dependency:tree -Doutput=/path/to/file

Causes:
The described issue is caused by transitive dependencies of Apache CXF 2 or Axiom.

SOLUTION:
To resolve this issue, exclude geronimo-javamail_1.4_spec from the build, and just rely on javax's mail-1.4.x.jar.

    
  org.apache.cxf   
  cxf-rt-frontend-jaxws    
  2.2.6    
            
                  
       org.apache.geronimo.specs            
       geronimo-javamail_1.4_spec        
      
      
      org.apache.geronimo.specs 
      geronimo-activation_1.1_spec
         
 



  
  org.apache.ws.commons.axiom  
  axiom-api  
  1.2.8  
           
      
      org.apache.geronimo.specs 
      geronimo-activation_1.1_spec
     
     
      org.apache.geronimo.specs 
      geronimo-javamail_1.4_spec
     
    

Thursday, 15 April 2010

Accessing properties file using Java and Spring.

You can save crosscutting data in a properties file for your Java application. This approach has been adopted by several application and consequently not unconventional to see various post related to this subject. And so today, after scratching my chin for thoughts on what to post, I decided to highlight slightly on this rather conventional approach.

Typical crosscutting details includes username, password, connection urls, MIME types etc. For Java applications, saving these data in a properties file avoid having to dig through your codes to re-factor changes, re-compile and hence deploy.

So if you are a beginner looking for 'How to' or an advance looking for a quick refresh, this is how it is done. First create a properties file and save it in your classpath. Typical properties file looks as shown below:
#File name is 'yourfile.properties'
#This file holds crosscutting details.

database.username=your username
database.password=your password
database.url=jdbc:mysql//your url

lang=eng
lang=ger
Core Java option
Then to access values within this properties file, you build a simple handler util as shown below with various helper functions to aid access the elements within the properties file.
public class PropsUtil
{
  private static Logger logger = Logger.getLogger(PropsUtil.class);
  private final static String file = "yourfile.properties";//Properties file name
  private static Properties props = null;

  /**
   * Find the properties file in the class path and load it.
   * @throws IOException
   */
  private static void loadPropertiesFromClasspath() throws IOException
  {
    props = new Properties();
    InputStream inputStream = PropsUtil.class.getClassLoader().getResourceAsStream(file);

    if (inputStream == null)
    {
      throw new FileNotFoundException("Property file '" + file + "' not found in the classpath");
    }
    props.load(inputStream);
  }

  /**
   * Look up a property from the properties file.
   * @param key The name of the property to be found
   * @return The value of the property
   */
  public static String getProperty(String key)
  {
    if (props == null)
    {
      try
      {
        loadPropertiesFromClasspath();
      }
      catch (Exception IOException)
      {
        logger.warn("Unable to load properties file.");
        return null;
      }
    }
    return props.getProperty(key);
  }

  /**
   * Look up a property from the properties file.
   * @param key The name of the property to be found
   * @return The value of the property
   */
  public static String getProperty(String key, String defaultValue)
  {
    if (props == null)
    {
      try
      {
        loadPropertiesFromClasspath();
      }
      catch (Exception IOException)
      {
        logger.warn("Unable to load properties file.");
        return null;
      }
    }
    return props.getProperty(key, defaultValue);
  }

  /**
   * Looks up the value of a key from the properties file and converts it to an integer.
   * @param key
   * @return The value of that key
   */
  public static int getIntProperty(String key)
  {
    String property = getProperty(key);

    if (property == null)
    {
      logger.warn("Could not load integer property " + key);
      return -1;
    }
    try
    {
      return Integer.parseInt(property);
    }
    catch (NumberFormatException nfe)
    {
      logger.warn("Invalid format for a number in properties file: " + property, nfe);
      return -1;
    }
  }
}
Using above util we can access the value of database.username in our file simply like this:
 String dbUser=PropsUtil.getProperty("database.username");//access using property name
 String dbUser=PropsUtil.getProperty("lang", "ger");//fetch match value using both property name and default value
Spring based
Another option is Spring base properties injection. It is common this days to adapt a common framework to wrap your application, one typical framework which has grown with strength over the years is Spring. Like other frameworks Spring comes packed with wrappers for almost anything your application is deemed to support, and one that this post is concern is wrapper for properties file.

PropertyPlaceholderConfigurer wrapper is the most common and easy properties file injector bean supported and used mostly by Spring based application. A typical usage is as straight forward as shown below:

   
 

 
  ${database.username}
 

Note the setting classpath:yourfile.properties assumes yourfile.propertie is located at your project classpath location src/main/resources.

Annotations option
Spring also provides you another wrapper for injecting properties into your bean using annotations. This makes it handy for accessing values at application level. For example classes which are not defined in your-app-context.xml as beans can still access this properties using annotations. Achieving this is as simple as adding below definition:
 
This provides access to the properties via simple constucts as demostrated in below class:
 public class Example
 {
  @Value("#{myAppProps['database.username']}")
  private String dbUser;
 
  public void foo()
  {
   System.out.println(dbUser);
  }
 }
So far you have seen how to construct a simple util class using Core Java to handlle properties file. You have also seen how easy to use Spring based support wrappers to handle properties within your application. Please do let me know if you have any suggestion or enchancement or if this post has helped you in some way.

Tuesday, 30 March 2010

Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists:

Are you working on Hibernate Many-To-One/One-To-Many with MySQL? If you're, then beware of this culprit. So how does it happens? You have two objects say 'Site' and 'Partner'. Here 'A' Partner will be dealing with multiple sites and hence the multiplicity of Many-To-One and One-To-Many mapping from both objects.

For example the Site mapping will resemble something like this;
  @Entity
  @Table(name = "site")
  public class Site
  {
    private Partner partner;
    public Site()
    {
      super();
    }

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "partnerid", nullable = true)
    public Partner getPartner()
    {
      return partner;
    }

    public void setPartner(Partner partner)
    {
      this.partner = partner;
    }
  }

While the Partner object mapping will resemble something like this;
  @Entity
  @Table(name = "partner")
  public class Partner
  {
    private List<Site> sites;
    public Partner()
    {
      super();
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "partner")
    public List<Site> getSites()
    {
      return sites;
    }

    public void setSites(List<Site> sites)
    {
      this.sites = sites;
    }
  }


From the above mappings, you'll notice that Partner has been mapped to Site using the partnerid of MySQL Table partner. A physical schema for partner and site Tables looks like this;
 Partner:
 +-----------+-------------+------+-----+
 | Field     | Type        | Null | Key |
 +-----------+-------------+------+-----+
 | id        | int(11)     | NO   | PRI |
 | name      | varchar(50) | NO   |     |
 +-----------+-------------+------+-----+

 Site:
 +-----------+-------------+------+-----+
 | Field     | Type       | Null  | Key |
 +-----------+-------------+------+-----+
 | id        | int(11)    | NO    | PRI |
 | sitename  | varchar(50)| NO    |     |
 | partnerid | int(11)    | NO    |     |
 +-----------+-------------+------+-----+
 

Because the PartnerID is integer if you have a method say getParent() in Site for example like this;
  @Transient
  public Company getParent()
  {
    if (!(getPartner() == null))
    {
      return getPartner();
    }
    return null;
  }

In MySQL , default integer is '0' , not NULL. This will cause Hibernate String to load a Partner with non-existent row with id=0 and therefore throw:
 Exception in thread "main" org.hibernate.ObjectNotFoundException: No
 row with the given identifier exists: [com.lop.testing.Partner#0]at
 org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:409)at
 org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:108)at
 org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:97)at
 org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)at
 org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)at
 com.essensys.bluefin.Partner_$$_javassist_10.toString(Partner_$$_javassist_10.java)at 
 java.lang.String.valueOf(String.java:2826) at java.lang.StringBuilder.append(StringBuilder.java:115)

To resolve this, simply annotate the Site getPartner() method as shown below;
  @ManyToOne(fetch = FetchType.LAZY, optional = false)
  @JoinColumn(name = "partnerid", nullable = true)
  @NotFound(action = NotFoundAction.IGNORE)
  public Partner getPartner()
  {
    return partner;
  }

The existance
@NotFound(action = NotFoundAction.IGNORE)
fix the issue.
Job done! but then the question is, do you need to go through that?

Tuesday, 23 March 2010

java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String

What a weird title to start with. I have to say the caption needs to be pretty straight forward to address the related issue. So what is it? Apache CXF developers working on JAX-WS OR JAX-RS project on Maven and Java 6 are likely to experience this exception.


Exception in thread "main" java.lang.NoSuchMethodError: javax.xml.ws.WebFault.messageName()Ljava/lang/String;
[java] at com.sun.xml.ws.model.RuntimeModeler.processExceptions(RuntimeModeler.java:1162)
[java] at com.sun.xml.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:898)
[java] at com.sun.xml.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:666)
[java] at com.sun.xml.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:420)
[java] at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel

After digging around you'll realised the only option is to download the webservices-api.jar file, plus wack it onto C:\Program Files\Java\jdk1.6.0_18\jre\lib\endorsed directory to resolve it.

You might have probably ask yourself by now, where to grab webservices-api.jar easily from? two advice, download metro, unzip its content and the finally reach the lib directory to locate it OR right here.

Hold on! does it really resolves it? You are likely to enter into another annoyance when finally below exception spits onto your console log:

Exception in thread "main" java.lang.ClassCastException: $Proxy66 cannot be cast to com.sun.xml.internal.ws.developer.WSBindingProvider.

Like most people, the first thing that comes to mind is revisit and amend your service login object to see if it does the job. You are likely also to be told 'since you’re using CXF and not the JAX-WS reference implementation, the steps to set headers are probably going to be different and therefore Check the CXF docs', forgetting Apache CXF supports both JAX-WS OR JAX-RS implementations.

I tell you what don't explode yourself from annoyance, just take a close look at the Exception. You're referencing some of your object imports from com.sun.xml.internal.ws, and there is where your issue is.

Do NOT bombard yourself with new exceptions trying to regenerate your stubs with extra arguments as shown below, suggested by few people on the web.


-exsh
true


To resolve this Exception, just replace;

import com.sun.xml.internal.bind.api.JAXBRIContext;
import com.sun.xml.internal.ws.api.message.Header;
import com.sun.xml.internal.ws.api.message.Headers;
import com.sun.xml.internal.ws.developer.WSBindingProvider;

With

import com.sun.xml.bind.api.JAXBRIContext;
import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.Headers;
import com.sun.xml.ws.developer.WSBindingProvider;


Job done! Now go grab a cuppa coffee and relax.

Saturday, 6 February 2010

Demise of waterfall, concept or reality?


Agile development approach has been the most adopted methodology for 21st century development, and software project management. "Some have said that 2007 was the year that Agile arrived, with agile development best practices such as automated builds, test automation, and continuous integration finally beginning to reach critical mass among Java developers. While this is true in theory, the fact is that most Java enterprise projects are still based on more traditional development methods, such as the Waterfall model".

Take Scrum for instance, we know a strongly modelled scrum is a projects that are "divided into succinct work cadences, known as sprints, which are typically one week, two weeks, or three weeks in duration. At the end of each sprint, stakeholders and team members meet to assess the progress of a project and plan its next steps".

Isn’t this what developers and stakeholders has conceptually been practicing since the prime times of waterfall, which many believe is at its demise. At each stage of the waterfall model is a well iterative concept (such as Scrum) adopted to make sure before we proceed to the next stage of the development process, deliverables would have been well designed, coded and well tested.

Waterfall methodology is still utilised in today’s software development, practically because – each stage of the development process is an adopted agile process interactively and iteratively utilised to derive a quality working product. One might argue, but waterfall never iterates the actual project, simply because water flows downwards and ends there.

When a project exit the deadline, it has exited the deadline - any subsequent call for modification triggers a call for design changes, code modification, testing and walkthrough and modification of documentations and re-implementation. This put together is water pouring from one glass to another.

Friday, 5 February 2010

Trusting the untrusted.


Most internet users are reluctant to change their password, trusting they are not victims of exploits. Well I suppose we all do it thinking what possibly could our credential worth. Password change is very vital when operating from home networks. These are more susceptible to exploit attack as witness from Twitter and not long ago Hotmail. "An intruder doesn't have to be inside your home or office building to manipulate a wireless signal. For example, they could be sitting outside in their car sniffing out your data all while enjoying a sandwich. Before they have a chance to complete the meal, the intruder can learn just who you work for, how to access the company network or even transfer money out of your bank account if the right security is not implemented."

Not only that, changing your web password from work area networks can be prone to exploits due to exploit sniffing tools utilised by trusted network and security engineers and other internal staffs, to filter, sniff and intrude in our private mails and explore your private life around social networks. I think everyone is purely aware of the capabilities of the expert, consequently an oversight and perhaps a little trust is what is keeping our virtual instance alive.

A few days ago "Officials at Twitter linked the resetting of passwords to a malicious Torrent sites and other schemes. According to Twitter, the company began its investigation after noticing a surge in followers for certain accounts during the past five days. Twitter revealed more details about the phishing attacks that caused the company to reset the passwords on some user accounts today." Darknet blogged.

"According to Twitter Director of Trust and Safety Del Harvey, there was a sudden surge in followers for certain accounts during the last five days. For that reason, the company decided to push out a password reset to the accounts, he said. After launching an investigation, Twitter officials linked part of the problem to malicious torrent sites." Darknet blogged.

"It appears that for a number of years, a person has been creating torrent sites that require a login and password as well as creating forums set up for torrent site usage and then selling these purportedly well-crafted sites and forums to other people innocently looking to start a download site of their very own," Harvey blogged. "However, these sites came with a little extra — security exploits and backdoors throughout the system. This person then waited for the forums and sites to get popular and then used those exploits to get access to the username, email address, and password of every person who had signed up."

Wednesday, 7 October 2009

Restoring minimized JInternalFrame.

This is going to be straight forward as I assume you have got some basic or perhaps an advance knowledge of Java Swing JInternalFrame. Also if you are a beginner opting to learn more about Java Swing and it's components, then I suggest you visit here .

Straight to what we are here for - Assuming you have a button, on which when you click will open an InternalFrame. At times you might want to restrict the frame from opening again if it is currently opened, and then perhaps restore it to JDesktop if perhaps minimized. Now lets look into how to block the frame from been opened twice.

We will start by creating a helper bean which will hold the status of the internalFrame. Note this status will either be displayed or not displaying.

Helper bean:
  public final class global
  {
    public global()
    {
    }

    private boolean displayed;

    public boolean isDisplayed()
    {
      return displayed;
    }

    public void setDisplayed(boolean displayed)
    {
      this.displayed = displayed;
    }
  }

We then move on to creating the JInternalFrame. Notice that the code below set the status of Displayed to false in the helper bean, anytime the iFrame is closed. In doing so, the button ActionEvent will determine the status as not displayed and hence open the frame.

I implement it this way..
  public class iFrame extends javax.swing.JInternalFrame
  {
    /** Creates iFrame */
    public iFrame()
    {
      initComponents();
      addInternalFrameListener(new InternalFrameAdapter()
      {
        public void internalFrameClosed(InternalFrameEvent e)
        {
          /** Set the the status of iFrame in helper **/
          new global().setDisplayed(false);
        }
      });
    }

    @SuppressWarnings("unchecked")
    private void initComponents()
    {
      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
      getContentPane().setLayout(layout);
      layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 394, Short.MAX_VALUE)
      );

      layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGap(0, 274, Short.MAX_VALUE)
      );
      pack();
    }
  }

Lastly the jDesktop Pane. This holds the button and ActionEvent to determine whether the iFrame is displaying or otherwise. Here if the iFrame is displayed, we restrict double opening and then make sure the iFrame is restored to jDesktop if minimized.

Note: The implementation here is pretty generic - but you could tweak it a little bit down to suite your environment and requirement. Also the 'If Checks' can be reduced down depending on your requirement.
 public class Main extends JFrame
  {
    JDesktopPane desktop;
    public static void main(String[] args)
    {
      SwingUtilities.invokeLater(new Runnable()
      {
        public void run()
        {
          new Main().displayUI();
        }
      });
    }

    public void displayUI()
    {
      desktop = new JDesktopPane();
      JButton button = new JButton("Open");
      button.addActionListener(new ActionListener()
      {
        public void actionPerformed(ActionEvent ae)
        {
          try
          {
            iFrame sites = new iFrame();
            if (!sites.isDisplayable())
            {
              if (new global().isDisplayed())
              {
                if (!sites.isMaximum())
                {
                  for (int x = 0; x < desktop.
                  getAllFrames().length; x++)
                  {
                    JInternalFrame frames =(JInternalFrame) desktop.getAllFrames()[x];

                    if (frames.getClass().equals(sites.getClass()))
                    {
                      frames.setIcon(false);
                      frames.toFront();
                      frames.setSelected(true);
                    }
                  }
                }
              }
              else
              {
                sites.setVisible(true);
                desktop.add(sites);
                sites.setSelected(true);
                new global().setDisplayed(true);
              }
            }
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }
        }
      });

      JFrame frame = new JFrame();
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(400, 400);
      frame.setLocationRelativeTo(null);
      frame.add(desktop, BorderLayout.CENTER);
      frame.add(button, BorderLayout.SOUTH);
      frame.setVisible(true);
    }
  }


Hope this helps!