Pages

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



/* */