I have a filter where I am dinamically mapping servlet classes:
@Override
public void init( FilterConfig filterConfig ) throws ServletException {
servletContext = filterConfig.getServletContext();
File directory = getConventionDirectory();
FileSystemInspector fileInspector = new FileSystemInspector();
Set<ActionInfoData> actions = fileInspector.getActions( directory );
for ( ActionInfoData action : actions ) {
servletContext
.addServlet( action.getServletName(), action.getClassName() )
.addMapping( action.getServletMapping() );
}
}
Then when I access a given mapping the EJB is not injected.
@EJB
private I18nManager i18nManager;
@Override
protected void doGet( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
I18nManager i18n = i18nManager; //null
}
If I manually create a mapping in the web.xml the given EJB is working in that servlet. It makes me wonder if the fact I am registering the servlets at runtime the container does not consider those servlets as managed.
If that is the case what is the proper way to inject the EJBs into my servlets without changing the way they are dinamically registered via filter?
Is via JNDI the only way to inject my EJBs?
EDIT 1:
I have tried to implement a ServletContextListener
class as suggested by "Will" using the following code in the web.xml
:
<listener>
<listener-class>com.megafone.web.filter.convention.InitServlet</listener-class>
</listener>
And the relevant part of the implementation:
...
@Override
public void contextInitialized( ServletContextEvent sce ) {
ServletContext servletContext = sce.getServletContext();
FileSystemInspector fileInspector = new FileSystemInspector();
Set<ActionInfoData> actions = fileInspector.getActions( getConventionDirectory() );
for ( ActionInfoData action : actions ) {
servletContext
.addServlet( action.getServletName(), action.getClassName() )
.addMapping( action.getServletMapping() );
}
}
...
Unfortunately it does not make the container inject the EJBs and the null pointer remains. I am currently making a custom type safe JNDI lookup to the service. Obviously this is far more expensive than using the proper injection (correct me if I am wrong, have done no experiments regarding performance yet).
Using:
Java EE 6
JBoss AS 7.1