Posts tagged Java

svncheckout

Shared Talend Open Studio Job Repository with Subversion

3

Talend Open Studio is an open source Data Integration/ETL tool that allows creating complex jobs through an easy-to-use graphical interface based on the Eclipse platform.  It allows for rapid development through its hundreds of prebuilt components to source and target systems.

However, as great as Talend is, there is one caveat; the FREE version does not come with version control and a shared job repository integrated into the product.

Problem

This means that if one developer created a job design, and a second developer needs to make modifications to it in the future to handle new requirements, that second developer would not able to do it because that job is in another’s developer workstation.

Prerequisites

  1. You will need to have a Subversion Repository (SVN Server).
  2. You will need a Subversion client, TortoiseSVN. This will allow you to commit code (or any other type of file you want to version) and checkout code from Subversion server. I recommend that everybody is on the same version, Iuse the latest version at the moment, which is 1.7.5
  1. In order to develop new and or maintain existing Talend jobs you will need Talend Open Studio. You can also download it from Sourceforge.net (no questions asked). We are using version 5.0.2. I would also recommend that everybody is on the same version.
  1. In order to run jobs from the command line (like they are going to run once deployed to the server) you are going to need the Java JDK 1.5 or greater on your machine.  Instructions on how to set up java on your machine can be found here

Solution

Here, I will show you how to integrate Talend with SVN so that an entire team can work on the same jobs code base.

  1. Checking Out a Talend Project from a Shared Job Repository
  2. I Cannot View all my Jobs, Contexts, and Metadata in my  TOS!!!
  3. Creating a Shared Job Repository
  4. Checking In New Changes to a Shared Job Repository
  5. Updating your local workspace
  6. Resolving File Conflicts

Checking Out a Talend Project from a Shared Job Repository

  1. If you have TOS open, close it.
  2. Go to your Talend workspace. In my case(C:\Talend5.0.1\TOS_DI-Win32-r74687-V5.0.1\workspace)
  3. Right click with your mouse->SVN Checkout…
  4. Put the SVN Server URL of your Repository:
     
  5. The Talend Project from the server should be in your workspace now:

  6. Open TOS. You should see the project listed as follows:
     
  7. All the Jobs associated to that Project should be visible. If not, read the next section of the tutorial.

I cannot view my Jobs, Contexts, and Metadata in my TOS!!!

After checking out an entire Project from Subversion or doing an SVN Update on an existing Project in your workspace it is possible that your GUI has not picked up the changes. You can do two things to take care of that:

  1. Do a Refresh of the Repository left panel
     
  2. Do an Import Items. From TOS, Right click on Job Designs->Import Items
     

Creating a Shared Job Repository

  1. Create a Talend Project. This Talend project will house multiple Jobs. (Remember not to confuse  Project with Job)
  2. Navigate to your Talend workspace. Right clickon the project->TortoiseSVN->Import…

  3. The following prompt will come up. Enter your repository location and a message
     
  4. You should see the following message:

  5. Type your SVN Repo URL on the browser and verify that contents are there

Checking In New Changes to a Shared Job Repo

Rule of Thumb: ALWAYS, ALWAYS, ALWAYS before checking in anything, do an SVN Update first and resolve any existing conflicts. Read the next section for how to resolve conflicts.

If you do not have any conflicts to resolve, you are ready to commit your changes. Do as follows:

  1. Right Click on the Project through your C:/->TortoiseSVN->Check For Modifications
    Note:  You can skip this step and go to Step 2.

    This will look for modifications locally.

  2. Right click on your project in your workspace->SVN Commit…

  3. Click’OK’. Now other developers should be able to do an SVN Update and work off of the latest changes.
     

Updating your local Workspace with latest stuff from the Job Repo

  1. Right click your Project folder in C:\ drive->SVN Update

    In this case there was nothing new in the server, so nothing was updated. If you would have got conflicts, please read the next section. 

Resolving File Conflicts

When doing shared development with Version Control Systems (Subversion, Git, CVS, etc…) it could be that another person has edited a common file that you have also edited. What we want here is to keep the other developer’s change as well as ours. We have to resolve a conflict. This can be done in 5 easy steps.

  1. Go to your Project folder (C:/path_to_your_talend_workspace_project_folder) and do Right Click/SVN Update. This will update any local files with newer ones from the server
  2. If it encounters a file that you have also edited, it will raise a conflict. YOU MUST RESOLVE IT!!
  3. Right Click on the Conflicted file and select Edit Conflicts.  The TortoiseMerge editor will come up:
  4. To merge files do as follows:
  5. Finally, you must mark the file as resolved

What if I want to accept their file and Override mine?

Do Right Click on Conflicted file/Resolve conflict using ‘theirs’

or

Do Right Click on Conflicted file/Resolve conflict using ‘mine

It is a little bit cumbersome, but once you get the hang of it, it is not that bad. It is unfortunate that they do not release the Talend Open Studio version with hooks to Subversion and Git right out of the box. I doubt, that organizations are strictly buying their product Talend Integration Studio based mostly on the Shared Repository.

