12 Replies Latest reply on Sep 29, 2009 10:58 PM by indyjones2

    Seamm Pros....help with Session management.....

    indyjones2

      Here is the problem....


      My application does not have a database.....every thing is stored in another applications database.


      I get to the database through Web Services....


      I use the following Service and Call objects....




      import org.apache.axis.client.Call;
      import org.apache.axis.client.Service;



      I call the Web Service like this....




      String endpoint = "http://someurl/tosome/service";
                     
      Service service = new Service();
      service.setMaintainSession(true);
                     
      call = (Call) service.createCall();
      call.setMaintainSession(true);
      
      call.setTargetEndpointAddress(new URL(endpoint));
                    
      call.setOperationName(new QName("processABC") );
      
      String strXMLresponse = (String) call.invoke(new Object[] {new String(xml)});




      Notice I maintain the Session with both the Service and Call objects.


      The Service and Call sessions need to be managed the exact same way as the Seam Session....


      What is the best way to handle this?


      Should I have a Call and Service property on my User object that gets outjected after authentication?


      Should I have some kind of Bean that manages this?


      I tried using a Stateful bean of scope Session that gets AutoCreated....


      When I needed to call something, I just injected the bean and called it....


      This worked fine until performance dropped after and hour or so....


      And ideas would be very helpful...


      Thanks


      indy


        • 1. Re: Seamm Pros....help with Session management.....

          Casey Boyd wrote on Sep 25, 2009 17:49:


          Here is the problem....

          My application does not have a database.....every thing is stored in another applications database.

          I get to the database through Web Services....

          I use the following Service and Call objects....



          import org.apache.axis.client.Call;
          import org.apache.axis.client.Service;




          Why are you using Axis and not ApacheCXF? (IMO ApacheCXF is better)



          I call the Web Service like this....



          String endpoint = "http://someurl/tosome/service";
                         
          Service service = new Service();
          service.setMaintainSession(true);
                         
          call = (Call) service.createCall();
          call.setMaintainSession(true);
          
          call.setTargetEndpointAddress(new URL(endpoint));
                        
          call.setOperationName(new QName("processABC") );
          
          String strXMLresponse = (String) call.invoke(new Object[] {new String(xml)});




          Notice I maintain the Session with both the Service and Call objects.

          The Service and Call sessions need to be managed the exact same way as the Seam Session....

          What is the best way to handle this?

          Should I have a Call and Service property on my User object that gets outjected after authentication?

          Should I have some kind of Bean that manages this?

          I tried using a Stateful bean of scope Session that gets AutoCreated....

          When I needed to call something, I just injected the bean and called it....


          Please post some of you code.



          This worked fine until performance dropped after and hour or so....

          And ideas would be very helpful...

          Thanks

          indy




          Where did it drop? in the client? or in the server? both? why did it drop? too much memory use? to much processor use? What application servers are you using for your Seam client and your axis server?


          • 2. Re: Seamm Pros....help with Session management.....
            indyjones2

            Some more information....


            I don't know why I am using Axis....will take a look at ApacheCXF.


            Here is the class that gets injected to make the Web Service Calls....





            import org.apache.axis.client.Call;
            
            import com.broadsoft.protocols.oci.schema.core.OCIRequest;
            import com.broadsoft.protocols.oci.schema.core.OCIResponse;
            import com.broadsoft.protocols.oci.schema.core.OCICommand;
            import com.broadsoft.protocols.oci.schema.core.OCIMessage;
            import com.broadsoft.protocols.oci.schema.core.BroadsoftDocumentDocument1;
            
            import org.jboss.seam.annotations.Logger;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.jboss.seam.annotations.AutoCreate;
            
            import org.jboss.seam.ScopeType;
            
            import org.jboss.seam.annotations.In;
            
            import org.jboss.seam.log.Log;
            
            @Name("sendXMLService")
            @AutoCreate 
            @Scope(ScopeType.SESSION)
            public class SendXMLService {
                 
                 @Logger 
                 private Log log;
                 
                 @In
                 ConnectionManagerService connMgrService;
                 
                 private String sessionId = "123.454.343.34" + "," + "123456789" + "," + System.currentTimeMillis();
                 
                 public OCIResponse sendXML(OCIRequest objOCIrequest){
                      
                      OCIResponse objOCIresponse = null;
                      
                      try{
                                       
                      OCIRequest arrOCIrequest[] = new OCIRequest[1];
                           
                         arrOCIrequest[0] = objOCIrequest;  
                           
                         OCIMessage ocimessage = OCIMessage.Factory.newInstance();
                         
                         ocimessage.setProtocol(OCIMessage.Protocol.OCI);
                         
                         ocimessage.setSessionId(sessionId);
                         
                         ocimessage.setCommandArray(arrOCIrequest);
                         
                         BroadsoftDocumentDocument1 objBSDocumentRequestFactory = BroadsoftDocumentDocument1.Factory.newInstance();
                        objBSDocumentRequestFactory.setBroadsoftDocument(ocimessage);
                          
                         Call call = connMgrService.getCall();
                        
                        log.debug("\n==========================SENT===============================>\n\n" + objBSDocumentRequestFactory.xmlText() + "\n\n=============================================================>");
                         
                          String strXMLresponse = (String) call.invoke(new Object[] {new String(objBSDocumentRequestFactory.xmlText())});
                         
                         log.debug("\n=======================RECIEVED==============================>\n\n" + strXMLresponse + "\n\n=============================================================>");
                         
                         BroadsoftDocumentDocument1 objBSDocumentResponseFactory = BroadsoftDocumentDocument1.Factory.parse(strXMLresponse);
                          
                         OCIMessage objOCIMessageresponse = objBSDocumentResponseFactory.getBroadsoftDocument();
                    
                         OCICommand arrOCIresponse[] = objOCIMessageresponse.getCommandArray();
                         
                      }catch(Exception e){
                           
                           log.error("ERROR - " + e.toString());
                      }
            
                      return objOCIresponse;
                 }
            }



            This method gets called every time I need to retrieve data....


            After about an hour of 5 or so people on the application.....the used by JBoss is over 90%.


            I think the maintain session on the Service and Call objects are not being cleaned up after the Seam Session closes.....

            • 3. Re: Seamm Pros....help with Session management.....

              Casey Boyd wrote on Sep 25, 2009 23:29:


              After about an hour of 5 or so people on the application.....the used by JBoss is over 90%.



              You mean RAM memory? (because you forgot to say what is used over 90% memory? processor? hard disk space?) An if RAM memory, how much memory is available for your JBoss? 64Mbytes? 128Mbytes? 1Gbyte? are there any other applications running in that JBoss instance?




              I think the maintain session on the Service and Call objects are not being cleaned up after the Seam Session closes.....



              The Seam session is only closed after the user logouts from its session, so if 5 people are using the system, and none of them log out, it does not get released.

              • 4. Re: Seamm Pros....help with Session management.....
                indyjones2

                Yeah....it is RAM that is being eaten up.


                The JBoss server has 1G available. No other applications are running....


                So, here is what I think my problem is....


                When a User logs into Seam I create an Object that connects to a Web Service through Axis. It uses the Service and Call objects with their maintain session attribute set to true. I then outject that object with is then injected by all other classes to make Web Service calls.


                This works fine until 5 or so users are on the system for about an hour. At that point, the RAM uses by JBoss is over 90%. The application is incredibly slow.


                So....how would I solve this?


                This is how I create the Service and Call objects...




                private Call createCall(){
                          
                          Service service;
                          
                          try{
                          
                               String endpoint = "http://someurl/toService";
                
                               service = new Service();
                
                               service.setMaintainSession(true);
                               
                               call = (Call) service.createCall();
                               
                                        call.setMaintainSession(true);
                               
                               call.setTargetEndpointAddress(new URL(endpoint));
                              
                               call.setOperationName(new QName("someWebServiceProcess") );
                          
                          }catch(Exception e){
                          
                          }
                          
                          return call;
                     }



                How would I use ApacheCXF? Are there any other APIs I should look at?


                Should I try to end the Axis session? What if there are 100 users? Will Axis be able to perform?


                What if the User just closes the browser? How long does it take for the Seam session to close? Instant?


                The Web Service is a simple XML based application (No SOAP).


                ANY help would be very appreciated....


                thanks


                indy

                • 5. Re: Seamm Pros....help with Session management.....

                  Casey Boyd wrote on Sep 28, 2009 15:53:


                  Yeah....it is RAM that is being eaten up.


                  Ok...



                  The JBoss server has 1G available. No other applications are running....


                  you mean that the computer has 1G of physical memory? Or you mean 1G is what you
                  belive is left for JBoss (how much physical memory does it have then?). What monitoring tool do you use to ensure how much memory is free for JBoss? (Hyperic? GroundWork? other?)


                  How did you configure the Xms, Xmx and XX:MaxPermSize  values for your JVM?. Are you using JConsole to validate that those values were picked up on startup and monitor the performance of the JVM that is running your JBoss instance?



                  So, here is what I think my problem is....

                  When a User logs into Seam I create an Object that connects to a Web Service through Axis. It uses the Service and Call objects with their maintain session attribute set to true. I then outject that object with is then injected by all other classes to make Web Service calls.

                  This works fine until 5 or so users are on the system for about an hour. At that point, the RAM uses by JBoss is over 90%. The application is incredibly slow.


                  You mean that at that point the JVM where your JBoss is running weights 0.9Gbytes? What monitoring tool are you using to verify this?




                  So....how would I solve this?



                  First you need to diagnose what is really happening, I have seen a lot of cases where the servers had a lot of free memory (2Gbytes) but since the Xms, Xmx and XX:MaxPermSize parameters where configured incorrectly, the JVM could only see around 64mbytes.

                  • 6. Re: Seamm Pros....help with Session management.....

                    Casey Boyd wrote on Sep 25, 2009 17:49:


                    Here is the problem....

                    My application does not have a database.....every thing is stored in another applications database.

                    I get to the database through Web Services....



                    Oh, and finally, all this monitoring and JVM parameter verification I am recommending you to do... are you (or someone else) also doing it also in the server where the remote webservice is running? is someone also monitoring the network connection between your server and the remote webservice server? (Because if that is becoming slow, that could also be the reason your application is going slow)

                    • 7. Re: Seamm Pros....help with Session management.....
                      indyjones2

                      Here is the JVM parameters for my server;




                      -Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m 



                      I use Windows Task Manager to monitor the memory useage.


                      When I first fire up the server, JBoss takes up around 700 Megs. Then, after some people use the server, it gets over 1000 Megs. Well, that's what Task Manager is telling me....


                      The other (where the web service is hosted) server hardly moves from the initial server start up. Its also running a Web Portal at the same time. The Portal performance never changes. I don't think its a problem with the server hosting the Web Service.


                      Also....does Seam close the session when a user simply closes the browser? We have not implemented the logout functionality yet, so users simply close the browser when they are done using the system.



                      • 8. Re: Seamm Pros....help with Session management.....

                        Casey Boyd wrote on Sep 28, 2009 17:19:


                        Here is the JVM parameters for my server;

                        -Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m 



                        I use Windows Task Manager to monitor the memory useage.


                        Ok. Not bad, but it would be a better to use JConsole, Lambda Probe or Hyperic to get more detailed and persistent information.



                        When I first fire up the server, JBoss takes up around 700 Megs. Then, after some people use the server, it gets over 1000 Megs. Well, that's what Task Manager is telling me....

                        The other (where the web service is hosted) server hardly moves from the initial server start up. Its also running a Web Portal at the same time. The Portal performance never changes. I don't think its a problem with the server hosting the Web Service.


                        And what about the performance of the network? The portal and the remote webservice connect to the same database? Are you monitoring the performance of that database?



                        Also....does Seam close the session when a user simply closes the browser? We have not implemented the logout functionality yet, so users simply close the browser when they are done using the system.



                        Not, it does not, that is not the way things work for any web application (in Java, in .NET or in PHP). For Java you have the following options:



                        1. Trap window close event and finish the session then (not very safe, because it will not be called if the browser crashes or if the network fails).

                        2. Ask the user to logout by clicking on a link or button (the user has to remember to click it)

                        3. Set a timeout for  you session, after the server detects that the session has been inactive for some time, it closes, this is controlled with an configuration section in the web.xml file (In this example a session will close after 30 minutes of inactivity). The default value is 20 minutes:



                        
                        <session-config>
                                    <session-timeout>30</session-timeout>
                        </session-config>
                        
                        



                        • 9. Re: Seamm Pros....help with Session management.....
                          indyjones2

                          THANKS!!!!


                          Ok....i think I am getting closer.


                          I will monitor the other server and network for performance....


                          I am going to set up the session time out in the web.xml and let you know what happens....


                          I still think the users are just closing the browser witch is leaving the Axis Service and Call objects connected to the server. Which is eating all my memory after awhile.....


                          Thanks for helping me....

                          • 10. Re: Seamm Pros....help with Session management.....
                            indyjones2

                            Ok....i am really stuck now....


                            I have removed AXIS and now I am creating a direct Socket Connection....


                            Here is my SocketHelper Class.




                            import java.io.BufferedReader;
                            import java.io.IOException;
                            import java.io.InputStreamReader;
                            import java.io.PrintWriter;
                            import java.net.Socket;
                            import java.net.SocketException;
                            import java.net.UnknownHostException;
                            
                            public class SocketHelper {
                                 
                                 private Socket socketObject;
                                 
                                 private BufferedReader socketInputReader;
                            
                                 private PrintWriter socketOutputWriter;
                            
                                 public SocketHelper(String ipAddressOrHostname, Integer serverPort) throws UnknownHostException, SocketException, IOException {
                                      
                                      this.socketObject = new Socket(ipAddressOrHostname, serverPort);
                            
                                      this.setSocketOptions();
                                 }
                            
                                 public void setSocketOptions() throws IOException {
                            
                                      this.socketObject.setKeepAlive(true);
                                      
                                      this.socketObject.setTcpNoDelay(true);
                            
                                      this.socketObject.setSoLinger(false, 0);
                            
                                      this.socketObject.setReceiveBufferSize(8192);
                            
                                      this.socketObject.setSendBufferSize(8192);
                            
                                      this.socketInputReader = new BufferedReader(new InputStreamReader(socketObject.getInputStream()));
                            
                                      this.socketOutputWriter = new PrintWriter(socketObject.getOutputStream(), false);
                                 }
                            
                                 public synchronized void sendXmlRequest(String xmlRequest) throws IOException {
                            
                                      if (this.socketObject.isConnected() && !this.socketObject.isOutputShutdown()) {
                            
                                           this.socketOutputWriter.flush();
                            
                                           this.socketOutputWriter.print("<?xml version='1.0' encoding='UTF-8'?>\n".concat(xmlRequest));
                            
                                           this.socketOutputWriter.flush();
                            
                                      } else {
                            
                                           throw new IOException();
                                      }
                            
                                 }
                            
                                 public Boolean isSocketReady() {
                            
                                      return (this.socketObject.isConnected() && !this.socketObject.isInputShutdown() && !this.socketObject.isOutputShutdown());
                                 }
                            
                                 public synchronized String readXmlResponse() throws IOException, InterruptedException {
                                      
                                      Integer maxWaitTimer = 30000;
                            
                                      Integer curWaitTimer = 0;
                            
                                      StringBuilder stringBuilder = new StringBuilder();
                            
                                      String tempStringReader = "";
                            
                                      curWaitTimer = 0;
                            
                                      while (!this.socketInputReader.ready()) {
                            
                                           Thread.sleep(100);
                            
                                           curWaitTimer += 100;
                            
                                           if (curWaitTimer % 1000 == 0) {
                            
                                                System.out.println("Waiting for socket (" + Integer.toString(curWaitTimer / 1000)+ " seconds)");
                                           }
                                           
                                           if (curWaitTimer > maxWaitTimer) {
                                                
                                                System.out.println("Socket connection to : " + socketObject.getRemoteSocketAddress() + "\n" + "* state currently : " + (socketObject.isConnected() ? "CONNECTED" : "DISCONNECTED"));
                                                System.out.println("* input currently : " + (socketObject.isInputShutdown() ? "SHUTDOWN" : "ACTIVE"));
                                                System.out.println("* output currently : " + (socketObject.isOutputShutdown() ? "SHUTDOWN" : "ACTIVE"));
                            
                                                throw new IOException();
                                           }
                                      }
                            
                                      while ((tempStringReader = this.socketInputReader.readLine()) != null) {
                                           
                                           stringBuilder.append(tempStringReader);
                            
                                           if (tempStringReader.endsWith("</end>")){
                            
                                                break;
                                           }     
                                      }
                            
                                      return (stringBuilder.toString());
                                 }
                            
                                 public void closeHandles() {
                                      
                                      try {
                                           
                                           this.socketInputReader.close();
                                           
                                           System.out.println("Disconnected from server");
                                           
                                      } catch (IOException e) {
                                           
                                           // TODO Auto-generated catch block
                                           e.printStackTrace();
                                      }
                                      
                                      this.socketOutputWriter.close();
                                 }
                            }



                            Again, this works just fine for awhile......then the memory (RAM) is gone. The server (JBoss) NEVER goes down in RAM used.


                            I am only creating 1 connection (Application Scope Bean) witch is shared by all other beans to send and recieve XML.


                            What is the best practices in Seam for Sending and Receiving XML from a Socket?



                            • 11. Re: Seamm Pros....help with Session management.....

                              Casey Boyd wrote on Sep 29, 2009 21:02:


                              Ok....i am really stuck now....

                              I have removed AXIS and now I am creating a direct Socket Connection....



                              Replacing AXIS with ApacheCXF is a good idea, replacing AXIS with a direct Socket Connection is not (unless you are masochistic).




                              Again, this works just fine for awhile......then the memory (RAM) is gone. The server (JBoss) NEVER goes down in RAM used.


                              What is JConsole telling you? what actions increase your memory? you can not fix a memory leak using a lets blindly alter something that perhaps is related to the problem approach. You need to understand what is happening.



                              I am only creating 1 connection (Application Scope Bean) witch is shared by all other beans to send and recieve XML.



                              Well, If you do not understand what is happening any theory is as good as any other (please use something like JConsole, or Netbeans profiler, or Eclipse TPTP to understad what is causing the problem before blindly modifying your code). Have you considered the idea, that maybe your call to the webservice has nothing to do with your memory leak?




                              What is the best practices in Seam for Sending and Receiving XML from a Socket?



                              MU


                              • 12. Re: Seamm Pros....help with Session management.....
                                indyjones2

                                :)


                                Ok....I set up JConsole for my application.


                                You must excuse my lack of knowledge, but what I am looking for with JConsole vs TaskManager?


                                I can see the memory usage going up in both.....but I think I am missing something.....


                                Is there an option to show the names of the loaded classes instead of just the number of them?


                                Its hard for me to tell the system classes vs my classes.....