Wednesday, 13 June 2012

GWT 2.4 custom widget for editing time

I had to take some time to make a "showcase" of the GWT basics. So, I started to think about something that make sense to someone to see and also useful for me. I remembered my self, not so long ago, trying to find a widget for time edition, so I told my self, why not to seize the time for that.

Maybe, I just failed to find the solution to time edition over the Internet, so I will say that I couldn't find the widget.

I started by planning what to do to show a little bit of all of the basic aspects of GWT programing. To do so it seemed to me essential to develop a widget, listening events and fire events, use generics, some low level manipulation of DOM and CSS through GWT elements, and some other peculiarities.

My idea is to present my way of doing a custom widget in a very fast way. This widget will get a java.util.Date and it will allow the developer to show and edit the time. So it will have to status(showing and editing), by capturing the focus event it will change from showing to editing. Once editing, the user is allowed to enter it typing the hour and minutes, or simply by using the arrow keys, up and down.



To control the typing, I will write a "Named inner class" to show one of the approaches to add event handlers.

As you can see, this spaghetti of code would be improved, but it aims to prevent the user to "type" an invalid time. To do so, it listens the key down event and prevents the character to be written, by stopping the event to be triggered.

Doing corrections to the key pressed, allowing or preventing to be changed, setting the next position of the cursor, data entry can be controlled.
Another thing to notice, is that the left and right arrows are permitted to rise, so the user can move freely through the widget.

The AM / PM(refering to before midday(AM) and after midday(PM)) is also managed ether by doing click onto it or using the arrows up and down on the hour.

I have code this enum to keep the logic of AM/PM as much encapsulated as possible. That way you can ask the enum "instance" to give you its opposite value.
Lets go for the constructor. Here is where I show the three different ways of adding an implementation of an event handler interface. Depending on the use you are going to give to that classes, if you will prefer a named inner class, an anonymous inner class or just doing the Composite to implement whatever event you want to handle.

I intended to get this widget independent of CSS setting to be shown properly, while I show some GWT code to manipulate the the look and feel. I have coded this method to do so.

What I meant here was to set the basic gwt-TextBox to my widget and make some changes to it and fix some padding and border defaults to make it look better. I know that you guys can make this look better so give me some tips.

There is something else to play with. I have discovered that GWT has implemented the Timer class that does the same as JRE java.util.Timer class almost ever since.
So I decided to put the clock ticking. To do so, I had to create a class extending Timer and then override the run method.

Because I don't want to boring you with so much details, I will paste the whole thing, and you can ask whatever you want...

Hope you like it!!

Wednesday, 15 February 2012

Making a decoupled sequence generator, in JPA with MySQL.

I faced this problem recently and there is no good or easy solutions out there. I have made a research looking for a JPA annotation that provides this, with no luck.

After a while, I decided to solve the problem by my self, doing it manually. I usually have not enough time to analyze problems to come up with an academic solution, so I will tell you what I have done to move forward, and you can post alternative solutions.

What I did was to create a table where I'm going to store all the independent sequences, giving them a name and the actual value.


So, as you may notice, there will be a row per sequence where the value will be modified by an update sql query. The best way to avoid concurrence problems updating the sequence is to create a function we can select when we need a new sequenced number.

Designed like that you can create so many functions as sequences you need. All stored in a single table and you just need to execute an SQL query selecting the proper function to get you sequence number.

Assuming you are using Hibernate as your JPA implementation framework, you can not use an HQL query to get this sequence, because you are invoking a function and as far as I know this is not possible using HQL. The workaround here is to create a native query to execute.

I hope you find this useful!!

Tuesday, 16 August 2011

Are you tired of using 3 or 4 different browsers to test your web apps?

One of the problems programmers have working with web applications is testing with different users.

The browsers uses your session coockies to maintain state throughout your browsers instances. That means that you can "open firefox"(or at least that what you think), many times and your gmail(for example) will remember that you are already logged in. Indeed, that is a headache for programmers, because you have to install and open two or three different browsers to do the job.

But there's a workaround to that issue that seems to be ignored for a quite a lot of programmers, and I will let you know how to do that. Firefox works with profiles and we usualy not aware of that.

When you install it, it will create a profile called "default" for you and you will use it any time you run it. By executing you firefox you will be running as "default" no matter how many times you open it. Regardless of how you work with it you will share all the "default" profile information. So the workaround is very easy to deduct.

