我的应用程序使用GAE的这个API:
URLFetchServiceFactory.getURLFetchService().fetch
哪个适用于devserver
,但在30到60分钟后(时间不同),它会开始投掷StackOverflowError
。
对标准网址的fetch
调用实际上会导致URLFetchServiceFactory.getURLFetchService().fetch
抛出SO错误的方式。
这是完整的日志:https://pastebin.com/WCcmXCH3(长)
答案 0 :(得分:1)
完整日志中的堆栈深度具有非常可疑的值1025 = 1024 +1。
仔细观察会发现您有这种重复的递归调用序列:
[INFO] at java.io.File.isDirectory(File.java:844)
[INFO] at sun.net.www.ParseUtil.fileToEncodedURL(ParseUtil.java:269)
[INFO] at sun.security.provider.PolicyFile.canonicalizeCodebase(PolicyFile.java:1735)
[INFO] at sun.security.provider.PolicyFile.access$700(PolicyFile.java:258)
[INFO] at sun.security.provider.PolicyFile$5.run(PolicyFile.java:1188)
[INFO] at sun.security.provider.PolicyFile$5.run(PolicyFile.java:1186)
[INFO] at java.security.AccessController.doPrivileged(Native Method)
[INFO] at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1185)
[INFO] at sun.security.provider.PolicyFile.getPermissions(PolicyFile.java:1132)
[INFO] at sun.security.provider.PolicyFile.implies(PolicyFile.java:1086)
[INFO] at com.google.appengine.tools.development.IsolatedAppClassLoader$ProxyPolicy$2.run(IsolatedAppClassLoader.java:418)
[INFO] at com.google.appengine.tools.development.IsolatedAppClassLoader$ProxyPolicy$2.run(IsolatedAppClassLoader.java:415)
[INFO] at java.security.AccessController.doPrivileged(Native Method)
[INFO] at com.google.appengine.tools.development.IsolatedAppClassLoader$ProxyPolicy._implies(IsolatedAppClassLoader.java:415)
[INFO] at com.google.appengine.tools.development.IsolatedAppClassLoader$ProxyPolicy.implies(IsolatedAppClassLoader.java:42005)
[INFO] at java.security.ProtectionDomain.implies(ProtectionDomain.java:285)
[INFO] at java.security.AccessControlContext.checkPermission(AccessControlContext.java:450)
[INFO] at java.security.AccessController.checkPermission(AccessController.java:884)
[INFO] at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
[INFO] at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:429)
[INFO] at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
[INFO] at java.io.File.isDirectory(File.java:844)
... repeating 49 times or so
我不是Java用户,但如果我正确解释它,您可能会处理目录结构太深。
如果是这样,要么重新安排目录结构,要么修改你的代码以限制它一次进入它的深度。
答案 1 :(得分:0)
经过几个小时的挖掘后,我发现了StackOverflowError的罪魁祸首,显然在调用fetch之前的for循环导致了这一点,这里:
List<String> cachedLinks = (List<String>) memcache.get(url);
for(String link : cachedLinks) { // size range from 0 to 1000 or more...
// Do something
}
// then a bit later
URLFetchServiceFactory.getURLFetchService().fetch(...);
然而,cachedLinks
包含数千个String值。删除for循环会停止抛出StackOverflowError
。
也许Java大师可以更好地解释这种现象,以及为什么 for-loop 在fetch
调用之上。