Anteo Java News: Spring 2006

We appreciate and welcome all of your comments and submissions as we are tailoring the newsletter for you. Please send any comments and/or submissions for future articles to Anteo Group Marketing. To receive Anteo Java News by email, contact us.

Thanks and enjoy!

Quartz Job Scheduling
By: Chuck Cavaness

Building software applications that run on predetermined schedules has always been a demand placed on IT organizations. Whether it's checking file systems for EDI-type file drops or sending out reminders to customers that it's time to reorder, the need to execute jobs based on a schedule has and always will be a requirement from the business.

As the tentacles of business reach out geographically, the IT organization and/or products produced by them must be prepared to operate on many different schedules with many different types of partners. The need for job scheduling is more crucial today than ever before, and this need is driving the software community to search for a wholesale solution that works in the enterprise. With the advent and growth of the open source community, a Java open source Job Scheduling solution is "the right thing at the right time."

The Quartz Job Scheduling system has been around for some time. It was created by James House several years ago and has been quietly gaining notice and usage. Quartz is starting to show up in many well known places, including several Enterprise Service Bus (ESB) implementations like ServiceMix. For a list of the various commercial and open source applications using Quartz, check out the Quartz Wiki.

Quartz is built around the Quartz Scheduler, which is the heart of the framework. The Scheduler allows you to create and schedule many, potentially hundreds or thousands of jobs. In Quartz vernacular, a job is any Java class which implements the Quartz org.quartz.Job interface. The interface contains a single execute() method that your job must implement:

public interface Job {

public void execute(JobExecutionContext context)
throws JobExecutionException;

}

The execute () method is called when the Scheduler determines its time to call your job. You can perform whatever logic you want within the Job class, including calling EJBs, sending emails or simply just invoking methods on POJOs. The jobs are executed based on Quartz Triggers. In Quartz, Triggers are separate from jobs, which allows for jobs to have multiple Triggers defined for it. Quartz supports several types of Triggers, but the most useful is the CronTrigger. As the name implies, this version of the Trigger is based on Unix cron. Similarly to the Unix cron, you have ultimate control and flexibility for when and how often your jobs are executed. For example, if you need to execute a job every Monday and Friday night at 11:59pm, but only at the end of each business quarter, Quartz triggers can handle it.

Quartz is truly an enterprise solution. It includes many features that make it useful as a standalone solution or within a much larger J2EE application. For example, support for RMI, clustering, Plugins, listeners and support for web applications. All of which comes with the base framework. Quartz also comes with pre-built jobs, including ones for talking to EJBs, Java Messaging Service (JMS) and sending emails with JavaMail.

While many are just becoming aware of the Quartz project, the word is beginning to spread and Quartz is proving itself worthy of the buzz. If you have a need for job scheduling and you're not afraid of open source initiatives, be sure to download and check out Quartz. The publication Quartz Job Scheduling Framework: Building Open Source Enterprise Applications may also prove useful. The time and money you can save by using Quartz and avoiding the more costly commercial solutions will pay big dividends on the downstream of your development projects.



Using Reflection to Copy Common Data Between Objects
By: Nedda Kaltcheva

How this topic came about:
While working on a web application for a client, I came across pages and pages of code, which consisted of invoking setter and getter methods to copy data from one object to another. I am a stickler for elegance and re-usability in code so I set out to find a smarter, prettier way of getting the same result. I grabbed some snacks and walked over to my colleague's cube to share some ideas and discuss the topic. Shelton and I came up with a utility class that uses reflection to do the job.

Area of applicability:
Operations in multi-tiered systems often require that data be copied between objects residing in the different tiers. For example, a back-end bean may represent a set of data (i.e. one or more database tables) and a front -end bean used to display information on a web page or in a window may contain a subset of the data. In a system with numerous such beans, it can become cumbersome to write code that copies data from one bean to the other invoking the setter and getter methods of the objects resulting in many lines of code that look something like this: beanA.setFieldA(beanB.getFieldA()).

While there is nothing wrong with such code, it lacks elegance and re-usability, creates clutter and is difficult to maintain. The example below shows a utility class that contains methods to copy common data between two beans. The example shows how to copy fields of type String and ArrayList but can be extended to fields of any other type. The requirement is that all common data methods are named the same in both objects. The advantage of using reflection in this way is that it eliminates the need to write code to copy data between two beans every time new beans are created, new methods of existing beans are added, or new functionality is added to the application. Simply invoke the utility class methods, pass the two beans and voila - common data is populated from one bean to the other.

