Pages

Thursday, December 29, 2011

Exceptions: Best Practices


Last days I had a discussion with few colleagues about best practices on handling exception in the code (more precisely in the JEE application server). As we exposed each one his point of view, we arrived to point the performance issue that may arrive. At that moment, I remembered an older entry on Xebia French blog that illustrated such performance issue related to exception management.

First off all, the author explains that it was not obvious to find the source of its performance problem. Fortunately, he was using an open source framework and he was able to isolate the code causing the problem. In fact there was a method that threw a NoClassDefFoundError at each call. This method body was looking something like that:
try {
 variable = new SomeClass();
} catch (Throwable t) {
    try {
        variable = new SomeNewClass();
    } catch (Throwable t2) {
        variable = new SomeOtherClass();
    }
}
 
I must confess I spent a whole day to find a bug in one of our projects, caused by a similar code in an external jar file that for some reason threw an exception:
try {
 // doing something
} catch (Throwable t) {
};

Another subject that the author illustrates (and the one of the users argued and proved) is that comparing two method calls, one with nominal execution and the other one throwing an exception, there were significant differences on the execution time between the two cases. This is caused, on the one hand by the object creation and on the other hand by the synchronized fillInStackTrace method in Throwable class.

In conclusion, what we have learn from these examples when using exceptions:
  • exceptions must be used in order to handle errors, an exceptional event that disrupts the normal execution of the program; do not use exceptions in order to transfer values, return parameters from methods etc; 
  • if you catch an exception, log an appropriate message or do something that help the debugging
  • do not catch Throwable, Error or RuntimeException (well there may be some exceptions here  :p)

Wednesday, November 16, 2011

To Agile or not to Agile, that is the challenge


Last week I read one of Nicole Bellios articles on true Agile stories. I found this article and the comments very interesting and confirmed me the idea that I have on Agile.

Indeed, Agile has obvious advantages: ability to respond to changing requirements, collaboration with the stakeholder, team interaction. In my company, agile has also brought us more white boards in the rooms and work area :p. Agile is a MUST in some projects, and it proved the added value for the client and for us. Consequently, we have several agile success stories.

On the other hand, we also have a lot of successful projects that followed a classical process. Agile is not always the right answer. Agile does not fit well in all environments (and this is a postulate from Agile defenders). There are many ways to do agile. Or better, we can successfully apply Agile concepts to projects that are not conducted in a pure agile way: continuous integration, intensive tests, stand-up (even if we were sited) meetings etc.

Moreover, there are people thinking that Agile is focusing on team and result forgetting the main actors, the individuals. Not fully sticking with Agile is OK. Agile or not Agile, there are advantages and disadvantages, constraints and benefits, best practices and individuals beats processes and tools, the success of a project is made by motivated people.

Monday, November 14, 2011

Using EMF in standalone Java application


During the last days I was working with Eclipse Modeling Framework (EMF) within the context of an R&D project. As our architecture became distributed, I had to use EMF outside an Eclipse-based application. Therefore, this article deals with us of EMF in a standalone Java application (standalone meaning here not running in en Eclipse framework like server-side components, Swing applications, etc). I will not present here how to use EMF to create models and generate the respective Java code (you may find a good tutorial on that at http://www.vogella.de/articles/EclipseEMF/article.html), but I will focus on using the generated code in a standalone Java application.

Let us remind that EMF project is a modeling framework and code generation facility for building tools and other applications based on a structured data model. Models can be specified using annotated Java, XML documents, or modeling tools and then can be used to produce a set of Java classes for the model, along with a set of adapter, factories and utility classes. You may find information and  documentation about the EMF project at http://www.eclipse.org/modeling/emf/docs/ .

Naturally, EMF (and its subprojects: EMF Core, CDO, Compare, Teneo, Model Query, etc) fits well in an Eclipse environment (Eclipse IDE or RCP). Nevertheless, EMF’s runtime features (use of generated code, notification, change recording, validation, persistence, etc) can be used in a standalone Java application. In order to benefits from EMF in such application, you must add all the needed jars to your classpath. In the book “EMF Eclipse Modelling Framework” you may find a table that clearly identifies the required jars based on the desired feature:

  • Core runtime, reflective API, validation: org.eclipse.emf.common_<version>.jar and org.eclipse.emf.ecore_<version>.jar
  • XML/XMI persistence: org.eclipse.emf.ecore.xmi_<version>.jar and the previous core runtime jars
  • EMF.Edit: org.eclipse.emf.edit_<version>.jar and the core runtime jars
  • Change model: org.eclipse.emf.change_<version>.jar and the core runtime jars
  • Ecore to XML persistence mapping: org.eclipse.emf.mapping.exore2xml_<version>.jar and the core runtime and XML/XMI jars
  • XML schema Infoset Model: org.eclipse.xsd_<version>.jar and the core runtime jars.


When using EMF under Eclipse, the plug-in extension mechanism is used to perform registration at runtime. In a standalone environment, default resource factories are not registered. Therefore, for each file extension or scheme the application wants to load or save, one needs to register the corresponding resource factory. For example, to load and save XML documents, it is necessary to add a similar line in your the application:
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new XMLResourceFactoryImpl());

