Results 1 to 4 of 4

Thread: thread safety in webflow

Hybrid View

  1. #1
    Join Date
    Mar 2009
    Posts
    4

    Default thread safety in webflow

    Hi All,

    I am new to SpringWebflow .I have build a flow with multiple decisions states.

    The flow works perfect with a single user, however when 2 or more users are connected the flow is acting bizarre and throws NullPointerEXception.

    It seems as if my flow isn't thread safe

    Is there a bug within webflow? are am I implementing it wrong?

    I am using springframework 2.0.6

    <code>

    <decision-state id="decisionTXTState">
    <on-entry>
    <evaluate expression="fileExtension.createFromFileName(fileU ploadCommand.file)" result="flowScope.extension"></evaluate>
    <!--<evaluate expression="clientService.retrieveClients()" result="flashScope.clientList"></evaluate>-->
    <evaluate expression="clientService.retrieveClient(fileUploa dCommand.clientId)" result="flowScope.selectedClient"></evaluate>
    </on-entry>

    <if test="extension.isDBF()" then="changeNumberToEnglishFormat" />
    <if test="extension.isTxt() and branchService.isTextEnabled(ipAddress)" then="profileConfirmationState" else="txtNotEnabledState"/>
    </decision-state>

    <!-- Profiel bevestigen -->
    <view-state id="profileConfirmationState" view="fileupload/profileConfirmation">
    <transition on="continue" to="changeNumberToEnglishFormat"/>
    <transition on="cancel" to="canceledFileUploadState"/>
    </view-state>

    <view-state id="txtNotEnabledState" view="fileupload/txtNotEnabled">
    </view-state>

    <!-- to change the number format of the hash, batch from the command to English -->
    <action-state id="changeNumberToEnglishFormat">
    <evaluate expression="convertNumberToEnglishFormat.returnCom mandWithEnglishFormat(fileUploadCommand)" result="flowScope.fileUploadCommand"></evaluate>
    <transition to="ipAddressDecisionState"></transition>
    </action-state>

    <!-- Verify is the upload will be done from a valid ipaddress -->
    <decision-state id="ipAddressDecisionState">
    <on-entry>
    <evaluate expression="branchService.retrieveBranch(ipAddress )" result="flowScope.branch"></evaluate>
    <evaluate expression="branchService.retrieveBranchName(ipAdd ress)" result="flowScope.branchName"></evaluate>
    <evaluate expression="ipValidation.checkIfExistingIp(branch) " result="flowScope.errorList"></evaluate>
    </on-entry>
    <if test="errorList.isEmpty()" then="validateCheckSumActionState" else="errorState"/>
    <exception-handler bean="flowExceptionResolver"/>
    </decision-state>

    <!-- Checksum van the file -->
    <decision-state id="validateCheckSumActionState">
    <on-entry>
    <evaluate expression="validateCheckSum.calculateCheckSum(fil eUploadCommand.fileContent)" result="flowScope.checkSum"></evaluate>
    <evaluate expression="fileExtension.createFromFileName(fileU ploadCommand.file)" result="flowScope.extension"></evaluate>
    </on-entry>
    <if test="clientFileService.checkSumIsUnique(checkSum) " then="generateRecordsState" else="checkSumNotUniqueState"/>
    <exception-handler bean="flowExceptionResolver"/>
    </decision-state>

    <!-- Indien de checksum al voorkomt wordt een melding gegeven -->
    <view-state id="checkSumNotUniqueState" view="fileupload/checksum.not.unique">
    <transition on="continue" to="generateRecordsState"/>
    <transition on="cancel" to="canceledFileUploadState"/>
    <exception-handler bean="flowExceptionResolver"/>
    </view-state>

    <end-state id="canceledFileUploadState" view="externalRedirect:contextRelative:/fileupload/fileupload.htm">
    </end-state>



    <!-- Generate records (dbf and txt) -->
    <decision-state id="generateRecordsState">
    <on-entry>
    <evaluate expression="integration.readForFaults(extension, fileUploadCommand.clientId, fileUploadCommand.fileContent, fileUploadCommand.bankCodeFile)"></evaluate>
    <evaluate expression="integration.getFilteredRecords().get(1 )" result="flowScope.errorRecords"></evaluate>
    </on-entry>
    <if test="errorRecords.isEmpty()" then="hashBatchValidationState" else="errorRecordsState"/>
    <exception-handler bean="flowExceptionResolver"/>
    </decision-state>

    <decision-state id="hashBatchValidationState">
    <on-entry>
    <evaluate expression="integration.doForHashBatchValidation(f ileUploadCommand)"></evaluate>
    <evaluate expression="integration.getValidationMessages()" result="flowScope.errorList"></evaluate>
    </on-entry>
    <if test="errorList.isEmpty()" then="postValidationState" else="errorState"/>

    <exception-handler bean="flowExceptionResolver"/>
    </decision-state>

    <action-state id="postValidationState">
    <on-entry>
    <evaluate expression="integration.doForPostValidation(fileUp loadCommand.fee)"></evaluate>
    <evaluate expression="integration.getClient()" result="flowScope.client"></evaluate>
    <evaluate expression="integration.getRecords()" result="flowScope.records"></evaluate>
    </on-entry>
    <evaluate expression="integration.getHashBatchRecordsBalance ()" result="flowScope.hashBatchRecordsBalance"></evaluate>
    <transition to="fileUploadCompleteState"></transition>
    <exception-handler bean="flowExceptionResolver"/>
    </action-state>

    <view-state id="errorRecordsState" view="fileupload/errorRecords">
    <!-- <attribute name="errorRecords" value="errorRecords"></attribute>-->
    <transition on="continue" to="hashBatchValidationState"/>
    <transition on="cancel" to="canceledFileUploadState"/>
    <exception-handler bean="flowExceptionResolver"/>
    </view-state>

    <view-state id="fileUploadCompleteState" view="fileupload/fileupload.complete">
    <on-entry>
    <evaluate expression="processTransactionService.setClientChe cksum(records,checkSum,client,branch,hashBatchReco rdsBalance,fileUploadCommand)" result="flowScope.clientFile"></evaluate>
    <evaluate expression="processTransactionService.persistAll(c lient,clientFile, fileUploadCommand.file)" ></evaluate>
    <evaluate expression="cfmletter.letter(fileUploadCommand,cli ent,hashBatchRecordsBalance,branchName, errorRecords)" result="flowScope.dsbByteArrayOutputStream"></evaluate>
    <evaluate expression="confirmationLetterFlowController.fill( dsbByteArrayOutputStream,clientFile.id)"></evaluate>
    <evaluate expression="fileCopyService.copyFile(fileUploadCom mand,clientFile.id, extension)" result="flowScope.copyMessages"></evaluate>
    </on-entry>
    <transition on="continue" to="letterState">
    </transition>
    <!-- <exception-handler bean="flowExceptionResolver"/> -->
    </view-state>

    <view-state id="letterState" view="externalRedirect:contextRelative:/fileupload/bevestiging.htm">
    <exception-handler bean="flowExceptionResolver"/>
    </view-state>

    <code>

    thanks in advance

  2. #2
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Use [ code][/code ] tags when posting code...

    The flow is always thread safe as a new isntance is started per session. So if there is something weird one of the beans you use (singletons) is propably not threadsafe.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  3. #3
    Join Date
    Mar 2009
    Posts
    4

    Default

    thanks for you're quick reply.

    If the flow is always threadsafe, why do I get NullPointerExceptions with multiple users.

    Do you know why it is behaving strange.Where can I search for the problem

    Code:
      <!-- Decide txt/dbf -->
        <decision-state id="decisionTXTState">
        	<on-entry>
        	<evaluate expression="fileExtension.createFromFileName(fileUploadCommand.file)" result="flowScope.extension"></evaluate>
        	<!--<evaluate expression="clientService.retrieveClients()" result="flashScope.clientList"></evaluate>-->
        	<evaluate expression="clientService.retrieveClient(fileUploadCommand.clientId)" result="flowScope.selectedClient"></evaluate>
        	</on-entry>
        	
        	<if test="extension.isDBF()" then="changeNumberToEnglishFormat" />
        	<if test="extension.isTxt() and branchService.isTextEnabled(ipAddress)" then="profileConfirmationState" else="txtNotEnabledState"/>
        </decision-state>   
        
          <!-- Profiel bevestigen -->
      	<view-state id="profileConfirmationState" view="fileupload/profileConfirmation">
    		<transition on="continue" to="changeNumberToEnglishFormat"/>
    		<transition on="cancel" to="canceledFileUploadState"/>    
        </view-state>
        
      	<view-state id="txtNotEnabledState" view="fileupload/txtNotEnabled">
        </view-state>
        
    <!-- to change the number format of the hash, batch from the command to English -->
    	<action-state id="changeNumberToEnglishFormat">
    		<evaluate expression="convertNumberToEnglishFormat.returnCommandWithEnglishFormat(fileUploadCommand)" result="flowScope.fileUploadCommand"></evaluate>			
    		<transition to="ipAddressDecisionState"></transition>
    	</action-state>
    
    <!-- Verify is the upload will be done from a valid ipaddress -->  
        <decision-state id="ipAddressDecisionState">
        	<on-entry>
        		<evaluate expression="branchService.retrieveBranch(ipAddress)" result="flowScope.branch"></evaluate>
        		<evaluate expression="branchService.retrieveBranchName(ipAddress)" result="flowScope.branchName"></evaluate>
        		<evaluate expression="ipValidation.checkIfExistingIp(branch)"  result="flowScope.errorList"></evaluate>
        	</on-entry>
        		<if test="errorList.isEmpty()" then="validateCheckSumActionState" else="errorState"/>
        		 <exception-handler bean="flowExceptionResolver"/> 
        </decision-state>
    
    <!-- Checksum van the file -->     
        <decision-state id="validateCheckSumActionState">
    	    <on-entry>
    	    	<evaluate expression="validateCheckSum.calculateCheckSum(fileUploadCommand.fileContent)" result="flowScope.checkSum"></evaluate>
    	    	<evaluate expression="fileExtension.createFromFileName(fileUploadCommand.file)" result="flowScope.extension"></evaluate>
    	    </on-entry>
        	<if test="clientFileService.checkSumIsUnique(checkSum)" then="generateRecordsState" else="checkSumNotUniqueState"/>
        	 <exception-handler bean="flowExceptionResolver"/> 
        </decision-state>
    
    <!-- Indien de checksum al voorkomt wordt een melding gegeven -->    
        <view-state id="checkSumNotUniqueState" view="fileupload/checksum.not.unique">
    		<transition on="continue" to="generateRecordsState"/>
    		<transition on="cancel" to="canceledFileUploadState"/>    
    		 <exception-handler bean="flowExceptionResolver"/> 
        </view-state>
    
    	<end-state id="canceledFileUploadState" view="externalRedirect:contextRelative:/fileupload/fileupload.htm">
        </end-state>
        
        
    
    <!-- Generate records (dbf and txt)  --> 
         <decision-state id="generateRecordsState">
        	<on-entry>
        		<evaluate expression="integration.readForFaults(extension, fileUploadCommand.clientId, fileUploadCommand.fileContent, fileUploadCommand.bankCodeFile)"></evaluate>
        		<evaluate expression="integration.getFilteredRecords().get(1)" result="flowScope.errorRecords"></evaluate>
        	</on-entry>
        	<if test="errorRecords.isEmpty()" then="hashBatchValidationState" else="errorRecordsState"/>
        	 <exception-handler bean="flowExceptionResolver"/>	
        </decision-state>   
    
         <decision-state id="hashBatchValidationState">
        	<on-entry>
        		<evaluate expression="integration.doForHashBatchValidation(fileUploadCommand)"></evaluate>
        		<evaluate expression="integration.getValidationMessages()" result="flowScope.errorList"></evaluate>
        	</on-entry>
        	<if test="errorList.isEmpty()" then="postValidationState" else="errorState"/>
    
        	 <exception-handler bean="flowExceptionResolver"/>	
        </decision-state>   
    
         <action-state id="postValidationState">
        	<on-entry>
        		<evaluate expression="integration.doForPostValidation(fileUploadCommand.fee)"></evaluate>
        		<evaluate expression="integration.getClient()" result="flowScope.client"></evaluate>
        		<evaluate expression="integration.getRecords()" result="flowScope.records"></evaluate>
        	</on-entry>
        	<evaluate expression="integration.getHashBatchRecordsBalance()" result="flowScope.hashBatchRecordsBalance"></evaluate>
        	<transition to="fileUploadCompleteState"></transition>
        	 <exception-handler bean="flowExceptionResolver"/>	
        </action-state>
    
        <view-state id="errorRecordsState" view="fileupload/errorRecords">
    <!--		<attribute  name="errorRecords" value="errorRecords"></attribute>-->
    			<transition on="continue" to="hashBatchValidationState"/>
    			<transition on="cancel" to="canceledFileUploadState"/>
    		<exception-handler bean="flowExceptionResolver"/> 
        </view-state> 
       
        <view-state id="fileUploadCompleteState" view="fileupload/fileupload.complete">
        	<on-entry>
    			<evaluate expression="processTransactionService.setClientChecksum(records,checkSum,client,branch,hashBatchRecordsBalance,fileUploadCommand)" result="flowScope.clientFile"></evaluate>
        		<evaluate expression="processTransactionService.persistAll(client,clientFile, fileUploadCommand.file)" ></evaluate>
        		<evaluate expression="cfmletter.letter(fileUploadCommand,client,hashBatchRecordsBalance,branchName, errorRecords)" result="flowScope.dsbByteArrayOutputStream"></evaluate>
    			<evaluate expression="confirmationLetterFlowController.fill(dsbByteArrayOutputStream,clientFile.id)"></evaluate>
    			<evaluate expression="fileCopyService.copyFile(fileUploadCommand,clientFile.id, extension)" result="flowScope.copyMessages"></evaluate>
        	</on-entry>
    			<transition on="continue" to="letterState">
    			</transition>
    <!--			 <exception-handler bean="flowExceptionResolver"/> -->
        </view-state>
         
        <view-state id="letterState" view="externalRedirect:contextRelative:/fileupload/bevestiging.htm">
        	 <exception-handler bean="flowExceptionResolver"/> 
        </view-state>

  4. #4
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,695

    Default

    Quote Originally Posted by mdeinum
    So if there is something weird one of the beans you use (singletons) is propably not threadsafe.
    Check the beans you use, probaly one of those isn't threadsafe...
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •