2012-12-24 32 views
5

我是新來的,也是CDI世界的新手,我在工作中得到的第一個任務是找到一種控制CDI上傳的方法。控制EJB 3.1內的CDI啓動

我們同時使用EJB 3.1CDI 1.0,因爲它們是由不同的容器控制的,我們可以控制何時以及以什麼順序EJB管Bean將使用@Startup@Singleton註釋待漲。

但是我在我的類中聲明的@Inject CDI bean由於CDI容器尚未啓動而變爲null。

我一直在嘗試幾天尋找解決方案,我發現here沒有工作(仍然爲空)。

我們使用的是Java EE 6和運行WebSphere Application Server 8

請在應用程序中,如果你能幫助我找到一個方法來控制內,無論EJB的CDI上傳?

這裏是它的一個示例代碼:

import javax.annotation.PostConstruct; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 

@Singleton 
@Startup 
public class BaseStartupLoader{ 


/** 
* Default constructor. 
*/ 
@Inject @MyStartup 
BaseStartUp myStartup; 

private static Logger m_logger = LoggerFactory.getLogger(BaseStartupLoader.class); 
public BaseStartupLoader() { 

} 

@PostConstruct 
public void init(){ 

    String applicationName = null; 

    try { 

      applicationName = myStartup.getClass().getName(); 
      myStartup.load(); 

    } catch (IllegalAccessException e) { 
     m_logger.error("Faild to load data into preload system. "+e);    
    } catch (InstantiationException e) { 
     m_logger.error("Faild to load data into preload system. "+e);    
    } catch (ClassNotFoundException e) { 
     m_logger.error("Faild to load data into preload system - Class "+ applicationName + "Not found. "+e);    
    } 
    } 
} 

這裏是BaseStartup接口:

public interface BaseStartUp { 
public void load() throws IllegalAccessException, InstantiationException, ClassNotFoundException; 
} 

限定符與實現

@Retention(RetentionPolicy.RUNTIME) 
@Target ({ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE, ElementType.METHOD}) 
@Qualifier 
@Dependent 
public @interface MyStartup { 
} 


@MyStartup 
public class MyStartUpLoader implements BaseStartUp { 

    @Inject 
    SomeConfigLoader config; 

    @Override 
    public void load() throws IllegalAccessException, InstantiationException, ClassNotFoundException { 
    conifg.init();  
} 
} 
+0

您可以加入一些示例代碼,你是怎麼做到的 –

+0

我用Code Samples編輯了這個問題。 – user1917984

+0

只是想知道,但是有什麼「控制上傳」來處理問題的其餘部分呢? –

回答

3

也許仔細檢查CDI是實際上可以在應用程序的所有位置啓用。嘗試添加該代碼BaseStartupLoader作爲一個實驗:

@Singleton 
@Startup 
public class BaseStartupLoader { 

    @Inject @MyStartup 
    BaseStartUp myStartup; 

    @Inject 
    private InjectionTest test; 


    public static class InjectionTest {} 
} 

如果test變量在@PostConstruct出現null,則CDI可能在BaseStartupLoader聲明罐未啓用。

如果說,例如,BaseStartupLoader在名爲orange.jarMyStartUpLoader罐子宣佈了一個名爲yellow.jar罐子,被宣告那麼這兩個文件必須存在:

  • orange.jar!/META-INF/beans.xml
  • yellow.jar!/META-INF/beans.xml

如果通過META-INF/beans.xml在兩個罐子中正確啓用了CDI,則這是容器中的一個錯誤。所有@Inject點需要完成(對於啓用CDI的罐子),在調用@PostConstruct之前。無論是否使用@Startup,並且其中一個bean碰巧是EJB,情況都是如此。

+0

靜態內部類注入是一個巧妙的技巧!感謝您分享此提示。 –

+0

感謝您的快速響應,我已經完成了測試,並確實在@PostConstruct中變量爲null,更多的jar文件存在於META-INF/beans.xml中,但真正的問題是在EBJ容器已經啓動時CDI容器尚未初始化,我在Web上發現了一個解決方案 - 使用開始加載Servlet強制在EJB之前啓動CDI容器。但是這個解決方案對我們來說並不好(我們不會在後端獲取WAR文件,如果任何人有任何其他的想法,我願意提出... – user1917984

0

看看DeltaSpike。有一個CDI控制模塊應該可以做你現在正在尋找的東西。我相信Java EE 7也應該解決這個問題。

+0

你沒有弄錯,我發現這個問題將會是在CDI 1.1 Release中解決了,但是我仍然很驚訝地發現沒有活動的解決方案(除了Servlet的load-on-startup)。 – user1917984

5

大量的研究後,我發現在IBM的球員一些幫助,因爲我們與WebSphere Application Server的工作我可以再補充一個JVM屬性稱爲:

「com.ibm.ws.cdi.immediate。 EJB。開始」 =真

到管理控制檯樣,他將確保一旦我會在@Startup豆的EJB @PostConstruct方法我創建了CDI容器將已經啓動並運行。已注入

它的作品!

這裏是在IBM網站上的鏈接的問題及對策:

http://www-01.ibm.com/support/docview.wss?uid=swg1PM62774

+0

注意這改變了類加載器,導致JPA提供者從Eclipse Link改變到OpenJPA(在WebSphere 8.5.5.4下發現), – Pool