Pages

Wednesday, April 6, 2011

How to Work on an Android Project from Multiple Computers

Note: I would never recommend this solution for an actual development company.  This really is intended for personal projects, or developing a small-scale app with one or two developers at most. As always, try this at your own risk, as I will not be responsible for any lost, corrupted or otherwise broken projects.


When I started developing my first Android application, I quickly found that it would be really nice to be able to work on the same source code from multiple computers, without having to copy things to an external hard drive, or uploading it somewhere and then downloading it and hoping that everything is in sync.

I already had a free Dropbox account (available here) that I had been using to sync a small number of files on separate computers, so I started thinking -- why not keep my Android project in my Dropbox?  Would it work? Would there be any "gotchas"?  If nothing else, I thought it was worth a try.

So, when I created my Android project in Eclipse (available here) I decided to set it up in my local Dropbox folder.  I added a few files, built the project and ran it -- so far so good.  I then opened the Dropbox app on my computer and let the syncing do its thing.  In my case, not only was I dealing with two different computers, I was also dealing with two different OSes.  My desktop computer is running Windows, while my laptop is running Mac OS X.  I figured if anything could go wrong, it would in this scenario.

Before I go any further, I'd like to mention that I also wanted to use some kind of Source Control (the ability to check in and check out files, and mark certain versions of projects as version numbers that corresponded with the versions of my app).  Eclipse seemed to have some built-in functionality for using CVS Source control, so I started on the hunt.  In short, I ended up using WinCVS / MacCVS (available here).  Setting up the CVS server isn't too complicated, so I'll leave that to you.

After you have the CVS portion set up (Server and functionality within Eclipse), you should be able to Right-Click on your project and select Team -> Share Project.  Once you do this, you'll have to step through the wizard, but when you're done, you should have a version-controlled Android Project sitting in your Dropbox.

Now for accessing that project from your second computer.  In my case, I installed Dropbox, Eclipse and the MacCVS server and configured everything similar to that of my Windows PC.  After everything finishes syncing in your Dropbox, open Eclipse and go to File -> New -> Project.  From the list of options, select CVS then Project from CVS.  Select Use existing repository location (which should have your local repository after setting up CVS), choose your local repository and click Next.  Select Use an existing module, and select the project you created on your first computer and click Finish.  This should create a new Project in your workspace complete with the current versions of your source code.

So -- you should now be able to work freely on your code from both computers, and commit changes as you make them, and watch them sync to your Dropbox.

Potential Gotchas:

  • Each time you log into a different computer from the last time you committed, you'll need to Update your project by Right-Clicking on the project, and then select Team -> Update.
  • In my case, running on one Windows computer and one Mac, I had very different build paths for my projects.  If you're doing something similar, you may or may not want to check in your project as a whole (instead, just check in individual files as you change them).  If you do happen to check in your project as a whole, you'll just need to remember to update the build properties on your other computer the next time you use it.
  • When you actually build your application and install it on a phone through Eclipse, the apk will most likely have different signatures from each computer, so you'll also want to uninstall any previous versions on your phone before switching computers.  If you just use the simulator, this is a non-issue.
  • Speaking of Signatures -- when you go to Export a Signed APK, you'll have to create (or use an existing) keystore.  I also keep this in my dropbox so that no matter which computer I'm on, I can always export an APK ready to be uploaded to the Market.
In general, I imagine this technique could also be applied to iPhone/iOS development (between Macs obviously), or other Java-based projects, and more.

Monday, March 21, 2011

Setting up KMS for Windows Activation on Server 2008 x64

We initially set up all of our Windows Servers using MAK keys.  For those not familiar, MAK keys are very simple: you copy them from your licensing agreement with Microsoft and paste them into Windows activation, and then you're done.  Simple right?  The only trouble with using MAK keys is that you can only use them a limited number of times before you need to call Microsoft to increase the number of times that you can use them.  In our Citrix environment, I regularly image about 10 servers at a time when we make changes -- so you can see how I'd chew up the limited number of activations very quickly.

Enter KMS.  With KMS, you need to set up one server on your network as a KMS host, and then all of your Windows machines can activate against it an unlimited number of times as KMS clients.  The only potential "gotcha" is that each of these KMS clients need to periodically check in with the KMS host to remain activated.  Since our Citrix farm is all on the same network and never gets shut down, this would not be a problem for us.  To understand more about KMS please check out this article.

