{"action":"created","issue":{"url":"https://api.github.com/repos/stoicflame/enunciate/issues/528","repository_url":"https://api.github.com/repos/stoicflame/enunciate","labels_url":"https://api.github.com/repos/stoicflame/enunciate/issues/528/labels{/name}","comments_url":"https://api.github.com/repos/stoicflame/enunciate/issues/528/comments","events_url":"https://api.github.com/repos/stoicflame/enunciate/issues/528/events","html_url":"https://github.com/stoicflame/enunciate/issues/528","id":185094121,"number":528,"title":"File handle leaks","user":{"login":"allenhadden","id":4704268,"avatar_url":"https://avatars.githubusercontent.com/u/4704268?v=3","gravatar_id":"","url":"https://api.github.com/users/allenhadden","html_url":"https://github.com/allenhadden","followers_url":"https://api.github.com/users/allenhadden/followers","following_url":"https://api.github.com/users/allenhadden/following{/other_user}","gists_url":"https://api.github.com/users/allenhadden/gists{/gist_id}","starred_url":"https://api.github.com/users/allenhadden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/allenhadden/subscriptions","organizations_url":"https://api.github.com/users/allenhadden/orgs","repos_url":"https://api.github.com/users/allenhadden/repos","events_url":"https://api.github.com/users/allenhadden/events{/privacy}","received_events_url":"https://api.github.com/users/allenhadden/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-10-25T11:50:07Z","updated_at":"2016-10-25T16:10:19Z","closed_at":null,"body":"I believe that I've found two places where Enunciate is not properly closing opened files.  In my project this causes some files to be opened (and not closed) 10 or more times.  The result for me is an intermittent \"Too many files open\" operating system error.\r\n\r\nI used the \"File Leak Detector\" (http://file-leak-detector.kohsuke.org/) to help pin down where the problems are occurring.  It revealed the following methods:\r\n\r\nEnunciate.java:\r\n```\r\n    @Override\r\n    public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {\r\n      StringBuilder content = new StringBuilder();\r\n      InputStream in = openInputStream();\r\n      byte[] bytes = new byte[2 * 1024];\r\n      int len;\r\n      while ((len = in.read(bytes)) >= 0) {\r\n        content.append(new String(bytes, 0, len, this.encoding));\r\n      }\r\n      return content;\r\n    }\r\n```\r\n\r\nThe solution to the above issue is to use try-with-resources to close the InputStream (since it's never used outside the method).\r\n\r\nand the following (BasicGeneratingModule.java):\r\n\r\n```\r\n  public long findSourceTimestamp(DecoratedProcessingEnvironment env, Element apiElement) {\r\n    SourcePosition sp = env.findSourcePosition(apiElement);\r\n    URI uri = sp == null ? null : sp.getPath() == null ? null : sp.getPath().getCompilationUnit() == null ? null : sp.getPath().getCompilationUnit().getSourceFile() == null ? null : sp.getPath().getCompilationUnit().getSourceFile().toUri();\r\n    if (uri != null && \"file\".equalsIgnoreCase(uri.getScheme())) {\r\n      //it's a file uri.\r\n      try {\r\n        return uri.toURL().openConnection().getLastModified();\r\n      }\r\n      catch (IOException e) {\r\n        return 0;\r\n      }\r\n    }\r\n\r\n    return 0;\r\n  }\r\n```\r\n\r\nThe issue here is a longstanding issue with Java and the use of the FileURLConnection, which is what openConnection() returns when the URL is a file-based one.  Basically, whenever FileURLConnection actually opens the file it uses a FileInputStream that it never closes.  You can see this in the following bug report from 1999 (which was closed as 'Not an Issue'):\r\n\r\nhttp://bugs.java.com/bugdatabase/view_bug.do?bug_id=4257700\r\n\r\nThe workaround described in that bug is to use knowledge of the inner workings of FileURLConnection and call urlConnection.getInputStream().close().  Because of the absurdity of this recommendation, I'd suggest abandoning the use of openConnection/URLConnection and instead use this code:\r\n\r\n```\r\nnew File(uri.getPath()).lastModified()\r\n```\r\n"},"comment":{"url":"https://api.github.com/repos/stoicflame/enunciate/issues/comments/256081921","html_url":"https://github.com/stoicflame/enunciate/issues/528#issuecomment-256081921","issue_url":"https://api.github.com/repos/stoicflame/enunciate/issues/528","id":256081921,"user":{"login":"stoicflame","id":145838,"avatar_url":"https://avatars.githubusercontent.com/u/145838?v=3","gravatar_id":"","url":"https://api.github.com/users/stoicflame","html_url":"https://github.com/stoicflame","followers_url":"https://api.github.com/users/stoicflame/followers","following_url":"https://api.github.com/users/stoicflame/following{/other_user}","gists_url":"https://api.github.com/users/stoicflame/gists{/gist_id}","starred_url":"https://api.github.com/users/stoicflame/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stoicflame/subscriptions","organizations_url":"https://api.github.com/users/stoicflame/orgs","repos_url":"https://api.github.com/users/stoicflame/repos","events_url":"https://api.github.com/users/stoicflame/events{/privacy}","received_events_url":"https://api.github.com/users/stoicflame/received_events","type":"User","site_admin":false},"created_at":"2016-10-25T16:10:19Z","updated_at":"2016-10-25T16:10:19Z","body":"Thanks for the report!"}}
{"actor":{"display_login":"stoicflame"}}