First Impressions: Android Studio (I/O Preview) and the Gradle Build System

Before I joined my current company, I was an avid JetBrains IntelliJ IDEA user, both professionally and personally. When I joined my current company it turned out that most of their internal tools had plugin support only via Eclipse and I settled in to start understanding and accepting Eclipse again. I even started to use it personally because I was messing up all the keyboard commands. I’ve switched teams a few times in my current company (from ACX, to the web team, to Discovery, and now to the Android team). When I switched to my most recent team we were using Eclipse with the ADT plugin, as well as the Android Ant-based build system. It was pretty atrocious getting everything to work well together. When Google announced its new build system, we decided to jump on it, thinking its better to be ahead of the curve and not stuck on the mediocre Ant build system.

We’ve been pretty happy with the new build system, using plugin versions 0.2 and 0.3 mostly (0.4 was announced on the same day as Android Studio). We’ve had to accept some of its short-comings or work around certain things:

  • lack of integration with the Java plugin – this lack of integration means that certain plugins (such as Cobertura, Licensing, etc.) cannot be currently used when the Android build system is in play. This is apparently because the Android plugin doesn’t use standard source sets which are required for proper compatibility. The Android team is apparently working with Gradleware team to make required changes to get this compatibility back.
  • its in flux – every plugin revision (0.2 -> 0.3 -> 0.4) has required some change to our build.gradle files in order to actually now work. The changes typically aren’t huge but depending on how quickly you jump on the new plugin, they may not be documented yet. I’ve found that having the source code checked out combined with generating debug level messages for a Gradle error has allowed me to figure out what changed.
  • lack of Eclipse support – The Eclipse plugin as of right now had not been upgraded to work with the Gradle-based build system. This is not much of an issue now that Android Studio is out, but if you prefer Eclipse (apparently still needed for Native support), you’ll need to accept a few things:
    • You can’t completely use the new Gradle directory structure – Eclipse expects the AndroidManifest.xml and the /res directory to both be off the root. Placing them anywhere else causes the Eclipse plugin to complain.
    • You’ll need to roll your own additional Eclipse configuration. I had additional configuration in place to look for the existence of src/main/java, src/main/aidl, src/test/java, etc. and manually add them to the Eclipse XML file. Similarly, you need to add the required Eclipse project natures, etc. manually. We’re migrating to Android Studio so I’ve deleted that code now and moved our files to their proper locations.
  • Lack of understanding of typical configurations – we had to define the testCompile configuration in order to have separate configurations. I expect this to go away with proper Java plugin integration.
    configurations { testCompile }
    

As you can see, we’ve encountered a few issues that we either worked around or accepted. You obviously may encounter more or less issues depending on your project complexity. Overall, I think jumping on the Gradle plugin has made us more productive:

  • Proper project dependencies definition – easy for us to tell what we’re depending on plus we’re not relying on binaries in source control
  • better ecosystem and configuration – plugin availability (especially once Java integration works) along with a clear concise way to script things or reference plugins (I always found it personally annoying to rely on an Ant task).
  • industry standard directory structure – whether you love or hate Maven (I happen to be okay with it), their standardization/conventions for directories is quite handy and nice.

The Gradle plugin on its own is nice, but combined with Android Studio, my developer happiness has skyrocketed. Usage of the Android Studio has been quite pleasant so far (though the IDEA key commands are only slowly coming back to me) and its obvious some pretty decent effort has been put into the Gradle integration. That said, some things I’ve encountered so far:

  • Surprise, it needs Gradle 1.6 and plugin 0.4! – somewhere people forgot to make the 0.4 announcement. Its in the Maven repositories though. Plan on using it if you want to use Android Studio
  • Closing and Opening a Project – I’ve gotten some weird dependency stuff or that the project doesn’t auto-update. Closing/re-opening solves all these issues. I need to confirm if I forgot to turn on auto-import (normal IDEA has that for Maven projects) or if there is some weird bug.
  • Modules depend on the Android Library – I’ve found that modules that depend on other modules are relying on the compiled Android Library file, which has basically forced me to associate that binary file with the source project manually in order to click through to the source. Strange. I am assuming it will get fixed.
  • build directory clean up – I found in a few instances it wasn’t cleaning up build directories correctly. I had deleted some AIDL files and the compiled/generated code was still in the build directory causing confusion when I went to rename something.

