在seam中使用Richfaces使得前台的页面对于后台开发人员来讲变得十分简单,而且在Richfacse的Demo网站上有相当详细的例子,所有的demo源文件也可以下载到。但是也有很多需要注意的地方。如用到rich:tree时, 难免在需要在自己的code中加入org.richfaces.TreeNodeImp或者实现org.richfaces.TreeNode接口,code非常简单,可在运行的时候就没那么容易了,对于jar包的位置要求相对严格了许多。
运行环境:
1. Jboss-4.2.3GA
2. Jboss-seam-2.2.0GA
3. Richfaces-3.3.0.GA.
java文件:
2
3 import java.util.List;
4
5 import org.jboss.seam.ScopeType;
6 import org.jboss.seam.annotations.AutoCreate;
7 import org.jboss.seam.annotations.In;
8 import org.jboss.seam.annotations.Name;
9 import org.jboss.seam.annotations.Scope;
10 import org.richfaces.model.TreeNode;
11 import org.richfaces.model.TreeNodeImpl;
12
13 import com.logile.elm.ta.common.TACommonQueryDAO;
14 import com.logile.elm.ta.workbench.model.AttributeParameter;
15 import com.logile.elm.ta.workbench.model.AttributeType;
16 import com.logile.elm.ta.workbench.model.Fact;
17 import com.logile.elm.ta.workbench.model.RuleHelpNode;
18
19 @Name( " xmlManger " )
20 @Scope(ScopeType.CONVERSATION)
21 @AutoCreate
22 public class XmlManger {
23 @In(create = true )
24 private TACommonQueryDAO taCommonQueryDao;
25
26 private TreeNode < RuleHelpNode > helpNode;
27
28
29
30 public void setupHelp()
31 {
32 if (helpNode == null ){
33 helpNode = new TreeNodeImpl < RuleHelpNode > ();
34 RuleHelpNode help = new RuleHelpNode();
35 helpNode.setData(help);
36 List < Fact > facts = taCommonQueryDao.getFact();
37 for (Fact fact : facts){
38 helpNode.addChild(fact.getDisplayName(), getNodeFromFact(fact));
39 }
40 }
41 }
42
43 private TreeNode < RuleHelpNode > getNodeFromFact(Fact fact)
44 {
45 RuleHelpNode factHelp = new RuleHelpNode();
46 factHelp.setId(fact.getId());
47 factHelp.setType(RuleHelpNode.NODE_TYPE_FACT);
48 factHelp.setIcon(RuleHelpNode.NODE_ICON_FACT);
49 factHelp.setName(fact.getDisplayName());
50 TreeNode < RuleHelpNode > factNode = new TreeNodeImpl < RuleHelpNode > ();
51 factNode.setData(factHelp);
52 for (AttributeType attribute : fact.getAttributeSet()){
53 factNode.addChild(attribute.getDisplayName(), getNodeFromAttribute(attribute));
54 }
55 return factNode;
56 }
57
58 private TreeNode < RuleHelpNode > getNodeFromAttribute(AttributeType attribute){
59 RuleHelpNode attributeHelp = new RuleHelpNode();
60 attributeHelp.setId(attribute.getId());
61 attributeHelp.setName(attribute.getDisplayName());
62 attributeHelp.setType(RuleHelpNode.NODE_TYPE_ATTRIBUTE);
63 if (attribute.getMethodFlag()){
64 attributeHelp.setIcon(RuleHelpNode.NODE_ICON_METHOD);
65 } else {
66 attributeHelp.setIcon(RuleHelpNode.NODE_ICON_FIELD);
67 }
68 TreeNode < RuleHelpNode > attributeNode = new TreeNodeImpl < RuleHelpNode > ();
69 attributeNode.setData(attributeHelp);
70 for (AttributeParameter parameter : attribute.getParameters()){
71 attributeNode.addChild(parameter.getDisplayName(), getNodeFromParameter(parameter));
72 }
73 return attributeNode;
74 }
75
76 private TreeNode < RuleHelpNode > getNodeFromParameter(AttributeParameter parameter){
77 RuleHelpNode paramHelp = new RuleHelpNode();
78 paramHelp.setId(parameter.getId());
79 paramHelp.setName(parameter.getDisplayName());
80 paramHelp.setType(RuleHelpNode.NODE_TYPE_PARAMETER);
81 paramHelp.setIcon(RuleHelpNode.NODE_ICON_PARAMETER);
82 TreeNode < RuleHelpNode > paramNode = new TreeNodeImpl < RuleHelpNode > ();
83 paramNode.setData(paramHelp);
84 return paramNode;
85 }
86
87 public void setHelpNode(TreeNode < RuleHelpNode > helpNode) {
88 this .helpNode = helpNode;
89 }
90
91 public TreeNode < RuleHelpNode > getHelpNode() {
92 return helpNode;
93 }
94
95 }
96
2
3 public class RuleHelpNode {
4
5 private static final long serialVersionUID = 1L ;
6
7 public static final String NODE_TYPE_FACT = " FACT " ;
8 public static final String NODE_TYPE_ATTRIBUTE = " ATTRIBUTE " ;
9 public static final String NODE_TYPE_PARAMETER = " PARAMETER " ;
10
11 public static final String NODE_ICON_FACT = " /img/workbench/node_fact.png " ;
12 public static final String NODE_ICON_FIELD = " /img/workbench/node_field.png " ;
13 public static final String NODE_ICON_METHOD = " /img/workbench/node_method.png " ;
14 public static final String NODE_ICON_PARAMETER = " /img/workbench/node_parameter.png " ;
15
16 private Long id;
17 private String type;
18 private String icon;
19 private String name;
20
21 public Long getId() {
22 return id;
23 }
24
25 public void setId(Long id) {
26 this .id = id;
27 }
28
29 public String getType() {
30 return type;
31 }
32
33 public void setType(String type) {
34 this .type = type;
35 }
36
37 public String getIcon() {
38 return icon;
39 }
40
41 public void setIcon(String icon) {
42 this .icon = icon;
43 }
44
45 public String getName() {
46 return name;
47 }
48
49 public void setName(String name) {
50 this .name = name;
51 }
52
53 }
54
Xhtml code:
2 value ="#{xmlManger.helpNode}" id ="tree" var ="item"
3 nodeFace ="#{item.type}" rendered ="#{xmlManger.helpNode != null}" >
4 < rich:treeNode type ="FACT" iconLeaf ="#{item.icon}" icon ="#{item.icon}" >
5 < h:outputText value ="#{item.name}" />
6 </ rich:treeNode >
7 < rich:treeNode type ="ATTRIBUTE" iconLeaf ="#{item.icon}" icon ="#{item.icon}" >
8 < h:outputText value ="#{item.name}" />
9 </ rich:treeNode >
10 < rich:treeNode type ="PARAMETER" iconLeaf ="#{item.icon}" icon ="#{item.icon}" >
11 < h:outputText value ="#{item.name}" />
12 </ rich:treeNode >
13 </ rich:tree >
代码就是这么简单,可已发布问题就来了。
第一个问题:java.lang.NoClassDefFoundError: org/richfaces/model/TreeNode,jboss直接无法启动。
说 明: 在EAR和WAR的WEB-INF/lib下面都已经有richfaces-api.jar、richfaces-impl.jar、richfaces-ui.jar了。
解决方法:尝试着将richfaces-*.jar复制到/server/defaut/lib中,问题貌似解决,结果高兴早了。
第二问题: org.richfaces.model.TreeNodeImpl cannot be cast to javax.swing.tree.TreeNode,正常启动,但是前台页面无法显示。
说明:在程序中从未使用过javax.swing.tree.TreeNode。
解决方法:1. /server/defaut/lib中只保留richfaces-api.jar;2. EAR下面只保留richfaces-api.jar; 3. WAR的WEB-INF/lib下面只保留richfaces-impl.jar、richfaces-ui.jar。发布,重启jboss ,一切正常。
问题总结:
1. 在用到rich:tree或者说在自己的code里面需要引用Richfaces,需要特别的注意richfaces-*.jar的位置。
2. 问题解决了,问题的根源是什么,为什么一定要按上面的位置来放jar包?
猜想:问题1--jboss启动时依赖的jar包在/server/defaut/lib中;
问题2--EAR工程中,JAR和WAR貌似使用了不同的classLoader,但是都受EAR的控制。
至于真正的原因,希望看到这篇文章的人能给予指出,不胜感激。