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.)