2016-03-26 7 views
1

Вот класс, который генерируется/загружается во время выполнения приложения Java EE (@Default Bar боб обеспечивается тем же приложением):инъекционное Java EE ресурсов в динамически загружаемых классов

public class Foo { 

    @PersistenceContext private EntityManager em; 
    @Resource private UserTransaction tx; 
    @EJB private MyEJB ejb; 
    @Inject Bar bar; 

    public Foo() { 
    } 

    @PostConstruct 
    public void postConstruct() { ... } 

    public void businessMethod() { ... } 

} 

Вот как это экземпляр:

import javax.enterprise.inject.spi.Unmanaged; 
    ... 

    @Inject private BeanManager bm; 
    ... 

    Class clazz = loadClazz(); 

    Unmanaged unmanaged = new Unmanaged(bm, clazz); 

    Object obj = unmanaged.newInstance() 
      .produce() 
      .inject() 
      .postConstruct() 
      .get(); 

С JBoss/WildFly, все поля вводятся правильно, в том числе EntityManager, EJB, и т.д. UserTransaction

Wit h TomEE и GlassFish, ресурсы Java EE игнорируются, и вводится только поле bar.

  1. Следует ли считать это ошибкой в ​​TomEE и GlassFish, или это просто пятно в спецификации JavaEE/CDI, которое реализовано по-разному на серверах приложений? Это определенно не чистая проблема CDI, так как GlassFish и WildFly используют одну и ту же реализацию CDI, а именно JBoss Weld;
  2. Как я могу достичь вышеуказанного с помощью TomEE и GlassFish? Портативное решение предпочтительнее, но какой-то серверный код в порядке (я боюсь, что это неизбежно с такими проблемами).

Общая цель состоит в том, чтобы обеспечить полный спектр инъекций CDI (простой @Inject, а также Java EE ресурсы, такие как @PersistenceContext, @Resource, @EJB и т.д.) динамического кода. Моя первая попытка состояла в том, чтобы создать класс «на лету», который включал бы аннотированные поля + динамическую бизнес-логику (и да, это сработало, хотя и в WildFly). Вообще говоря, у меня есть набор определений динамических инъекций, как это:

@Annotation(param = "value") @Qualifier1 @Qualifier2 ... Type name; 

где Annotation является одним из Inject, PersistenceContext, Resource, EJB и т.д., и я хочу, чтобы получить экземпляр, который был бы впрыскивается, если это были внутри управляемого бина CDI. Таким образом, гипотетический метод был бы приемлемым, чтобы принять метаданные для инъекций и вернуть соответствующий экземпляр.

+0

Какую версию TomEE вы используете? –

+0

TomEE 7.0.0-M3 (последний снимок с поддержкой JavaEE 7) – Dimitri

ответ

0

Вы попробовали declaring resources via producer fields?

Выполнение этого действия: @InjectEntityManager, UserTransaction и т. Д., Не прибегая к аннотациям до CDI.

Поскольку инъекция CDI через @Inject, похоже, работает во всех ваших средах, это может быть жизнеспособным решением.

+0

При таком подходе будут исправлены такие параметры, как 'lookup' для' @ Resource', 'unitName' для' @ PersistenceContext' и т. Д. Я хочу, чтобы они были динамичными. Или, может быть, вы также можете создать класс продюсера (который служит мостом между аннотациями до CDI и '@ Inject')? Я боюсь, что контейнер CDI не подберет динамически загруженный класс производителя – Dimitri

Смежные вопросы