Even with these issues, if you were a former IntelliJ IDEA user who settled for Eclipse while doing Android development, I encourage you to not be scared of the “0.1″ version number and give it a try. Even with these minor issues I’ve been much happier (and also not getting out of memory exceptions like I was in Eclipse despite giving it 2gb of memory!). I’ll continue to post my impressions as I use it longer and continue to upgrade Gradle versions and Android Studio versions.

ASUS Transformer Infinity TF700 10.1-inch Tablet and Developer Options

Hopefully, this can hep out other people. I was looking to manually install some Android APKs onto my personal ASUS TF700 tablet, and had to enable the appropriate options in the “Developers” sub-menu in settings. Unfortunately it was not to be found. Scanned through all the settings at least 10 times, thinking it was me being dumb. Searched to see if ASUS has sneakily disabled it in recent builds (I am on 4.2.1) and how to re-enable it. Turns out its not disabled, but hidden by default. The trick?

To enable the Developers options to be seen on the ASUS, you MUST:

  1. Go to Settings->About Tablet
  2. Tap on the build number 7 times (the thing will count down for you so that you know its having some affect.

Doing that will make the Developers menu re-appear. Why is it like that? Well, I have no clue.

Source: http://www.transformerforums.com/forum/transformer-pad-infinity-general-discussion/35720-solved-developer-options-setting-gone-missing.html

Be Useful

When its your job to reach out to people who probably have less time than you to chat, its always a good bet that you should provide useful information if you want them to contact you back. Tell me, why I am I going to spend 15 minutes of *my* time chatting with you when you’ve given me no reason to:

How are you? I noticed your profile on LinkedIn and was impressed. I have a terrific position that looks excellent for your background. Can we talk?
If you’re not interested, please just simply archive my message.

Yes, I am going to call you back when you’ve provided me no useful information about this position, location, what part of my background makes it an excellent fit, etc. Respect people’s time if you want them to take you seriously.

Android Bricking

My new favorite permission, per file: https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml

<!-- Required to be able to disable the device (very dangerous!). -->
    <permission android:name="android.permission.BRICK"
        android:label="@string/permlab_brick"
        android:description="@string/permdesc_brick"
        android:protectionLevel="signature" />

Review: Spring Security 3.1 by Robert Winch and Peter Mularien

I was given a copy of Spring Security 3.1 by Robert Winch and Peter Mularien to review on my blog. A few disclaimers to get out of the way first:

  • I was/am a Spring Security committer (I think I still technically have access but don’t actively develop right now)
  • My copy of the book was free (electronic version, compatible with Kindle)
  • Speaking of Kindle, I do work for Amazon/Audible, however, my opinions here are my own.
  • I was the technical reviewer for the Spring Security 3 version (but not for 3.1)
  • I am a committer and member of the steering committee for Jasig CAS

To make this easier, I want to get the non-content comments out of the way first. I read this on a Kindle Fire (non-HD version), meaning I believe the screen is about 7 inches. This is rather small for many of the tables unless you want to rotate the screen when viewing the table. Tables get cut off in portrait mode with no real way scroll to the right. Attempting to zoom in on some of the images also causes all sorts of weirdness (things actually seemed to get smaller), though I don’t know if that was an artifact of the book or the Kindle itself. I found the flow diagrams to be a bit amateurish in design. Finally, I did notice a few typos in some of the content, but for the most part the text or style was not distracting. None of this, minus the grammar/typos would affect readers or larger tablets or the paper edition.

With that said, let’s just straight into a review of the content. The book covers the basics of Spring security, authentication (CAS, LDAP, X.509, OpenID, JDBC, etc.), authorization (ACLs, RBAC, etc.), and some of the features specific to Spring Security (its session-fixation support, etc.). The first question that always comes up is who is the target audience for this? I read pretty much the whole book (I will admit I did skip a few XML definitions), and its definitely geared towards people who want a broad overview, and then want to jump straight into integrating the security they need (whether it be LDAP, X.509, etc.). If you’re familiar with Spring, and don’t care about the details or heavy customization, you could just straight to the specific chapter you’re looking for and be done. I guess that makes this in many ways more of a cookbook style. They do go in-depth on some of the harder/less straightforward sections (i.e. authorization, ACLs, etc.).

Its very clear that the authors did significant research on each topic they presented (I was particularly impressed with their section on Jasig CAS). You never left a chapter thinking that they left something unexplored. On the other hand, sometimes the amount of information was overwhelming because its not something you would normally need. The authors sometimes struggled with the level of detail that they needed to provide, going in-depth on topics that would have been better left to the reader to use their favorite search engine to find more information about. In some instances, they overwhelmed the user with details on the harder way of doing something, when just introducing the simpler way would have been better.

Each chapter on authentication did a good job of giving a decent explanation of the authentication method itself (which is conceptually independent from Spring Security), the architecture of the feature, and how to configure it. If you were not reading this as a cookbook (i.e. just jumping to relevant chapters), but as a book to learn security concepts, I feel like it would be a decent primer on many of the various authentication methods, when they are useful, and their pros/cons.

The book does a good job of explaining some of the other features of Spring Security, detailing the myriad of options, trade-offs, and extension points. Reading the chapters on session fixation, remember-me, ACLs, I felt that I gained a good understanding on how they worked, how to configure them, and their trade-offs. The ACLs chapter was a bit overwhelming, but then that feature has been a bit of a mess since day 1. I have no plans on ever using JSF, so I skipped that section :-) .