Oracle Forms & Reports Login

Achieving Transparency with JNDI

0

Enterprise Web Applications are distributed systems. Typically, enterprise solutions are composed of many computers with different Operating Systems, one or more data sources (in many occasions from different vendors) and even of different architecture (relational, hierarchical, dimensional, ISAM, etc…). One important thing to remember is that to the end user it looks like one system.

The advantages of distributed systems are the different types of Transparency:

  1. Enterprise resources should be accessible and how they are accessed should be hidden from the user.
  2. The communication protocols the web application uses (HTTP, SOAP, JMS, JNDI etc…) to interact with other services or applications should be hidden from the user.
  3. The user should not be able to tell that different resources are scattered across the network, neither where they are located.
  4. The user should not have any critical information that might compromise the security/integrity of a subsystem.
  5. Distributed applications should be easy to extend, repair, or even move components around.

In this post I am going to talk about how to achieve Access, Location and Migration Transparency with JNDI (Java Naming Directory Interface).

Problem: Have you ever seen this at your Enterprise?

Oracle Forms & Reports Login

This is a typical log in screen to enterprise applications that use Oracle Forms & Reports technology. Even though this is old technology you will be surprised to see how many enterprises are running business critical applications under this platform; there is nothing really wrong with that, just that there are better enterprise application development platforms in the market than Oracle Forms and its successor APEX. For example J2EE nowadays most commonly known as JavaEE and .NET.

The main disadvantages are as follows:

  1. Oracle Forms only work with Oracle RDBMS (PL/SQL as the language).
  2. Migrating to a new database would require to rewrite your entire business logic to the platform of choice (Java, .NET, T-SQL, SQL PL, Postgres PL, etc…).
  3. Cannot benefit from current agile software trends of Test Driven Development and Continuous Integration (at least to my knowledge).

However,  the biggest problem (what we are going after here according to the topic of the post from the screenshot above) is as follows:

  1. The database text field.
  2. The Database Administrator (DBA) will have to maintain as many database user accounts as users are in the application.

What problems do you see?

  • Since when an end user should know the database name to connect to?  You have violated Access Transparency here.
  • If the application has 100 users for example. Will the DBAs have to maintain 100 users in QA and PROD environments? That sounds like a lot of tedious work and opportunity for mistakes.
  • What happens if you encounter a tech savvy user that manages to create an ODBC connection to your production database? Now you have a big security problem here.
  • Did you enforce all UPDATE, DELETE logic to go through Stored Procedures? Have you given the database user accounts rights to execute Stored Procedures only?
  • If not, the user accounts to the application now have direct rights to execute UPDATES and DELETES on certain tables. Now you have a big security problem here.

A lot of these problems can be easily solved in JavaEE by using JNDI.

Solution: Setup a JNDI Connection Pool with GlassfishV3 App Server

To illustrate the solution I have installed the following components:

  1. GlassFish Server Open Source Edition 3.1: A full blown Java EE 6 compliant application server.
  2. PostgreSQL Database Server 9.0.4: The world’s best open source database.

Note: I have chosen these two components but any other RDBMS (MySQL, MSSQLServer, Oracle, DB2, etc..) and any of these app servers (JBoss, Oracle WebLogic, Websphere) would have a similar way of setting up a JNDI Connection Pool.

Do as follows:

  1. Download the appropriate PostgreSQL JDBC driver jar and place it in C:\glassfish3\glassfish\lib.
  2. Start GlassFish application server by exectuting startserv.bat located at C:\glassfish3\glassfish\bin (or wherever you decided to install it).
  3. Open up a browser tab and go to the GlassFish Administration Console. http://localhost:4848/
  4. In the left navigation menu click on the New… button under Resources/JDBC/JDBC Connection Pools .
  5. Enter a Pool Name and select the appropriate database drivers as follows (Click on the image to enlarge):Create a Connection Pool
  6. Click Next and fill Step two as appropriate based on your settings as follows (Click on the images to enlarge):

    Insert Your Database Vendor Settings

    Insert Your Database Vendor Settings

  7. Click the Ping button. You should see a message as follows:
  8. Click the Finish button.
  9. Now we have created Connection Pool Successfully. Our next step is to make it available through a logical name with JNDI.
  10. In the left navigation menu click on the New… button under Resources/JDBC/JDBC Resources.
  11. Enter a JNDI Name and select the Connection Pool that we have just created and Click OK (Click on the image to enlarge):
    Bind JNDI name to DataSource Connection Pool

Advantages