Our current Citrix farm is installed on Server 2008 R2; however, the domain controller that I made to be the KMS host, is running Server 2008 x64.  Setting up the KMS host was pretty straightforward: Change the current license key to our KMS B license key (B is for Standard and Enterprise edition servers), and then restart the Software Licensing Service.  By default, if you have Dynamic DNS enabled, this should create some new records on your DNS server to let clients know where the KMS host is listening.  If you don't have Dynamic DNS enabled, you'll need to create these records manually.  Plenty of information on that and other fun KMS topics can be found in this article.

Now for the client side of things.  By default, Windows installations are KMS clients (I didn't know this before, so that's a fun fact) -- they will check in with the DNS server to see if there is a KMS host out there, and then try to activate against it (note: for Windows Server, the KMS host must receive at least 5 activation requests before it will start activating).  I had a little more work to do since I had previously entered our MAK key for activation.  In order to switch the server back to a KMS client, I had to type in the following command from an elevated command prompt:
slmgr.vbs /ipk KMSSetupKey


where KMSSetupKey is a key that is provided by Microsoft that is not part of a licensing agreement -- it's just a generic key.  I pulled the one I needed from this site.  Then, to attempt an activation, you can type in the following command from an elevated command prompt:
slmgr.vbs /ato


Unfortunately, my attempt was not very successful.  Instead, I was prompted with the error "The key management service is unavailable."  This can mean a number of different things, but to get to the bottom of it, I pulled up the Event Log on the KMS host and noticed the following error number: 0xC004F042, which according to this site of common activation errors, means that there is a mismatch of some kind between our KMS host and our KMS client.  After a bit of digging, I discovered that I needed to apply an update to our KMS host running Server 2008 x64 to allow KMS clients running 2008 R2 to activate against it.  If you are in need of this update, it is currently available here.


Now, that's not the end of the story.  After applying the update and rebooting the KMS host, I was still unable to activate our 2008 R2 Servers.  In order to complete the update process, you must install the Server 2008 R2 KMS host key using the same command (slmgr.vbs /ipk KMSSetupKey) as mentioned above, except you'll need to use the KMS key from your license agreement with Microsoft.  Then, I just needed to activate it (slmgr.vbs /ato) and restart the Software Licensing Service one more time.  Now we can activate R2 servers against our KMS host.


Next stop will be determining how this all affects my Altiris imaging process...

Tuesday, March 15, 2011

Installing Red Hat Enterprise Linux 5.5 on a Multipath Device

Note: Most, if not all, of the tips I'm providing in this post are available in Red Hat or IBM documentation.  It took me awhile to find it though, so I thought it may be nice to save for a quick reference.

This week, our team was tasked with installing Red Hat Enterprise Linux (RHEL) 5.5 on an IBM server.  This server connects to two different drives provided by a DS8100 storage system, and has two paths to each drive.  In our first attempt to install RHEL, we had to use the text-based installer since this server does not have a video card, which made this entire process a little more fun.

In going through the installer, it detected the two paths to each of our two drives, so instead of showing just the two drives it showed four (counting each path as an individual drive).  We went through the motions and targeted one of the drives it detected for the install.  Unfortunately, when we rebooted the machine, it didn't see that drive as a bootable device, marking our first defeat.

To make things a little easier on ourselves, we decided to go with the recommended graphical installer.  How did we do this without a video card, you may ask?  With our friend, VNC.  If you're interested in using VNC to connect to your install, the documentation mentions the TigerVNC client, so that's what we went with.  In order to get the installer to start a VNC server, you need to add the following option at boot when prompted:
boot: linux vnc
You'll be prompted to configure the IP address for the server to run VNC on the machine, but once it's up and running you will be presented with the display to connect to.

Now that we had a graphical installer to work with, we were feeling much better and went through another install.  It failed.  So, we tried again testing various disk layouts.  They failed.  We made a few more attempts before the end of the day, but just couldn't get this installer to lay down a bootable OS on the drive.

In the back of my mind, I was thinking it had to do with multipath aspect.  If we could somehow get this installer to only see two drives, instead of four, maybe our luck would change.  After doing a little research through the Red Hat documentation, I discovered that if you try to install to a multipath device, it's probable that it will fail and/or it won't be bootable.  The key to solving this problem: adding just one additional boot parameter.  So, in the end, our boot parameters looked like:
boot: linux vnc mpath
Then, in the installer, it detected two multipath devices, we installed the OS to the first multipath device, and like magic, we had a working installation of RHEL 5.5!

The following section only applies if you are running an IBM Storage System, specifically something in the DS6000 or DS8000 series.  So, if that doesn't apply to you, feel free to move along :)

After the install, there were a couple additional steps to make sure multipath was configured correctly for our DS8100 system.  You will need to make sure the following packages are installed:
device-mapper
device-mapper-multipath

Next, you'll need the multipath config file from the IBM website (currently located on this page in the section labeled "Device Mapper Multipath Configuration File for ESS DS6000 DS8000 and SVC".  Make sure you grab the one for the RHEL 5 Platform).  After obtaining multipath.conf, back up your existing one under /etc/multipath.conf and then simply copy this one into the /etc directory.  In order to get my system to recognize the new config, I had to run the following command:
multipath -r

You can then confirm that the drives are discovered with the following command:
multipath -l


Hopefully this post will save you a little bit of time and heartache!

Friday, February 25, 2011

7 Things to Convince Me to Switch to the iPhone 5

UPDATE: I have published a follow-up post to this article here.

A couple of disclaimers first: I currently own the original Motrola Droid on Verizon.  I like my Droid, but there have definitely been times that I've wanted to throw it out the window.  As a loyal Verizon customer, I've never had the option of an iPhone, but with my contract renewal coming up in July, it appears as though I may have a choice to make.  Now, I am not necessarily a "phandroid" even though I've developed Android apps and while I own a Macbook and an iPod, I'm not really an iFanBoy either.  I'm just a fan of using the best technology that simply "works" while providing the best features for me at the time.

With that out of the way, I've started thinking about the possibility of the iPhone 5 coming out this June -- which is a good possibility, right?  I've been wondering, what would it take for me to switch over to "the dark side"?  I have come up with a list of things that if completely implemented, I wouldn't hesitate to buy the next iPhone.  However, if only some (or none) of the following are included, I'll have quite the dilemma on my hands:

1) The iPhone 5 must be released on Verizon the same time as ATT
I would assume that this would be the case going forward, but since we haven't seen this happen yet, I have to include this as a possibility.  If the iPhone 5 gets released on Verizon much later than ATT, it will be a no-go because I don't like starting with outdated technology at the beginning of a 2-year contract.

2) The iPhone 5 must be capable of utilizing 4G / LTE 
I don't currently live in a city that is blanketed with LTE, so there may be a little bit of wiggle room here. However, I am trying to future-proof for 2 years, and I would think that by then my city will have that coverage.
3) The iPhone 5 must have a dual-core processor
One of the major benefits of an Apple product is that the hardware and software are coupled together very nicely, which virtually ensures that users will have a pleasant experience with the device. So, if they achieve the results they want without including a dual-core processor, I could understand; however, I'd like to see it included, again, mostly as an insurance policy so that as mobile apps and games start getting developed with two-cores in mind, I can enjoy them to their full potential, even 2 years from now.
4) The iPhone 5 must include an NFC implementation
If you have no idea what NFC is, ReadWriteWeb has put together a very nice write up on it here. As the article mentions, this technology is not huge right now, but it is poised to take off very, very soon.
5) The iPhone 5 must use a better notification system
In my opinion, this is one of the places where Android completely shines. I love the way notifications are handled in Android with the notification bar -- it brings all of your notifications to one place and you can pick and choose what you'd like to respond to in any order, without interrupting what you're currently doing. I would love for Apple to introduce a similar centralized way of handling notifications. Also -- I also like the idea of the use of a notification light on the outside of the phone. It's not intrusive, and alerts you when your screen is off.

6) The iPhone 5 must have a dependable, free (or inexpensive) turn-by-turn Navigation application
This is another thing that I think I take for granted with Android. The Google Navigation app is great -- I've used it on several trips, and I don't think that's it's ever really let me down. From what I understand, there are some free crowdsourced apps available for the iPhone, but that doesn't cut it in my mind.
7) Along side the iPhone 5, Apple must provide free MobileMe access
Now, I must confess that I didn't think of this one on my own. A few articles, like this one, have recently surfaced pointing to the possibility of this very thing. I currently use Google for a lot of things: calendar, email, contacts, etc. and I'd like to see a similar type of functionality available, for free, in the Apple world. The possibility of MobileMe being reintroduced as a media storage locker for music, pictures, video and the like is even more intriguing.

Well -- that's my list for now. What else would I be missing with the move from Android to the iPhone? Has anyone made that transition (or visa versa) and regretted it?  Perhaps I'm just suffering from "the grass is always greener on the other side" syndrome?
I'd love to hear your thoughts in the comment section below.