The code:
/**
* Bean utility class
*/
public class BeanUtils {

/**
* Copies values of common fields from one object to another.
* All other fields are ignored.
*
* @param fromBean - object to copy from
* @param toBean - object to copy values to
*
* @author Nedda Kaltcheva
* @author Shelton Johnson
*/
public static void dissimilarBeanCopy(Object fromBean, Object toBean) {
Method toBeanMethod = null;
Method fromBeanMethod = null;
String methodName = null;
String temp = null;

// Gets all methods of the object from which values are to be copied
Method[] fromBeanMethods = fromBean.getClass().getMethods();

// An array containing the String class
Class[] setterArgs = {"".getClass()};
// Iterate through the methods of the bean, from which values are to be
  // copied
  for (int i = 0; i < fromBeanMethods.length; i++) {
            methodName = fromBeanMethods[i].getName();
            // If this is a get method, we want to invoke it, retrieve
            // the value and then pass it to the corresponding set method
            // of the object we are copying to - toBean
     if (methodName.startsWith("get")) {
                try {
// try to get the setter corresponding to the get method
// replace the set<methodname> with get<methodname>
// call the toBean class to retrieve the getter which takes                  
// String as an argument - note that setterArgs is a Class
// array containing one element - the String class
toBeanMethod = toBean.getClass().getMethod(
       methodName.replaceFirst("get", "set"), setterArgs);
                    // if there is such a setter then we have a common field
if (toBeanMethod != null) {
    // Common field exists if we are in this loop
    fromBeanMethod = fromBeanMethods[i];
// invoke the getter - temp holds the value returned by   // the getter
   temp = (String) fromBeanMethod.invoke(fromBean, null);
   if (temp != null) {
       Object[] args = {temp};
// Call the  setter on toBean and pass it temp as the // value to set
toBeanMethod.invoke(toBean, args);
                       }
                   }
  } catch (SecurityException e) {
      // Indicates jvm problem
      e.printStackTrace();
  } catch (IllegalArgumentException e) {
      e.printStackTrace();
  } catch (NoSuchMethodException e) {
                   // Non-fatal - skip and continue with the for loop
                   // This catches all cases of uncommon methods
  } catch (IllegalAccessException e) {
                   // Non-fatal - skip and continue with the for loop
      e.printStackTrace();
  } catch (InvocationTargetException e) {
// Non-fatal - skip and continue with the for loop
e.printStackTrace();
  }
           }  
}
}

/**
  * Copies values of common fields of type ArrayList from one object to
  * another.
  * All other fields are ignored.
  *
  * @param fromBean object to copy from
  * @param toBean object to copy values to
  *
     * @author Nedda Kaltcheva
     */    
public static void dissimilarBeanCopyArrayFields(
Object fromBean, Object toBean) {
Method toBeanMethod = null;
Method fromBeanMethod = null;
String methodName = null;
ArrayList temp = null;
        // Gets all methods of the object from which values are to be copied
Method[] fromBeanMethods = fromBean.getClass().getMethods();
        // An array containing the Array class
Class[] setterArgs = {(new ArrayList()).getClass()};
// Iterate through the methods of the bean, from which values are to be
// copied
for (int i = 0; i < fromBeanMethods.length; i++) {
    methodName = fromBeanMethods[i].getName();
            // If this is a get method, we want to invoke it, retrieve
            // the value and then pass it to the corresponding set method
            // of the object we are copying to - toBean
if (methodName.startsWith("get")) {
    try {
   // try to get the setter corresponding to the get method
   // replace the set<methodname> with get<methodname>
   // call the toBean class to retrieve the getter which
   // takes an ArrayList as an argument - note that  
   // setterArgs is a Class array containing one element –
                       // the ArrayList class
toBeanMethod = toBean.getClass().getMethod(methodName.replaceFirst("get", "set"), setterArgs);
// if there is such a setter then we have a common  // field
     if (toBeanMethod != null) {
     // Common field exists if we are in this loop
     fromBeanMethod = fromBeanMethods[i];
// invoke the getter - temp holds the value returned by the getter
temp = (ArrayList) fromBeanMethod.invoke(fromBean, null);
     if (temp != null) {
     Object[] args = {temp};
// Call the  setter on toBean and pass it temp as the value to set
     toBeanMethod.invoke(toBean, args);
     }
     }
   } catch (SecurityException e) {
     // Indicates jvm problem
     e.printStackTrace();
   } catch (IllegalArgumentException e) {
     e.printStackTrace();
   } catch (NoSuchMethodException e) {
     // Non-fatal - skip and continue with the for loop
     // This catches all cases of uncommon methods
   } catch (IllegalAccessException e) {
     // Non-fatal - skip and continue with the for loop
     // e.printStackTrace();
   } catch (InvocationTargetException e) {
     // Non-fatal - skip and continue with the for loop
     //e.printStackTrace();
   }
                   }
  }
}