You need to start firefox on diferent "profiles". It surprised me how easy was to do it. If you read the command line help of the application, you will see an option called "-P profile" firefox -P "new profile" -no-remote The -P option allow you to run firefox specifing a profile and there is the magic. As this is almost a completely new firefox, you will need to install all plugins and bookmarks again but this is just a side effect. :D The -no-remote option will tell firefox not to connect this instance with any other running instances of firefox. The first time you run this command line, you will probably be taken to the Profile Manager because the "new profile" doesn't exist. There you will realise what I am talking about.


So, to test your application using different session coockies you just need to create as many profiles you need and that's it. As a tip, I can suggest you to create launchers for each of the profiles and put them in the desktop so you will have them handy.

 I hope you like it...

Wednesday, 16 February 2011

Real estate application for Android(RSS) part 2

Continuing with the RSS android application, we are going to take a closer look at LazyAdapter class which has the most relevant code of the application.
To begin with, notice that the class implements OnScrollListener. The reason why is that we need some scrolling behaviour on the list view and the most reasonable way to do that is making this class an implementation of that interface. That is why this class acts as an adaper and as a scroll listener to the list view.
public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        ViewHolder holder;
        
        if (convertView == null) {
            vi = inflater.inflate(R.layout.item, null);
            holder = new ViewHolder();
            holder.text = (TextView) vi.findViewById(R.id.text);;
            holder.image = (ImageView) vi.findViewById(R.id.image);
            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }
        
        if (data.size() <= position) {
         readRss(10);
        }
        
        lastViewedPosition = position;
        
        holder.text.setText(data.get(position).getTitle());
        holder.image.setTag(data.get(position).getImage());
        imageLoader.DisplayImage(data.get(position).getImage(), activity, holder.image);
        
        return vi;
    }
More in particular the method getView(mandatory because it is extending android.widget.Adapter) is called every time a ListView's item will be shown. Here is where you must return a view of the element. On our case, a thumbnail and a brief description of the property.
@Override
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  if (totalItemCount - lastViewedPosition <= 3) {
   readRss(10);
  }
 }
On the other hand, we have onScroll method which is mandatory since we implemented OnScrollListener interface. This method will be called every time the user tries to view an element that is not on the screen at that moment in particular. This is the appropriate moment to check if we have enough elements to continue scrolling. That way, we can manage list view scrolling on the fly.
private boolean connect() {
     try {
      if (xpp == null) {
    URL url = new URL(feedString);
    URLConnection connection = url.openConnection();
    
    HttpURLConnection httpConnection = (HttpURLConnection)connection; 
    int responseCode = httpConnection.getResponseCode(); 
    
    if (responseCode == HttpURLConnection.HTTP_OK) {
     InputStream in = httpConnection.getInputStream();
     
        factory = XmlPullParserFactory.newInstance();
           factory.setNamespaceAware(true);
           xpp = factory.newPullParser();
           
           xpp.setInput(in, "ISO-8859-1");
    }
      }
   
   return true;
   
     } catch (XmlPullParserException xe) {
      Log.e("RssReader", "Connection", xe);
      return false;
      
     } catch (IOException eio) {
      Log.e("RssReader", "Connection", eio);
      return false;
      
     }
    }
    
    private void readRss(int itemsToRead) {
     boolean insideItem = false;
     boolean insideTitle = false;
     boolean insidePubDate = false;
     boolean insideDescription = false;
     Property property = null;
     
     try {
      if (connect()) {
          int eventType = xpp.getEventType();
          
          while (eventType != XmlPullParser.END_DOCUMENT && itemsToRead >= 0) {
           if(eventType == XmlPullParser.START_TAG) {
      if (xpp.getName().equalsIgnoreCase("item")) {
       insideItem = true;
       property = new Property();
      } else if (insideItem && xpp.getName().equalsIgnoreCase("title")) {
       insideTitle = true;
      } else if (insideItem && xpp.getName().equalsIgnoreCase("pubDate")) {
       insidePubDate = true;
      } else if (insideItem && xpp.getName().equalsIgnoreCase("description")) {
       insideDescription = true;
      }
      
     } else if(eventType == XmlPullParser.END_TAG) {
      if (xpp.getName().equalsIgnoreCase("item")) {
       insideItem = false;
       data.add(property);
       --itemsToRead;
      }
         
     } else if(eventType == XmlPullParser.TEXT && insideItem) {
      if (xpp.getText() != null) {
       if (insideTitle) {
        property.setTitle(xpp.getText());
        insideTitle = false;
       } else if (insidePubDate) {
        property.setDate(xpp.getText());
        insidePubDate = false;
       } else if (insideDescription) {
        getDetails(property, xpp.getText());
        insideDescription = false;
       }
      }
      
     }
     
     eventType = xpp.next();
          }
      }
      
  } catch (XmlPullParserException e) {
      Log.e("RssReader", "Connection", e);
  } catch (IOException e) {
      Log.e("RssReader", "Connection", e);
  }
    }
