[jbossseam-issues] [JBoss JIRA] Commented: (JBSEAM-3368) conversation id evaluated to null (natural conversations)

Shane Bryzak (JIRA) jira-events at lists.jboss.org
Fri Sep 26 00:20:20 EDT 2008


    [ https://jira.jboss.org/jira/browse/JBSEAM-3368?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12431293#action_12431293 ] 

Shane Bryzak commented on JBSEAM-3368:
--------------------------------------

Does this issue only occur if it's a war project in Tomcat?  Or does it also happen in JBossAS?

> conversation id evaluated to null (natural conversations)
> ---------------------------------------------------------
>
>                 Key: JBSEAM-3368
>                 URL: https://jira.jboss.org/jira/browse/JBSEAM-3368
>             Project: Seam
>          Issue Type: Bug
>          Components: Core
>    Affects Versions: 2.0.3.CR1
>         Environment: Linux Ubuntu 7.10, Intel Pentium 4, 3GHz, 1 GB RAM, Tomcat 6.0.16
>            Reporter: Arron Ferguson
>            Assignee: Shane Bryzak
>            Priority: Critical
>             Fix For: 2.1.0.GA
>
>
> If the user attempts to go to a page that is restricted based on what is in the pages.xml file, two things go wrong: 1) an exception is thrown (java.lang.IllegalStateException: conversation id evaluated to null: [name of natural conversation]), 2) the user can still view the page that is supposed to be restricted (i.e., using the restrict element in the pages.xml file).
> Setup Instructions:
> 1.) Set up Tomcat 6.x
> 2.) Create web app project structure
> 3.) Use the following for your pages.xml file (copy/paste):
> <?xml version="1.0" encoding="UTF-8"?>
> <pages xmlns="http://jboss.com/products/seam/pages"
>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>        xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd"
>        http-port="8080" https-port="8443"
>        no-conversation-view-id="/index.xhtml"
>                  login-view-id="/index.xhtml">
>   <conversation name="regmem"
>     parameter-name="memberID"
>     parameter-value="#{memberreg.tempKey}"/>
>   <page view-id="*" scheme="http" />
>   <page view-id="/register.xhtml">
>     <description>Register Member: #{memberreg}</description>
>     <navigation from-action="#{memberreg.start}">
>       <begin-conversation join="true" conversation="regmem"/>
>       <redirect view-id="/register1.xhtml"/>
>     </navigation>
>     <navigation>
>       <rule if="#{identity.loggedIn}">
>         <redirect view-id="/memberadmin.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.acceptedInformation}">
>         <redirect view-id="/register3.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.agree}">
>         <redirect view-id="/register2.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.started}">
>         <redirect view-id="/register1.xhtml"/>
>       </rule>
>     </navigation>
>   </page>
>   <page view-id="/register1.xhtml" conversation-required="true"
>     conversation="regmem">
>     <description>Register Member: #{memberreg}</description>
>     <restrict>#{memberreg.started}</restrict>
>     <navigation from-action="#{memberreg.agreeToLicense}">
>       <redirect view-id="/register2.xhtml"/>
>     </navigation>
>     <navigation from-action="#{memberreg.cancel}">
>       <end-conversation/>
>       <redirect view-id="/index.xhtml"/>
>     </navigation>
>     <navigation>
>       <rule if="#{identity.loggedIn}">
>         <redirect view-id="/memberadmin.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.acceptedInformation}">
>         <redirect view-id="/register3.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.agree}">
>         <redirect view-id="/register2.xhtml"/>
>       </rule>
>     </navigation>
>   </page>
>   <page view-id="/register2.xhtml" conversation-required="true"
>     conversation="regmem">
>     <description>Register Member: #{memberreg}</description>
>     <restrict>#{memberreg.agree}</restrict>
>     <navigation from-action="#{memberreg.next}">
>       <rule if="#{memberreg.readyToConfirm}">
>         <redirect view-id="/register3.xhtml"/>
>       </rule>
>       <rule if="#{not memberreg.readyToConfirm}">
>         <redirect view-id="/register2.xhtml"/>
>       </rule>
>     </navigation>
>     <navigation>
>       <rule if="#{identity.loggedIn}">
>         <redirect view-id="/memberadmin.xhtml"/>
>       </rule>
>       <rule if="#{memberreg.acceptedInformation}">
>         <redirect view-id="/register3.xhtml"/>
>       </rule>
>     </navigation>
>   </page>
>   <page view-id="/register3.xhtml" conversation-required="true"
>     conversation="regmem">
>     <description>Register Member: #{memberreg}</description>
>     <restrict>#{memberreg.readyToConfirm}</restrict>
>     <navigation from-action="#{memberreg.acceptInformation}">
>       <redirect view-id="/register4.xhtml"/>
>     </navigation>
>     <navigation from-action="#{memberreg.editInformation}">
>       <redirect view-id="/register2.xhtml"/>
>     </navigation>
>     <navigation>
>       <rule if="#{identity.loggedIn}">
>         <redirect view-id="/memberadmin.xhtml"/>
>       </rule>
>     </navigation>
>   </page>
>   <page view-id="/register4.xhtml" conversation-required="true"
>     conversation="regmem">
>     <description>Register Member: #{memberreg}</description>
>     <restrict>#{memberreg.acceptedInformation}</restrict>
>     <navigation from-action="#{memberreg.end}">
>       <end-conversation before-redirect="false"/>
>       <redirect view-id="/index.xhtml"/>
>     </navigation>
>   </page>
>   <!-- START EXCEPTIONS -->
>   <exception class="org.jboss.seam.security.NotLoggedInException" log="false">
>     <redirect view-id="/index.xhtml">
>       <message severity="warn">Your session ended or expired.</message>
>     </redirect>
>   </exception>
>   <exception class="org.jboss.seam.security.AuthorizationException" log="false">
>     <end-conversation/>
>     <redirect view-id="/index.xhtml">
>       <message severity="warn">You are not authorized.</message>
>     </redirect>
>   </exception>
>   <!-- END EXCEPTIONS -->
> </pages>
> 4.) Create two Java classes (registration bean and POJO):
> Registration Bean:
> package com.test;
> import javax.ejb.Remove;
> import javax.persistence.Column;
> import javax.persistence.NoResultException;
> import java.io.Serializable;
> import java.util.Date;
> import javax.persistence.EntityManager;
> import org.jboss.seam.annotations.In;
> import org.jboss.seam.annotations.End;
> import org.jboss.seam.annotations.Destroy;
> import org.jboss.seam.annotations.Name;
> import org.jboss.seam.annotations.Out;
> import org.jboss.seam.annotations.Scope;
> import org.jboss.seam.faces.FacesMessages;
> import org.jboss.seam.faces.Renderer;
> import static org.jboss.seam.ScopeType.CONVERSATION;
> @Scope(CONVERSATION)
> @Name("memberreg")
> public class MemberRegistrationAction implements Serializable
> {
>     private static long tempKey = 0;
>     @Out(required = false) @In(required = false)
>     private Member newMember;
>     @In(create = true)
>     private Renderer renderer;
>     private boolean started = false;
>     private boolean agree = false;
>     private boolean acceptedInformation = false;
>     private boolean readyToConfirm = false;
>     private boolean stillNeedsToEdit = false;
>     private String confirm = "";
>     public String getConfirm() { return confirm; }
>     public void setConfirm(String confirm) { this.confirm = confirm; }
>     public long getTempKey() { return tempKey; }
>     public void setTempKey(long tempKey) { this.tempKey = tempKey; }
>     public Member getNewMember() { return newMember; }
>     /////////////////////////////////////////////
>     // CONVERSATION METHODS
>     /////////////////////////////////////////////
>     public void start()
>     {
>         newMember = new Member();
>         if(tempKey >= Long.MAX_VALUE)
>         {
>             tempKey = 0;
>         }
>         tempKey++;
>         started = true;
>     }
>     public void agreeToLicense() { agree = true; }
>     public void cancel()
>     {
>       started = false;
>       agree = false;
>       acceptedInformation = false;
>       readyToConfirm = false;
>       stillNeedsToEdit = false;
>     }
>     public void next() { readyToConfirm = this.verify(); }
>     private boolean verify() {
>         return true; // test purposes, always true
>     }
>     public void acceptInformation()
>     {
>         acceptedInformation = true;
>         stillNeedsToEdit = false;
>         this.complete();
>     }
>     public void editInformation()
>     {
>         stillNeedsToEdit = true;
>         acceptedInformation = false;
>     }
>     private void complete() {
>         ; // write to JPA/Hibernate
>     }
>     public void end() {
>         ; // something, something, something, dark side
>     }
>     /////////////////////////////////////////////
>     public boolean isStarted() { return started; }
>     public boolean isAgree() { return agree; }
>     public boolean isAcceptedInformation() { return acceptedInformation; }
>     public boolean isReadyToConfirm() { return readyToConfirm; }
>     public boolean isStillNeedsToEdit() { return stillNeedsToEdit; }
>     public void destroy()
>     {
>       started = false;
>       agree = false;
>       acceptedInformation = false;
>       readyToConfirm = false;
>       stillNeedsToEdit = false;
>     }
> }
> POJO:
> package com.test;
> import java.io.Serializable;
> import javax.persistence.Column;
> import javax.persistence.Entity;
> import javax.persistence.GeneratedValue;
> import javax.persistence.Id;
> import javax.persistence.Table;
> import org.hibernate.validator.Length;
> import org.hibernate.validator.NotEmpty;
> import org.hibernate.validator.NotNull;
> import org.jboss.seam.annotations.Name;
> @Entity @Name("member") @Table(name="member")
> public class Member implements Serializable {
>     @Id
>     @GeneratedValue
>     @Column(name = "id")
>     private long id = -1;
>     @NotNull
>     @Length(min=2, max=20, message="Must be between 2 and 20 chars long")
>     @Column(name = "lastname")
>     private String lastName;
>     @NotNull
>     @Length(min=2, max=20, message="Must be between 2 and 20 chars long")
>     @Column(name = "firstname")
>     private String firstName;
>     public long getId() { return id; }
>     public void setId(long id) { this.id = id; }
>     public String getLastName() { return lastName; }
>     public void setLastName(String lastName) { this.lastName = lastName; }
>     public String getFirstName() { return firstName; }
>     public void setFirstName(String firstName) { this.firstName = firstName; }
>    @Override
>    public String toString()  { return firstName + " " + lastName; }
> }
> 5.) Create XHTML files (template, index, register1 - register4):
> ///////////////////////////////////
> template.xhtml:
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
>           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:h="http://java.sun.com/jsf/html"
>       xmlns:f="http://java.sun.com/jsf/core" >
>   <head>
>     <title>something.com</title>
>   </head>
>   <body>
>     <div>
>       <h:messages globalOnly="true"/><br/><br/>
>       <ui:insert name="maincontent">
>       </ui:insert>
>     </div>
>   </body>
> </html>
> ///////////////////////////////////
> index.html:
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:s="http://jboss.com/products/seam/taglib">
>     <!-- <ui:composition template="./template.xhtml"> -->
>   <ui:composition template="./template.xhtml">
>     <ui:define name="maincontent">
>       <s:link view="/register.html" value="click here to register" propagation="none"/>
>     </ui:define>
>   </ui:composition>
> </html>
> ///////////////////////////////////
> register.html
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:h="http://java.sun.com/jsf/html"
>       xmlns:s="http://jboss.com/products/seam/taglib">
>   <ui:composition template="./template.xhtml">
>     <ui:define name="maincontent">
>         <p>Click to start natural conversation:</p>
>         <h:form id="testform">
>           <h:outputText value="Click: "/>
>           <h:commandButton value="Register" action="#{memberreg.start}">
>             <s:conversationName value="regmem"/>
>             <s:conversationPropagation type="join"/>
>           </h:commandButton>
>         </h:form>
>     </ui:define>
>   </ui:composition>
> </html>
> ///////////////////////////////////
> register1.xhtml
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:h="http://java.sun.com/jsf/html"
>       xmlns:s="http://jboss.com/products/seam/taglib" >
>     <ui:composition template="./template.xhtml">
>       <ui:define name="maincontent">
>         <h:form id="agreeform">
>           <h:commandButton id="agreebut1" value="Agree"
>             action="#{memberreg.agreeToLicense}">
>             <s:conversationName value="regmem"/>
>             <s:conversationPropagation type="join"/>
>           </h:commandButton>
>           <br/><p>Click cancel to kill the natural conversation early</p>
>           <h:commandButton id="disagreebut1" value="Disagree"
>             action="#{memberreg.cancel}">
>             <s:conversationName value="regmem"/>
>             <s:conversationPropagation type="end"/>
>           </h:commandButton>
>         </h:form>
>       </ui:define>
>     </ui:composition>
> </html>
> ///////////////////////////////////
> register2.xhtml
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:h="http://java.sun.com/jsf/html"
>       xmlns:s="http://jboss.com/products/seam/taglib" >
>   <ui:composition template="./template.xhtml">
>      <ui:define name="maincontent">
>      <h:form id="formfields">
>         <p>Content inserted for testing purposes when this button clicked:</p>
>         <h:commandButton id="next" value="Next" action="#{memberreg.next}">
>           <s:conversationName value="regmem"/>
>           <s:conversationPropagation type="join"/>
>         </h:commandButton>
>       </h:form>
>     </ui:define>
>   </ui:composition>
> </html>
> ///////////////////////////////////
> register3.xhtml
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:h="http://java.sun.com/jsf/html"
>       xmlns:rich="http://richfaces.org/rich"
>       xmlns:s="http://jboss.com/products/seam/taglib" >
>   <ui:composition template="./template.xhtml">
>     <ui:define name="maincontent">
>       <h:form id="formfields" rendered="#{not identity.loggedIn}">
>         <h:commandButton id="editinfo" value="Edit Information"
>           action="#{memberreg.editInformation}">
>           <s:conversationName value="regmem"/>
>           <s:conversationPropagation type="join"/>
>         </h:commandButton>
>         &#160;&#160;&#160;&#160;&#160;
>         <h:commandButton id="confirmreg" value="Confirm Registration"
>           action="#{memberreg.acceptInformation}">
>           <s:conversationName value="regmem"/>
>           <s:conversationPropagation type="join"/>
>         </h:commandButton> 
>       </h:form>
>     </ui:define>
>   </ui:composition>
> </html>
> ///////////////////////////////////
> register4.xhtml
> <html xmlns="http://www.w3.org/1999/xhtml"
>       xmlns:ui="http://java.sun.com/jsf/facelets"
>       xmlns:s="http://jboss.com/products/seam/taglib" >
>   <ui:composition template="./template.xhtml">
>     <ui:define name="maincontent">
>       <p>Click back to finish natural conversation.</p>
>       <s:link value="Back to home." action="#{memberreg.end}"
>         propagation="end"/>
>     </ui:define>
>   </ui:composition>
> </html>
> 6.) Use the following JARs for your web app (for running inside of Tomcat 6):
> activation.jar
> antlr.jar
> asm.jar
> cglib.jar
> commons-beanutils.jar
> commons-codec-1.3.jar
> commons-collections.jar
> commons-digester.jar
> commons-lang.jar
> commons-logging.jar
> DA.jar
> dom4j.jar
> ejb-api.jar
> filelist.txt
> hibernate-annotations.jar
> hibernate-commons-annotations.jar
> hibernate-entitymanager.jar
> hibernate.jar
> hibernate-search.jar
> hibernate-validator.jar
> javassist.jar
> jboss-archive-browsing.jar
> jboss-el.jar
> jboss-seam-debug.jar
> jboss-seam-ioc.jar
> jboss-seam.jar
> jboss-seam-mail.jar
> jboss-seam-ui.jar
> jsf-api.jar
> jsf-facelets.jar
> jsf-impl.jar
> jstl.jar
> jta.jar
> lucene-core.jar
> mail.jar
> persistence-api.jar
> richfaces-api.jar
> richfaces-impl.jar
> richfaces-ui.jar
> spring.jar
> urlrewrite-3.1.0.jar
> 7.) (Optional) Set up facelets but you may also want to make the default extension html:
>   <servlet-mapping>
>     <servlet-name>Faces Servlet</servlet-name>
>     <url-pattern>*.html</url-pattern>
>   </servlet-mapping>
> Steps to reproduce bug:
> 1.) Start web app inside of Tomcat 6
> 2.) using your browser's URL text field, type in the name of a register1.html, register2.html, or register3.html. At this point your web app will generate an exception stack which will be caused by:
> java.lang.IllegalStateException: conversation id evaluated to null:
> The conversation is evaluated to null. Since conversations are a layer on top of sessions, the same behavior is expected which is a faces message purporting of no conversation existing and a redirect to the URL specified in the pages.xml attribute no-conversation-view-id="/index.xhtml" (so in this case index.xhtml page). It should not allow the user to see the page and generate exceptions.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list