The one thing that did disappoint me on the book was that if you were a previous owner of the Spring Security 3 book, I didn’t see much to make you want to go out and purchase this new book. I didn’t find the appendix in the back of the book to be a compelling enough reason.

Pros:

  • In-depth coverage of each Spring Security topic, providing an overview, architecture, and configuration
  • The details can help you make relevant/educated decisions beyond just Spring Security configuration

Cons:

  • Formatting issues in Kindle edition
  • Sometimes the information is too overwhelming/irrelevant to learning Spring Security; could Google/Bing it if really wanted more information
  • No compelling reason for Spring Security 3 owners to upgrade that I could see

Bottom line: if the Spring Security 3.1 reference guide published by SpringSource is not cutting it for you or you need some basic guidance on authentication/authorization techniques, this is probably your best choice. If you’ve already got an infrastructure in place, and you just need some basic copy/pasting of configuration, then this may be overkill.

Maven Enforcer Plugin and Commons Logging

We’re migrating the Jasig CAS Client for Java from using Commons Logging to using SLF4J. We feel that SLF4J has enough critical mass at this point to make the jump. Unfortunately, not everyone makes the jump at the same time. We strive to exclude Commons Logging via exclusions wherever possible, but sometimes its difficult to keep up with transient dependencies. Enter the solution: the Maven Enforcer Plugin. We’ve added it to our build, such that every time, it checks to see if Commons Logging (or any other dependency we don’t want) is accidentally coming through, allowing us to use the Dependency Tree plugin to hunt it down. Its relatively easy to configure. Within your build tags, just do the following:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <id>enforce-banned-dependencies</id>
            <goals>
                <goal>enforce</goal>
            </goals>
            <configuration>
               <rules>
                   <bannedDependencies>
                       <excludes>
                           <exclude>commons-logging</exclude>
                       </excludes>
                   </bannedDependencies>
               </rules>
               <fail>true</fail>
           </configuration>
       </execution>
    </executions>
</plugin>

Until Maven gets global exclusions (ha!), this seems to be the best way to at least make sure you’re not pulling in things you don’t want.

Scaling for Customers

Recently, we had a service throw out of memory errors due to its inability to create new native threads. It turns out that each request was creating a new thread pool with a fixed size of eight. The service had received a spike in traffic and could not recycle the threads fast enough for the number of requests coming in. This highlights the importance of making individual requests as lightweight as possible. In order for a service to scale, there are many factors to consider. As mentioned previously, the impact of an individual request is an exceptionally important one. In order for a Java server application to scale as well as possible, garbage collection should be minimized and as many objects as possible should be in old generation instead of new generation. There are a number of things one can do to accomplish this:

  • Write Thread-Safe Code – Writing thread-safe code allows you to re-use core business components. This is the common pattern found with applications written using Spring. Your “service” layer, repositories, and controllers are all Spring-managed singletons. The bulk of the code required to execute your logic is created and accounted for at start up, and not per request.
  • Write Immutable Objects – Immutable objects can be cached and re-used safely. Like thread-safe code (of which they are), they can be used across threads/requests, meaning you need a lot less of them.
  • Don’t Allocate Expensive/Resource-Intensive Things per Request – Things that are expensive or resource intensive such as thread pools should not be created per request. Their recycle time and memory cost almost guarantee that a surge will take out your servers.

