The session timeout may have been the issue and we are looking into using the guidelines to setup loginRequiredMarkers. However, we don't believe this issue is related to markers. It appears that the client side is prematurely closing the socket connection. Show 1. SmartClient Version: v10.0p_2015-02-25/PowerEdition Deployment (built 2015-02-25) 2. Chrome Version 40.0.2214.115 m 3. === 2015-03-12 15:35:24,210 [sor2] INFO RequestContext - URL: '/<removed>/<removed>/<removed>', User-Agent: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36': Safari with Accept-Encoding header Mar 12, 2015 3:35:24 PM org.apache.catalina.core.ApplicationContext log SEVERE: Exception while dispatching incoming RPC call java.io.IOException: Stream closed at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:325) at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:162) at com.google.gwt.user.server.rpc.RPCServletUtils.readContent(RPCServletUtils.java:224) at com.google.gwt.user.server.rpc.RPCServletUtils.readContentAsGwtRpc(RPCServletUtils.java:252) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.readContent(AbstractRemoteServiceServlet.java:182) at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:364) at com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.alcatel_lucent.aware.web.wnganalytic.server.SecurityFilter.doFilter(SecurityFilter.java:79) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at com.isomorphic.servlet.CompressionFilter._doFilter(CompressionFilter.java:260) at com.isomorphic.servlet.BaseFilter.doFilter(BaseFilter.java:83) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190) at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291) at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:769)) at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:698) at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:891) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690) at java.lang.Thread.run(Thread.java:745) Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community. By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails. Already on GitHub? Sign in to your account Comments
Environment Details
Problem DescriptionJSP compiling process is done at the first access. at this time, I debug following the operating steps, IOException ("Stream closed") has occurred. it occur in the debug, but I think it will occur in high concurrent accessing apps. Is it a bug of Glassfish, since two threads get the same jarFile. Steps to reproduce1.Deploy test app1 and app2 and start cluster. 2.Set breakpoints
3.access app1 and app2. 4.At this time, two threads stop at the breakpoint. 5.First, resume the thread of app1. Leave the thread of app 2 stopped at the breakpoint. 6.When executing the thread of app 2, IOException ("Stream closed") is output because ★closed value is set to true. Impact of IssueThe following log is reported and the second app return '500' [#|2018-07-12T02:56:08.230-0700|WARNING|||_ThreadID=67;_ThreadName=http-thread-pool-28292(2);|ApplicationDispatcher[/Demo2] PWC1231: Servlet.service() for servlet jsp threw exception java.io.IOException: Stream closed at java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67) at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:121) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(XMLEntityManager.java:2873) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:664) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:812) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:243) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:347) at org.apache.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:298) at org.apache.jasper.xmlparser.ParserUtils.parseXMLDocument(ParserUtils.java:368) at org.apache.jasper.runtime.TldScanner.scanTld(TldScanner.java:600) at org.apache.jasper.runtime.TldScanner.scanJar(TldScanner.java:447) at org.apache.jasper.runtime.TldScanner.scanJars(TldScanner.java:737) at org.apache.jasper.runtime.TldScanner.scanTlds(TldScanner.java:350) at org.apache.jasper.runtime.TldScanner.getLocation(TldScanner.java:283) at org.apache.jasper.JspCompilationContext.getTldLocation(JspCompilationContext.java:589) at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:500) at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:582) at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1652) at org.apache.jasper.compiler.Parser.parse(Parser.java:185) at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:244) at org.apache.jasper.compiler.ParserController.parse(ParserController.java:145) at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:212) at org.apache.jasper.compiler.Compiler.compile(Compiler.java:451) at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:627) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:375) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:473) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:377) at javax.servlet.http.HttpServlet.service(HttpServlet.java:770) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:809) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:671) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:505) at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:476) at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:355) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:305) ... at java.lang.Thread.run(Thread.java:745) Occurrence condition:1.At the same time when accessing app 1 and app 2 (JSP compiling process is done at first access), two processing threads (thread 1, 2) are activated, and these two threads get the same jarFile ★ 1. 2.At the end of the scanJar () method of app 1 (thread 1), jarFile is closed. ★ 3. 3.Since jarFile is closed, the closed state of stream★2 of app 2 (thread 2) is true. 4.When app2 (thread 2) executes scanTld (), an IOException ("Stream closed") occurs because the closed state of stream has become true.
The text was updated successfully, but these errors were encountered:
Thoughts: When multiple threads read and close a jar file at the same time, exclusive control is performed. Verification result: Avoidable amendment: org.apache.jasper.runtime.TldScanner private void scanJar (JarURLConnection conn, List tldNames, boolean isLocal) throws JasperException { String resourcePath = conn.getJarFileURL (). ToString (); TldInfo [] tldInfos = jarTldCacheLocal.get (resourcePath); // Optimize for most common cases: jars known to NOT have tlds if (tldInfos! = null && tldInfos.length == 0) { try { conn.getJarFile (). close (); } catch (IOException ex) { // ignored } return; } // scan the tld if the jar has not been cached. + synchronized (TldScanner.class) { if (tldInfos == null) { JarFile jarFile = null; ArrayList tldInfoA = new ArrayList (); try { jarFile = conn.getJarFile (); if (tldNames! = null) { for (String tldName: tldNames) { JarEntry entry = jarFile.getJarEntry (tldName); InputStream stream = jarFile.getInputStream (entry); tldInfoA.add (scanTld (resourcePath, tldName, stream)); } } else { Enumeration entries = jarFile.entries (); while (entries.hasMoreElements ()) { JarEntry entry = entries.nextElement (); String name = entry.getName (); if (! name.startsWith ("META-INF /")) continue; if (! name.endsWith (". tld")) continue; InputStream stream = jarFile.getInputStream (entry); tldInfoA.add (scanTld (resourcePath, name, stream)); } } } catch (IOException ex) { if (resourcePath.startsWith (FILE_PROTOCOL) && ! ((new File (resourcePath)). exists ())) { if (log.isLoggable (Level.WARNING)) { log.log (Level.WARNING, Localizer.getMessage ("jsp.warn.nojar", resourcePath), ex); } } else { throw new JasperException ( Localizer.getMessage ("jsp.error.jar.io", resourcePath), ex); } } finally { if (jarFile! = null) { try { jarFile.close (); } catch (Throwable t) { // ignore } } } // Update the jar TLD cache tldInfos = tldInfoA.toArray (new TldInfo [tldInfoA.size ()]); jarTldCacheLocal.put (resourcePath, tldInfos); if (! isLocal) { // Also update the global cache; jarTldCache.put (resourcePath, tldInfos); } } +} // Iterate over tldinfos to add listeners or to tldlocations for (TldInfo tldInfo: tldInfos) { if (scanListeners) { addListener (tldInfo, isLocal); } mapTldLocation (resourcePath, tldInfo, isLocal); } }
There are some conditions to correctThe occurrence conditions can be divided into the case of using jstl and not using jstl, specifically refer to the following: Not using jstl:
case1
①The following definitions in JSP
case2
The following definitions in JSP
Using jstl: When the JSP contains jstl related tags (eg <c:>) Is there anyone who can respond as quickly as possible, thanks very much. :)
Is there anyone who can respond as quickly as possible, thanks very much. :)
Why don't you make a PR and test if you know the fix?
Why don't you make a PR and test if you know the fix? I fixed it with the amendment I commented and it worked well. But my amendment is not authoritative, is there a community guy to confirm it?
It is easier for people to discuss a PR than look for embedded code in a comment as the PR will highlight diffs etc. and people can comment on individual lines of code. A PR can also be run through Jenkins tests to see if it compiles and passes all tests.
I have two questions I would like to ask:
After we corrected it according to our amendment, we reproduced it according to the reproduction step, and found that we could avoid the problem. I hope that you can help us confirm whether there is a problem with this correction.
Sorry this is late, we've been behind on updating the GlassFish web site. In the mean time, you can find out more about Pull Requests here. I'm not at all familiar with the code you're looking at, so I have some questions... For this problem to occur, it seems like the same JarURLConnection object would need to be used in the call to TldScanner.scanJar for both applications. Where is the JarURLConnection object coming from? Why is it the same for both applications? Is the scanning being done for some shared tag library? Is something caching the JarURLConnection object, causing it to be shared across applications? Maybe the right fix is to ensure there's a separate JarURLConnection object for each application?
The reproduction is performed in accordance with the reproduction handwriting provided by itself, and the conn object is viewed during the reproduction. Conn when accessing app1: conn JarURLConnection (id=6231) Conn when accessing app2: conn JarURLConnection (id=6271) According to the results, they are not the same object. But the jarFile taken from conn is the same object. jarFile when accessing app1: jarFile URLJarFile (id=6229) jarFile when accessing app2: jarFile URLJarFile (id=6229) According to your correction suggestion, make sure that the two apps have two different JarURLConnections. But from the current survey, they are indeed different JarURLConnection, the same jarFile is obtained. Therefore, is it still according to my correction method, or there are still other corrections. Please point the specific correction direction.
I see the JarURLConnection is using a cache that shares the cached JarFile
between all JarURLConnection objects with the same URL. That's what's
preventing each app from getting its own copy. The right fix might be to call
I'm only worried about what impact that would have on performance or memory use. Your alternative of single-threading the TLD scanner might turn out to be better, but it has a potential performance cost as well. Since the problem is that multiple threads are operating on the same JarFile object, why not just synchronize on the JarFile object itself? Since both threads are racing to process the JarFile and add the TLD entries to the cache, there's no point in both of them doing that. One of them might as well update the cache while the other waits and checks the cache again. It's surprising that no other use of JarURLConnection in GlassFish runs into this issue. Do other uses do something to ensure that two threads aren't operating on the same JarFile object?
In the original code, this setting has been made, but the settings have not taken effect.
When this method is executed, useCaches is not set to false.
The useCaches in FileURLConnection.setUseCaches are successfully set to false. But when returned, useCaches becomes true again. I can't understand this point. Do you have any good ideas?
0 I'm not sure when this method will be called. I did some instruction execution, but didn't call this method. About this method, do you know when it is called?
I don't know why 1 isn't working, but it's probably not the best solution so let's abandon that.For 2, the goal should be that if two threads are both calling scanJar at the "same time",one of them gets the synchronization lock and does all the work, while the other one waits for the synchronization lock and then discovers that all the work has been done and so does nothing. The right way to do this is to move the check of "has this jar file already been scanned" to inside the
1 block. That would require some rearranging of the code. Note that I'm not really familiar with this code or what it's trying to accomplish. There's a whole bunch of work that's done if
2, and then some work after that that's done whether it's null or not. I believe this latter work is application-specific and so should be outside the synchronized block, but let me know if that sounds wrong. If you can change the code in this way and test it, and submit a Pull Request, I'll review and approve it. I don't know about 3; that looks like a problem for another day! :-)Thanks.
I am very sorry to have responded for so long. I have fixed and tested it according to your prompts, and I have summitted a pull request. In addition, TldScanner belongs to eclipse-ee4j/jsp-api instead of eclipse-ee4j/glassfish. Can you help to deal about it?Thanks!
jsp-api is a different project with potentially different team members.
This issue has been marked as inactive and old and will be closed in 7 days if there is no further activity. If you want the issue to remain open please add a comment |