    // Clear all fields of a bean - note that only String fields are cleared.
    public void clear(Object bean) {
        Field[] fields = bean.getClass().getFields();
        String fieldName = null;
        for (int i = 0; i < fields.length; i++) {
            try {
                fields[i].set(bean, "");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

A few words about reflection:
In today's modern world, we hear new buzzwords just about every day as new technologies spring out on the market. While trying to keep up with new technologies, it is important not to lose sight of how important it is to understand the foundation, which is a good command of the language. Reflection is one of the areas in Java that is avoided by many programmers because of the lack of understanding. It can be a very powerful tool to create re-usable and elegant software, as long as performance impact is kept in mind.



Java Platform, Micro Edition (Java ME)
By: Keith Miller

The Java Platform, Micro Edition (known as Java ME or J2ME) facilitates the development and execution of Java applications intended to run on consumer devices with resource-constraints not usually found on desktop or server platforms. At its core, the Java ME consists of configurations and profiles. Configurations are specifications that define the basic APIs across a class of devices and profiles complete the runtime environment by building upon the Configuration and adding higher-level APIs for a specific category of device. The Java ME allows Java developers to create rich Java applications that run on a variety of consumer devices, such as mobile phones, BlackBerry devices, and embedded devices including media players. This article looks at two hot applications of Java ME technology: Mobile Devices and Blu-Ray.

Mobile Devices (Phones and BlackBerry)
A mobile phone's Java ME includes the Connected Limited Device Configuration (CLDC) and the Mobile Information Device Profile (MIDP). MIDP defines the user interface API and other mobile information device-specific APIs not necessarily found on all resource-constrained devices. Java applications written for CLDC/MIDP devices are called MIDlets. Almost all new mobile devices include a Java ME (CLDC/MIDP) virtual machine capable of running MIDlets. The Java ME contains the core API of the Java language; therefore, mobile business applications (both standalone and networked) can be developed within the constraints of the mobile phone. As the penetration of Java ME-capable mobile phones expands, the opportunity for the Java ME developer also increases. In June 2001, Research In Motion (RIM) introduced its first BlackBerry device based completely on the J2ME. After transitioning from C++-based systems, all current BlackBerry devices now utilize the J2ME as their core operating system. J2ME-based BlackBerry devices include the CLDC and MIDP.

BlackBerry developers have a choice when choosing how to implement their Java-based applications. Developers wishing to target a wide range of mobile devices (not just the BlackBerry) should implement their application using the standard J2ME APIs. However, those developers specifically targeting BlackBerry devices should implement their applications using the BlackBerry API, a superset of the J2ME provided by RIM. The BlackBerry API provides access to BlackBerry features, such as the Phone API and Mail API, as well as BlackBerry-specific user interface components. Consultants wishing to specialize in the BlackBerry API should become familiar with RIM's Java Development Environment (JDE).

Blu-ray
The reader may be aware of the next generation optical disc war currently being waged in the media and consumer electronics shows between Blu-ray and HD DVD. What the reader might not know is that Blu-ray will utilize a subset of the Java ME to handle its interactivity. While HD DVD designers adopted iHD (a Microsoft authoring language) to handle their user interface duties, Blu-ray architects developed a new Java specification called BD-J. BD-J provides Blu-ray with development flexibility, inherent networking and security, and the ability to create cross-platform applications required by the different manufacturers' Blu-ray players. DVB-GEM serves as the BD-J foundation, and it permits Java implementations based on Java ME's Personal Basis Profile (JSR 129). Personal Basis Profile is built from the Java ME's Connected Device Configuration (CDC) and Foundation profile. It provides a core Java ME API including basic graphics display behavior.

Each Blu-ray player will incorporate its own Java virtual machine. Java is already a proven solution in mobile/embedded devices and interactive television; consequently it is a great fit for Blu-ray. BD-J will provide interactive user interfaces far surpassing the capabilities of Blu-ray's predecessor, the DVD. However, the use of BD-J will not be limited to user interfaces. BD-J will facilitate new possibilities not found on DVD, such as new content downloads (think movie trailers and other special features), online shopping for items related to the particular Blu-ray disc being viewed, Java-based gaming, and more. Blu-ray and BD-J will launch original and creative opportunities for the Java ME consultant encompassing both Blu-ray disc authoring and BD-J authoring tool development.

Conclusion
Since Java ME's introduction in 1999 by Sun Microsystems, it has continued to expand into various markets. BlackBerry and Blu-Ray are only two examples of Java ME's affect on consumer devices. Java ME capable mobile devices are becoming more and more standard, and new opportunities continue to evolve in other areas of resource-constrained consumer devices. The expansion of Java ME technology provides many new and exciting opportunities for the Java consultant.



Current Openings

For our most current openings, click here.

back to newsletters >

For more information about the Anteo Group, contact us.










"The need for job scheduling is more crucial today than ever before, and this need is driving the software community to search for a wholesale solution that works in the enterprise."

Chuck Cavaness



















































"The advantage of using reflection in this way is that it eliminates the need to write code to copy data between two beans every time new beans are created, new methods of existing beans are added, or new functionality is added to the application,"

Nedda Kaltcheva





















































































































































































































"The Java ME allows Java developers to create rich Java applications that run on a variety of resource-constrained consumer devices..."
Keith Miller

Anteo UK Los Angeles Office Dallas Office Atlanta Office