Есть ли ситуация, когда лучше использовать JNDI, чем внедрять сессионный компонент без сохранения состояния с помощью аннотации @EJB?
Нет ситуации, где лучше - но ситуации, когда это необходимо:
когда имя для поиска неизвестно во время компиляции (я бы сказал, что это плохой дизайн, но это другая проблема)
когда аннотации не поддерживаются, например в обычных неуправляемых вспомогательных классах и в нескольких других случаях (мы снова можем спорить о том, хорошо или плохо зависеть от EJB в этих классах).
Если имя для поиска является постоянным и инъекция возможна, предпочтительнее @EJB аннотации:
Упростите тестирование
Меньше проблем с определением локальных / глобальных имен JNDI
Поиск JNDI может быть важен в случае SFSB (убедитесь, что вы все время обращаетесь к одному и тому же экземпляру), но в случае SLSB я не знаю ни одного случая, когда JNDI был бы «лучше» в любом случае.
Я бы определенно пошел с @EJB. Его легче читать (код меньше подвержен ошибкам), легче поддерживать (вам не важно расположение компонента в пространстве имен JNDI) и легче тестировать (нет неприятного кода поиска, который нужно отключать при выполнении модульных тестов).
Говоря о причинах производительности - я не уверен на 100%, но я не удивлюсь, если случится так, что сервер приложений фактически выполняет поиск JNDI за кулисами, когда вы используете аннотации.
Есть ли ситуация, когда лучше использовать JNDI, чем внедрять сессионный компонент без сохранения состояния с помощью аннотации @EJB?
Конкретная ситуация, требующая JNDI-поиска SLSB, описана в этом вопросе и относительном ответе: Наследование JPA и полиморфизм EJB. По сути, когда имя класса SLSB определяется во время выполнения.