UPDATE (3-3-2011): In light of the iPad 2 announcement, a few updates:
Item 1) The iPad 2 will be available on both ATT's and Verizon's networks on the same day. This bodes well for a simultaneous iPhone 5 release. Interestingly though, iOS 4.3 will only be available for the ATT iPhone 4 at launch.
Item 2) Surprisingly, the iPad 2 does not have any tie ins to 4G networks. Does this mean that the iPhone 5 won't either? Not necessarily, but I don't like seeing this one.
Item 3) With the release of the A5 processor, which happens to be dual-core, I would say that there is a very good chance that this chip will land in the iPhone 5.
Item 7) There was no mention of MobileMe at all. Perhaps this was wishful thinking to begin with? Only time will tell!

UPDATE (3-28-2011): WWDC 2011 was formally announced today with the tagline: "Join us for a preview of the future of iOS and Mac OS X." Now, a few sites have published articles like this and this that take this (along with some information from their 'sources') to mean that there will not be an iPhone 5, or any kind of hardware announcement for that matter, this summer at WWDC. In fact, they believe that the soonest that we may even see a new iPhone would be this Fall. At this point, I'm not sure if I'd like to see some kind of 4GS minor refresh of the iPhone 4, or just see them wait to announce the availability of the iPhone 5 and iOS 5. I'm hopeful that if nothing else, we'll have a REALLY good idea of what's in store (in terms of features and timelines) for the iPhone 5 and iOS 5 during WWDC so that I can at least determine if it's worth waiting for, even if it's not available yet. Otherwise, it may make it an easy decision to stay on the Android train.

UPDATE (4-22-2011): On Apple's Q2 financial results conference call, COO Tim Cook made it sound like 4G/LTE is still a relatively immature technology (which it is), and that Apple is not willing, at least at this time, to make the design compromises required to include 4G/LTE in the iPhone. If it's anything like the HTC Thunderbolt, that would likely mean requiring two chips -- one for 3G and one for 4G. I've also heard pretty bad things about battery life in regards to using 4G on the Thunderbolt -- also not a good sign that the technology is ready for prime time. So, at this point, wishing for 4G/LTE in the next iteration of the iPhone seems like an incredible long shot. Here's an interesting discussion on why.

UPDATE (5-19-2011): Verizon's CFO confirmed Item 1 (that Verizon and AT&T would release the next iPhone at the same time). See the confirmation here and check one off of the list!

UPDATE (6-13-2011): The week of WWDC 2011 has come to an end, and a LOT of features were revealed regarding iOS5. Among these were my points 5 (a better notification system) and 7 (iCloud). So, check those off of the list as well! That leaves the question of 4G, NFC and Navigation. I did discover MapQuest as a free Nav app, but I have no idea if it's any good -- so if anyone has any experience in that department, I'd love to hear about it. Either way, unfortunately, it looks like the next iPhone won't be available until September!

Tuesday, December 14, 2010

Slowness with RPC as root on AIX

I was responsible for writing a little RPC client (and server) program that talks to our Unidata database to retrieve some arbitrary values.  The client has been running fine on Linux, but when we moved it to our AIX server, we noticed something interesting: in a loop of 1000 calls, it would take about 13 seconds on Linux, and 45 seconds on AIX.  It was absolutely maddening, and made no sense since it was the exact same code, just recompiled (and our AIX box has FAR superior hardware specs).

Then I made a discovery: when we ran the program as a non-root user, we got comparable times to the Linux box.  So, what is it about root on AIX that was causing the hold up?  Well, apparently, in AIX there is something built in that uses reserved, or privileged, ports for that kind of communication when running as root.  So, instead of having thousands of ports the client program could communicate on, it had a very limited subset of ports, which resulted in waiting for one of those ports to be available before completing the request.

Long story short, the result was to set the sticky bit on the client application (which has owner and group as non-root), to force it to always run in non-user space.  In case you come across a similar issue, here are the steps to fix it:
1) Use chmod and chgrp to make sure that the permissions on the application are non-root for ownership/group
2) Enable the setuid sticky bit on the application with the following syntax:
chmod u+s AppNameHere

This caused quite the headache and resulted in a support call to IBM, so hopefully this will help someone out there!

Monday, October 18, 2010

New Look and Feel

I've never really liked the default template I've been using for this blog, so I figured it was time for a change.  Welcome to the new look!

Wednesday, October 13, 2010

Setting up a Web Server on AIX 6.1

