Announcement Announcement Module
Collapse
No announcement yet.
configuration help: pool problems create deadlocks Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Originally posted by dr_pompeii View Post
    one favor,can you show an extract of your code, when you use JRBeanCollectionDataSource but with more classes to fill the object, like my case when i use the JRResultSetDataSource???
    The code was from a previous closed sourced project so I can't post it here. I'm sure there are lots of good examples on the net though.
    Last edited by karldmoore; Aug 29th, 2007, 12:18 PM.

    Comment


    • #17
      The code was from a previous closed sourced project so I can't post it here.
      privacy code mmm

      dont worry man, thanks for your time

      I'm sure there are lots of good examples on the net though.
      i will see

      regards

      Comment


      • #18
        I think the implementation is conceptually the same thing, it's just that you have packaged up the data in objects instead of reading it from the ResultSet.
        Last edited by karldmoore; Aug 29th, 2007, 12:18 PM.

        Comment


        • #19
          problems with ResultSet.

          hi karl

          pls see this code
          Code:
          @Override
          protected Event doExecute(RequestContext context)throws Exception{
             logger.info("\n TransaccionSalidaAlmacenJasperReportAction doExecute \n");
             Connection connection=null;
              PreparedStatement ps=null;
              ResultSet resultSet=null;
              try{
              	CabeceraSalidaAlmacen cabeceraSalidaAlmacen = 
              		(CabeceraSalidaAlmacen) (context.getFlowScope().get("cabeceraSalidaAlmacenCommand"));
              	AlmacenPK almacenPK = cabeceraSalidaAlmacen.getAlmacenPK();
          	       	    
              	String query = " SELECT * FROM CabeceraAlmacen c, DetalleAlmacen d, Articulo             
                                        a, Medida m  WHERE " +
          	    			 " c.idnumero=d.idnumero AND c.serie=d.serie AND " +
          	    			  " d.idArticulo=a.idArticulo AND a.idMedida=m.idMedida AND " +
          	    			  " c.serie='SAL' AND c.idnumero=?";
          	    		 
          	    	connection = dataSource.getConnection();
          	    	ps=connection.prepareStatement(query);
          	    	ps.setString(1, almacenPK.getIdnumero());
          	    	resultSet = ps.executeQuery();	    
          	    
          	    	JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(resultSet);
          	    	context.getRequestScope().put("datasource", resultSetDataSource);
          	    	
          	    }
          	    catch(Exception e){
          		logger.info("\n TransaccionSalidaAlmacenJasperReportAction doExecute  
                                           Exception: \n"+
          					e.getMessage() );
          		}
          		finally{
          			logger.info("\n TransaccionSalidaAlmacenJasperReportAction doExecute B4 CLOSE RS");
          			resultSet.close();
          			logger.info("\n TransaccionSalidaAlmacenJasperReportAction doExecute A4 CLOSE RS");
          		}
          		return success();
          	}
          my log

          Code:
          08:23:48 INFO                    TransaccionSalidaAlmacenJasperReportAction doExecute                 
           TransaccionSalidaAlmacenJasperReportAction doExecute 
          
          08:23:48 INFO                    TransaccionSalidaAlmacenJasperReportAction doExecute                 
           TransaccionSalidaAlmacenJasperReportAction doExecute B4 CLOSE RS
          08:23:48 INFO                    TransaccionSalidaAlmacenJasperReportAction doExecute                 
           TransaccionSalidaAlmacenJasperReportAction doExecute A4 CLOSE RS
          08:23:50 ERROR tainerBase.[Catalina].[localhost].[/lagranjita].[lagranjita] invoke                    Servlet.service() para servlet lagranjita lanzó excepción
          net.sf.jasperreports.engine.JRException: Unable to get next record.
          	at net.sf.jasperreports.engine.JRResultSetDataSource.next(JRResultSetDataSource.java:99)
          	at net.sf.jasperreports.engine.fill.JRFillDataset.advanceDataSource(JRFillDataset.java:842)
          	at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:760)
          	at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1078)
          	at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:107)
          	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:751)
          	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:679)
          	at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:89)
          	at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:601)
          	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.fillReport(AbstractJasperReportsView.java:604)
          	at org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView.renderMergedOutputModel(AbstractJasperReportsView.java:546)
          	at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:247)
          	at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1105)
          	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:841)
          	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:755)
          	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:396)
          	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:350)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
          	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:264)
          	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:107)
          	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:72)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:110)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:142)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:81)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:217)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java:106)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:229)
          	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:274)
          	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:148)
          	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:98)
          	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
          	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
          	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
          	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
          	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
          	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
          	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
          	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
          	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
          	at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
          	at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
          	at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
          	at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
          	at java.lang.Thread.run(Thread.java:595)
          Code:
          
          Caused by: java.sql.SQLException: You can't operate on a closed ResultSet!!!
          	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:104)
          	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
          	at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:3047)
          	at net.sf.jasperreports.engine.JRResultSetDataSource.next(JRResultSetDataSource.java:95)
          	... 54 more
          Caused by: java.lang.NullPointerException
          	at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:3041)
          	... 55 more
          i am doom, how i can resolve this karl???

          thanks for advanced

          Comment


          • #20
            I think if you need to close anything, it's going to need to be after you've built the report.
            Last edited by karldmoore; Aug 29th, 2007, 12:17 PM.

            Comment


            • #21
              It's really not a 'deadlock' but more of an 'out of resources' condition. If there is a size limit to the number of connections in your pool, the application server execute threads will wait around until a connection becomes available or a timeout. If connections are in use and never returned back to the pool with a .close() then your threads will not proceed once the pool has no unused connections.

              Comment


              • #22
                ki karl
                thanks for the reply again
                I think if you need to close anything, it's going to need to be after you've built the report.
                sounds logic, but how, my code dont let does that, JR need the ResultSet open, should i think in AOP?

                jonnio:
                thanks for the reply
                It's really not a 'deadlock' but more of an 'out of resources' condition.
                ok, i would be agree

                If there is a size limit to the number of connections in your pool, the application server execute threads will wait around until a connection becomes available or a timeout.
                ok, i understand this

                If connections are in use and never returned back to the pool with a .close() then your threads will not proceed once the pool has no unused connections.
                ok, but the ResultSet is part of the connection and the connection is closed by
                Code:
                <bean id="dataSource"      
                         class="com.mchange.v2.c3p0.ComboPooledDataSource"  
                     destroy-method="close">
                so the ResultSet should be closed by ComboPooledDataSource too?


                both of you are right

                pls help me, i am out of ideas


                regards

                Comment


                • #23
                  Originally posted by dr_pompeii View Post
                  ok, but the ResultSet is part of the connection and the connection is closed by
                  Code:
                  <bean id="dataSource"      
                           class="com.mchange.v2.c3p0.ComboPooledDataSource"  
                       destroy-method="close">
                  so the ResultSet should be closed by ComboPooledDataSource too?
                  I fear this question is serious.
                  (No offense meant, but sometimes I'm really frightened.)

                  ComboPooledDataSource is a singleton and the destroy method is only called on close of the application context. This means when you stop your servlet container (in general).

                  Even if it would close the ResultSet it's an absolute anti-pattern to rely on such behavior. Even if it is part of the spec there can be an error in the implementation. You should ALWAYS close all and everything that needs to be closed explicitly and as early as possible and free the attached resources.

                  I remember having read this somewhere under the topic "Be a good citizen" or something like that but can't find the actual article. (When I google it I can only find religious stuff or something about neighborhood watch.) The best I found is "Always close streams" which does actually mean the same though I'd not restrict it to streams. Actually I also close ByteArray(In|Out)putStreams though I know their close() implementation does nothing. But: You should neither rely on implementations.

                  Jörg

                  Comment


                  • #24
                    I fear this question is serious.
                    (No offense meant, but sometimes I'm really frightened.)
                    no offense was taken, but maybe you thought that i am silly, i am worry about that
                    the reason of the question is because in the book doesnt "close" the ResultSet, so i trust in the book

                    and i thought that the
                    Code:
                    destroy-method="close"
                    was like Hibernate that control or is the management of the resources related with the db

                    but with

                    ComboPooledDataSource is a singleton and the destroy method is only called on close of the application context. This means when you stop your servlet container (in general).
                    i see now the reality


                    Even if it would close the ResultSet it's an absolute anti-pattern to rely on such behavior. Even if it is part of the spec there can be an error in the implementation. You should ALWAYS close all and everything that needs to be closed explicitly and as early as possible and free the attached resources.
                    thats the problem

                    ok, now how i shown in a previous post, if i close the ResultSet i cant fill thew JR and i recieve an exception
                    so, what should i do now?

                    regards

                    your advice are appreaciate

                    Comment


                    • #25
                      Originally posted by Jörg Heinicke View Post
                      I remember having read this somewhere under the topic "Be a good citizen" or something like that but can't find the actual article.
                      Found probably a quote at PicoContainer website where they use it for propagating constructor injection. It does not say something about closing/ freeing resources in particular, but the idea is the same. I also like this answer to the question if call Dispose is always necessary despite being empty-implemented:

                      Today, the only thing that SqlConnection's Dispose method does is make sure the connection is closed. Tomorrow, it could do something else. If you want to be a good citizen, call Dispose and pretend that you don't know what it does.
                      That's exactly why I close ByteArray(In|Out)putStreams as well.

                      Or from the same thread:
                      There is a reason Close exists period, and its not just to look pretty.
                      Another one adds one restriction to the rule:
                      You should always dispose the object if the object implements IDisposable *and* you own the object (in other words, you know that no-one else is going to use the object after you are done with it).
                      That means:
                      1. If you open a resource close it as well at the end.
                      2. If you got it passed, don't close it since the object that passed it to you might still need to do something with it. Since the other object is a good citizen as well it will also behave either following rule 1 or 2.
                      Least surprise, least paranoia.

                      Jörg

                      Comment


                      • #26
                        Originally posted by dr_pompeii View Post
                        ok, now how i shown in a previous post, if i close the ResultSet i cant fill thew JR and i recieve an exception so, what should i do now?
                        Ah, ok, after re-reading the thread I see where you were coming from. Your action can indeed not close your ResultSet, but I wonder if it should open it at all. What is supposed to work with the ResultSet or JRResultSetDataSource?

                        Jörg

                        Comment


                        • #27
                          hi Jörg

                          thanks for both links

                          That means:
                          1)If you open a resource close it as well at the end.
                          2)If you got it passed, don't close it since the object that passed it to you might still need to do something with it. Since the other object is a good citizen as well it will also behave either following rule 1 or 2.
                          i am in a 100% agree with you

                          but if ........
                          if i close the ResultSet i cant fill thew JR and i recieve an exception so, what should i do now?

                          Ah, ok, after re-reading the thread I see where you were coming from
                          good

                          Your action can indeed not close your ResultSet, but I wonder if it should open it at all. What is supposed to work with the ResultSet or JRResultSetDataSource?
                          wondered me too

                          but according with the exception
                          Code:
                          Caused by: java.sql.SQLException: You can't operate on a closed ResultSet!!!
                          	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:104)
                          	at com.mchange.v2.sql.SqlUtils.toSQLException(SqlUtils.java:65)
                          	at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:3047)
                          	at net.sf.jasperreports.engine.JRResultSetDataSource.next(JRResultSetDataSource.java:95)
                          	... 54 more
                          
                          it seems that work with the ResulSet,

                          but in the code
                          Code:
                           String query = "SELECT .....";
                          	    		 
                           connection = dataSource.getConnection();
                           ps=connection.prepareStatement(query);
                           ps.setString(1, almacenPK.getIdnumero());
                           resultSet = ps.executeQuery();	    
                          
                          	    
                            JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(resultSet);
                            context.getRequestScope().put("datasource", resultSetDataSource);
                            return success();
                          
                          the object resultSetDataSource has the resultSet and then send it to the flow

                          but seems that again in the .jasper this object resultSetDataSource is used of course and need again the resulset, but how was closed, the exception is thrown

                          here are the trick and the problem

                          regards

                          Comment


                          • #28
                            Originally posted by dr_pompeii View Post
                            here are the trick and the problem
                            But you did not answer my question:

                            What is supposed to work with the ResultSet or JRResultSetDataSource?
                            I mean there must be a reason you put the JRResultSetDataSource exactly at that key into the request scope. What component does it get from there? Is it an extension of AbstractJasperReportsView?

                            Anyhow, you have two options sticking to the rules mentioned above: Let the component open the database connection that creates the report and that can also close the connection afterwards. Or open the connection in your web flow action, convert the ResultSet to a collection as recommended by Karl at the very beginning and close the connection in the action as well.

                            Option 2 is bad for huge reports since the whole ResultSet needs to be retrieved into the memory while with option 1 working row by row is possible. Don't know if Jasper is doing this. Huge depends heavily on your environment/ resources, but I think of at least 1,000 rows in the ResultSet.

                            To go with option 1 you can inject the data source into the JasperReportsView. It calls JasperFillManager.fillReport(JasperReport, Map, Connection); by default. No idea how it is supposed to work and retrieve the exact data internally. But you can extend AbstractJasperReportsView and overwrite the method fillReport(Map), execute exactly the JDBC code you are executing now in the webflow action, create the report and close the ResultSet immediately afterwards.

                            To convert ResultSet to Collection Spring's RowMappers might be an option, especially ColumnMapRowMapper. Or you use JdbcTemplate.queryForList(String sql) directly.

                            Hope this helps.

                            Jörg

                            Comment


                            • #29
                              What is supposed to work with the ResultSet or JRResultSetDataSource?
                              I mean there must be a reason you put the JRResultSetDataSource exactly at that key into the request scope. What component does it get from there? Is it an extension of AbstractJasperReportsView?
                              well is almost a copy of the code(programming way) of the book
                              http://www.packtpub.com/JasperReports/book
                              and its about of spring/jasper report integration , chapter 11

                              here its code
                              Code:
                              package net.ensode.jasperbook.spring;
                              
                              import java.io.IOException;
                              import java.sql.Connection;
                              import java.sql.ResultSet;
                              import java.sql.SQLException;
                              import java.sql.Statement;
                              import java.util.HashMap;
                              import java.util.Map;
                              
                              import javax.servlet.ServletException;
                              import javax.servlet.http.HttpServletRequest;
                              import javax.servlet.http.HttpServletResponse;
                              import javax.sql.DataSource;
                              
                              import net.sf.jasperreports.engine.JRResultSetDataSource;
                              
                              import org.springframework.web.servlet.ModelAndView;
                              import org.springframework.web.servlet.mvc.Controller;
                              
                              public class JasperSpringController implements Controller
                              {
                                private DataSource dataSource;
                                
                                public ModelAndView handleRequest(HttpServletRequest request,
                                    HttpServletResponse response) throws ServletException, IOException, ClassNotFoundException, SQLException
                                {
                                  return new ModelAndView("report", getModel());
                                }
                              
                                private Map getModel() throws ClassNotFoundException, SQLException
                                {
                                  Connection connection;
                                  Statement statement;
                                  ResultSet resultSet;
                                  HashMap model = new HashMap();
                                  
                                  String query = "select a.tail_num, a.aircraft_serial, " 
                                    + "am.model as aircraft_model, ae.model as engine_model from aircraft a, "
                                    + "aircraft_models am, aircraft_engines ae where a.aircraft_engine_code in ("
                                    + "select aircraft_engine_code from aircraft_engines "
                                    + "where horsepower >= 1000) and am.aircraft_model_code = a.aircraft_model_code "
                                    + "and ae.aircraft_engine_code = a.aircraft_engine_code";
                                  
                                  connection = dataSource.getConnection();
                                  statement = connection.createStatement();
                                  resultSet = statement.executeQuery(query);
                                  
                                  JRResultSetDataSource resultSetDataSource = new JRResultSetDataSource(resultSet);
                                  
                                  model.put("datasource", resultSetDataSource);
                                  
                                  
                                  return model;
                                }
                                
                                public void setDataSource (DataSource dataSource)
                                {
                                  this.dataSource=dataSource;
                                }
                              
                              }
                              with this context configuration
                              Code:
                              <beans>
                              	<bean id="dataSource"
                              		class="org.springframework.jdbc.datasource.DriverManagerDataSource"
                              		destroy-method="close">
                              		<property name="driverClassName">
                              			<value>com.mysql.jdbc.Driver</value>
                              		</property>
                              		<property name="url">
                              			<value>jdbc:mysql://localhost:3306/flightstats</value>
                              		</property>
                              		<property name="username">
                              			<value>root</value>
                              		</property>
                              		<property name="password">
                              			<value>password</value>
                              		</property>
                              	</bean>
                              
                              	<bean id="publicUrlMapping"
                              		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                              		<property name="mappings">
                              			<props>
                              				<prop key="report">jasperController</prop>
                              			</props>
                              		</property>
                              	</bean>
                              
                              	<bean id="jasperController"
                              		class="net.ensode.jasperbook.spring.JasperSpringController">
                              		<property name="dataSource">
                              			<ref local="dataSource" />
                              		</property>
                              	</bean>
                              so, i trust in the book, i hope this answer your question

                              Let the component open the database connection that creates the report and that can also close the connection afterwards
                              yes, its better

                              But you can extend AbstractJasperReportsView and overwrite the method fillReport(Map), execute exactly the JDBC code you are executing now in the webflow action, create the report and close the ResultSet immediately afterwards.
                              mmm, a lot of work, and my skills are not ready to overwrite this world,
                              i think that should exists a simple and better way

                              To convert ResultSet to Collection Spring's RowMappers might be an option, especially ColumnMapRowMapper. Or you use JdbcTemplate.queryForList(String sql) directly.
                              it would be better

                              tell me friend Jörg ,
                              how do you work wtih this case???
                              JdbcTemplate.queryForList(String sql) or ColumnMapRowMapper. ??
                              it seems that JdbcTemplate.queryForList(String sql) is more easier than ColumnMapRowMapper.

                              if you can share an extract of code, i really appreciate

                              regards

                              Manuel

                              Comment


                              • #30
                                I haven't read this book, nor have I used this technique before, but it must be a pretty common problem. If you are leaving ResultSets open, who is supposed to clean them up. JRResultSetDataSource doesn't have a close method. Is this a recommended example from the book, or is it simply this implementation that's causing the problems?
                                Last edited by karldmoore; Aug 29th, 2007, 12:17 PM.

                                Comment

                                Working...
                                X