Nevertheless, the issue now is how can we read a resource from Internet on demand. There is a solution to this too. We can read the xml by creating an instance of XmlPullParserFactory. Through this parser you can get elements from the xml, one by one, to show as many elements as you need. Moreover, you can get the instance of the parser and read a set of elements again to get into the view. The parser's instance will preserve pointing where you are, so you will always can get it and read another set of elements til the end of the document. Then we have ImageLoader class that is just an in-memory cache implementation. The idea of this is show a default image while the final one is bring from the internet. This allows us to continue adding elements to the list view independently of the images completition. Lets go back to the MainActivity to see what happens when we click on an element. As we saw in the last post, a click listener was created in order to attend this event.
list.setOnItemClickListener(new OnItemClickListener() {
         public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {
          selectedProperty = properties.get(_index);
          showActivity();
         }
     });
        list.setOnScrollListener(adapter);
        list.setAdapter(adapter);
The selected property is set and the activity that show it is created. Lets show the code for the method showActivity.
private void showActivity() {
     Intent imageView = new Intent(this, ImageFromUrl.class);
     
 String propertyDescription = selectedProperty.getTitle() + "\n" +
              "Bedrooms " + selectedProperty.getBedrooms()  + "\n" +  
               "Bathrooms " + selectedProperty.getBathrooms();
     
     Bundle bundle = new Bundle();
     bundle.putString("imageUrl", selectedProperty.getImage());
     bundle.putString("propertyDescription", propertyDescription);
     imageView.putExtras(bundle);
     
     startActivity(imageView);
    }
As you can see, an Intent is created based on the ImageFromUrl class. This class will take care of how a property should be shown. The idea is that the Activity can be shown even if the image haven't been loaded yet.
public class ImageFromUrl extends Activity {
    
    private String url = null;
    private String description = null;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image_viewer);
        
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
         url = extras.getString("imageUrl");
         description = extras.getString("propertyDescription");
        }

        ImageView imgView = (ImageView) findViewById(R.id.ImageView);
        TextView txtView = (TextView) findViewById(R.id.DescriptionView);
        
        Drawable drawable = LoadImageFromWebOperations(url);
        imgView.setImageDrawable(drawable);
        txtView.setText(description);
    }

   private Drawable LoadImageFromWebOperations(String url) {
 try {
     InputStream is = (InputStream) new URL(url).getContent();
     Drawable d = Drawable.createFromStream(is, "src name");
     return d;
  
 }catch (Exception e) {
     return null;
 }
   }
}
Lastly I want to add something I forgot to mention. The application was based on the real estate site http://www.suburbview.com and I use in particular I used the housing rental from Melbourne RSS. This information was written down into a resource file named strings.xml.


    House Rental RSS
 http://www.suburbview.com/files/vic/3000/rent/melbourne.rss

Because we are not going to see the entire application here, I will give you this link for you to download the eclipse project so you can play with it as much as you want.

HouseRentalRSS.zip

And if you want to try it here you have the application.
I may forget some other things so please, don't hesitate asking questions.

Have fun!!

Monday, 7 February 2011

Real estate application for Android(RSS) part 1

Android is an open-source operating system for smartphones. Android was the name of the company that began the challenge of making this operating system for smartphones and Google bought the company to develop the project on their own. The first Android come to light only a few month after the IPhone, back in 2007. By those days the event was announced that way: "Google Android, a new software platform designed to provide open access to mobile phones for application developers." Google's idea was always the same, bring people closer to content on the Web in a easy and organised way. Anyway, this is just history.

I will try to do a little piece of work that you can find useful to learn and enough challenging to keep reading.

I will assume that you have a working environment base on eclipse. If not, you can go here and follow the recipe.

To create an Android application, you will need to create a corresponding Android
project. The project will hold all of your source code, resources, third-party JARs, and related materials.

The application we will develop is very simple. As I plan to go to Australia on holiday, I thought it will be great to use this material to make a useful application.

I've been using suburbview as part of my investigation and they have a great service of RSS that we can use as an excuse to make some piece of work.

