是否有人使用JSF的MyFaces 2.1.x实现使用JSF 2运行Seam Mail(Seam 2.3)?
我无法使Seam Mail工作,因为无法创建Seam的org.jboss.seam.faces.renderer
组件。它具有与com.sun.faces.facelets.Facelet
的类依赖关系,并且MyFaces中不存在此类。
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.faces.renderer")
@AutoCreate
@Install(value = true, precedence = Install.BUILT_IN,
classDependencies = "com.sun.faces.facelets.Facelet")
public class FaceletsRenderer extends Renderer {
...
}
因此,以下语句失败,并且“@In属性需要非空值”异常。
@In(create = true)
private Renderer renderer;
我该怎么办?我是否还应该从Mojarra实现添加jsf-api?!
干杯 弗兰克
答案 0 :(得分:3)
好的我修好了!
我刚用自己的组件替换了错误的Seam FaceletsRenderer:
@Scope(ScopeType.STATELESS)
@BypassInterceptors
@Name("org.jboss.seam.faces.renderer")
@AutoCreate
@Install(value = true, precedence = Install.APPLICATION)
// dependency to the evil Sun JSF class is removed:
// , classDependencies = "com.sun.faces.facelets.Facelet")
public class FaceletsRenderer extends Renderer {
/**
* Render the viewId, anything written to the JSF ResponseWriter is returned
*/
@Override
public String render(final String viewId) {
// call our fixed RendererRequest class instead of the original one.
de.jw.filesio.webapp.renderer.RendererRequest rendererRequest = new de.jw.filesio.webapp.renderer.RendererRequest(
viewId);
try {
rendererRequest.run();
} catch (IOException e) {
throw new RuntimeException("error rendering " + viewId, e);
}
return rendererRequest.getOutput();
}
}
Seam-Ui的原始RendererRequest
类与Sun JSF结合良好,因此您还必须更换它。只需要修复方法faceletForViewId(String)
。你走了:
/**
* Get a Facelet for a URL
*/
protected Facelet faceletForViewId(String viewId) throws IOException {
URL url = ResourceLoader.instance().getResource(viewId);
if (url == null) {
throw new IllegalArgumentException("resource doesn't exist: " + viewId);
}
// OLD CODE tightly coupled to Sun JSF
// return
// ApplicationAssociate.getCurrentInstance().getFaceletFactory().getFacelet(url);
// NEW CODE for MyFaces
// see
// http://stackoverflow.com/questions/15813582/how-to-programmatically-instantiate-a-composite-component-or-a-tag-component
FaceletFactory ff = DefaultFaceletFactory.getInstance();
if (ff == null) {
FaceletViewDeclarationLanguage vdl = new FaceletViewDeclarationLanguage(facesContext);
Method createCompiler = null;
Method createFaceletFactory = null;
try {
createCompiler = FaceletViewDeclarationLanguage.class.getDeclaredMethod("createCompiler",
FacesContext.class);
createFaceletFactory = FaceletViewDeclarationLanguage.class.getDeclaredMethod("createFaceletFactory",
FacesContext.class, org.apache.myfaces.view.facelets.compiler.Compiler.class);
createCompiler.setAccessible(true);
createFaceletFactory.setAccessible(true);
org.apache.myfaces.view.facelets.compiler.Compiler compiler = (org.apache.myfaces.view.facelets.compiler.Compiler) createCompiler
.invoke(vdl, facesContext);
ff = (FaceletFactory) createFaceletFactory.invoke(vdl, facesContext, compiler);
} catch (Exception ex) {
log.error("Error creating FaceletFactory.", ex);
}
}
Facelet facelet = null;
try {
facelet = ff.getFacelet(url);
} catch (Exception ex) {
log.error("Error creating facelet for url " + url, ex);
}
log.debug("Successfully created facelet for " + url + ": " + facelet);
return facelet;
}
我希望这有助于其他人面对我的问题。