With this new setup we have the advantages as follows:

  • Access Transparency: We are not giving any clue how the resource is accessed. Now nobody knows the database name.
  • Location Transparency: Only GlassFish administrators and DBA(s) now know where the resource is actually located. Even the developers would not know where the database really is (I know this does not actually happen) but there will be nothing in the application code or configuration files that will unveil that.
  • Migration Transparency: The database now can be moved from one server to another, the DBA might want to change the default port, or the user name and password need reset. Any of these changes will not affect the application at all because it can be manged by an administrator through the GlassFish Admin Console.
  • LDAP Authentication: With this setup we can now delegate the Authentication piece of the application to an LDAP service, which would allow for Single Sign On across the Enterprise.
  • 1 Database User Account Only per Connection Pool: We now have reduced all the database user accounts to one and only one.
  • Same JNDI name, multiple environments: In an Enterprise you will most likely have a GlassFish QA instance and a GlassFish PROD instance. If you set up your JNDI Name to be the same in both (jdbc/grailsRocksApp in our example) you can deploy interchangeably without having to do any changes anywhere.

 

 

Configuring your Spring JDBC application to use JNDI

If you are using Spring JDBC to persist you database, this is what you have to do to obtain a DataSource through JNDI. Usually, in Spring web applications you will separate you context xml files in several as follows:

  • appName-servlet.xml
  • appName-datasource.xml
  • appName-services.xml
  • appName-security.xml

In the appName-datasource.xml put the following snippet:






Configuring your Spring + Hibernate app to use JNDI

If you are using the Hibernate in your Spring application to handle persistance. You would do as follows:







     
         
     



           
           
                               
                  com/companyName/appname/domain/Student.hbm.xml
                  com/companyName/appName/domain/Course.hbm.xml
               
           
           
            
              false
              org.hibernate.cache.NoCacheProvider
              hibernate.grailsRocks
              false
              org.postgresql.Driver
              1
              thread
              postgres
              org.hibernate.dialect.ProgressDialect
              true
              true
              true
              true
              1
              pool_postgres
              yes 'Y', no 'N'
              false
              
              
              true
            
            
        

Configuring your Grails application to use JNDI

If you are developing in Grails and want to use JNDI for connection pooling, you would do as follows in the DataSource.groovy:

dataSource {
     pooled = true
}

hibernate {
    cache.use_second_level_cache=true
    cache.use_query_cache=true
    cache.provider_class='net.sf.ehcache.hibernate.EhCacheProvider'
}

// environment specific settings
environments {

    production {
        dataSource {
            jndiName="jdbc/grailsRocksApp"
        } 
    }
}

 

Conclusions

Asides from the advantages mentioned above we also get the following:

  • Connection pooling management and distributed transactions: If you use a regular DataSource like illustrated in the Spring JDBC example above, it’s ok for very small applications because it is not thread-safe, it’s single threaded. The server will lock down other requests, this will impact performance. So if you are in a concurrent environment you are better off using JNDI as the application server take care of handling connection pools threads for you.
Factory Method

How to use “Factory Method”

2

The Factory Method design pattern is a creational design pattern. This means that its main objective is to create objects. The official definition by GOF is as follows:

Define an interface for creating an object, but let the subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Note 1: By “decide” in the definition above it does not mean that the subclass magically decides which object to create (at least not in a parameterized version of the Factory Method). The decision actually happens in the client; however, the work of creating the appropriate object that the client is going to work with is done by the subclass that overrides the Factory Method.

Note 2: This pattern relies on inheritance for creating objects. The current trend is to use the Abstract Factory Pattern, which relies on composition.

Note 3: By “client” I mean the calling code, the final user of the API that makes up the subsystem.

The Problem

Consider a simple application that deals with vehicles with the following hierarchy in the mind map below:

Factory Method

Question: What would happen if we want to create a particular type of vehicle and we do not use any kind of Factory Pattern?

That we would be giving the client the responsibility of having to know how to instantiate a particular type of Vehicle. As far as the client is concerned it just wants a Vehicle, then it’s going to do whatever he wants with it.

Question: What would happen if we add many more types (Car, Truck, Bike) and many more subtypes (Van, Sedan …)?

In this example it may not be as obvious as we only have three types of Vehicles (Car, Truck, and Bike) and two specific implementations under each. But if we had ten different cars, trucks, and bikes then the amount of if/else logic that you would have to do in the client in order to instantiate the right type would be quite tedious. This is considered boilerplate code at the same time that is difficult to maintain.

Question: What if you want to add a new type of Vehicle (e.g a Boat)?

If you do not use the Factory Method or other Abstraction layer you would have to make changes to the client to support that.

Solution

The Factory Method

Since the definition of the Factory Method states that the purpose is to defer instantiation of an object in the family to a subclass, then we have to make the class that will contain the factory method abstract. Also to ensure that subclasses are the ones really responsible for the creation of a particular object (in our case it will be a Vehicle) we have to provide with an abstract method, this way subclasses must provide the implementation. This method is what is popularly known as the factory method. It usually takes the name of createXYZ or newXYZ (that seems to be the industry standard for what I have seen) . It looks as follows:

package factorymethod;

public abstract class VehicleFactory {

	//Factory method
	abstract Vehicle newVehicle(String type);

}