There have been several occasions when I have needed to set up web servers on either Windows or Linux.  Pretty much every time it has been a simple process of installing binaries through a GUI and making sure everything plays nice together.  Well, for the first time I needed to set up Apache, PHP and MySQL on an AIX machine that is completely GUI-less (Note: the GUI-less portion isn't the hard part).  In going through this process I learned a few things, so I thought that I would share them here.

Step One: Trying to find binaries for AIX
This step in itself is a little difficult.  Previously I have used Bull Freeware (http://www.bullfreeware.com/) for AIX binaries.  However, in this case, most of the binaries available are fairly outdated and I really wanted to put something together that was a little more recent.  This drove me to the discovery of PmWiki (http://www.perzl.org/aix/index.php) maintained by Michael Perzl.  This repository of RPMs built for AIX is very thorough, and very recent!  I highly recommend this site for anyone looking for binaries for AIX in general.  I quickly snatched up binaries for Apache and PHP, but no MySQL binaries were available.  Have no fear, MySQL actually maintains their own, so I was able to download them from their website (http://dev.mysql.com/downloads/mysql/).

Step Two: Trying to install the binaries
This quickly turned into a dependency hunt for both Apache and PHP, but the PmWiki site had every package that I needed, so although tiring, it was simple work.... especially since each RPM install tells you exactly which packages it's missing.  Installing MySQL was as simple as unzipping the directory to /usr/local/mysql and following a few quick steps found in the install readme included with the binaries.  At this point, Apache was up and running, PHP was configured and MySQL was up and running.  In order to get MySQL to run at system startup I copied the mysql.server script to /etc/rc.d/init.d and then created symbolic links to it under rc2.d, rc3.d and rc5.d.  (Note: If for some reason, you are following this like a tutorial, do not install the PHP binaries just yet.... you'll see why).

Step Three: Trying to get PHP to connect to a MySQL database
This is when things started going downhill a little bit.  In a quick test, I got an error in my PHP script noting that the mysqli_connect (and mysql_connect) functions were undefined... this is not a good sign.  In going through the PHP info, I discovered that the PHP binary I downloaded was not compiled with MySQL support.  Bummer -- this meant that I now needed to compile PHP on my own on AIX.  Fun stuff!

Step Four: Compiling and Installing PHP on AIX
This part was the most painful of this entire process.  I don't have too much experience building and compiling from source (especially on AIX), so it probably took a little bit longer than it should have.  I did discover a few interesting things though:

  • You must use the 32-bit version of MySQL if you want PHP to compile using it
  • You must use gmake/GNU make instead of the AIX make command for compilation to complete
  • I had to install the apxs (from the httpd-devel package) to reference in my configure command.  The AIX one (under /opt/pware64) made a libphp5.so library that caused Apache to fail to start up.
  • The --enable-maintainer-zts configure option is required to make php thread safe.  Without it, Apache complains and won't load the library.
  • I also came across a very odd problem when I did the "make install".  The first part of the script deletes libphp5.so and then subsequently tries to call chmod on it, at which point it bombs out since it can't find the file.  Nice.  I came across a hack that also worked for me: Have two windows open, one ready to do the make install, and one ready to copy libphp5.so to the directory the script is expecting it to be in.  Start the make install, and then as soon as it has tried to delete libphp5.so, copy it where the script expects it to be.  By doing this, the file will be there when it's looking for it.  It requires a little bit of timing, so it may take a few tries to get it right.
For anyone interested, this is the configure line I used: 
configure '--cache-file=../config.cache' '--prefix=/opt/freeware' '--with-config-file-path=/opt/freeware/etc' '--enable-shared' '--enable-static' '--without-pear' '--with-gd=/opt/freeware' '--with-openssl=/opt/freeware' '--with-zlib' '--with-bz2' '--with-curl=/opt/freeware' '--with-t1lib=/opt/freeware' '--with-freetype-dir=/opt/freeware' '--with-jpeg-dir=/opt/freeware' '--with-png-dir=/opt/freeware' '--with-xpm-dir=/opt/freeware' '--with-zlib-dir=/opt/freeware' '--enable-soap' '--enable-bcmath' '--enable-ftp' '--with-iconv' '--enable-dom' '--enable-json' '--with-pcre-regex=/opt/freeware' '--with-apxs2=/opt/freeware/sbin/apxs' '--with-mysql=/usr/local/mysql' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--enable-maintainer-zts'

Step 5: Testing and Completion
At this point, I now had Apache running with PHP with support for MySQL.  I happily connected to the database and then handed the server over to another developer who would actually be using it.  This was definitely a learning experience, so I hope someone finds this information useful.

UPDATE: I also discovered that by default, cgi scripts were not executing.  This was due to the file permissions set on the httpd log file directory.  So, if you also run into this problem, just run a chmod 775 on your httpd log file directory (mine was located at /var/log/httpd).