Enterprise Java

Reduce Legacy from Java EE 5 to 7

code-from-another-time-300x163Java EE 5 was first introduced in 2005, while Java EE 7 came out in 2013. There is a 7 year gap between both versions and in technology terms it’s like a century.

Many organizations are still stuck using Java EE 5 and there are many valid reasons why they choose not to upgrade. Still, these become irrelevant if you look into some of the reasons to move forward:

  • Benefit from the Latest Improvements
  • Java 6 EOL in Q1 2013
  • Increased Maintenance Costs
  • Hard to keep Developers interested

These reasons are somehow debatable and may not be enough to convince someone to upgrade.

Over the last few years, I’ve worked in an application with a considerable dimension and just recently it was migrated from Java EE 5 to 7.

Stop the Legacy

code-graph

Every year, new features were introduced that increased the application code base. It even surpassed 1 Million lines of code! This fact alone is an indicator that it’s hard to navigate this huge code base. If the application keeps growing, this will only get worse with time. Since the beginning of the application inception, we can observe that the grow was steady with each year, until 2015, when the migration happened. Afterwards, the code still grew but at a slower pace.

How?

In fact, by changing to Java EE 7, it was possible to produce the same results, but by writing less code. This may not seem a very big deal with small applications, but when we are talking about 1 Million, it makes a huge difference.

Not only you are being more productive, by consuming less time to implement the same feature, but also the chance to introduce bugs is smaller, since you also have less code to mess around.

No one really wants to change old code, especially if it’s working and even worst, you don’t know exactly why it’s used. But there are a few easy to use features from Java EE 7 (and 6), that you can use straight away when moving from Java EE 5.

CDI

Remember the tedious work to get an EJB in a different context, like a Servlet:

public static <T> T getLocalBean(final Class<T> klass) {
    try {
        LocalBinding localBinding = klass.getAnnotation(LocalBinding.class);
        if (localBinding == null) {
            throw new BeanNotFoundException(“…”);
        }
        return (T) initialContext.lookup(localBinding.jndiBinding());
    } catch (Exception e) {
        throw new BeanNotFoundException(“…”);
    }
}

Most of these can be simply replaced with @Inject.

No more Local Interfaces

Tedious to always have to define an Interface for your Beans, especially if they were only used locally:

@Stateless
@Local(UserBusiness.class)
public class UserBusinessBean implements UserBusiness {
    ...
}

Just Replace by:

@Stateless
public class UserBusinessBean {
    ...
}

Singletons

Old fashioned Singleton (maybe not the most correct way to do it):

public class ModuleListener {
    
    private static ModuleListener moduleListener;
    
    private static ModuleBusiness moduleBusiness;

    
 
    private ModuleListener() {
       
        moduleBusiness = BeanFactory.getLocalBean(ModuleBusinessBean.class);
    
    }

    
 
    public static ModuleListener getInstance() {
        
        if (moduleListener == null) {
            
            moduleListener = new ModuleListener();
        
        }
        
        return moduleListener;
    
    }
}

You just change it to:

@Singleton

@Lock(LockType.READ)

public class ModuleListener {

    
    @EJB
    
    private ModuleBusiness moduleBusiness;
}

Validations

Since you didn’t have Bean Validation available in Java EE 5, sometimes you had to resort in doing things like this:

public static int fieldEntityMaxLenght(Class clazz, String field) throws Exception {
    
    int maxLength = 0;
    
    if (field != null) {
        
        Column annotation = clazz.getDeclaredField(field).getAnnotation(Column.class);
         
        maxLength = annotation.length();
    
    }
    
    return maxLength;

}

public static void rejectIfMaxLengthExceeded(String field, int maxLength) {
    
    if (field != null && field.length() > maxLength) { 
        … 
    }
}

Now we can just use @NotNull and @Max annotations into the field that we want to validate.

JMS

It’s a pain to use JMS in Java EE 5:

@Resource(mappedName = "java:/JmsXA")
private ConnectionFactory connectionFactory;
@Resource(mappedName = "java:/jms/queue/EmailQueue")
private Destination destination;

public void sendAlertsByEmail(Map<Long, String> toSend, List<AlertAttachment> files) {
    try {
        Connection connection = connectionFactory.createConnection();
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        MessageProducer producer = session.createProducer(destination);

        HashMap<String, Alert> dataToSend = new HashMap<>();
        for (Long alertId : toSend.keySet()) {
            log.info(String.format("Sending alert %d to %s", alertId, toSend.get(alertId)));
            Alert alert = findAlert(alertId);
            alert.getAlertContent()
                 .setBodyMail(undecorateHTMLLinks(
                         TemplateContextUtils.createMailMessage(alert, Configuration.getInstance())));
            dataToSend.put(toSend.get(alertId), alert);
        }
        ObjectMessage messageToSend = session.createObjectMessage();
        messageToSend.setObject(dataToSend);
        producer.send(messageToSend);

        // send message and then clean up
        session.close();
        connection.close();
    } catch (Exception e) {
        log.error("Unexpected error occured", e);
    }
}

With JMS 2.0 and Java EE 7 you can drastically reduce the code and use chaining calls:

@Inject    
private JMSContext context;    
@Resource(mappedName = "java:/jms/queue/EmailQueue")    
private Queue inboundQueue;    

public void sendMessage (Map<Long, String> toSend, List<AlertAttachment> files) {
    HashMap<String, Alert> dataToSend = new HashMap<>();
    for (Long alertId : toSend.keySet()) {
        log.info(String.format("Sending alert %d to %s", alertId, toSend.get(alertId)));
        Alert alert = findAlert(alertId);
        alert.getAlertContent()
             .setBodyMail(undecorateHTMLLinks(
                     TemplateContextUtils.createMailMessage(alert, Configuration.getInstance())));
        dataToSend.put(toSend.get(alertId), alert);
    }

    context.createProducer()
        .setPriority(1)!               
        .setTimeToLive(1000)!               
        .setDeliveryMode(NON_PERSISTENT)!               
        .send(inboundQueue, dataToSend);    
}

Moving Forward

These examples are just the tip of the iceberg on how you can simplify your code. There are many more examples, but these are the main ones used in this project.

Please post your examples in the comments section.

Also, if you would like to learn more about check my session, Migration Tales from Java EE 5 to 7 which covers some of the solutions we had to implement to completely migrate an application. Each case is different and there is no right recipe, but it can give you a good idea on the path you need to walk to achieve your goal.

Slides

Video

Reference: Reduce Legacy from Java EE 5 to 7 from our JCG partner Roberto Cortez at the Roberto Cortez Java Blog blog.

Roberto Cortez

My name is Roberto Cortez and I was born in Venezuela, but I have spent most of my life in Coimbra – Portugal, where I currently live. I am a professional Java Developer working in the software development industry, with more than 8 years of experience in business areas like Finance, Insurance and Government. I work with many Java based technologies like JavaEE, Spring, Hibernate, GWT, JBoss AS and Maven just to name a few, always relying on my favorite IDE: IntelliJ IDEA.Most recently, I became a Freelancer / Independent Contractor. My new position is making me travel around the world (an old dream) to customers, but also to attend Java conferences. The direct contact with the Java community made me want to become an active member in the community itself. For that reason, I have created the Coimbra Java User Group, started to contribute to Open Source on Github and launched my own blog (www.radcortez.com), so I can share some of the knowledge that I gained over the years.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button