The Common Interface

The client should work with a known interface, this way it will allow us to change the subsystem transparently. It will look as follows:

package factorymethod;

import java.util.List;

public abstract class Vehicle {

    public abstract List<String> getFeatures();

    public abstract List<String> getSpecs();
}

The Factory

A Car Factory would be responsible for knowing all the types that fall under the category of Car. Do you see how much cleaner is to have the branching logic in this factory rather than having a big method somewhere with all types in there? It would look as follows:

package factorymethod;

public class CarFactory extends VehicleFactory {

	@Override
	Vehicle newVehicle(String type) {

       if(type.equals("Sedan")){
            return new Sedan();
       }else{
            return new Van();
       }
	}
}

The Product

This is what the client asked for:

package factorymethod;

import java.util.List;

public class Sedan extends Vehicle{

    //Put some specific properties of a SEDAN here

    //Put some other specific methods of a SEDAN here  (To differentiate from Van for example)

    @Override
    public List<String>getFeatures() {

        //Put code to query your Car database here
        return null;
    }

    @Override
    public List<String>getSpecs() {

        //Put code to query your Car database here
        return null;
    }
}

The Client

Notice how the client uses the appropriate factory to go get the specific type of product. If the client wanted a Bike for the example, the Car and Truck factories would be ignored. Also notice that since the client gets a generic Vehicle product you can add many more specific products transparently without affecting the client code. It looks as follows (You could improve the client using Reflection like done at the end of this other post) :

package factorymethod;

public class Starter {

	public static void main(String[] args) {

		VehicleFactory vehicleFactory = new CarFactory();
		Vehicle vehicle = vehicleFactory.newVehicle("Sedan");
        vehicle.getFeatures();
		vehicle.getSpecs();
	}
}

Now you could repeat what I have done above for the BikeFactory, and TruckFactory and its corresponding products as follows (Click on the image to enlarge):

Factory Method UML

Important: Your Specific “Products” should really be different (algorithm or logic wise)

While studying this pattern carefully from Head First Design Patterns (p.129) there was something that bothered me with their Pizzas example. If you look at all their specific Pizzas there wasn’t really any difference between the products, only String values!!! Yes that is different but what good is that in real life? If all that was read from a database for example you could get away with one class only. There was no need for 8 different Pizza types.

So my point is to make sure that you really have a different algorithm or logic in each specific product. Otherwise you will have added DRY (Don’t Repeat Yourself) in your application. (Unless I am totally missing something here :) )

In our example we could say that we originally started our application supporting Cars only (Sedans and Vans), but then our application became popular and we decided to buy two existing databases that had support for Trucks(Pickup and Commercial) and Bikes(Scooter and DirtBike). Then it is safe to say that we need all these concrete objects as each getFeatures() and getSpecs() would contain an specific query targeting that particular data model and RDBMS.

Conclusions

Similar to the Adapter pattern where the main goal was to decouple the client from the actual implementation by giving it a known interface, the Factory Method Pattern also gives us that kind of flexibility. You should use a factory method:

  1. When you want to hide object creation knowledge from the client.
  2. When you want the client to always get a known interface. In this case, it will be an abstract object.
  3. When you want to add multiple implementations transparently in the future without affecting the client(s) API.
  4. To avoid branching “spaghetti code” when you have multiple variations of an object and you try to solve it by means of a lot of “if/elses” in a single location.
  5. When you have multiple variations of a particular object and you do not have a default one.
  6. It is also very good to illustrate how Polymorphism works.

Disadvantages:

  1. It depends on inheritance, so changes to the superclass can break existing code in subclasses. Inheritance usually requires thorough testing so Joshua Bloch in Effective Java recommends to use Composition over Inheritance.
  2. Joshua Bloch also recommends to use inheritance only when classes are designed for inheritance. (The factory method is designed for inheritance, so not really a disadvantage).
  3. This pattern is only good for a hierarchy of three levels. I have tried solving this with more levels and I had to much more inconveniences than advantages (had to create intermediate empty classes that were not bringing more information). For such situations, you should look into the Builder Pattern.
Adapter Pattern

How to use the Adapter pattern

4

The definition of the Adapter design pattern according to GOF (Gang Of Four) in Design Patterns: Elements of Reusable Object-Oriented Software is as follows:

Converts the interface of class into another interface the clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. (p.139)

To illustrate it we are going to start with a code base and then try to integrate it to an “external” code base using the Adapter design pattern.

The adapter pattern comes in two flavors:

  1. Object Adapter: Uses interfaces to benefit from polymorphism; this flavor is used if your language of implementation is Java.
  2. Class Adapter: Can be used in languages that support multiple inheritance, this technique can be used if your language of implementation is C++.

In this example we are going to look at the Object adapter implementation.

Note 1: I interpret that “clients” in the definition by Gang of Four above means the calling code. In some instances “client” might also refer to the starting code base.