In addition, one also needs to register one’s package, which happens as a side effect of accessing XyzPackage.eINSTANCE attribute. For example, to register the example model, it is necessary to add the following lines to the program:
MyEMFExamplePackage.eINSTANCE.eClass();
   ChangePackage.eINSTANCE.eClass(); // only if using EMF change feature

In my application I choose to code a class ResourceManager (which additionally is a Singleton) and put all these registrations in the initialization part of this object.
public class ResourceManager {

 /**
  * Create the resource manager.
  */
 private ResourceManager() {
  
  resourceSet = createResourceSet();

  // register factories
  Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new XMLResourceFactoryImpl());

  // register packages
  MyEMFExamplePackage.eINSTANCE.eClass();
  ChangePackage.eINSTANCE.eClass(); // only if using EMF change feature
 }

 /**
  * Create the resource set.
  */
 private ResourceSet createResourceSet() {
  ResourceSet rs = new ResourceSetImpl();
  // Register the default resource factory -- only needed for stand-alone
  rs.getResourceFactoryRegistry()
    .getExtensionToFactoryMap()
    .put(Resource.Factory.Registry.DEFAULT_EXTENSION,
      new XMIResourceFactoryImpl());
  rs.setURIConverter(new MapItURIConverter());

  return rs;
 }
 
 // Other methods ...
}

Now that we have registered all needed factories and packages, we can use the code generated by EMF in order to manipulate, save and load objects. In this example I instantiate a “dummy” model and, save it in an xml file. Subsequently,  I load the model and record the modification in order to apply it later.

In this entry, we have seen an example of using EMF outside Eclipse, i.e., in a standalone Java application which could be a server component, a Swing GUI etc. It is to note that in order to use EMF feature in such environment, it is necessary to perform two important steps:

  • Add required jars in the classpath
  • Register Factories and packages prior to model utilization.


Wednesday, October 26, 2011

Things that I like about Git


I have started to use Git sometime ago for my professional and private projects. I will expose here some features that I like about Git based on these experiences.

Integration with SVN
A large number of projects are still using SVN. Therefore the git-svn command allowed me to use Git locally and commit my changes on the central SVN repository.

Amend previous commit
It happens to me to forget some files or to add code comments in commits. With Git I have the opportunity to amend last commit and update my files.

Stash
Who has never had to suspend the current task in order to correct a new blocking bug or to implement an urgent unrelated feature? With Git, you save the current state of your work and retrieve it later.

Git is fast
Even if wasn’t convinced at the beginning, I found that Git commits are fast (especially when there is no merge :p). I am looking forward to see the behavior on larger projects.

Configuration
It is very easy to configure Git using configuration files: .gitignore, config, adding hooks, trigger scripts.

Branch and merging : multi-branch repositories and managing branch-heavy workflows
Those that use Git know what I am talking about. Git deals very well with branches, do not hesitate to use them. Moreover, new original workflows may be used to facilitate your work.

Using JAXB


One recurrent topic in my projects is the serialization of Java beans in XML and vice versa. Currently, I am using Java Architecture for XML Binding (JAXB), so I decided to write a small example based on Maven to illustrate the use of the framework.

In order to use JAXB, I followed several steps:

- Create XML schema files under /src/main/xsd. In this example, I created the "Person.xsd".


 
  
   
   
  
 