The RSS publishes the properties in rent or for sale. We are going to use this to pull properties and make a lazy list showing them. The idea is to use Layouts, Widgets, and Internet access to make a useful application that allows us to look rentals.

I will suppose that you have a clean project with an Activity named MainActivity, and a layout named main.xml. Here is the first problem for newbies. There is no a good tool to make layouts and you probably going to deal with xmls.



 


This is the main layout and basically holds the application on a LinearLayout. There inside, its adds a ListView in which the properties will be shown.

Each item of the ListView needs its own Layout that we named item.xml:



  
  


The next stage to define is the click event on the ListView. An Activity named ImageFromUrl will be responsible. Let's see the layout:



 
  
 
 
  
 


This layout is base on a TableLayout. It's pretty similar the the HTML tag so there is not much to tell. The idea is display the details of the property in a more extended way.

Now that we have the GUI, we have to start programming. An Android program starts by executing on an Activity. The start-up Activity needs to be specifically set in the AndroidManifest.xml along with other things that we won't explain here. Let's see the code:



 
  
   
    
    
   
  
 
 
 
  
 


As you can see above, there are two activities inside the application tag. The one that has the intent-filter inside is that main activity. We are telling this to Android by adding the action and category tags.


    
    
   

I'm not going to give a detailed explanation, but you can ask for answers.

Let's move forward and see some java code. We are going to start by coding the main activity. All custom activities has to extend from Activity android class. Then you have to override onCreate method and there you have to do your staff. That means that you have to create your application(mainly graphically) because Android will invoke this method:

@Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  
  list = (ListView) findViewById(R.id.list);
  adapter = new LazyAdapter(this, getString(R.string.rental_feed), properties);
  
  list.setOnItemClickListener(new OnItemClickListener() {
   public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {
    selectedProperty = properties.get(_index);
    showActivity();
   }
  });
  list.setOnScrollListener(adapter);
  list.setAdapter(adapter);
 }

First two lines are almost default. We are going to focus on the rest of the method. The third line gets the list in which the process will add the properties. As you may see, there's a static class that Android auto-generate and has all the resources constants. In this case we use the one that represents the list we define in the layout "R.id.list".

Then we create a class LazyAdapter. This class has the behavioural responsibility of the list.

Here is where the first challenge appear. The main goal of the application is to get properties from a RSS. We don't know how much properties this file is going to have. If the file is really big we should spend a lot of resources and time trying to read it entirely before showing the user some information. That is why we have to get a more efficient approach to give the user a better experience. There's a way of doing this and consist in reading the file as necessary.

To do this we need the logic that allows us to parse the file as needed and we can do this, implementing OnScrollListener interface. That will force us to implement two methods, onScroll and onScrollStateChanged. In this case, I made both things in the same class, meaning extends BaseAdapter and implement OnScrollListener.

Because we are extending from BaseAdapter we need to implement some more methods: getCount(), getItem(), getItemId(), getView().

Let's see the class.

public class LazyAdapter extends BaseAdapter implements OnScrollListener {
 
 private int lastViewedPosition = 0;
 
 private XmlPullParserFactory factory = null;
 private XmlPullParser xpp = null;
 
 private Activity activity;
 private ArrayList data;
 
 private static LayoutInflater inflater = null;
 public ImageLoader imageLoader;
 private String feedString;
 
 public LazyAdapter(Activity a, String feedString, ArrayList d) {
  this.feedString = feedString;
  activity = a;
  data = d;
  inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  imageLoader = new ImageLoader(activity.getApplicationContext());
 }

 public int getCount() {
  return data.size();
 }

 public Object getItem(int position) {
  return position;
 }

 public long getItemId(int position) {
  return position;
 }
 
 public static class ViewHolder{
  public TextView text;
  public ImageView image;
 }

 public View getView(int position, View convertView, ViewGroup parent) {
  View vi = convertView;
  ViewHolder holder;
  
  if (convertView == null) {
   vi = inflater.inflate(R.layout.item, null);
   holder = new ViewHolder();
   holder.text = (TextView) vi.findViewById(R.id.text);;
   holder.image = (ImageView) vi.findViewById(R.id.image);
   vi.setTag(holder);
  } else {
   holder = (ViewHolder) vi.getTag();
  }
  
  if (data.size() <= position) {
   readRss(10);
  }
  
  lastViewedPosition = position;
  
  holder.text.setText(data.get(position).getTitle());
  holder.image.setTag(data.get(position).getImage());
  imageLoader.DisplayImage(data.get(position).getImage(), activity, holder.image);
  
  return vi;
 }
 
