{"action":"created","comment":{"url":"https://api.github.com/repos/robolectric/robolectric/pulls/comments/29482467","id":29482467,"diff_hunk":"@@ -1,22 +1,45 @@\n package org.robolectric.internal;\n \n-import org.robolectric.manifest.AndroidManifest;\n-import org.robolectric.res.FsFile;\n+import org.robolectric.internal.bytecode.InstrumentingClassLoader;\n+import org.robolectric.internal.bytecode.InstrumentingClassLoaderConfig;\n+import org.robolectric.internal.dependency.DependencyResolver;\n+import org.robolectric.util.Pair;\n \n-import java.lang.ref.SoftReference;\n-import java.util.HashMap;\n+import java.net.URL;\n+import java.util.LinkedHashMap;\n import java.util.Map;\n \n public class EnvHolder {","path":"robolectric/src/main/java/org/robolectric/internal/EnvHolder.java","position":16,"original_position":16,"commit_id":"116cf5e5c7acb35476efcabba4fde0481b98d83c","original_commit_id":"116cf5e5c7acb35476efcabba4fde0481b98d83c","user":{"login":"jongerrish","id":6314616,"avatar_url":"https://avatars.githubusercontent.com/u/6314616?v=3","gravatar_id":"","url":"https://api.github.com/users/jongerrish","html_url":"https://github.com/jongerrish","followers_url":"https://api.github.com/users/jongerrish/followers","following_url":"https://api.github.com/users/jongerrish/following{/other_user}","gists_url":"https://api.github.com/users/jongerrish/gists{/gist_id}","starred_url":"https://api.github.com/users/jongerrish/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jongerrish/subscriptions","organizations_url":"https://api.github.com/users/jongerrish/orgs","repos_url":"https://api.github.com/users/jongerrish/repos","events_url":"https://api.github.com/users/jongerrish/events{/privacy}","received_events_url":"https://api.github.com/users/jongerrish/received_events","type":"User","site_admin":false},"body":"I'll probably rename this class in a follow up PR, perhaps InstrumentingClassloaderFactory ?","created_at":"2015-05-01T00:15:29Z","updated_at":"2015-05-01T00:15:29Z","html_url":"https://github.com/robolectric/robolectric/pull/1746#discussion_r29482467","pull_request_url":"https://api.github.com/repos/robolectric/robolectric/pulls/1746","_links":{"self":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/comments/29482467"},"html":{"href":"https://github.com/robolectric/robolectric/pull/1746#discussion_r29482467"},"pull_request":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/1746"}}},"pull_request":{"url":"https://api.github.com/repos/robolectric/robolectric/pulls/1746","id":34373982,"html_url":"https://github.com/robolectric/robolectric/pull/1746","diff_url":"https://github.com/robolectric/robolectric/pull/1746.diff","patch_url":"https://github.com/robolectric/robolectric/pull/1746.patch","issue_url":"https://api.github.com/repos/robolectric/robolectric/issues/1746","number":1746,"state":"open","locked":false,"title":"Implement caching of SdkEnvironments","user":{"login":"jongerrish","id":6314616,"avatar_url":"https://avatars.githubusercontent.com/u/6314616?v=3","gravatar_id":"","url":"https://api.github.com/users/jongerrish","html_url":"https://github.com/jongerrish","followers_url":"https://api.github.com/users/jongerrish/followers","following_url":"https://api.github.com/users/jongerrish/following{/other_user}","gists_url":"https://api.github.com/users/jongerrish/gists{/gist_id}","starred_url":"https://api.github.com/users/jongerrish/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jongerrish/subscriptions","organizations_url":"https://api.github.com/users/jongerrish/orgs","repos_url":"https://api.github.com/users/jongerrish/repos","events_url":"https://api.github.com/users/jongerrish/events{/privacy}","received_events_url":"https://api.github.com/users/jongerrish/received_events","type":"User","site_admin":false},"body":"Replace rudimentary caching of SdkEnvironment in RobolectricTestRunner + SoftReferences (we don't want caching to depend on GC) with a basic LRU cache in EnvHolder. (We might want to rename EnvHolder to SdkEnvironmentCache maybe).\r\n\r\nThe cache is sized at the number of api levels supported by Robolectric since most test suites\r\nwill only ever have this number of environments. It is possible to have more environments than this\r\nif multiple InstrumentingClassloaderConfigs are used which is rare, but is the case in the\r\nRobolectric test suite. This is why we need to also include the test runner class name as part of the\r\nkey as a substitute for InstrumentingClassloaderConfig. We could consider refactoring InstrumentingClassloaderConfig to make it final, constructed using a builder and having properties (like instrumented packages / classes etc) that can be compared in a .equals() / .hashCode() sense. Alexander Blom also suggested only caching where config.getClass() == InstrumentingClassloaderConfig.class directly, so custom derived classes would not get cached. I'm open to ideas here.\r\n\r\nOther cleanups included:-\r\n\r\n* Don't pass the classlaoder into the ResourceExtractor in order to control the scope of references\r\nto the classloader.\r\n* Empty the map of loaded test classes at the end of the test as this keeps transient references to\r\nthe classloaders alive.\r\n\r\nMove file -> manifest mapping from EnvHolder to test runner since EnvHolder is concerned with managing SdkConfig -> Classloader mappings.","created_at":"2015-04-29T15:21:51Z","updated_at":"2015-05-01T00:15:29Z","closed_at":null,"merged_at":null,"merge_commit_sha":"06dd559a981dcb822c65594e8f0bb2b838ce2f81","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/robolectric/robolectric/pulls/1746/commits","review_comments_url":"https://api.github.com/repos/robolectric/robolectric/pulls/1746/comments","review_comment_url":"https://api.github.com/repos/robolectric/robolectric/pulls/comments{/number}","comments_url":"https://api.github.com/repos/robolectric/robolectric/issues/1746/comments","statuses_url":"https://api.github.com/repos/robolectric/robolectric/statuses/116cf5e5c7acb35476efcabba4fde0481b98d83c","head":{"label":"jongerrish:new_sdk_env_caching","ref":"new_sdk_env_caching","sha":"116cf5e5c7acb35476efcabba4fde0481b98d83c","user":{"login":"jongerrish","id":6314616,"avatar_url":"https://avatars.githubusercontent.com/u/6314616?v=3","gravatar_id":"","url":"https://api.github.com/users/jongerrish","html_url":"https://github.com/jongerrish","followers_url":"https://api.github.com/users/jongerrish/followers","following_url":"https://api.github.com/users/jongerrish/following{/other_user}","gists_url":"https://api.github.com/users/jongerrish/gists{/gist_id}","starred_url":"https://api.github.com/users/jongerrish/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jongerrish/subscriptions","organizations_url":"https://api.github.com/users/jongerrish/orgs","repos_url":"https://api.github.com/users/jongerrish/repos","events_url":"https://api.github.com/users/jongerrish/events{/privacy}","received_events_url":"https://api.github.com/users/jongerrish/received_events","type":"User","site_admin":false},"repo":{"id":20038258,"name":"robolectric","full_name":"jongerrish/robolectric","owner":{"login":"jongerrish","id":6314616,"avatar_url":"https://avatars.githubusercontent.com/u/6314616?v=3","gravatar_id":"","url":"https://api.github.com/users/jongerrish","html_url":"https://github.com/jongerrish","followers_url":"https://api.github.com/users/jongerrish/followers","following_url":"https://api.github.com/users/jongerrish/following{/other_user}","gists_url":"https://api.github.com/users/jongerrish/gists{/gist_id}","starred_url":"https://api.github.com/users/jongerrish/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jongerrish/subscriptions","organizations_url":"https://api.github.com/users/jongerrish/orgs","repos_url":"https://api.github.com/users/jongerrish/repos","events_url":"https://api.github.com/users/jongerrish/events{/privacy}","received_events_url":"https://api.github.com/users/jongerrish/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jongerrish/robolectric","description":"Android Unit Testing Framework","fork":true,"url":"https://api.github.com/repos/jongerrish/robolectric","forks_url":"https://api.github.com/repos/jongerrish/robolectric/forks","keys_url":"https://api.github.com/repos/jongerrish/robolectric/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jongerrish/robolectric/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jongerrish/robolectric/teams","hooks_url":"https://api.github.com/repos/jongerrish/robolectric/hooks","issue_events_url":"https://api.github.com/repos/jongerrish/robolectric/issues/events{/number}","events_url":"https://api.github.com/repos/jongerrish/robolectric/events","assignees_url":"https://api.github.com/repos/jongerrish/robolectric/assignees{/user}","branches_url":"https://api.github.com/repos/jongerrish/robolectric/branches{/branch}","tags_url":"https://api.github.com/repos/jongerrish/robolectric/tags","blobs_url":"https://api.github.com/repos/jongerrish/robolectric/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jongerrish/robolectric/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jongerrish/robolectric/git/refs{/sha}","trees_url":"https://api.github.com/repos/jongerrish/robolectric/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jongerrish/robolectric/statuses/{sha}","languages_url":"https://api.github.com/repos/jongerrish/robolectric/languages","stargazers_url":"https://api.github.com/repos/jongerrish/robolectric/stargazers","contributors_url":"https://api.github.com/repos/jongerrish/robolectric/contributors","subscribers_url":"https://api.github.com/repos/jongerrish/robolectric/subscribers","subscription_url":"https://api.github.com/repos/jongerrish/robolectric/subscription","commits_url":"https://api.github.com/repos/jongerrish/robolectric/commits{/sha}","git_commits_url":"https://api.github.com/repos/jongerrish/robolectric/git/commits{/sha}","comments_url":"https://api.github.com/repos/jongerrish/robolectric/comments{/number}","issue_comment_url":"https://api.github.com/repos/jongerrish/robolectric/issues/comments{/number}","contents_url":"https://api.github.com/repos/jongerrish/robolectric/contents/{+path}","compare_url":"https://api.github.com/repos/jongerrish/robolectric/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jongerrish/robolectric/merges","archive_url":"https://api.github.com/repos/jongerrish/robolectric/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jongerrish/robolectric/downloads","issues_url":"https://api.github.com/repos/jongerrish/robolectric/issues{/number}","pulls_url":"https://api.github.com/repos/jongerrish/robolectric/pulls{/number}","milestones_url":"https://api.github.com/repos/jongerrish/robolectric/milestones{/number}","notifications_url":"https://api.github.com/repos/jongerrish/robolectric/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jongerrish/robolectric/labels{/name}","releases_url":"https://api.github.com/repos/jongerrish/robolectric/releases{/id}","created_at":"2014-05-21T21:36:21Z","updated_at":"2015-03-17T20:01:27Z","pushed_at":"2015-05-01T00:13:35Z","git_url":"git://github.com/jongerrish/robolectric.git","ssh_url":"git@github.com:jongerrish/robolectric.git","clone_url":"https://github.com/jongerrish/robolectric.git","svn_url":"https://github.com/jongerrish/robolectric","homepage":"http://robolectric.org/","size":31279,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"robolectric:master","ref":"master","sha":"e5af6d166c986f6d304485803f047a99a13c05e3","user":{"login":"robolectric","id":3988212,"avatar_url":"https://avatars.githubusercontent.com/u/3988212?v=3","gravatar_id":"","url":"https://api.github.com/users/robolectric","html_url":"https://github.com/robolectric","followers_url":"https://api.github.com/users/robolectric/followers","following_url":"https://api.github.com/users/robolectric/following{/other_user}","gists_url":"https://api.github.com/users/robolectric/gists{/gist_id}","starred_url":"https://api.github.com/users/robolectric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robolectric/subscriptions","organizations_url":"https://api.github.com/users/robolectric/orgs","repos_url":"https://api.github.com/users/robolectric/repos","events_url":"https://api.github.com/users/robolectric/events{/privacy}","received_events_url":"https://api.github.com/users/robolectric/received_events","type":"Organization","site_admin":false},"repo":{"id":867564,"name":"robolectric","full_name":"robolectric/robolectric","owner":{"login":"robolectric","id":3988212,"avatar_url":"https://avatars.githubusercontent.com/u/3988212?v=3","gravatar_id":"","url":"https://api.github.com/users/robolectric","html_url":"https://github.com/robolectric","followers_url":"https://api.github.com/users/robolectric/followers","following_url":"https://api.github.com/users/robolectric/following{/other_user}","gists_url":"https://api.github.com/users/robolectric/gists{/gist_id}","starred_url":"https://api.github.com/users/robolectric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/robolectric/subscriptions","organizations_url":"https://api.github.com/users/robolectric/orgs","repos_url":"https://api.github.com/users/robolectric/repos","events_url":"https://api.github.com/users/robolectric/events{/privacy}","received_events_url":"https://api.github.com/users/robolectric/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/robolectric/robolectric","description":"Android Unit Testing Framework","fork":true,"url":"https://api.github.com/repos/robolectric/robolectric","forks_url":"https://api.github.com/repos/robolectric/robolectric/forks","keys_url":"https://api.github.com/repos/robolectric/robolectric/keys{/key_id}","collaborators_url":"https://api.github.com/repos/robolectric/robolectric/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/robolectric/robolectric/teams","hooks_url":"https://api.github.com/repos/robolectric/robolectric/hooks","issue_events_url":"https://api.github.com/repos/robolectric/robolectric/issues/events{/number}","events_url":"https://api.github.com/repos/robolectric/robolectric/events","assignees_url":"https://api.github.com/repos/robolectric/robolectric/assignees{/user}","branches_url":"https://api.github.com/repos/robolectric/robolectric/branches{/branch}","tags_url":"https://api.github.com/repos/robolectric/robolectric/tags","blobs_url":"https://api.github.com/repos/robolectric/robolectric/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/robolectric/robolectric/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/robolectric/robolectric/git/refs{/sha}","trees_url":"https://api.github.com/repos/robolectric/robolectric/git/trees{/sha}","statuses_url":"https://api.github.com/repos/robolectric/robolectric/statuses/{sha}","languages_url":"https://api.github.com/repos/robolectric/robolectric/languages","stargazers_url":"https://api.github.com/repos/robolectric/robolectric/stargazers","contributors_url":"https://api.github.com/repos/robolectric/robolectric/contributors","subscribers_url":"https://api.github.com/repos/robolectric/robolectric/subscribers","subscription_url":"https://api.github.com/repos/robolectric/robolectric/subscription","commits_url":"https://api.github.com/repos/robolectric/robolectric/commits{/sha}","git_commits_url":"https://api.github.com/repos/robolectric/robolectric/git/commits{/sha}","comments_url":"https://api.github.com/repos/robolectric/robolectric/comments{/number}","issue_comment_url":"https://api.github.com/repos/robolectric/robolectric/issues/comments{/number}","contents_url":"https://api.github.com/repos/robolectric/robolectric/contents/{+path}","compare_url":"https://api.github.com/repos/robolectric/robolectric/compare/{base}...{head}","merges_url":"https://api.github.com/repos/robolectric/robolectric/merges","archive_url":"https://api.github.com/repos/robolectric/robolectric/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/robolectric/robolectric/downloads","issues_url":"https://api.github.com/repos/robolectric/robolectric/issues{/number}","pulls_url":"https://api.github.com/repos/robolectric/robolectric/pulls{/number}","milestones_url":"https://api.github.com/repos/robolectric/robolectric/milestones{/number}","notifications_url":"https://api.github.com/repos/robolectric/robolectric/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/robolectric/robolectric/labels{/name}","releases_url":"https://api.github.com/repos/robolectric/robolectric/releases{/id}","created_at":"2010-08-28T00:28:25Z","updated_at":"2015-04-30T19:39:17Z","pushed_at":"2015-05-01T00:13:36Z","git_url":"git://github.com/robolectric/robolectric.git","ssh_url":"git@github.com:robolectric/robolectric.git","clone_url":"https://github.com/robolectric/robolectric.git","svn_url":"https://github.com/robolectric/robolectric","homepage":"http://robolectric.org/","size":55278,"stargazers_count":1676,"watchers_count":1676,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":654,"mirror_url":null,"open_issues_count":125,"forks":654,"open_issues":125,"watchers":1676,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/1746"},"html":{"href":"https://github.com/robolectric/robolectric/pull/1746"},"issue":{"href":"https://api.github.com/repos/robolectric/robolectric/issues/1746"},"comments":{"href":"https://api.github.com/repos/robolectric/robolectric/issues/1746/comments"},"review_comments":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/1746/comments"},"review_comment":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/robolectric/robolectric/pulls/1746/commits"},"statuses":{"href":"https://api.github.com/repos/robolectric/robolectric/statuses/116cf5e5c7acb35476efcabba4fde0481b98d83c"}}}}