Note 2: “Interface” in the definition by Gang of Four above means properties and methods of a class. But it can also be a proper Java interface.

Requirements

Conceptually both systems that you are trying to integrate must have a coherent conceptual correspondence.

Implementation

A real life example of adapters I faced is when I have purchased Europe based electronic devices that I later had to use in the US. In order to power them up, or charge them up depending on the device I had to get a Targus Travel AC Power Adapter. Recall that the adapter worked in that case because even though the interfaces were different, the problem domain was the same.

Let’s say that we have a program that works with US based heating devices; its reputation is so good that it has become a market leader, so now we want to go global and sell it in Europe and other parts of the world.

Starting Code Base

Because we are good OO coders, we code to interfaces. Here is our interface for US heating devices:

package adapter;

public interface USHeatingDevice {

     public int voltage();
     public int frequency();

}

Here is an implementation of our interface:

package adapter;

public class TowerHeater implements USHeatingDevice {

    public int voltage() {
        return 120;
    }

    public int frequency() {
        return 60;
    }
}

Here is what I interpret as the client per Note 1 above:

package adapter;

public class Starter {

       public static void main(String[] args){

          USHeatingDevice usHeatingDevice = new TowerHeater();
          System.out.println(usHeatingDevice.voltage() + " V");
          System.out.println(usHeatingDevice.frequency() + " Hz");

       }
}

Running the program produces the following output:
120 V
60 Hz

Now we want/need to expand our program to work with foreign heating devices manufactured in Europe, South America, Asia etc. The problem is that their voltage and frequency are not the same, so our program will not work. Imagine that there is a vendor that has already developed an interface that can be hooked into our program so that it can work internationally. The code is illustrated below.

Vendor Code Base

Because the vendor also uses good OO techniques, here is their interface for non US heating devices:

package adapter.vendor;

public interface NonUSHeatingDevice {

    public int tension();

    public int hertz();
}

Here is their European implementation:

package adapter.vendor;

public class EUTowerHeater implements NonUSHeatingDevice {

    public int tension() {
        return 230;
    }

    public int hertz() {
        return 50;
    }
}

Notice two things here:

  1. The voltage and frequency have different values.
  2. The interface methods developed by the vendor have different names.

Problem

In order to use our program using the non US implementation we would have to find all our places where we make calls to voltage() and frequency() and put some sort of if/else logic to support calling tension() and hertz() methods when using the program in Europe.

Solution

Well that could be quite tedious, couldn’t it? Here is where the design pattern comes into place; the goal is to write and adapter that will implement our current existing interface (USHeatingDevice) but in reality will be executing an implementation of (NonUSHeatingDevice) interface. This technique will allow us to keep voltage() and frequency() calls throughout or code  and we will only have to make a small change in the calling code, the client.

Note: Some authors state that the adapter pattern allows you to not do any code changes in the “client” once you have created the adapter class see (p.237) of Head First Design Patterns. I completely disagree with that and you will see it in the following snippets.

First let’s create the adpater:

package adapter;

import adapter.vendor.NonUSHeatingDevice;

public class HeaterAdapter implements USHeatingDevice {      

     private NonUSHeatingDevice europeanHeatingDevice;     

     public HeaterAdapter(NonUSHeatingDevice europeanHeatingDevice){

         this.europeanHeatingDevice = europeanHeatingDevice;
     }

     public int voltage() {

         return europeanHeatingDevice.tension();
     }  

     public int frequency() {  

         return europeanHeatingDevice.hertz();
     }
}

We see as follows:

  1. The Adapter class implements our known interface (USHeatingDevice), the one we are used to work with (because it will be the one that the client will continue to work with).
  2. The Adapter class has a data member that is of type that we are adapting to (NonUSHeatingDevice).
  3. The implemented methods call the matching methods in the non US heating device interface.

As you can see we are dressing up the HeaterAdapter by making it look like a US heater device, but really behaving like a non US heater device.

Now let’s make the changes to the client to work with the HeaterAdapter that we have just created:

package adapter;

import adapter.vendor.EUTowerHeater;
import adapter.vendor.NonUSHeatingDevice;

public class Starter {

       public static void main(String[] args){

          USHeatingDevice usHeatingDevice = null;
          NonUSHeatingDevice euTowerHeater = null;

          if(args[0].equals("US")){

            usHeatingDevice = new TowerHeater();

          }else if(args[0].equals("EU")){

            euTowerHeater = new EUTowerHeater();
            usHeatingDevice = new HeaterAdapter(euTowerHeater);

          }

          System.out.println(usHeatingDevice.voltage() + " V");
          System.out.println(usHeatingDevice.frequency() + " Hz");

       }
}

Notice the changes in the client from the original Starter.java; Pay attention to lines 19 and 20, we go through the adapter to instantiate a USHeatingDevice, which will behave as a non US heating device. As we can see on lines 24 and 25 The rest of the program is still working with the same interface as it was using before the vendor code was integrated into our application.