 private boolean connect() {
  try {
   if (xpp == null) {
    URL url = new URL(feedString);
    URLConnection connection = url.openConnection();
    
    HttpURLConnection httpConnection = (HttpURLConnection)connection; 
    int responseCode = httpConnection.getResponseCode(); 
    
    if (responseCode == HttpURLConnection.HTTP_OK) {
     InputStream in = httpConnection.getInputStream();
     
     factory = XmlPullParserFactory.newInstance();
     factory.setNamespaceAware(true);
     xpp = factory.newPullParser();
     
     xpp.setInput(in, "ISO-8859-1");
    }
   }
   
   return true;
   
  } catch (XmlPullParserException xe) {
   Log.e("RssReader", "Connection", xe);
   return false;
   
  } catch (IOException eio) {
   Log.e("RssReader", "Connection", eio);
   return false;
   
  }
 }
 
 private void readRss(int itemsToRead) {
  boolean insideItem = false;
  boolean insideTitle = false;
  boolean insidePubDate = false;
  boolean insideDescription = false;
  Property property = null;
  
  try {
   if (connect()) {
    int eventType = xpp.getEventType();
    
    while (eventType != XmlPullParser.END_DOCUMENT && itemsToRead >= 0) {
     if(eventType == XmlPullParser.START_TAG) {
      if (xpp.getName().equalsIgnoreCase("item")) {
       insideItem = true;
       property = new Property();
      } else if (insideItem && xpp.getName().equalsIgnoreCase("title")) {
       insideTitle = true;
      } else if (insideItem && xpp.getName().equalsIgnoreCase("pubDate")) {
       insidePubDate = true;
      } else if (insideItem && xpp.getName().equalsIgnoreCase("description")) {
       insideDescription = true;
      }
      
     } else if(eventType == XmlPullParser.END_TAG) {
      if (xpp.getName().equalsIgnoreCase("item")) {
       insideItem = false;
       data.add(property);
       --itemsToRead;
      }
      
     } else if(eventType == XmlPullParser.TEXT && insideItem) {
      if (xpp.getText() != null) {
       if (insideTitle) {
        property.setTitle(xpp.getText());
        insideTitle = false;
       } else if (insidePubDate) {
        property.setDate(xpp.getText());
        insidePubDate = false;
       } else if (insideDescription) {
        getDetails(property, xpp.getText());
        insideDescription = false;
       }
      }
      
     }
     
     eventType = xpp.next();
    }
   }
   
  } catch (XmlPullParserException e) {
   Log.e("RssReader", "Connection", e);
  } catch (IOException e) {
   Log.e("RssReader", "Connection", e);
  }
 }
 
 private void getDetails(Property property, String description) {
  int start = description.indexOf("");
  String imageURL = description.substring(start, end);
  property.setImage(imageURL);
  
  String desc = description.replaceAll("\\<.*?\\>", "");
  String[] parts = desc.split("\n");
  
  for (String line : parts) {
   for (Filter filter : Filter.values()) {
    if ((line.toUpperCase()).startsWith(filter.name())) {
     switch (filter) {
      case CATEGORY:
       property.setCategory((line.substring(filter.name().length() + 1)).trim());
       break;
       
      case BEDROOMS:
       property.setBedrooms(Integer.valueOf((line.substring(filter.name().length() + 1)).trim()));
       break;
       
      case BATHROOMS:
       property.setBathrooms(Integer.valueOf((line.substring(filter.name().length() + 1)).trim()));
       break;
     }
    }
   }
  }
 }

 @Override
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  if (totalItemCount - lastViewedPosition <= 3) {
   readRss(10);
  }
 }

 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState) {
 }

}
To hold the property we need to create a class. We called it Property(yes, terrible creative) and here we are going to save the information parsed from the rss.
public class Property {
 
 private String title;
 private String date;
 private String category = null;
 private int bedrooms = 0;
 private int bathrooms = 0;
 private String image = null;
 
 public String getTitle() {
  return title;
 }
 
 public void setTitle(String title) {
  this.title = title;
 }
 
 public String getDate() {
  return date;
 }
 
 public void setDate(String date) {
  this.date = date;
 }
 
 public String getCategory() {
  return category;
 }
 
 public void setCategory(String category) {
  this.category = category;
 }
 
 public int getBedrooms() {
  return bedrooms;
 }
 
