-
1. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 21, 2008 3:57 PM (in response to nimo22)Where are you programmatically building your richfaces component ? Is it in an EJB3 ? If so richfaces jar cannot be seen from ejb module. The webapp classloader is further down the classloader hierarchy.
Try moving your richfaces creational code in a regular pojo living in your war and tell me your results.
-
2. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 21, 2008 3:59 PM (in response to nimo22)another solution would be to move up your richfaces jar in the lib dir of your EAR file though I don't recommend it, richfaces stuff should stay at the web layer.
-
3. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
blabno Aug 21, 2008 4:12 PM (in response to nimo22)I've have my rich:tree creating/updating code in EJB jar, but your solution remark
Try moving your richfaces creational code in a regular pojo living in your waris clever to me. I can still inject into such pojo reference to my EJB with business logic. Thanks for that hint.
-
4. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 21, 2008 9:20 PM (in response to nimo22)Yes, the source of my RichFaces-Component is in an EJB3-SessionBean.
You say
richfaces stuff should stay at the web layer
.Why? Because of keeping the MVC?
I generate an UI-component in a SessionBean. Looking at the SEAM-Reference (7.10. Conversational components and JSF component
bindings), there is a UI-component not embedded in a regular pojo.But I will do that:
Try moving your richfaces creational code in a regular pojo living in your warBernard says:
I can still inject into such pojo reference to my EJB with business logicDo you inject the class with its empty constructer? What about dynamic htmlTables needing business logic such as retrieving the values from the database and put it in the datatable. I do not want to place such code in my WAR-File..
Can u provide an example, what is the best case to generate UI components in EJB via JAVA-CODE?
I can not find any information about the best way.
For example, look at this pojo:
public class Grid implements GridLocal { private HtmlPanelGrid htmlPanelGrid; private HtmlOutputLabel outputLabel; // getters/setters public Grid() { } public Grid(HtmlPanelGrid htmlPanelGrid, HtmlOutputLabel outputLabel) { super(); this.htmlPanelGrid = htmlPanelGrid; this.outputLabel = outputLabel; List<UIComponent> children = htmlPanelGrid.getChildren(); List children = htmlPanelGrid.getChildren(); for (int count = 0; count < 10; count++) { outputLabel = new HtmlOutputLabel(); htmlPanelGrid.getChildren().add(outputLabel); } } }
How I inject this component in an EJB Session Bean?
I tried it with:@In (create=true) Grid newGrid;
but obviously, the session-bean called the empty-constructer, therefore no components are generated.
Another point is:
When I do this in my SESSION-BEAN...
@Factory("newGrid") public HtmlPanelGrid getGrid() { for (int count = 0; count < 10; count++) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); grid.getChildren().add(outputLabel); return grid; }
and bind this factory in my view:
<h:panelGrid binding="#{newGrid}"></h:panelGrid>
...then all works fine!
But I have the UI-Code in my SessionBean !!!
So what is the best-case to generate UI via JAVA-Code in SEAM ???
-
5. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 21, 2008 10:28 PM (in response to nimo22)I'm not saying it's not possible to use richfaces classes in EJB3, the reason why I recommend putting this in the WAR is because this is view related logic. This way you keep business methods in EJB3 which are view-agnostic allowing for better re-usability among clients. Maybe in your case the only client is the webapp but even in this case you will end up with a better architected solution.
You can define a seam managed pojo and store in your war file:
@Name("foo") @Scope(ScopeType.CONVERSATION) public class Foo { @In MySessionEJBInterface mySessionEjb; @Factory("newGrid") public HtmlPanelGrid createGrid() { Data data = mySessionEjb.getData(); // populate grid with data return grid; } }
When you say you can put richfaces class references in your session ejb, did you leave your richfaces jars in the WAR WEB-INF/lib and/or you moved/copied them in EAR/lib or server/lib ? Using
@Factory
versus some other methods to instantiate your richfaces component should have no impacts on ClassLoading. ClassLoading rules are not specific to Seam but are specific to the J2EE container you are using. See JBoss ClassLoading Overview -
6. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 22, 2008 12:39 PM (in response to nimo22)Hello Guillaume,
I tried to do it as you said as it sounds good:-)
Look at my view-logic, which works well:
@Stateful @Name("dataTable") @Scope(CONVERSATION) public class DataTable implements DataTableLocal { @In private EntityManager entityManager; @Factory("newGrid") public HtmlPanelGrid createGrid() { HtmlPanelGrid grid = new HtmlPanelGrid(); List <Entity> test = entityManager.createQuery("from Entity e").getResultList(); for (Entity e: entity) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); outputLabel.setValue("Hello World:-) "+ e); grid.getChildren().add(outputLabel); } return grid; } @Destroy @Remove public void destroy() {} }
Now, I want to inject my EJB-SessionBean, instead of the EntityManager to retrieve the values from there.
Look at my view-logic, which does NOT work:@Stateful @Name("dataTable") @Scope(CONVERSATION) public class DataTable implements DataTableLocal { // now I inject my EJB-SessionBean @In (create=true, required=false) TestEJBBean myTestLocal; @Factory("newGrid") public HtmlPanelGrid createGrid() { List <Entity> test= myTestLocal.getEntityList(); HtmlPanelGrid grid = new HtmlPanelGrid(); for (Entity e: entity) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); outputLabel.setValue("Hello World:-) "+ e); grid.getChildren().add(outputLabel); } return grid; } @Destroy @Remove public void destroy() {} }
In my TestEJBBean exists the method:
... @In (create=true) private EntityManager entityManager; ... @Factory("entityList") public List <Entity> getEntityList() { return entityManager.createQuery("from Entity e").getResultList(); }
By injecting the TestEJBBean, the following error occurs:
Caused by: java.lang.NullPointerException at com.DataTable.createGrid(DataTable.java:40) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112) at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166) at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44) at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:5
I assume that my Converation-Scope in the class DataTable needs an entityManager explicitly.
How can I solve that?
-
7. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 22, 2008 3:17 PM (in response to nimo22)Your DataTable class is also an EJB due to
@Stateful
so you are not following my recommendations here. In any case it shouldnt affect the NPE you are getting.Can you post the TestEJBBean declaration and class level annotations ?
-
8. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 22, 2008 4:28 PM (in response to nimo22)Thanks for helping:-)
Okay, my TestEJBBean declaration and class level annotations:
@Stateful @Name("userManager") @Scope(CONVERSATION) public class TestEJBBean implements TestEJBLocal { ... @In (create=true) private EntityManager em; @Factory("setup") @Begin(join = true) public void myTest() { ... } @Factory("entityList") public List <Entity> getEntityList() { return entityManager.createQuery("from Entity e").getResultList(); } .... }
(I do not know, if this matters: SEAM-Manual 7.10. Conversational components and JSF component bindings)
Do you need more informations?
I tried to change the scope of TestEJBBean from conversation to session, but this did not help. I also changed my DataTable.java to a regular POJO:
@Name("dataTable") public class DataTable { .. }
but the same problem still occurs.
-
9. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 22, 2008 4:41 PM (in response to nimo22)I think the injection in DataTable doesnt work:
@In (create=true, required=false) TestEJBBean myTestLocal;
Seam will try to find a seam component named myTestLocal.
@Name("userManager")
is the seam component name you gave to TestEJBBean class. Either rename it to:
@Name("myTestLocal")
or rename your variable name in Datatable class to
@In (create=true, required=false) TestEJBBean userManager;
You also want a reference to your EJB interface injected otherwise you will have problems so you can use this:
@In (create=true) TestEJBLocal userManager;
-
10. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 25, 2008 1:12 PM (in response to nimo22)hello Guillaume,
great, that was my fault! Now, my View can be generated via JAVA-Code.
As I want to decouple my SessionBean from my view,
I store all view-related things in my WAR-File.With the @EJB or @In,
I can access all the methods via Interfaces from the SessionBeans.BUT:
What about the SCOPE of my (GUI-)POJO stored in WEB-INF ?
In the SEAM-Reference 7.10. Conversational components and JSF component bindings, it is shown, that I have to declare the SCOPE of my GUI-POJO as an EVENT and inject it in my SESSION-BEAN to retrieve the values from the GUI-Instance.
My Intention is, to search the best-practice, buildung JSF-GUIs via JAVA-Code, as JAVA-Code generated Views are faster than using JSF-Tags.
Should I really inject the GUI-POJO to my SessionBean to retrieve the values coming from the view? Is this best-practice?
Look at the following scenario:
My View:
@Name("viewRegisterUser") public class DataTable { ... @In (create=true) TestEJBLocal userManager; //generating the VIEW List <Entity> test= myTestLocal.getEntityList(); HtmlPanelGrid grid = new HtmlPanelGrid(); for (Entity e: entity) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); outputLabel.setValue("Hello World:-) "+ e); grid.getChildren().add(outputLabel); } return grid; } HtmlInputText username = new HtmlInputText(); HtmlInputText password = new HtmlInputText(); // calling the method from SessionBean userManager.registerUser(username.getValue, password.getValue); }
My SessionBean:
@Stateful @Name("userManager") @Scope(CONVERSATION) public class TestEJBBean implements TestEJBLocal { .. // I do not need the Factory-Annotation anymore !! // the Values of the Query will automatically retrieved, // when the Client calls the method public List <Entity> getEntityList() { return entityManager.createQuery("from Entity e").getResultList(); } public void registerUser(String username, String password) {..} }
You see, my View has no SCOPE, so what I am wondering is, how can I access the values from my view? Is there a better solution for all that ? (I used JSF-Tags before and retrieved the values directly from my xhtml. I know, this is common practice, but I do not want to use Tags.)
I think, to decouple the view from my sessionBean, I have to retrieve the values coming from the view-instance directly in my view-logic and call the business-logic via Interfaces. This is, what EJB suggests! What do you think about?
-
11. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 25, 2008 2:06 PM (in response to nimo22)Hmm..am I right with my assumption:
I have to develop an JSF-backing-bean and a SFSB and need to have an injection of the SFSB in my JSF-backing-bean.And In the JSF-backing-bean, I construct my CONVERSATION-SCOPE?
So I have to do delete the Scope from my SFSB:
Stateful @Name("userManager") // @Scope(CONVERSATION) deleted in my SFSB public class TestEJBBean implements TestEJBLocal {..}
and put the Scope to my JSF-backing-bean which is placed in WEB-INF/classes:
@Name("viewRegisterUser") @Scope(CONVERSATION) public class DataTable { @In (create=true) TestEJBLocal userManager; @Begin(join=true) public HTMLDataTable getHtmlDataTable() { //generating the VIEW List <Entity> test= myTestLocal.getEntityList(); HtmlPanelGrid grid = new HtmlPanelGrid(); for (Entity e: entity) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); outputLabel.setValue("Hello World:-) "+ e); grid.getChildren().add(outputLabel); } return grid; } HtmlInputText username = new HtmlInputText(); HtmlInputText password = new HtmlInputText(); // calling the method from SessionBean @End public void end() { userManager.registerUser(username.getValue, password.getValue); }
SEAM does not need managedBeans, but EJB does..?!
-
12. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
gjeudy Aug 25, 2008 4:17 PM (in response to nimo22)
nimo mayr wrote on Aug 25, 2008 14:06:
Hmm..am I right with my assumption:
I have to develop an JSF-backing-bean and a SFSB and need to have an injection of the SFSB in my JSF-backing-bean.JSF-backing-bean is configured in faces-config.xml, you don't need this when using Seam. I suggest you read more Seam documentation to get familiar with the framework and it's purpose.
And In the JSF-backing-bean, I construct my CONVERSATION-SCOPE?A scope cannot be constructed but can only be declared again, refer to Seam reference doc and examples packaged in the distribution...
So I have to do delete the Scope from my SFSB:Stateful @Name("userManager") // @Scope(CONVERSATION) deleted in my SFSB public class TestEJBBean implements TestEJBLocal {..}
and put the Scope to my JSF-backing-bean which is placed in WEB-INF/classes:@Name("viewRegisterUser") @Scope(CONVERSATION) public class DataTable { @In (create=true) TestEJBLocal userManager; @Begin(join=true) public HTMLDataTable getHtmlDataTable() { //generating the VIEW List <Entity> test= myTestLocal.getEntityList(); HtmlPanelGrid grid = new HtmlPanelGrid(); for (Entity e: entity) { HtmlOutputLabel outputLabel = new HtmlOutputLabel(); outputLabel.setValue("Hello World:-) "+ e); grid.getChildren().add(outputLabel); } return grid; } HtmlInputText username = new HtmlInputText(); HtmlInputText password = new HtmlInputText(); // calling the method from SessionBean @End public void end() { userManager.registerUser(username.getValue, password.getValue); }
SEAM does not need managedBeans, but EJB does..?!I don't understand your last question. Seam is a framework that manages beans declared with the @Name or declared in components.xml files. These beans can be either POJOs or EJBs. EJBs are themselves managed by the EJB container (your J2EE application server). When you declare for example
@Stateless @Name("myEjb")
you are declaring your class as an EJB and a seam component. When you inject such a component with a seam In annotation; Seam will lookup the EJB in the EJB container, perform any injections on it and set the In-annotated instance variable.
-
13. Re: SEAM and Caused by: java.lang.NoClassDefFoundError:
nimo22 Aug 25, 2008 5:24 PM (in response to nimo22)Sorry, my question was a little vague but now, I understand. Thanks!
It would be fine to get the opportunity to implement the GUI only via JAVA-Code in relation to SEAM and EJB. I know, I can dynamically generate the view in JAVA via JSF-API..but..
Look at Wicket, GWT, jSeamless or wingsframework.
I know, Seam can handle GWT or Wicket, but I do not know, if EJB can do also in an performant and reliably manner. I try.
Thanks!