The bottom line being that the bulk of the memory consumed by a request should be directly related the required domain objects to fulfill that request. Everything else should be minimized. One could argue that even these objects should be minimized. I’ve found that the benefit of reducing them is marginal. It won’t save much memory but it will create confusing, bug-ridden code. Which of course, will cause all sorts of other problems :-) .

There’s obviously more that can be done with regard to scaling for customers. I’ve found however, that this is often one of the things that most people don’t take into account.

Managing Potentially Large Code Reviews

A co-worker of mine recently asked the question:

“How can we handle code reviews of this magnitude and still be respectful of other people’s time?”

We had a few large code reviews go by including one that was 112 files and one that was 56 files. In addition, we had a code change that spanned four code reviews (I can’t recall how many files it was). These are obviously huge burdens on teams that have their own committments. Having seen a decent number of these, there are some guidelines that can help minimize them:

Do The Architecture/Design Code Review First

Many code reviews that “must” be large often include some new architecture or design. That portion of the code review should be done first in its own code review, often accompanied by a design review. Hopefully, there is sufficient design documentation to give the reviewers sufficient insight into why the code was designed this way, preventing iterations on the APIs and architecture as the other code reviews come into play.

Break Code Reviews into Small Pieces Logically

Sending targeted code reviews to the right people can often get better results. This typically means organizing your code reviews into smaller code reviews by feature, not necessarily by Java package, Maven module, etc. Its better to send a code review for the “product detail page” and not all the controllers that changed. It gives people complete insight into the code and allows you to approach people who may be familiar with a particular piece of code. Sending disparate pieces of code in a review is a recipe for the code review being ignored until someone is forced by management to look at it.

Assuming you’ve done the above, but you’ve still got a large code review, here are some tips to keep the size manageable:

Format First Before Code Reviewing

Sometimes there’s a file that never got formatted using the team’s formatter, or another co-worker just feels they’re above formatting. If you encounter one of those files while doing your code review and want to format it, your best bet is to format it first and commit the change. It will make reviewing the code easier later on. You may want to let your team know in case anyone else had any outstanding changes.

Separate Changes that *MUST* Happen from Changes That *SHOULD* Happen

When you’ve already got a large code review, you can often minimize your code review by separating the changes you have to make from those you feel should also be made. Every change that doesn’t need to happen can unecessarily increase the size of your code review. For example, if you find a variable that you feel is incorrectly named, or could be better named, and its used in multiple places, that could add multiple lines to an already long code review. Those changes would best be left until later. Your code review should reflect the changes that have to be made to complete your task.

Refactor Code that Makes a Difference, Not Code that Offends You

We can always find code that we want to change, whether it needs to be changed, or because the previous person didn’t do it how we like it. However, we should restrict ourselves to refactoring code that makes a meaningful improvement to the task at hand, holding ourselves back from making changes because we don’t like the code. Meaningless code changes just increase the size of the code review, and without sufficient unit test coverage, the burden on an already burdened QA department.

Make Backwards Compatible Changes Whenever Possible

Making non-backwards compatible changes is another major way to increase the scope of the change. These types of changes force you to change every file that references the change. For example, if you add a new abstract method to a parent class, then you now have to modify each subclass. Sometimes backward compatible changes are not possible or not worth it, but they should be considered whenever possible. Backwards compatible change also reduce risk and QA resources required.

Raise Concerns Early About Large Changesets

If you’re noticing that you can’t avoid a large change, notify management early in order to make sure sprints allocate proper code review resources as well as QA resources. Nothing is more painful than trying to do a code review while getting your sprint work done.

Automated Tests, Unit Tests

The above guidelines are important, but its also important to note that the scope of your changes should also be proportional to the code coverage you have, whether its via unit tests of automated tests (preferably both).

You can’t always avoid large changesets but taking the steps above shows respect for your fellow co-workers and reduces risks. Remember that they may have to read through your code review multiple times as you implement improvements.