If we were to run this program with the EU command line argument we would get the result as follows:
230 V
50 Hz

Adapter Pattern as an abstraction layer

Another advantage of this pattern is that many implementations of the adaptee (vendor interface) could be added by the vendor and we would not have to touch a line of code in our HeaterAdapter.java thanks to Polymorphism.

Let’s say that the vendor add implementations of their non US heating device interface for countries such as Jamaica, Libya, and Colombia which have different electric power specification.

package adapter.vendor;

public class JamaicaTowerHeater implements NonUSHeatingDevice {

     public int tension() {
         return 110;
     }

     public int hertz() {
         return 50;
     }
}

The colombian implementation….

package adapter.vendor;

public class ColombianTowerHeater implements NonUSHeatingDevice {

    public int tension() {
        return 110;
    }

    public int hertz() {
        return 60;
    }
}

…and the Libya implementation

package adapter.vendor;

public class LibyaTowerHeater implements NonUSHeatingDevice {

    public int tension() {
        return 127;
    }

    public int hertz() {
        return 50;
    }
}

Let’s see the changes we have to make to the client, without touching the adapter at all.

package adapter;

import adapter.vendor.*;

public class Starter {

     public static void main(String[] args) {

        if (args.length > 0) {

            USHeatingDevice usHeatingDevice = null;

           if (args[0].equals("US")) {

                usHeatingDevice = new TowerHeater();

           } else if (args[0].equals("EU")) {

                NonUSHeatingDevice euTowerHeater = new EUTowerHeater();
                usHeatingDevice = new HeaterAdapter(euTowerHeater);

           } else if (args[0].equals("JM")) {

                NonUSHeatingDevice jamaicaTowerHeater = new JamaicaTowerHeater();
                usHeatingDevice = new HeaterAdapter(jamaicaTowerHeater);

           } else if (args[0].equals("CO")) {

                NonUSHeatingDevice colombianTowerHeater = new ColombianTowerHeater();
                usHeatingDevice = new HeaterAdapter(colombianTowerHeater);

           } else if (args[0].equals("LY")) {

                NonUSHeatingDevice libyaTowerHeater = new LibyaTowerHeater();
                usHeatingDevice = new HeaterAdapter(libyaTowerHeater);

           } else {
               System.out.println("You must pass an apppropriate region parameter");
           }

           System.out.println(usHeatingDevice.voltage() + " V");
           System.out.println(usHeatingDevice.frequency() + " Hz");

        }

     }
}

As you can see supporting new functionality is just as easy as adding the highlighted lines above.

The UML diagram below summarizes our example:

Adapter Pattern

Adding flexibility to the Adapter Pattern

Thanks to Lariza Saenz a colleague from JavaHispano user group for pointing this out in the post comments. Let’s suppose that you are not interested in implementing all the methods of the interface. You could do it as follows:

1. Implement the method in the HeaterAdapter class and throw an UnsupportedOperationException.
2. or create an abstract class AbstractHeaterAdapter.

Let’s illustrate step #2. The AbstractHeaterAdapter class would look as follows:

package adapter;

public abstract class AbstractHeaterAdapter implements USHeatingDevice {

	@Override
	public int voltage() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int frequency() {
		// TODO Auto-generated method stub
		return 0;
	}

}

The implementation class would looks as follows:

package adapter;

public class Starter2 {

	public static void main(String[] args) {

		USHeatingDevice usHeatingDevice = new AbstractHeaterAdapter(){

			public int voltage() {

				return 125;
			}
		};

		System.out.println(usHeatingDevice.voltage());

    }
}

A real world example of this technique can be found in the java.awt.event package. Every listener interface (e.g MouseListener) has its correspondent adapter (MouseAdapter). The MouseAdapter is an abstract class that implements the MouseListener interface. So when you want to attached a mouseClicked event to a button you an either do it through a MouseListener or a MouseAdapter. If you do it trhough the MouseListener you will have to implement all the methods defined in the interface (mouseClicked, mousePressed, mouseReleased, mouseEntered). But what happens if you are only interested in one of the methods? Then you would use a MouseAdaper and provide the implementation for the method(s) that you are interested only similar to the example in Starter2.java above.

Bonus: Improving the client

Bladimir Rondon another colleague from the JavaHispano users group has suggested to use a ResourceBundle and reflection to clean up the if/else ugly code in Starter.java . The main advantage of using a resource bundle is as follows:

  1. You will be able to add implementations and not have to do any client code changes (except for the first time when you add support for the NonUSHeatingDevice).
  2. You will only have to make entries in the implementation.properties file for each new implementation.

The implementation.properties file will look as follows:

US=adapter.TowerHeater
EU=adapter.vendor.EUTowerHeater
CO=adapter.vendor.ColombianTowerHeater
JM=adapter.vendor.JamaicaTowerHeater
LY=adapter.vendor.LibyaTowerHeater

The Starter.java will look as follows:

package adapter;

import java.util.ResourceBundle;