 public void setBedrooms(int bedrooms) {
  this.bedrooms = bedrooms;
 }
 
 public int getBathrooms() {
  return bathrooms;
 }
 
 public void setBathrooms(int bathrooms) {
  this.bathrooms = bathrooms;
 }
 
 public String getImage() {
  return image;
 }
 
 public void setImage(String image) {
  this.image = image;
 }
 
 @Override
 public String toString() {
  return title;
 }

}

I will give you this to start thinking on and I will be back with the rest as soon as a can!!

Continue...

Thursday, 30 December 2010

Java conccurency -a brief overview

Java is typically compiled to bytecode language that it's later interpreted by the JVM(Java Virtual Machine). This approach has advantages and disadvantages. On one hand, application developers can "write once, run anywhere" as one of the most remarkable benefits, but on the other hand this approach also make Java a low performance programming language.

Java has been criticised for its performance compared to other languages and as a result an entire set of performance practices has been utilised.

Java bytecode can either be interpreted at run time by a virtual machine, or it can be compiled at load time or runtime into machine code which runs directly on the computer's hardware. Interpretation is slower than native execution, and compilation at load time or runtime has an initial performance penalty for the compilation. Although this concepts can explain much of the performance issues, there is something we can do to improve our programs performance.

Concurrent programming has always been difficult, and this is one of the most important deficiencies in the programmers knowledge since ever. However, the Java Team have been building packages to manage this in the painless manner. Nevertheless, it is necessary to know the basics to use this in an application and get the wanted results.

A computer system normally has many active processes and threads. This is true even in systems that only have a single execution core, and thus only have one thread actually executing at any given moment. Processing time for a single core is shared among processes and threads through an OS feature called time slicing.

A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space. Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads lives within a process and a process has at least one thread.

A computer system normally has many active processes and threads. This is true even in systems that only have a single execution core, and thus only have one thread actually executing at any given moment. Processing time for a single core is shared among processes and threads through an OS feature called time slicing.

A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space. Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads lives within a process and a process has at least one thread.

In order to answer some questions I will give my best(:)) and I will present a scenario to give some sense to all of these. Suppose you want to simulate a situation in which you have multiple threads asking for process some information and you want to maximise your resources by having multiple threads processing those request. The first that come to my mind is a producer-consumer scenario.

The next big question for me was which one would be the topic of this short application that allows me to make my point. And I thought in the most common situation. Threads trying to make a deposit or withdraw from one only account. That way you have multi-threading, control over the amount of threads that are consuming resources and data sharing where you can have data corruption.

Let's see some code:

First of all I will implement the Accout class:

public class Account {
    private static ReentrantLock lock = new ReentrantLock(true);
    
    private long balance = 200;
    
    public Account() {
    }
    
    public long transfer(long amount) throws CorruptedAccountException {
//        lock.lock();
//        try {
            if (balance < 0)
                throw new CorruptedAccountException();
        
            if ((balance + amount) < 0)
                return balance;
            
            // This emulate a complex task after the control and before the
            // operation that affect the shared variable.
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            balance += amount;
            
            return balance;
        
//        } finally {
//            lock.unlock();
//        }
    }
}
The Account class is created once only and then passed by value to all other classes as you will see further. This will gives us the perfect scenario to the data sharing and is the critical piece of code also. Pay attention to the method transfer that is where all happens. There is a control there that throws an exception if the balance is 0 or less. That way we will know if two threads access the same variable and leave inconsistent data there. Now we have the producer, which in this case is divided in two classes. DepositRequestsProducer that is responsible of add money to the account and WithdrawRequestsProducer which is responsible of withdraw from the account. Both are almost identical except for the sign of the amount(that was done like this to clarify the idea). Furthermore, it is important to note that both producers add transactions to a queue. This is not a minor detail, indeed this queue is the clue to prevent that the amount of transactions growth infinitely demanding more and more resources until an "out of memory" stop the program. That would the case if the producers add transactions more quickly that the consumer can process.
public class DepositRequestsProducer implements Runnable {
    
    private Thread tread;
    private BlockingQueue queue;

    public DepositRequestsProducer(BlockingQueue q) {
        queue = q;
        tread = new Thread(this);
        tread.start();
    }

