Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

JDBC Driver closing inputstream before i have a chance to use it?  RSS feed

 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi everyone!

In my code, I am using the Apache POI libraries to generate some Excel and Word documents from templates, which are stored in a database as BLOBs. I load the template as an InputStream, and then use that stream to create the objects the Apache POI library uses. It works in full when I run my code locally. The issue I'm running into is when I deploy my code to a Dev or QA server, I'm getting the exception below. Line 7 in my sample code below the exception is Line 659 in "FileOpsImpl.java", as referenced in the exception. It looks to me like somehow that input stream is being closed before I get to that line in the code. Does that make sense? Is that possible? Is there any way to resolve this? I'm obviously not manually closing it until wayyy later in the code. Is there anything I can do about this?

Thanks a ton!

java.io.IOException: [BEA][Oracle JDBC Driver]Object has been closed.
at weblogic.jdbc.base.BaseInputStreamWrapper.validateClosedState(Unknown Source)
at weblogic.jdbc.base.BaseInputStreamWrapper.read(Unknown Source)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at java.io.PushbackInputStream.read(PushbackInputStream.java:169)
at java.util.zip.ZipInputStream.readFully(ZipInputStream.java:397)
at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:230)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:74)
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.(ZipInputStreamZipEntrySource.java:51)
at org.apache.poi.openxml4j.opc.ZipPackage.(ZipPackage.java:83)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:228)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:39)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.(XSSFWorkbook.java:187)
at com.capitalone.citrix.ssp.services.FileOpsImpl.generateDownload(FileOpsImpl.java:659)
at com.capitalone.citrix.ssp.controller.DownloadController.display(DownloadController.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3498)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Unknown Source)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)


My code is as follows:



 
Rob Spoor
Sheriff
Posts: 21088
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you show us the code for katetDao.getTemplate?
 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Indeed -

 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm actually suspicious that this might be a Weblogic issue, something about how it's handling the JNDI connection while retrieving something out of the database larger than, say, a set of Strings, but that's just a guess at this point.
 
Claude Moore
Ranch Hand
Posts: 891
8
IBM DB2 Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ryan Kostrzewa wrote:I'm actually suspicious that this might be a Weblogic issue, something about how it's handling the JNDI connection while retrieving something out of the database larger than, say, a set of Strings, but that's just a guess at this point.

You may be right...how long does the method takes to read all data and write them in xls file? Is it possible that it takes so long that weblogic timeouts the transaction?
 
Rob Spoor
Sheriff
Posts: 21088
85
Chrome Eclipse IDE Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Line 27 is the culprit, and if you remove that then you still have line 30. Closing a Connection closes all of its JDBC resources. That includes statements. Closing a Statement closes all of its JDBC resources. That includes ResultSets. And closing a ResultSet closes all of its JDBC resources. And that in the end causes the issue - one of those resources is the InputStream.
 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Claude - about 3 seconds when it's run locally - I can't imagine it would be too much longer in other environments, but possibly a little bit more.

Rob - ahhh, that makes sense! Let me add that in. In that case, when SHOULD I close the connection? Seems like maybe returning an inputstream isn't a good idea then, because you'd have to manage that connection in whichever method is calling "getTemplate()" in this case, right?
 
Rob Spoor
Sheriff
Posts: 21088
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Correct. You could possibly wrap the input stream into a custom implementation that keeps a reference to the result set, prepared statement and connection, and closes all three when the input stream is closed, but that still does not seem like a very good solution. Letting the DAO method return the worksheet also seems wrong (logic goes into a DAO... not good).

If you use a Java 8 enabled container (don't know if WebLogic is one) you could change your getTemplate method into a processTemplate method that takes a Consumer<InputStream> or a similar functional interface, then you could keep the logic to the calling method but still keep the closing of resources local to the DAO method (which just takes the logic as a parameter).
 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just for kicks (ignoring convention, for a moment) I tried just hardcoding the getTemplate() function into the code instead of calling it, and handling the streams, connections, and statements all from there, but still no dice. It's bizarre because this does work when I'm running the code locally, so I'm getting the feeling more and more that it's a Weblogic issue. I'm also not 100% sure it's a timeout, because the error seems to come up immediately upon clicking the "download" button. It's not like it's sitting there thinking for a few seconds and then it crashes.

Man, this is tough.
 
Ryan Kostrzewa
Ranch Hand
Posts: 31
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Resolved! By complete and total dumb luck...

In the getTemplate function, I changed the segment of code from



to



No idea why it worked, but it does. Hooray for not getting fired!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!