import adapter.vendor.NonUSHeatingDevice;

public class Starter { 

	public static void main(String[] args) { 

		if (args.length > 0) { 

			ResourceBundle resBun = ResourceBundle.getBundle("implementations");

			USHeatingDevice heatingDevice = null;

			//If creation of a USHeatingDevice fails, then try to create a NonUSHeatingDevice
			try {
				heatingDevice = (USHeatingDevice) Class.forName(resBun.getString(args[0])).newInstance(); 

			} catch (Exception e){

				NonUSHeatingDevice foreignDevice = null;
				try {
					foreignDevice = (NonUSHeatingDevice) Class.forName(resBun.getString(args[0])).newInstance();
					heatingDevice = new HeaterAdapter(foreignDevice);
				} catch (Exception z){
					System.out.println("Check your properties file");
				}

			} 

			System.out.println(heatingDevice.voltage() + " V");
			System.out.println(heatingDevice.frequency() + " Hz"); 

		} else {
			System.out.println("You must pass an apppropriate region parameter");
		}
	}
}

Now you could put a Facade Pattern to hide all the ugly try/catch out the main class into an static method in another class to improve this further.

Conclusions

The adapter pattern can be used in the situations as follows:

  1. To match methods of a new interface that has similar behavior but different method names.
  2. To allow one and only one adapter to work with many different implementations of the Adaptee.
  3. To provide custom behavior for a desired method(s) of the interface without having to implement all methods of the contract.

It is also good for:

  1. Illustrating the power of Polimorphysm.
  2. Promoting the good OO technique of coding to interfaces.
Environment variables set up

How to set up your machine for Groovy & Grails development

1

The set up

In order to be able compile and run java, groovy, and grails applications from the command line you will need to add the path to the binaries to the Environment variables (Right click on “My Computer” icon, click on the “Advanced” tab, the “Environment Variables” button should be at the bottom.

  1. Install JDK 1.6
    • Download latest JDK from http://java.sun.com
    • Create a JAVA_HOME system environment variable
    • Append ;%JAVA_HOME%\bin; to the Path environment variable
  2. Install latest Groovy
    • Download the latest groovy from http://groovy.codehaus.org/Download
    • Create a GROOVY_HOME system environment variable
    • Append ;%GROOVY_HOME%\bin; to the Path environment variable
  3. Install Grails
    • Download the latest grails from http://www.grails.org/Download
    • Create a GRAILS_HOME system environment variable
    • Append ;%GRAILS_HOME%\bin; to the Path environment variable

The environment variables set up should look like this (Replace the Value accordingly based on the location of your install).

The Path in your system environment variables as well should look as follows:

;%JAVA_HOME%\bin;%GROOVY_HOME%\bin;%GRAILS_HOME%\bin;

Note: You can copy paste this and append it at the end of your Path variable, be very careful and do not delete any existing entries unless you know what you are doing

The verification

Open up a command prompt and type the commands below.

  1. java -version
  2. groovy -v
  3. grails -version

If you installed all three components correctly, you should see something very similar to this screen shot.

javap SoccerPlayer

Objects: equals() + hashCode() + toString() methods

0

I have finally decided to start my own blog, my first post will be about some basics of Java objects.

During my years of experience in the field I have come across peers from a wide variety of seniority levels that do not know or do not know how to apply correctly basic concepts.
Here I will talk about the need of overriding the default implementations of the methods as follows:

  • toString()
  • equals()
  • hashCode()

These methods  are inherited from the parent of all parents the java.lang.Object class.

Let’s suppose that we have a SoccerPlayer.java class defined as follows:

public class SoccerPlayer {

    private String name;
    private String lastName;
    private int jerseyNumber;
    private String teamName;

    public String getName() {
        return name;
    }

    public String getLastName() {
        return lastName;
    }

    public int getJerseyNumber() {
        return jerseyNumber;
    }

    public String getTeamName() {
        return teamName;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public void setJerseyNumber(int jerseyNumber) {
        this.jerseyNumber = jerseyNumber;
    }

    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }

}

Notice how we use the access modifier keyword private and provide the set/get access methods with the public modifier. This is a best practice for two reasons:

  1. To make sure that other objects in your program are not allowed to change the data member variables directly
  2. To prohibit a subclass from inheriting (possibly a very business critical data member)

Enough fundamentals, back to the goal of the post. Let’s create now a class named Starter.java as follows:

public class Starter {

    public static void main(String[] args){

        SoccerPlayer sp = new SoccerPlayer();
        sp.setName("Zinedine");
        sp.setLastName("Zidane");
        sp.setJerseyNumber(5);
        sp.setTeamName("Real Madrid");

        System.out.println(sp);
    }
}

We will get something like this in the console: SoccerPlayer@19821f which is the memory address of the object, very useless.

Overriding the toString() method

Add the following snippet to the SoccerPlayer.java

  @Override
   public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("SoccerPlayer [jerseyNumber=");
		builder.append(jerseyNumber);
		builder.append(", lastName=");
		builder.append(lastName);
		builder.append(", name=");
		builder.append(name);
		builder.append(", teamName=");
		builder.append(teamName);
		builder.append("]");
		return builder.toString();
	}