    public void run() {
        try {
            Random randomGenerator = new Random();
            while (true) {
                int amount = randomGenerator.nextInt(100);            
                queue.put(new Long(amount));
                Thread.yield();
            }
            
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
public class WithdrawRequestsProducer implements Runnable {

    private Thread thread;
    private BlockingQueue queue;

    public WithdrawRequestsProducer(BlockingQueue q) {
        queue = q;
        thread = new Thread(this);
        thread.start();
    }

    public void run() {
        try {
            Random randomGenerator = new Random();
            while (true) {
                int amount = randomGenerator.nextInt(300);
                queue.put(new Long(amount*-1));
                Thread.yield();
            }
            
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
Note that both classes receives a queue. This queue is where the transactions produced by them are going to be put. Lately, the consumer will get the transactions from there to process them. On the other side of the desk we need the Consumer, which is responsible of process the transactions:
public class TransactionConsumer implements Runnable {
    
    private Thread tread;
    private BlockingQueue queue;
    private Account account;

    public TransactionConsumer(BlockingQueue q, Account account, int thread) {
        queue = q;
        this.account = account;
        tread = new Thread(this, "Consumer_" + thread);
        tread.start();
    }

    public void run() {
        long request, result = 0;
        Runtime s_runtime = Runtime.getRuntime();
        
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setRoundingMode(RoundingMode.DOWN);

        try {
            while (true) {
                request = queue.take().longValue();
                result = account.transfer(request);
                
                double freeMemory = (s_runtime.freeMemory() / 1048576);
                
                System.out.println("Calculated result after add " + request + " is " + result + " -- Free Memory: " +  numberFormat.format(freeMemory) + " / " + numberFormat.format(s_runtime.totalMemory() / 1048576));
            }
            
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        
        System.exit(0);
    }
}
This class also receives the queue in the constructor and open a thread to run as soon as a transaction were found in the queue. Lastly we have the class that makes it work:
import java.util.concurrent.ArrayBlockingQueue;

public class TestConcurrency {

    public static void main(String[] args) {
        Account account = new Account();
        final ArrayBlockingQueue queue = new ArrayBlockingQueue(40);
        
        for (int i = 0; i < 15; i++)
            new TransactionConsumer(queue, account, i);

     for (int i = 0; i < 30; i++) {
         new Thread(new DepositRequestsProducer(queue)).start();
         new Thread(new WithdrawRequestsProducer(queue)).start();
     }
    }
}

As you can see, when you run the program, the first thread executes the main method. Here an ArrayBlockingQueue is created as final and this is the first clue to analyse. This queue, as we mentioned above, protects the program of an infinite increase on the resource demand. Once the queue reaches the highest of it's capacity, all the threads that intend to put transactions in, will be put to sleep until a consumer takes a transaction out. At this moment all the threads that were sleeping waiting for a place in the queue, are wake up to compete for the queue. The implementation of this ArrayBlockingQueue is very useful because it avoids us a lot of work regarding monitoring threads.

Then we can see that a specified number of threads are created to run producers and consumers, and we are going to have at least 75 threads running as sub-processes of the main one.

Back in the Account class, all the threads will access transfer method code without any synchronisation. This will produce shared data corruption when two threads access to critical sections of code. Lets present a simple example:

Suppose that two threads(which we'll call A and B) access transfer method. Let say that balance variable is 125 and and the thread A is invoked with -100 and the thread B with -50. The thread A passes through the "if" that prevent negative balance and reaches the sleep command. Meanwhile, thread B passes through the balance check before the thread A updates the balance amount. Consequently, the balance will be updated by thread A leaving the balance in 25. When thread B reaches the balance update operation, the shared data gets corrupted.

This is the moment in which we realise that this is "a critical code". Here is when we have to add some protection to transfer method. In Account class you will see some commented lines of code which you should un-comment in order to see the difference.

I have added some extra lines in order to add some information related to memory use. Try to run the program with and without comments to see the difference.

Have luck!!!

Tuesday, 13 July 2010

A simple example of Java Reflection API

Java reflection API allows us to inspect classes on runtime. This is a very powerful tool but it's also very bad on performance. I use that technique on class converting. Suppose you have an entity you named User, and you don't want to serialize it to the client layer. You have to create a serializable class that has all the attributes you want to send back to the client and fill it with the entity content. This is a very good work for reflection.

I faced this problem on a project and I made a utility class to help resolve that. This is a very basic approach to a real solution but it works for me.

Let's see some code:

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.jflow.entities.GenericEntity;
import com.jflow.exceptions.EWConversionException;

public class ReflectionUtil {

    private static String capitalize(String s) {
        if (s.length() == 0) return s;
        return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }
    
 public static <T> T convertClass(GenericEntity source, Class<T> destinationClass) throws EWConversionException {
  T desteny = null;
  try {
   if (source == null) {
    return desteny;
   }
   
   desteny = destinationClass.newInstance();
   Class<?> sourceClass = source.getClass();
         
         Field destFieldList[] = destinationClass.getDeclaredFields();
   for (Field field : destFieldList) {
    String name = field.getName();
    Field sourceField = null;
    
    try {
     sourceField = getField(sourceClass, name);
     
     field.setAccessible(true);
     sourceField.setAccessible(true);
     field.set(desteny, sourceField.get(source));
     
    } catch(IllegalAccessException e) {
     try {
      String methodName = capitalize(sourceField.getName());
      Method method;
      method = getMethod(sourceClass, "get" + methodName);
      method.setAccessible(true);
      field.set(desteny, method.invoke(source));
      
     } catch (IllegalArgumentException e1) {
      e1.printStackTrace();
     } catch (InvocationTargetException e1) {
      e1.printStackTrace();
     } catch (IllegalAccessException e1) {
      e1.printStackTrace();
     } catch (NoSuchMethodException e1) {
      e.printStackTrace();
     }
    } catch (NoSuchFieldException e) {
     e.printStackTrace();
    }
   }
  
  } catch (SecurityException e1) {
   throw new EWConversionException(e1.getMessage());
  } catch (InstantiationException e1) {
   throw new EWConversionException(e1.getMessage());
  } catch (IllegalAccessException e1) {
   throw new EWConversionException(e1.getMessage());
  }
  
  return desteny;
 }
 
 private static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
  Field field = null;
  while (clazz != Object.class) {
       try {
        field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        break;
       } catch (NoSuchFieldException ex) {
        clazz = clazz.getSuperclass();
       }
  }
  
  if (field == null)
   throw new NoSuchFieldException(field + " no such a field.");
  
  // only needed if the two classes are in different packages
  return field;
 }
 
 private static Method getMethod(Class<?> clazz, String methodName) throws NoSuchMethodException {
  Method method = null;
  while (clazz != Object.class) {
       try {
        method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true); 
        break;
       } catch (NoSuchMethodException ex) {
        clazz = clazz.getSuperclass();
       }
  }
  
  if (method == null)
   throw new NoSuchMethodException(methodName + " no such a method.");
  
  // only needed if the two classes are in different packages
  return method;
 }
 
 @SuppressWarnings("unchecked")
 public static <T> HashSet<T> convertToHashSet(Collection<? extends GenericEntity> source, Class<T> destinationClass) throws EWConversionException {
  HashSet<T> returnCollection = new HashSet<T>();
  
  for (GenericEntity s : source) {
   T element = (T) ReflectionUtil.convertClass(s, destinationClass.getClass());
   returnCollection.add(element);
  }
  
  return returnCollection;
 }

 
 @SuppressWarnings("unchecked")
 public static <T> Map<Long, T> convertToMap(Collection<? extends GenericEntity> source, Class<T> destinationClass) throws EWConversionException {
  Map<Long, T> returnCollection = new HashMap<Long, T>();
  
  for (GenericEntity s : source) {
   T element = (T) ReflectionUtil.convertClass(s, destinationClass.getClass());
   returnCollection.put(s.getId(), element);
  }
  
  return returnCollection;
 }
 
 public static <T> List<T> convertToArrayList(Collection<? extends GenericEntity> source, Class<T> destinationClass) throws EWConversionException {
  List<T> returnCollection = new ArrayList<T>();
  
  for (GenericEntity s : source) {
   T element = (T) ReflectionUtil.convertClass(s, destinationClass);
   returnCollection.add(element);
  }
  
  return returnCollection;
 }
 
}

I also provide a couple of methods to help on more complex conversions, such as Map, List and Sets. GenericEntity is an abstract class from where all entities inherit.

I made some performance test with a class that has 5 attributes, based on the supposed that both has the same attributes. As a mean I get 2 milliseconds for the traditional way of fill one class with the content of the other one, and on the other hand an 8 milliseconds mean using the utility class.

I think that this is very useful for non real time applications and avoid you from being specific converting code for each class you need to send back to the client layer.

This is a wide open discussion field and most of you should have different opinions. The aim is to present one way of doing this. If you have buts or other ways to do this please don't hesitate to post a comment.

If you want to get more in deep details on "Java Reflection API" you can read this tutorial. He gave very good explanations on this concern.

See you!!