Instance lookup doesn't find implementations in WAR file.
verborghs Sep 14, 2010 5:38 PMI have a enterprise project with an ejb and web project in it.
The webproject uses what is an attempt at an CDI MVC framework i'm working on. The MVC framework is it's own jar. referenced by the webproject.
in the mcv framework i have a @ApplicationScoped
public class QualifierMappersProducer { @Inject @Any Instance<de.feo.mvc.spi.QualifierMapper> mappers; @Produces public List<QualifierMapper> getMappers() { List<QualifierMapper> mappersLst = new LinkedList<QualifierMapper>(); Iterator<de.feo.mvc.spi.QualifierMapper> mappersIter = mappers.iterator(); while (mappersIter.hasNext()) { de.feo.mvc.spi.QualifierMapper mapper = mappersIter.next(); System.out.println(mapper); mappersLst.add(mapper.getClass().getAnnotation(QualifierMapper.class)); } Collections.sort(mappersLst, new Comparator<QualifierMapper>() { @Override public int compare(QualifierMapper o1, QualifierMapper o2) { return new Integer(o1.priority()).compareTo(new Integer(o2.priority())); } }); return mappersLst; } }
There is also an implementation of a default QualifierMapper in this mvc project:
@de.feo.mvc.spi.annotations.QualifierMapper(name="ControllerActionURL", priority=99) public class ControllerActionURLQualifierMapper implements QualifierMapper { private static class ControllerQualifier extends AnnotationLiteral<Controller> implements Controller { private final String value; public ControllerQualifier(String value) { this.value = value; } @Override public String value() { return value; } } private static class ActionQualifier extends AnnotationLiteral<Action> implements Action { private final String value; private final String method; public ActionQualifier(String value, String method) { this.value = value; this.method = method; } @Override public String value() { return value; } @Override public String method() { return method; } } private static final Pattern URL_PATTERN = Pattern.compile("/([^/]+)(/([^/]+))?.*"); @Inject private HttpServletRequest req; @Override public boolean isRelevant() { String path = req.getPathInfo(); Matcher controllerMatcher = URL_PATTERN.matcher(path); return controllerMatcher.matches(); } @Override public List<? extends Annotation> getQualifiers() { String path = req.getPathInfo(); String controllerName = null; String actionName = null; if (path != null) { Matcher controllerMatcher = URL_PATTERN.matcher(path); if (controllerMatcher.find()) { controllerName = controllerMatcher.group(1); actionName = controllerMatcher.group(3); } } controllerName = controllerName == null ? "index" : controllerName; actionName = actionName == null ? "index" : actionName; //DETERMINE METHOD String httpMethod = "GET"; String methodParam = req.getParameter("_method"); if(methodParam == null || methodParam.trim().isEmpty()) { methodParam = req.getMethod(); } else if(Arrays.asList("DELETE", "PUT", "GET", "POST").contains(methodParam)) { httpMethod = methodParam; } ControllerQualifier controllerQualifier = new ControllerQualifier(controllerName); ActionQualifier actionQualifier = new ActionQualifier(actionName, httpMethod); return Arrays.asList(controllerQualifier, actionQualifier); } }
In the web application I have a custom QualifierMapper:
@de.feo.mvc.spi.annotations.QualifierMapper(name = "ApplicationMapper", priority = 25) public class ApplicationMapper implements QualifierMapper { private static class ControllerQualifier extends AnnotationLiteral<Controller> implements Controller { private final String value; public ControllerQualifier(String value) { this.value = value; } @Override public String value() { return value; } } private static class ActionQualifier extends AnnotationLiteral<Action> implements Action { private final String value; private final String method; public ActionQualifier(String value, String method) { this.value = value; this.method = method; } @Override public String value() { return value; } @Override public String method() { return method; } } @Inject private HttpServletRequest req; @Override public boolean isRelevant() { String path = req.getPathInfo(); return (path != null && (path.startsWith("/v2/"))); } @Override public List<? extends Annotation> getQualifiers() { String path = req.getPathInfo(); //main Pattern MAIN_PATTERN = Pattern.compile("/v2/main$"); if (path != null) { Matcher controllerMatcher = MAIN_PATTERN.matcher(path); if (controllerMatcher.find()) { ControllerQualifier controllerQualifier = new ControllerQualifier("main"); ActionQualifier actionQualifier = new ActionQualifier("show", req.getMethod()); return Arrays.asList(controllerQualifier, actionQualifier); } } // SOME MORE PATHS //... // UNRECOGNIZED PATH return Collections.emptyList(); } }
When I run this through a servlet:
@WebServlet(name = "DispatcherServlet", urlPatterns = {"/mvc/*"}) @MultipartConfig(location="/Applications/NetBeans/glassfish-3.0.1/glassfish/domains/domain1/upload") public class DispatcherServlet extends HttpServlet { @Inject private BeanManager beanManager; @Inject private Event<ActionEvent> event; @Inject private List<de.feo.mvc.spi.annotations.QualifierMapper> mapperAnnotations; @Inject @Any private Instance<QualifierMapper> mappers; @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //DETERMINE QUALIFIERS FROM URLMAPPERS Annotation[] annotations = new Annotation[0]; for (de.feo.mvc.spi.annotations.QualifierMapper mapperAnnotation : mapperAnnotations) { System.out.println(mapperAnnotation.name()); QualifierMapper mapper = mappers.select(mapperAnnotation).get(); if(mapper.isRelevant()) { annotations = (Annotation[]) mapper.getQualifiers().toArray(); break; } } //FIRE EVENT WITH QUALIFIERS event.select(annotations).fire(new ActionEvent()); } }
It only finds the QualifierMapper in the mvc lib, and not the one in the web project
(in a side note, i have notices that META-INF/service/javax.whatever
.Extension is ignored in a war file that is inside an ear file, not the case for a standalone war file.)