- Generate sources (bean) from previous xsd files:
mvn clean jaxb2:xjc

These two steps are optional if you create and annotate consequently your own java classes.

- Create utility methods to marshall Java objects object in xml
public static void serialize(Object o, Writer writer) throws JAXBException {
  // write it out as XML
  final JAXBContext jaxbContext = JAXBContext.newInstance(o.getClass());

  // for cool output
  Marshaller marshaller = jaxbContext.createMarshaller();
  marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  marshaller.marshal(o, writer);
 }

- Create utility methods unmarshall an xml document to obtain Java objects
public static  O deserialize(Class clazz, Reader reader)
   throws JAXBException {

  final JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
  final O object = (O) jaxbContext.createUnmarshaller().unmarshal(reader);
  return object;
 }

- Manipulate Java beans and XML documents
@Test
 public void testSerializeGeneric() throws IOException, JAXBException {
  Person person = new ObjectFactory().createPerson();
  person.setId(1);
  person.setName("John Doe");

  StringWriter expected = new StringWriter();
  Serializer.serialize(person, expected);

  Person p = Serializer.deserialize(Person.class, new StringReader(
    expected.toString()));
  StringWriter actual = new StringWriter();
  Serializer.serialize(p, actual);

  // Assert.assertEquals(person.getId(), p.getId());
  Assert.assertEquals(expected.toString(), actual.toString());
 }

Here is the pom that I used in this example.

 4.0.0
 
  MySuperPom
  org.example
  1.0
 
 org.examples.jaxb
 jaxb-example
 0.0.1-SNAPSHOT
 JAXB Example

 
  
   javax.xml.bind
   jaxb-api
   2.2
  

  
   com.sun.xml.bind
   jaxb-impl
   2.2.4
  

  
   junit
   junit
   4.8.1
   test
  

 

 
  
   
    org.codehaus.mojo
    jaxb2-maven-plugin
    1.3.1

    
     org.jaxb.example.model
    
   

   
    org.apache.maven.plugins
    maven-compiler-plugin
    2.3.1
    
     
     1.6
     1.6
     UTF-8
    
   
   
    org.apache.maven.plugins
    maven-jar-plugin
    2.3.1
    
     
     1.6
     1.6
     UTF-8
    
   

  
 


Access EJB remotely


This entry discusses the approach to provide the required jar files in the classpath of a Java client in order to access EJBs remotely. I will exemplify this approach for two JEE application servers, JBoss and GlassFish.

I have been using JBoss Application server for a while in my projects. One nice thing about JBossis that it provides a client folder containing a set of jars that you have to add to the classpath of remote applications in order to call EJB remotely. In this way, you have a clear view of what jars you are using.

On the other hand, for Glassfish you need to add one jar (gf-client.jar) in the classpath of the remote application. The drawback is that this jar has a lot of relative dependencies in the MANFEST.MF so it was hard to clearly identify only the files that are needed for a rich client for instance.

Well, this “manual” approach was used before Maven. Things changed with the rise and the efficiency of Maven. To set the classpath of your remote client, you should add the right dependencies in the pom.xml.
JBOSS community edition provides a maven dependency starting from version 5.1.0.

    org.jboss.jbossas
    jboss-as-client
    pom
    5.1.0.GA


Using this dependency, I was expecting that this will download the same jars as in the client folder… except that there are a lot more…

To perform a remote call to en EJB deployed in a GlassFish application server, you need to add next dependency in your pom:

    org.glassfish.appclient
    gf-client-module
    3.1
 

Moreover, if you want to isolate these jars (in order to use them if you can’t benefit from Maven – OSGi bundle for instance, or simply internet connection not available) use maven copy-dependencies to copy in a given folder and add them to your classpath:

    
        
            org.apache.maven.plugins
            maven-dependency-plugin
            
                
                    copy-dependencies
                    install
                    
                        copy-dependencies
                    
                    
                        false
                        ${basedir}/lib
                        true
                    
                
            
        
    
 
The line <excludeTransitive>false</excludeTransitive> is important here as you need to have all dependencies not only first level one.

PS: Obviously, in order to be able to access remotely the EJB:
  • You must use Remote interfaces
  • If you have configured a secure realm, you will need to set up a JAAS security login to the EJB tier
  • Configure properly the jndi properties



/* */