Notice two things here:

  1. @Override annotation (Annotations were introduced in Java 5.0). This tells the compiler that you are trying to override this method. It is helpful because if you miss type it, or miss type the method signature then the compiler says oh…wait a minute this is not an existing method in the base class, please check the signature. That’s all, nothing major.
  2. StringBuilder use over a StringBuffer or a regular String object: StringBuilder class was also introduced in Java 1.5, it’s an exact copy of StringBuffer but its methods are not thread safe, therefore there is a gain in performance when using StringBuilder over StringBuffer.

Run your main class again by typing the command java Starter. You should get a String representation of the object like this:

SoccerPlayer [jerseyNumber=5, lastName=Zidane, name=Zinedine, teamName=Real Madrid]

Over the years I have seen many POJOS (Plain Old Java Objects), that is entitty objects with sets and gets that did not have the toString() method overridden, they were not printing it of course but I still think is a  must have at least for debuging and testing purposes

Overriding the equals() method

We know that two compare primitive types you use the == operator. But how do you compare a more complex data type? You have to override the default implementation of the equals() method provided by the superclass java.lang.Object. This is what a typical implementation of the equals() method  will look like for the SoccerPlayer class:

@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		SoccerPlayer other = (SoccerPlayer) obj;
		if (jerseyNumber != other.jerseyNumber)
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (teamName == null) {
			if (other.teamName != null)
				return false;
		} else if (!teamName.equals(other.teamName))
			return false;
		return true;
	}

All these code is saying is the following:

The first if states that if the object passed in points to same memory reference as the object being compared to (reflection), return true.

The 2nd and 3rd if statement states that if the object passed in is null or is not of the same type as to the object that we are comparing against , return false.

The rest of the if statements check property by property and if one of them does not match, return false. Otherwise, if all property values match return true.

Let’s test it by adding the following code to the Starter.java:

        SoccerPlayer sp2 = new SoccerPlayer();
        sp2.setName("Zinedine");
        sp2.setLastName("Zidane");
        sp2.setJerseyNumber(5);
        sp2.setTeamName("Real Madrid");

        if(sp == sp2){
        	System.out.println("The 2 objects are equal");
        }else{
        	System.out.println("The 2 objects are not equal");
        }

        if(sp.equals(sp2)){
        	System.out.println("The two objects are equal");
        }else{
        	System.out.println("The two objects are not equal");
        }

The first if statement using the == operator will fall into the else block because it is trying to compare the memory address instead of the actual object properties.
The second if statement uses the equals() method which will call the overriden version that we provided will return true. See the output results in the command line:

The 2 objects are not equal
The two objects are equal

Alert!!: The equals method DOES NOT have to compare attribute per attribute to determine whether two objects are equal or not. This depends on your business rules. Say for example that the players would have some sort of unique identifier like an SSN or other known ID set up by FIFA, we could have used that ID field in our equals method to determine whether two players are the same or not and avoid comparing field by field. You are the best one to make that call based on your specs.

Overriding the hashCode() method

The hashCode() method seems to be this unforgotten method that everybody overrides with the auto generated code but without actually knowing what is it used for. The hashCode() is used to increase the search performance of large collections of objects. The hashCode() returns an integer, this integer value determines how an object is stored and to help locate the object once in the collection. By contract if two objects are equal using the equals() method then they must return the same hash code value. However, this does not imply that if two objects are not equal then they should have different hash code values., ultimately it depends on how efficient your algorithm is. Because it is possible  to have more than one object with the same hash code you will have to do two steps when searching for an object. The steps are as follows:

  1. Find the right position in the “Hash” Collection using the hashCode() method (to start the search from there)
  2. Iterate through the list of elements at that position using the equals() method to find what you are looking for

This is what the default implementation of a hashCode() override looks like from auto generated code from my favorite IDE IntelliJ:

@Override
 public int hashCode() {
     int result = name.hashCode();
     result = 31 * result + lastName.hashCode();
     result = 31 * result + jerseyNumber;
     result = 31 * result + teamName.hashCode();
     return result;
}

Usage:

Java based ETL tools such as Talend make extensive use of the hashCode() method in order to make the two steps above work efficiently when processing/transformation of data among components. In these type of tools is very important to have a decent hash code algorithm as it is going to be a critical component in determining the run time speed of the job. You do not have to worry about writing a hash code algorithm though as it in this GUI tools it will be automatically generated for you .

Alert!!:You can have a hashCode() method that always returns the same integer ,this is valid, but it will be very inefficient as you are going to be putting every object inside the same bucket and the search will be expensive as it will be a linear search. Remember that the ultimate goal is to come up with an algorithm that will put all the objects as dispersed as possible within a collection.

Go to Top