{"id":517,"date":"2018-05-01T10:00:12","date_gmt":"2018-05-01T15:00:12","guid":{"rendered":"http:\/\/jebware.com\/blog\/?p=517"},"modified":"2018-05-01T19:09:58","modified_gmt":"2018-05-02T00:09:58","slug":"best-practices-for-enabling-proguard","status":"publish","type":"post","link":"https:\/\/jebware.com\/blog\/?p=517","title":{"rendered":"Best Practices for Enabling ProGuard"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">I\u2019ve written <a href=\"https:\/\/jebware.com\/blog\/?cat=16\">several blog posts<\/a> recently about technical aspects of using ProGuard to obfuscate your code in Android apps. \u00a0Then, in March, I gave a talk at <a href=\"http:\/\/www.droidcon-boston.com\/\">DroidCon Boston<\/a> walking through an overview of <a href=\"https:\/\/jebware.com\/blog\/?p=510\">How ProGuard Works<\/a>. Through all of those, I tried to keep the content very matter-of-fact and technical. \u00a0I got a lot of technical questions in response, but I also got a lot of questions about the organizational and software engineering aspects &#8212; how to think about maintenance, and testing, and debugging, and communicating with your team. \u00a0So what follows are the less technical, but possibly more practical, guidelines I\u2019ve found for working with ProGuard.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You\u2019ll find that most of these tips are focused on the fact that obfuscation can expose problems that are only seen at runtime, and then only when a specific code path is executed. \u00a0This means that most of these rules are focused on making sure you\u2019re likely to discover those problems.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">As early as possible<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">If possible, start using ProGuard from day 1 of a new project. \u00a0I\u2019ve gone through the experience of enabling ProGuard on a project that\u2019s been worked on for years without it, and it\u2019s more difficult. \u00a0You\u2019ll get a warning about some code, and you\u2019ll find that nobody on the team remembers that code.<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2018\/05\/d695d51d4d415446484baa9646aadcea36ae908e00336551f5cec953399748bb.jpg\"><img loading=\"lazy\" class=\"size-full wp-image-526 alignnone\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2018\/05\/d695d51d4d415446484baa9646aadcea36ae908e00336551f5cec953399748bb.jpg\" alt=\"\" width=\"495\" height=\"420\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Enabling ProGuard from day 1 ensures that issues are encountered immediately, when the relevant code is fresh in your mind.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">As many builds as possible<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Don\u2019t enable ProGuard in your day-to-day dev builds*, it will increase your build times a little and cause you extra pain in debugging. \u00a0But for every other build &#8212; QA, beta, release &#8212; turn ProGuard on. You want as many testers as possible exercising the code as many ways as possible to ensure that you notice any ProGuard bugs early on.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">*There is an exception to this, which is when you get a report of a bug that you suspect might be triggered by obfuscation, you want to enable ProGuard in your dev environment so you can easily reproduce the bug. \u00a0This means that you want to have a single, easy, flag in your build.gradle that you can flip to true to enable ProGuard on your debug builds. Have all of the configuration files ready for that build type &#8212; the same configuration files you\u2019re using for the rest of your builds &#8212; you want the only effort on your part to be flipping the one flag.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">The Phased Approach<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">If you\u2019ve inherited a codebase that is already in production, you can\u2019t enable ProGuard from day 1, but you can try to fake it a bit. \u00a0Start by enabling ProGuard in your dev builds and fixing the compile-time errors. Then, run a ProGuard-ed build and exercise the app as much as possible. \u00a0Walk through each feature as well as you can, and try to find problems. Next, enable ProGuard for your QA builds, and wait for a bit. This is the real key.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You\u2019ll give your QA team time to work through the app and find problems. \u00a0You want to make sure they\u2019ve had time to exercise the app before you move on to the next phase, which is a beta build, if you have one. \u00a0A beta should hopefully expose your obfuscated app to a broad, but still small, set of users. Let that work for a bit, then you can enable for your public builds.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Make your Keep rules as specific as possible<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">I\u2019ve mentioned this in my blog post and in the talk, but it bears repeating. \u00a0There\u2019s no value in using ProGuard if you\u2019re going to kneecap it with overly-broad keep rules.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Document every keep rule<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">This is deceptively important. \u00a0It\u2019s tempting to just add the keep rule you need to a config file and be done, but you\u2019re hurting yourself in the long run. \u00a0A year from now, you\u2019ll look at the rule and wonder why it was there. It might be referring to code that\u2019s long gone, or a library that\u2019s no longer used. \u00a0Or it could be critically important. You don\u2019t know, because the rule itself doesn\u2019t tell you the reason it was added. And, perhaps more importantly, it doesn\u2019t tell you how to test whether it\u2019s still necessary.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Add a comment. \u00a0Explain what was broken and why that rule fixed it.<\/span><\/p>\n<h1>Conclusion<\/h1>\n<p>That&#8217;s it.\u00a0 Try it out.\u00a0 If you&#8217;ve got some different ideas, based on your experience, <a href=\"https:\/\/twitter.com\/jebstuart\">I would love to hear it<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I\u2019ve written several blog posts recently about technical aspects of using ProGuard to obfuscate your code in Android apps. \u00a0Then, in March, I gave a talk at DroidCon Boston walking through an overview of How ProGuard Works. Through all of those, I tried to keep the content very matter-of-fact and technical. \u00a0I got a lot &hellip; <a href=\"https:\/\/jebware.com\/blog\/?p=517\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Best Practices for Enabling ProGuard&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"twitterCardType":"summary","cardImageID":0,"cardImage":"http:\/\/s2.quickmeme.com\/img\/d6\/d695d51d4d415446484baa9646aadcea36ae908e00336551f5cec953399748bb.jpg","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":""},"categories":[4,16],"tags":[],"_links":{"self":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/517"}],"collection":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=517"}],"version-history":[{"count":8,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/517\/revisions"}],"predecessor-version":[{"id":527,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/517\/revisions\/527"}],"wp:attachment":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=517"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=517"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=517"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}