Статьи

Уменьшите Legacy от Java EE 5 до 7

кода из-другого времени, 300x163 Java EE 5 была впервые представлена ​​в 2005 году, в то время как Java EE 7 появилась в 2013 году. Между обеими версиями и технологическим разрывом существует 7-летний промежуток времени, это похоже на столетие.

Многие организации по-прежнему застряли на Java EE 5, и есть много веских причин, по которым они решили не обновляться. Тем не менее, они становятся неактуальными, если вы посмотрите на некоторые из причин двигаться вперед:

  • Воспользуйтесь последними улучшениями
  • Java 6 EOL в первом квартале 2013 года
  • Увеличение расходов на техническое обслуживание
  • Трудно поддерживать интерес разработчиков

Эти причины как-то спорны и могут быть недостаточными, чтобы убедить кого-то перейти на новую версию.

За последние несколько лет я работал в приложении со значительным измерением, и совсем недавно оно было перенесено с Java EE 5 на 7.

Останови наследие

Код-граф

Каждый год вводились новые функции, которые увеличивали базу кода приложения. Он даже превысил 1 миллион строк кода! Уже один этот факт является показателем того, что трудно ориентироваться в этой огромной базе кода. Если приложение продолжает расти, со временем это только ухудшится. С начала создания приложения мы можем наблюдать, что рост был стабильным с каждым годом, вплоть до 2015 года, когда произошла миграция. Впоследствии код все еще рос, но более медленными темпами.

Как?

Фактически, изменив Java EE 7, можно было получить те же результаты, но написав меньше кода. Это может показаться не очень важным для небольших приложений, но когда мы говорим о 1 миллионе, это имеет огромное значение.

Мало того, что вы работаете более продуктивно, тратя меньше времени на реализацию той же функции, но и вероятность появления ошибок меньше, так как у вас также меньше кода, чтобы возиться.

Никто на самом деле не хочет менять старый код, особенно если он работает и даже хуже, вы точно не знаете, почему он используется. Но есть несколько простых в использовании функций Java EE 7 (и 6), которые вы можете сразу использовать при переходе с Java EE 5.

КДИ

Вспомните утомительную работу по созданию EJB в другом контексте, например, сервлете:

01
02
03
04
05
06
07
08
09
10
11
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(“…”);
    }
}

Большинство из них можно просто заменить на @Inject .

Нет больше локальных интерфейсов

Утомительно всегда определять интерфейс для ваших компонентов, особенно если они используются только локально:

1
2
3
4
5
@Stateless
@Local(UserBusiness.class)
public class UserBusinessBean implements UserBusiness {
    ...
}

Просто замените на:

1
2
3
4
@Stateless
public class UserBusinessBean {
    ...
}

Одиночки

Старомодный синглтон (возможно, не самый правильный способ сделать это):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
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;
   
    }
}

Вы просто измените его на:

1
2
3
4
5
6
@Singleton
@Lock(LockType.READ)

public class ModuleListener {

   
    @EJB
   
    private ModuleBusiness moduleBusiness;
}

Validations

Поскольку в Java EE 5 не было доступно Bean Validation, иногда приходилось прибегать к таким вещам:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
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) {
        
    }
}

Теперь мы можем просто использовать аннотации @NotNull и @Max в поле, которое мы хотим проверить.

JMS

Трудно использовать JMS в Java EE 5:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@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);
    }
}

С JMS 2.0 и Java EE 7 вы можете существенно сократить код и использовать цепочечные вызовы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
@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);   
}

Движение вперед

Эти примеры — лишь вершина айсберга о том, как вы можете упростить свой код. Есть еще много примеров, но это основные, используемые в этом проекте.

Пожалуйста, оставьте свои примеры в разделе комментариев.

Кроме того, если вы хотите узнать больше о проверке моего сеанса, Migration Tales из Java EE 5–7, в которой описаны некоторые решения, которые нам пришлось реализовать для полной миграции приложения. Каждый случай индивидуален и нет правильного рецепта, но он может дать вам хорошее представление о пути, по которому вам нужно идти, чтобы достичь своей цели.

Слайды

видео

Ссылка: Уменьшите Legacy от Java EE 5 до 7 от нашего партнера JCG Роберто Кортеса в блоге