{"action":"closed","number":403,"pull_request":{"url":"https://api.github.com/repos/DozerMapper/dozer/pulls/403","id":122792464,"html_url":"https://github.com/DozerMapper/dozer/pull/403","diff_url":"https://github.com/DozerMapper/dozer/pull/403.diff","patch_url":"https://github.com/DozerMapper/dozer/pull/403.patch","issue_url":"https://api.github.com/repos/DozerMapper/dozer/issues/403","number":403,"state":"closed","locked":false,"title":"Banishing the singletons","user":{"login":"orange-buffalo","id":4532247,"avatar_url":"https://avatars1.githubusercontent.com/u/4532247?v=3","gravatar_id":"","url":"https://api.github.com/users/orange-buffalo","html_url":"https://github.com/orange-buffalo","followers_url":"https://api.github.com/users/orange-buffalo/followers","following_url":"https://api.github.com/users/orange-buffalo/following{/other_user}","gists_url":"https://api.github.com/users/orange-buffalo/gists{/gist_id}","starred_url":"https://api.github.com/users/orange-buffalo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/orange-buffalo/subscriptions","organizations_url":"https://api.github.com/users/orange-buffalo/orgs","repos_url":"https://api.github.com/users/orange-buffalo/repos","events_url":"https://api.github.com/users/orange-buffalo/events{/privacy}","received_events_url":"https://api.github.com/users/orange-buffalo/received_events","type":"User","site_admin":false},"body":"This is a pull request to implement changes suggested in #375.\r\nI will push commits gradually for easier review and tracking. \r\n\r\nThe roadmap for this pull request is:\r\n\r\n- [x] Hide `DozerBeanMapper` constructor and create new `DozerBeanMapperBuilder`.\r\n- [x] Deal with singleton `org.dozer.DozerInitializer`.\r\n- [x] Deal with singleton `org.dozer.config.BeanContainer`. \r\n- [x] Deal with singleton `org.dozer.loader.MappingsParser`.\r\n- [x] Deal with singleton `org.dozer.config.GlobalSettings`.\r\n- [x] Deal with singleton `org.dozer.loader.xml.XMLParserFactory`.\r\n- [x] Deal with singleton `org.dozer.stats.GlobalStatistics`.\r\n- [x] Deal with global state in `org.dozer.builder.DestBeanBuilderCreator#pluggedStrategies`.\r\n- [x] Deal with global state in `org.dozer.classmap.generator.BeanMappingGenerator#pluggedFieldDetectors`.\r\n- [x] Deal with global state in `org.dozer.propertydescriptor.PropertyDescriptorFactory#pluggedDescriptorCreationStrategies`.\r\n- [x] Implementations of `org.dozer.DozerModule` depend on global Dozer state which is now removed. Interface should be extended to provide necessary components to the modules. \r\n- [x] Remove `DozerBeanMapperSingletonWrapper`.\r\n- [x] Verify if there are more singletons.\r\n- [x] Update documentation according to the final solution changes. \r\n\r\nPotential problems / improvements discovered during implementation (follow-up issues to be created):\r\n* `org.dozer.util.ResourceLoader#getResource` uses thread context classloader to load requested resource instead of `classLoader` provided during instantiation. \r\n* It makes sense to use Project Lombok in Dozer to avoid some boilerplate coding.  \r\n* `org.dozer.config.GlobalSettings#setStatisticsEnabled` seems to be dangerous. Clients (even internal ones) could read/write the values in different order, making behaviour unpredictable. I believe, shared configuration should be immutable.\r\n* Extend `org.dozer.config.GlobalSettings` to:\r\n  * apply custom properties file via `DozerBeanMapperBuilder` (not only via system properties);\r\n  * apply any configuration option via `DozerBeanMapperBuilder` (not only via properties file);\r\n  * maybe after that this will not be Global settings any more, but perhaps `DozerSettings`. \r\n* `org.dozer.config.PropertyConstants#CLASS_LOADER_BEAN` usage is very suspicious. We first get classloader from `BeanContainer`, load properties using this classloader, read this property, and then set created classloader into `BeanContainer`. \r\n* `JMXPlatform` and its implementations are not designed to work with multiple `Mapper` instances:\r\n  * is there anyone using those MBeans? I cannot imagine real-world scenario for that;\r\n  * if they are used, what would be the expected behaviour for multiple `Mapper`s is one JVM? \r\n* `org.dozer.DozerBeanMapper#destroy` is an interesting method. It is only called within Spring environment and only when Spring context is stopped, the javadoc explanation is also intriguing: \"Used to release global Dozer resources for hot redeployment without stopping the JVM\". The only thing this method is doing is topping JMX Beans. I suggest considering making this functionality completely external to `DozerBeanMapper` or even removing it (especially if there is no application for JMX Beans, see above).\r\n* `DozerInitializer` and `BeanContainer` are tightly coupled, and they have functionality which now should reside in `DozerBeanMapperBuilder`.   \r\n* Removing global state from Dozer reveals how many dependencies are there between components of the system. For instance, now `DozerBeanMapper` explicitly requires 11 other components, which is a strong indicator that it does too may things. \r\n* `DozerModule` requires significant redesign. Current project implementation of this interface - `ProtobufSupportModule` - relies on internal classes like `BeanContainer`. I believe there should be a Dozer-API module, which provides abstractions over Dozer components, which are then injected into `DozerModule`. Dozer code should not encourage usage of internal classes. Perhaps following \"don't call us, we'll call you\" paradigm could help to build extensible API.   \r\n","created_at":"2017-05-28T11:33:39Z","updated_at":"2017-06-14T07:03:55Z","closed_at":"2017-06-14T07:03:55Z","merged_at":"2017-06-14T07:03:55Z","merge_commit_sha":"77f49b96f4e89e5bee34e7c53eeb8a06ba82aeb1","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":{"url":"https://api.github.com/repos/DozerMapper/dozer/milestones/7","html_url":"https://github.com/DozerMapper/dozer/milestone/7","labels_url":"https://api.github.com/repos/DozerMapper/dozer/milestones/7/labels","id":2546981,"number":7,"title":"6.1.0","description":"","creator":{"login":"garethahealy","id":8656974,"avatar_url":"https://avatars1.githubusercontent.com/u/8656974?v=3","gravatar_id":"","url":"https://api.github.com/users/garethahealy","html_url":"https://github.com/garethahealy","followers_url":"https://api.github.com/users/garethahealy/followers","following_url":"https://api.github.com/users/garethahealy/following{/other_user}","gists_url":"https://api.github.com/users/garethahealy/gists{/gist_id}","starred_url":"https://api.github.com/users/garethahealy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garethahealy/subscriptions","organizations_url":"https://api.github.com/users/garethahealy/orgs","repos_url":"https://api.github.com/users/garethahealy/repos","events_url":"https://api.github.com/users/garethahealy/events{/privacy}","received_events_url":"https://api.github.com/users/garethahealy/received_events","type":"User","site_admin":false},"open_issues":9,"closed_issues":3,"state":"open","created_at":"2017-05-28T14:28:54Z","updated_at":"2017-06-14T07:03:55Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/DozerMapper/dozer/pulls/403/commits","review_comments_url":"https://api.github.com/repos/DozerMapper/dozer/pulls/403/comments","review_comment_url":"https://api.github.com/repos/DozerMapper/dozer/pulls/comments{/number}","comments_url":"https://api.github.com/repos/DozerMapper/dozer/issues/403/comments","statuses_url":"https://api.github.com/repos/DozerMapper/dozer/statuses/9251fbae4932841657dbab533c411bfbec654d19","head":{"label":"orange-buffalo:banish-the-singletons","ref":"banish-the-singletons","sha":"9251fbae4932841657dbab533c411bfbec654d19","user":{"login":"orange-buffalo","id":4532247,"avatar_url":"https://avatars1.githubusercontent.com/u/4532247?v=3","gravatar_id":"","url":"https://api.github.com/users/orange-buffalo","html_url":"https://github.com/orange-buffalo","followers_url":"https://api.github.com/users/orange-buffalo/followers","following_url":"https://api.github.com/users/orange-buffalo/following{/other_user}","gists_url":"https://api.github.com/users/orange-buffalo/gists{/gist_id}","starred_url":"https://api.github.com/users/orange-buffalo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/orange-buffalo/subscriptions","organizations_url":"https://api.github.com/users/orange-buffalo/orgs","repos_url":"https://api.github.com/users/orange-buffalo/repos","events_url":"https://api.github.com/users/orange-buffalo/events{/privacy}","received_events_url":"https://api.github.com/users/orange-buffalo/received_events","type":"User","site_admin":false},"repo":{"id":88420260,"name":"dozer","full_name":"orange-buffalo/dozer","owner":{"login":"orange-buffalo","id":4532247,"avatar_url":"https://avatars1.githubusercontent.com/u/4532247?v=3","gravatar_id":"","url":"https://api.github.com/users/orange-buffalo","html_url":"https://github.com/orange-buffalo","followers_url":"https://api.github.com/users/orange-buffalo/followers","following_url":"https://api.github.com/users/orange-buffalo/following{/other_user}","gists_url":"https://api.github.com/users/orange-buffalo/gists{/gist_id}","starred_url":"https://api.github.com/users/orange-buffalo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/orange-buffalo/subscriptions","organizations_url":"https://api.github.com/users/orange-buffalo/orgs","repos_url":"https://api.github.com/users/orange-buffalo/repos","events_url":"https://api.github.com/users/orange-buffalo/events{/privacy}","received_events_url":"https://api.github.com/users/orange-buffalo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/orange-buffalo/dozer","description":"Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. ","fork":true,"url":"https://api.github.com/repos/orange-buffalo/dozer","forks_url":"https://api.github.com/repos/orange-buffalo/dozer/forks","keys_url":"https://api.github.com/repos/orange-buffalo/dozer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/orange-buffalo/dozer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/orange-buffalo/dozer/teams","hooks_url":"https://api.github.com/repos/orange-buffalo/dozer/hooks","issue_events_url":"https://api.github.com/repos/orange-buffalo/dozer/issues/events{/number}","events_url":"https://api.github.com/repos/orange-buffalo/dozer/events","assignees_url":"https://api.github.com/repos/orange-buffalo/dozer/assignees{/user}","branches_url":"https://api.github.com/repos/orange-buffalo/dozer/branches{/branch}","tags_url":"https://api.github.com/repos/orange-buffalo/dozer/tags","blobs_url":"https://api.github.com/repos/orange-buffalo/dozer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/orange-buffalo/dozer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/orange-buffalo/dozer/git/refs{/sha}","trees_url":"https://api.github.com/repos/orange-buffalo/dozer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/orange-buffalo/dozer/statuses/{sha}","languages_url":"https://api.github.com/repos/orange-buffalo/dozer/languages","stargazers_url":"https://api.github.com/repos/orange-buffalo/dozer/stargazers","contributors_url":"https://api.github.com/repos/orange-buffalo/dozer/contributors","subscribers_url":"https://api.github.com/repos/orange-buffalo/dozer/subscribers","subscription_url":"https://api.github.com/repos/orange-buffalo/dozer/subscription","commits_url":"https://api.github.com/repos/orange-buffalo/dozer/commits{/sha}","git_commits_url":"https://api.github.com/repos/orange-buffalo/dozer/git/commits{/sha}","comments_url":"https://api.github.com/repos/orange-buffalo/dozer/comments{/number}","issue_comment_url":"https://api.github.com/repos/orange-buffalo/dozer/issues/comments{/number}","contents_url":"https://api.github.com/repos/orange-buffalo/dozer/contents/{+path}","compare_url":"https://api.github.com/repos/orange-buffalo/dozer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/orange-buffalo/dozer/merges","archive_url":"https://api.github.com/repos/orange-buffalo/dozer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/orange-buffalo/dozer/downloads","issues_url":"https://api.github.com/repos/orange-buffalo/dozer/issues{/number}","pulls_url":"https://api.github.com/repos/orange-buffalo/dozer/pulls{/number}","milestones_url":"https://api.github.com/repos/orange-buffalo/dozer/milestones{/number}","notifications_url":"https://api.github.com/repos/orange-buffalo/dozer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/orange-buffalo/dozer/labels{/name}","releases_url":"https://api.github.com/repos/orange-buffalo/dozer/releases{/id}","deployments_url":"https://api.github.com/repos/orange-buffalo/dozer/deployments","created_at":"2017-04-16T14:55:35Z","updated_at":"2017-04-16T14:55:39Z","pushed_at":"2017-06-14T05:34:31Z","git_url":"git://github.com/orange-buffalo/dozer.git","ssh_url":"git@github.com:orange-buffalo/dozer.git","clone_url":"https://github.com/orange-buffalo/dozer.git","svn_url":"https://github.com/orange-buffalo/dozer","homepage":"http://dozer.sf.net","size":17808,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"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":"DozerMapper:master","ref":"master","sha":"a51e9142efce5a81f53b2de9d17c2028c5b45ff1","user":{"login":"DozerMapper","id":1372459,"avatar_url":"https://avatars2.githubusercontent.com/u/1372459?v=3","gravatar_id":"","url":"https://api.github.com/users/DozerMapper","html_url":"https://github.com/DozerMapper","followers_url":"https://api.github.com/users/DozerMapper/followers","following_url":"https://api.github.com/users/DozerMapper/following{/other_user}","gists_url":"https://api.github.com/users/DozerMapper/gists{/gist_id}","starred_url":"https://api.github.com/users/DozerMapper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DozerMapper/subscriptions","organizations_url":"https://api.github.com/users/DozerMapper/orgs","repos_url":"https://api.github.com/users/DozerMapper/repos","events_url":"https://api.github.com/users/DozerMapper/events{/privacy}","received_events_url":"https://api.github.com/users/DozerMapper/received_events","type":"Organization","site_admin":false},"repo":{"id":3250434,"name":"dozer","full_name":"DozerMapper/dozer","owner":{"login":"DozerMapper","id":1372459,"avatar_url":"https://avatars2.githubusercontent.com/u/1372459?v=3","gravatar_id":"","url":"https://api.github.com/users/DozerMapper","html_url":"https://github.com/DozerMapper","followers_url":"https://api.github.com/users/DozerMapper/followers","following_url":"https://api.github.com/users/DozerMapper/following{/other_user}","gists_url":"https://api.github.com/users/DozerMapper/gists{/gist_id}","starred_url":"https://api.github.com/users/DozerMapper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DozerMapper/subscriptions","organizations_url":"https://api.github.com/users/DozerMapper/orgs","repos_url":"https://api.github.com/users/DozerMapper/repos","events_url":"https://api.github.com/users/DozerMapper/events{/privacy}","received_events_url":"https://api.github.com/users/DozerMapper/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/DozerMapper/dozer","description":"Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another. ","fork":false,"url":"https://api.github.com/repos/DozerMapper/dozer","forks_url":"https://api.github.com/repos/DozerMapper/dozer/forks","keys_url":"https://api.github.com/repos/DozerMapper/dozer/keys{/key_id}","collaborators_url":"https://api.github.com/repos/DozerMapper/dozer/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/DozerMapper/dozer/teams","hooks_url":"https://api.github.com/repos/DozerMapper/dozer/hooks","issue_events_url":"https://api.github.com/repos/DozerMapper/dozer/issues/events{/number}","events_url":"https://api.github.com/repos/DozerMapper/dozer/events","assignees_url":"https://api.github.com/repos/DozerMapper/dozer/assignees{/user}","branches_url":"https://api.github.com/repos/DozerMapper/dozer/branches{/branch}","tags_url":"https://api.github.com/repos/DozerMapper/dozer/tags","blobs_url":"https://api.github.com/repos/DozerMapper/dozer/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/DozerMapper/dozer/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/DozerMapper/dozer/git/refs{/sha}","trees_url":"https://api.github.com/repos/DozerMapper/dozer/git/trees{/sha}","statuses_url":"https://api.github.com/repos/DozerMapper/dozer/statuses/{sha}","languages_url":"https://api.github.com/repos/DozerMapper/dozer/languages","stargazers_url":"https://api.github.com/repos/DozerMapper/dozer/stargazers","contributors_url":"https://api.github.com/repos/DozerMapper/dozer/contributors","subscribers_url":"https://api.github.com/repos/DozerMapper/dozer/subscribers","subscription_url":"https://api.github.com/repos/DozerMapper/dozer/subscription","commits_url":"https://api.github.com/repos/DozerMapper/dozer/commits{/sha}","git_commits_url":"https://api.github.com/repos/DozerMapper/dozer/git/commits{/sha}","comments_url":"https://api.github.com/repos/DozerMapper/dozer/comments{/number}","issue_comment_url":"https://api.github.com/repos/DozerMapper/dozer/issues/comments{/number}","contents_url":"https://api.github.com/repos/DozerMapper/dozer/contents/{+path}","compare_url":"https://api.github.com/repos/DozerMapper/dozer/compare/{base}...{head}","merges_url":"https://api.github.com/repos/DozerMapper/dozer/merges","archive_url":"https://api.github.com/repos/DozerMapper/dozer/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/DozerMapper/dozer/downloads","issues_url":"https://api.github.com/repos/DozerMapper/dozer/issues{/number}","pulls_url":"https://api.github.com/repos/DozerMapper/dozer/pulls{/number}","milestones_url":"https://api.github.com/repos/DozerMapper/dozer/milestones{/number}","notifications_url":"https://api.github.com/repos/DozerMapper/dozer/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/DozerMapper/dozer/labels{/name}","releases_url":"https://api.github.com/repos/DozerMapper/dozer/releases{/id}","deployments_url":"https://api.github.com/repos/DozerMapper/dozer/deployments","created_at":"2012-01-23T21:11:58Z","updated_at":"2017-06-12T12:28:22Z","pushed_at":"2017-06-14T07:03:55Z","git_url":"git://github.com/DozerMapper/dozer.git","ssh_url":"git@github.com:DozerMapper/dozer.git","clone_url":"https://github.com/DozerMapper/dozer.git","svn_url":"https://github.com/DozerMapper/dozer","homepage":"http://dozer.sf.net","size":18261,"stargazers_count":843,"watchers_count":843,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":305,"mirror_url":null,"open_issues_count":91,"forks":305,"open_issues":91,"watchers":843,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/DozerMapper/dozer/pulls/403"},"html":{"href":"https://github.com/DozerMapper/dozer/pull/403"},"issue":{"href":"https://api.github.com/repos/DozerMapper/dozer/issues/403"},"comments":{"href":"https://api.github.com/repos/DozerMapper/dozer/issues/403/comments"},"review_comments":{"href":"https://api.github.com/repos/DozerMapper/dozer/pulls/403/comments"},"review_comment":{"href":"https://api.github.com/repos/DozerMapper/dozer/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/DozerMapper/dozer/pulls/403/commits"},"statuses":{"href":"https://api.github.com/repos/DozerMapper/dozer/statuses/9251fbae4932841657dbab533c411bfbec654d19"}},"merged":true,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":{"login":"garethahealy","id":8656974,"avatar_url":"https://avatars1.githubusercontent.com/u/8656974?v=3","gravatar_id":"","url":"https://api.github.com/users/garethahealy","html_url":"https://github.com/garethahealy","followers_url":"https://api.github.com/users/garethahealy/followers","following_url":"https://api.github.com/users/garethahealy/following{/other_user}","gists_url":"https://api.github.com/users/garethahealy/gists{/gist_id}","starred_url":"https://api.github.com/users/garethahealy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/garethahealy/subscriptions","organizations_url":"https://api.github.com/users/garethahealy/orgs","repos_url":"https://api.github.com/users/garethahealy/repos","events_url":"https://api.github.com/users/garethahealy/events{/privacy}","received_events_url":"https://api.github.com/users/garethahealy/received_events","type":"User","site_admin":false},"comments":6,"review_comments":8,"maintainer_can_modify":false,"commits":16,"additions":2533,"deletions":1596,"changed_files":163}}
{"actor":{"display_login":"garethahealy"}}