Oct 26, 2018

Dumping my Mac for Linux

Dual Booting and Configuring a Dell Alienware 15 R4 with Ubuntu 18.04 for Android Development

Context: New Job. New Laptop.

After starting a new job, I decided to finally pull the trigger on my break up with Macbook Pros. Going steady with MBPs for over 10 years meant I had to carefully weigh my decision to leave but I hope that ultimately means I'm never going back!

My new laptop is a serious upgrade. From the i9 processor to the GTX 1080 graphics card, it's a total babe that's more powerful yet cheaper than my ex. The tough part is rebuilding what I had.

Setup

The goal was to dual boot Windows 10 and Ubuntu 18.10 but it turned out that 18.10 (cosmic cuttlefish) was a little too cutting edge so I had to downshift to the LTS release (18.04.1 bionic beaver). Getting everything working just right has not been easy. In fact, it's so difficult and temperamental that I decided to log everything here just in case I need to do it all again!

Background

Before diving into technical notes, lets reflect a bit. Apple seems to have forgotten developers, making progressively worse changes for us. The final straw for me was learning that the new Macbook "Pro" would have the hard drive AND RAM soldered to the motherboard! Replacing mechanical parts or upgrading RAM should not require a new machine or a trip to the "Genius Bar." Further, I heard rumors that the new machines were so obsessed with being thin that they do a terrible job cooling i9 processors, causing them to throttle down to i7 speeds. All of this made me consider what life would be like if I made the Linux switch. A good friend recommended Dell for their customer service. I called, spoke to an actual person and got several discounts, including FOUR years of premium service. Ultimately, my maxed out Alienware 15 was actually CHEAPER than the lack-luster Macbook Pro equivalent yet beefier in every way.

Switching was not as easy as I thought. From lost work productivity to retraining my muscle memory, I must admit that I severely underestimated how much time I would lose up front. It took me nearly a week to get this machine up and running. In the very first hour, I began learning the hard way that what Apple lacks in hardware, it makes up for with cohesiveness. For instance, in the 10 years that I've been using Macs, I never realized that BIOS had changed and UEFI is a thing! I never needed to know what model of graphics card or WiFi adapter was in my MBP. These are all things Linux forced me to grapple with on day one. With Apple, everything just worked . . . until suddenly it didn't! That's when Apple forces you to come crawling back with several grand in hand to repay them for all the trouble-free enjoyment you had. Sorry, I don't want to buy a new computer every 2 years. My laptop is not a smartphone and AT&T is not subsidizing it.

The moment I fully compiled my Android project, all of my second thoughts immediately faded away. Initial, side-by-side benchmarks showed that my Alienware was nearly 8 times faster than my existing MBP. I literally have never seen any Android project compile so fast. At first, I thought something was broken and deleted/reinstalled multiple times to confirm it was actually doing a clean build. Incremental builds are less than 1 second. Full builds are nearly 5 seconds. That's insane. Meanwhile, my MBP took ages and acted like it was going to overheat.

It's too early to be completely certain of whether I'm delighted with the switch. However, I'm already feeling much more like a hacker than a hipster and that, alone, might be worth it.
This is still a WIP and I may add things as I go.
[Update: 1 year later and I'm delighted and never looking back!]

Hardware Configuration

Trackpad

The trackpad was completely unresponsive. To get around this initially, I just used a corded USB mouse. Ultimately, fixing the issue required blacklisting a module and then rebooting which I found in this gist:
sudo su
echo 'blacklist i2c_hid' >> /etc/modprobe.d/blacklist.conf
depmod -a
update-initramfs -u

Network Adapter

Wifi worked perfectly on Ubuntu 18.10 but, sadly, the LTS version 18.04 did not recognize my wifi adapter, giving this defeating error in settings:


Of course, the laptop does have an adapter, the "Killer 1550 802.11ac 2x2 WiFi and Bluetooth 5.0" so I initially got around this severe limitation by pluggin in an ethernet cable. Then I followed these instructions on AskUbuntu to get the wifi card working:
sudo apt-get install git
git clone https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/backport-iwlwifi.git
cd backport-iwlwifi
make defconfig-iwlwifi-public
sed -i 's/CPTCFG_IWLMVM_VENDOR_CMDS=y/# CPTCFG_IWLMVM_VENDOR_CMDS is not set/' .config
make -j4
sudo make install

I cloned this to a place that I could easily find later because after every update it has to be reinstalled via:
cd backport-iwlwifi
make clean
make defconfig-iwlwifi-public
make -j4
sudo make install
*** The output of this install contains some errors that seem related to this bug in the NVidea-390 driver but it worked so I'm not too worried about it, for now.

NVidea Driver : Fix broken hibernate/suspend/resume

Resuming from hibernate did not work. If the laptop ever went to sleep, then it would never wake up! This is a terrible user experience. Fortunately, the fix for this was pretty easy; just install the Nvidea drivers with:
ubuntu-drivers devices
sudo ubuntu-drivers autoinstall

Other Tweaks During Setup

  • prevent double spaces
    There is a physical hardware problem with the spacebars on several of Dell's computers and this Alienware 15 is one of them. Tapping the spacebar near the edge results in a double space being typed and it is highly reproducible. At first, I thought adjusting the delay for repeating keys would help but I confirmed that it makes no difference. Literally, the only solution is to retrain my hands to hit the spacebar closer to the middle! I'm following this thread for any updates until I get the courage to try removing and cleaning the keys.

Developer Configuration

Eventually, I got the machine to function but that meant I was only at the starting block. Next, began the journey of making it fit for development. Here's a list of some of the things I required:
  • an iTerm2 replacement
    I chose Tilix and I'm VERY happy with it. I was able to recreate my "quake-like" terminal triggered by a hotkey. This required mapping Alt + ' to the command tilix --quake and then updating the settings so that the window closes whenever it loses focus.
  • install github & bitbucket ssh keys and .gitconfig (self-explanatory)
  • bring over all my setup/config files from github
  • apt install xclip to replace pbcopy and pbpaste
  • install oh-my-zsh via:
    sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
  • installed java
  • installed rust & cargo via rustup
  • download android studio and install it into the /opt folder (making sure to include CMAKE and the NDK for rust integration)
  • modify the .desktop launcher file to make certain that ANDROID_HOME is defined in the environment (rather than using local.properties files like a dinosaur)
    found here: ~/.local/share/applications/jetbrains-studio.desktop add: Exec=env ANDROID_HOME=/home/gmale/kg/setup/android/sdk /opt/android-studio-canary/bin/studio.sh %f
  • installed kvm for the android emulator with these instructions
  • installed pats-boostnote for note-taking and linked it to google drive using these instructions. This method worked best:
    sudo add-apt-repository ppa:alessandro-strada/ppa
    sudo apt install google-drive-ocamlfuse
    mkdir  ~/kg/work/google-drive
    google-drive-ocamlfuse ~/kg/work/google-drive
  • find a replacement for diffmerge (doesn't work on latest versions of ubuntu)
    Decided to go back to p4merge and it seems to work well. This post made it even easier.

Nov 16, 2016

Regex: Changing case in IntelliJ or Sublime Text

Regex is the ultimate swiss army knife. The kind you can use for years and still not exercise it all. That's how I felt years ago when I first stumbled on using it to solve capitalization problems. I needed a refresher on some of those techniques today and found myself sifting through a lot of incomplete answers online. Using one of them lead to disaster because it overlooked some important details. So I decided to do a quick write up on how to solve a couple real world uppercase and lowercase situations for the next time I need a refresher.

A Good Regex Editor

First, not all regex editors are created equal. You know you have a decent one when it supports upper and lower case conversion. This is one reason I chose Sublime years ago over other popular choices. Also, it was something I missed when I switched to Android Studio from Eclipse because this feature was missing until IntelliJ 15 (fixed in build 142.2822 but barely mentioned). Now that it's baked into Android Studio we no longer have to hop over to Sublime to do heavy lifting in Regex. Test your favorite editor or online regex tool for the techniques listed below and if it doesn't support them, maybe consider a switch.

Real World Example

String Constants into String Resources

We're working tech debt today and I was busy cleaning up an ugly file of String constants. I won't belabor why it existed for this client but only point out that my desire was to convert it into resources instead.

The goal was to convert this:

public static final String EXTERNAL_SHOP_URL = "http://buy.our.stuff.pretty/please";
public static final String EXTERNAL_PRIVACY_POLICY = "http://we.no.steal.you.info/promise";
public static final String EXTERNAL_TERMS_AND_CONDITIONS = "http://you.give.us.arm.and.leg/promptly";
public static final String EXTERNAL_HELP = "https://why.you.has.minor/problem?key=ABC123";

to this (dozens of times):

<string name="external_shop_url">http://buy.our.stuff.pretty/please</string>
<string name="external_privacy_policy">http://we.no.steal.you.info/promise</string>
<string name="external_terms_and_conditions">http://you.give.us.arm.and.leg/promptly</string>
<string name="external_help">https://why.you.has.minor/problem?key=ABC123</string>

The key to accomplishing this is the special \L and \E single character classes when replacing. Like the related \U \u and \l characters, these control the case of characters that come after. \L and \U will make everything that follows lowercase or uppercase, respectively. Similarly, \l and \u will make just the next character upper or lower case. Using that knowledge, press CMD+R to open find and replace and enter a regex similar to the following to pull out the capture groups and convert them to the desired case:

Find:

public static final String ([A-Z_0-9]+)\s*=\s*"([^"]+)";

Replace:

<string name="\L$1\E">$2</string>

Caution: Don't forget \E

When using \L and \U all subsequent characters are converted until the next \U or \L or \E is encountered. This is the detail that most online answers omit. It nearly caused a disaster while I converted URLs because public static final String EXTERNAL_HELP = "https://why.you.has.minor/problem?key=ABC123"; has a case-sensitive key on the end. Changing the case of the entire line also changes the URL keys and that can be very easy to overlook, introducing subtle bugs. Since I wanted the lowercase change to stop after the "name" attribute, I had to change the "replace" regex from:

<string name="\L$1">$2</string>
to:
<string name="\L$1\E">$2</string>
So don't forget \E when appropriate!

Real World Example

camelCaseVariables to/from CONSTANTS

As another quick example, when we want to change constants like VARIABLE_THAT_SHOULD_BE_CAMEL_CASE, it is easiest to do so in two steps. A fancy-pants regex like ([A-Z]+)(_[A-Z]+)* would group all the words together and be useful in a program, where you can iterate over them. Unfortunately, in the simplified world of find/replace, the final capture group ($2) is repeatedly replaced with the last match. So there's no easy way to do this in one step. Instead, use two:

  1. change the case
  2. find: [A-Z_]+\b replace: \L$0
  3. and then convert the underscores.
  4. find: _([a-z]) replace: \u$1

Note: using \b in step one helps avoid converting things like the first letter in "String" by only matching all caps that end with word boundaries. Also, because step 1 can be completed with the IDE shortcut CMD+SHIFT+U it is sometimes handy to use that, instead, and then skip to step 2 to replace the underscores.

To do this in reverse and create constants from variables

  1. convert the camel humps to underscores
  2. find: ([a-z])([A-Z]) replace: $1_\l$2
  3. and then convert to uppercase
  4. find: [a-z]+(_[a-z]+)+ replace: \U$0

Here we make step 2 a little more specific, requiring that the text we find must contain at least one word prefixed with an underscore, so that it only matches the underscored variables that we just created.

Summary (TL;DR)

Regex can be used to change the case of matched groups, which is powerful when done in bulk. Many tools now support this by default, including IntelliJ recently and that should be a factor when selecting an online regex tool. The key is to use \U \L \u \l and \E but most online posts forget to mention \E.

May 3, 2015

Android: Dynamically Coloring Images with Picasso

I'm working on an app where the server provides certain icon images but only in one color. Needing to tint these images, I checked whether the tinting from Lollipop was backward compatible. Nope. Not in AppCompat. That would be too easy! So I had to find another way.

Spoiler alert: Turns out I didn't technically need Picasso.

The Basic Idea: Use ColorFilters!

Fortunately, next Google pointed me to my friend Paul's awesome blog. He gave an excellent overview on Programmatically Coloring Drawables that's worth a quick read. After adapting his solution to my specific needs, I decided to post about my code so that the next time this comes up, I know exactly what to do:

Picasso.with(viewHolder.itemView.getContext())
 .load(iconUrl)
 .fit()
 .centerInside()
 .into(viewHolder.currentWeatherIcon);

int iconColor = viewHolder.itemView.getResources().getColor(R.color.weather_icon_color);
viewHolder.currentWeatherIcon.setColorFilter(
 new PorterDuffColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
);

The core idea was to apply a ColorFilter to the ImageView but, in my case, since I already had an ImageView, I didn't have to go the route of using a Transformer. Instead, I can just apply the ColorFilter to my ImageView, directly. Also, I could leverage a PorterDuffColorFilter since I knew I always want to use Porter Duff Compositing here.

One Step Further: Leverage the ViewHolder!

Given the way a ColorFilter works, I figured this could also be set on the ViewHolder, itself, during construction. So my final, working solution was along the lines of this:

public static class ViewHolder extends RecyclerView.ViewHolder {
    /* [other view holder stuff here] */
    public ImageView currentWeatherIcon;

    public ViewHolder(View v) {
        super(v);
        /* [other view holder stuff here] */
        currentWeatherIcon = (ImageView) v.findViewById(R.id.current_weather_icon);
        currentWeatherIcon.setColorFilter(
                new PorterDuffColorFilter(v.getResources().getColor(
                    R.color.weather_icon_color), PorterDuff.Mode.SRC_IN)
        );
    }
}

// elsewhere in code...
Picasso.with(viewHolder.itemView.getContext())
        .load(iconUrl)
        .fit()
        .centerInside()
        .into(viewHolder.currentWeatherIcon);

Of course, if I needed different icon colors, based on the data, then I'd have to set the color filter inside of onBindViewHolder but in my case, the icon color is always the same so this worked well. Bonus: this solution ended up not even requiring Picasso. I know I'll be coming back to this post in 8-12 months, after I've forgotten half this stuff...

Good thing I wrote it down!

Apr 26, 2015

Prevent Constant Security Popups on Genymotion with Google Play During ADB Installs

Problem

After installing Google Play services on Genymotion devices, I get a popup every time I try to install an APK. This popup prevents the adb install from completing until I either decline or accept. I've had this happen before but I keep forgetting how to turn it off. Googling doesn't help so I'm making this post for the next time I get into this mess.

Symptoms

A popup with the following message every time you try to install an app:

Allow Google to regularly check device activity for security problems, and prevent or warn about potential harm. Learn more in the Google Settings app.



Solution

Choose decline, then open the Google settings app (i.e. not the regular settings ... the other one. That's the key part I keep forgetting.) and turn off this option:

Scan device for security threats

Just to state the obvious, I think this is fine for an emulator but probably not something you want to disable on an actual phone that contains sensitive information. In that case, it's probably best to just "accept" the scanning, instead.

Apr 25, 2015

Upgrading to Google Play Services 7.0.0 Broke GCM

Problem

After upgrading from Google play services 6.5.87 to 7.0.0 I got compile errors in sections of code I hadn't touched.

Symptoms

I got errors similar to these:

  • error: package com.google.android.gms.gcm does not exist
    import com.google.android.gms.gcm.GoogleCloudMessaging;
  • error: package GoogleCloudMessaging does not exist
    if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
  • error: cannot find symbol
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

Solution

Simply put: add the GCM API to your gradle file:

Due to Dex limit issues, I stopped importing the full/bulky GooglePlayServices dependency the moment Google made that an option. Instead, I selectively compile the APIs that we need. It seems that version 7.0.0 of Google Play Services is a bit more modular than the previous one and more APIs have have been split out into individual packages.

So to fix this problem, all I had to do was add the new GCM api to my gradle build file. Compile errors went away and both the command-line and IDE builds were happy again!

compile 'com.google.android.gms:play-services-gcm:7.0.0'
As an added bonus, the "location" APIs have also been split out. After adding that, I was finally able to get rid of the play-services-base dependency that I previously relied on for the GCM & location packages.

Jun 28, 2013

Installing Genymotion for Mac OS X

Problem

After installing Genymotion, it doesn't work. Running the application gives errors and the shell script fails with segment faults.

Symptoms

  • The application fails with the following error: Unable to load VirtualBox engine
  • Accessing any device information from the shell script gives the following error: Segmentation fault: 11

Solution


UPDATE [7/15/13]: in addition to my initial post below, I just found some good information in the Genymotion docs. Not sure how I missed that the first time around. It covers everything in my post and more.

You need to download and install Oracle's VirtualBox from the VirtualBox site. Once this is installed and present in your Applications folder, Genymotion works!

It's easy to miss but on the Genymotion download page, it actually tells you that you need to download this. Of course, in my haste, I completely overlooked the underlined portion below:

Oops! It's also worth noting that I had problems registering on their website--it refused to send me a confirmation email. Once I switched from Chrome to Safari, it worked just fine. Now, I finally have Genymotion working and all is right with the world.

Mar 30, 2013

Using a Custom Prettify Theme with Blogger

This blog entry is using Google's Prettify, which was put in place following the setup outlined, below.


Out with the Old

I've been away from Blogger for some time. After returning, I've noticed a lot has changed. So I updated my template and made a bunch of changes, which promptly broke all the syntax highlighting I configured years ago!

Of course, I then looked into the old syntax highlighter I had. Although it has been moved to gitHub and has some fairly recent contributions, I still decided to go with something else. Partially because it's been around since 2004 and that's ancient in internet years--back in the time when dinosaurs were surfing the net--but mainly because I'm tired of seeing that same syntax highlighter everywhere.

In with the New

I quickly stumbled on this StackOverflow post, which had several solid responses. In my searches, I also found a site with a few "prettify themes" which are an improvement over the default. Combining all this together, here is some sample java code to show the final product:

Final Results (Java Sample)

    /**
     * Reads a file into a String. The current Thread's classloader will attempt
     * to load the given file as a resource and the result will be passed
     * through Apache Common's utility for creating a string from a File.
     * 
     * @param filePath The file to read.
     * @return The string to enjoy.
     * @throws IOException Thrown when the file cannot be found.
     * @see {@link FileUtils#readFileToString(File)}
     */
    public String readFileToString(final String filePath) throws IOException {
        File file = FileUtils.toFile(getClass().getResource(filePath));
        return FileUtils.readFileToString(file);
    }

How It Was Done

If I ever fundamentally change my Blogger theme, I may have to re-apply these settings. So I'm listing the steps to do so here, for future reference:

Step 1: Go to the "Template" section and choose the "Edit Html" button

Step 2: Cut / Paste the following lines of code under the <head> tag:

<!-- START: added to support syntax highlighting via prettify -->
    <link href='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css' rel='stylesheet' type='text/css'/>
    <script src='http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js' type='text/javascript'/>
    <script type='text/javascript'>
        document.addEventListener('DOMContentLoaded',function() {
            prettyPrint();
        });
    </script>
<!-- END: added to support syntax highlighting via prettify -->
Step 3: Go to a site that has prettify themes and download the CSS theme that you want
Step 4: Back in Blogger's "Template" section, click the "Customize" link (to the left of the "Edit Html" link in the picture, above)
Step 5: Paste your CSS in the "Advanced > Add CSS" section


That's it! Once setup is complete, syntax highlighting can be used with code along these lines
<pre class="prettyprint java">
    public void someFunction() {

    }
</pre>

Android Robolectric: java.lang.RuntimeException: Stub! while using libraries like JSONObject

Problem

While running a unit test under Robolectric on Android, the following error occurs:
java.lang.RuntimeException: Stub!

Symptoms

  • When you step through the code, portions of it work just fine
  • The exception occurs after returning from a constructor
  • Some library code is being used, like JSONObject

Solution

As stated in the Robolectric help documentation:

Make sure that robolectric and its dependencies (including JUnit) appear before the Android API jars in the classpath.

In other words, assuming you set things up correctly, then from that point forward, all you have to do is be sure that your classes are coming from either Robolectric or pure Java. In my case, the code under test was using JSONObject and that was coming from the android jar. To fix this, I had to:


  1. Add the JSONObject jar to my test project's dependencies. Depending on how your project is setup, that could be as simple as copying it to the lib folder
  2. Re-order the dependencies in the classpath such that Roboelectric and the other Java jars appear before anything Android-related. In Eclipse, that looks like this:

In this case, I pulled Robolectric and JSON up to the top and pushed android and maps down to the bottom. After this change, my test worked perfectly.

Mar 29, 2012

Arrow Keys and Backspace stop working in Flash Builder or Eclipse

I just ran into a problem SO annoying, I had to stop EVERYTHING and write down how to fix this, immediately. That way, the next time it happens, I won't pull the rest of my hair out!

Problem

Suddenly, the arrow keys and backspace button stop working in Flash Builder or Eclipse.

Symptoms

  • Arrow keys don't work in Flash Builder
  • Arrow keys work fine in other applications
  • Backspace key does nothing
  • Opening and closing Flash Builder or Eclipse doesn't necessarily fix the problem.

Solution

It's odd but to fix this, you just have to click every mouse button. For me, the problem went away as soon as I left-clicked.

I found the solution here:
http://board.flashkit.com/board/showthread.php?t=798172

Where the problem is described as:

"It seems to be a mouse driver issue. Sometimes the program will register one of the mouse buttons as stuck. To fix it, I have to press each button until it works again.

Apparently it was fixed in the new eclipse, but flex which is based off eclipse never fixed this bug."

Mar 24, 2012

Slow Mac WiFi but Internet Fine on PC?

Occasionally, my internet gets REALLY slow on my laptop. Then I go use my wife's PC and everything is fine. Since few things are more aggravating than Windows machines working better than Macs, I decided to post this solution so I won't forget it.

Problem

MacBook Pro internet is slow over wifi and ethernet.

Symptoms

  • After opening several tabs, they all show no content--just perpetual spinning
  • Things worked fine for a few seconds, then suddenly, everything is slow
  • You see none of these issues on your Windows machine on the same network
  • You do not have this issue on your mobile phone or tablet, using WiFi

Solution

Add DNS servers in "System Preferences > Network" under the "Advanced" options. By default, my settings were pointing to Comcast. Once I added Open DNS, instead, everything worked fine.


As an added bonus, you can create an account at opendns.com and get some pretty cool features.

Mar 3, 2011

Recovering Lost Data In Safari

While trying to recover lost data typed into a web page on Safari, I stumbled across this forum and one response was worth remembering for later:
"If you wish to open cache.db you'd use the sqlite3 command.
It comes with your mac and it's easy to use if you know SQL.
Open Terminal an type in:
"cd ~/Library/Caches/com.apple.Safari;sqlite3 cache.db".
it'll open up the database and you can type ".tables" to show
the table names  then ".output FILENAME" 
then "select * from TABLENAME;" and it'll output to the
desired file you could do "foo.txt" as the file name. I have
3 tables, cfurl_cache_blob_data, cfurl_cache_schema_version,
cfurl_cache_response, in it so i did the steps three times
starting with the .output command for three separate files..."
This is a handy way to search through your old safari data by dumping everything in a file and then grepping the contents. The exact commands I used to accomplish this were:
cd ~/Library/Caches/com.apple.Safari
sqlite3 cache.db
.output temp.txt
select * from cfurl_cache_blob_data;
It's kind of surprising to see what's actually in your cache! I had no idea that the pages I surf were being stored to this extent. Turned out to be very handy.

But scary.

Other useful commands:

.help
.schema cfurl_cache_blob_data
.exit

Mar 2, 2011

Clients and Servers on the Terminal: Simple File Transfers

I just stumbled across an interesting shell command: nc

It's used for simple client/server interactions from the shell. With it, you can do interesting things like take output from one machine, send it over the network to another machine that pipes this input into other commands. Here's an example:
# On the destination machine
nc -l -p 2345 | tar xv
# On the source machine
tar c PATH_TO_FILES > /dev/tcp/IP.OF.DESTINATION/2345
Which will tar PATH_TO_FILES, on the source machine and transmit it over the network on port 2345. The destination will receive the data and pipe it into a command that will extract the tar.

This is so useful, I had to jot it down!

Sep 16, 2010

Subclipse / SVN Working copy locked - Solution

Problem

I could not update or commit a certain folder in my subversion project using subclipse in eclipse.

Symptoms

Both commit and update failed with the error:

svn: Working copy 'path/to/folder/that/was/not/working' locked; try performing 'cleanup'

I also got warnings that the directory was not under version control.

To get this problem, I had copied files from one project to another (in the file system not in subclipse). Although I deleted the .svn directory after copying, I still ran into this issue.

Solution

On the command line, cd to the project directory and run svn cleanup as in:

cd path/to/folder/that/was/not/working
svn cleanup

The problem should go away!

Jul 15, 2010

Maven - Sun JAR Issues (javamail, jms, jmx, jdmk, persistence)

Problem

Compiling fails because of dependencies related to Sun, such as javamail, jms, jmx. These failures have some of the symptoms listed below.

Background. Many of Sun's Java projects do not have licenses that allow for redistribution. Basically, their stuff is somewhat "locked down." To get it, you have to click through a Software License Agreement; meaning, their libraries can, at times, be a pain to download. Historically, their JARs have not been in public Maven Repositories. As such, Maven tends not to automatically download Sun dependencies. Nowadays, they are available in the default repository . . . supposedly. However, over here IN REALITY, that doesn't really work.

If you have "Maven: The Definitive Guide," read page 73 under the section "Adding J2EE Dependencies" for related information.

Symptoms

Some symptoms of this problem I saw while trying to solve it include:

  • Failed to resolve artifact
  • Missing:
    ----------
    1) javax.persistence:ejb:jar:3.0-public_review
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository JBoss Repository (https://repository.jboss.org/nexus/content/groups/public/)
  • error: error reading /Users/keving/.m2/repository/com/sun/jdmk/jmxtools/1.2.1/jmxtools-1.2.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/javax/mail/mail/1.4.1/mail-1.4.1.jar; cannot read zip file
  • error: error reading /Users/keving/.m2/repository/com/sun/jmx/jmxri/1.2.1/jmxri-1.2.1.jar; cannot read zip file
  • [INFO] Unable to find resource 'javax.jms:jms:jar:1.1' in repository central (http://repo1.maven.org/maven2)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository maven.springframework.org (http://maven.springframework.org/snapshot)
  • [INFO] Unable to find resource 'javax.persistence:ejb:jar:3.0-public_review' in repository central (http://repo1.maven.org/maven2)
  • Failed to resolve artifact. com.sun.jmx:jmxri:jar:1.2.1
  • Failed to resolve artifact. com.sun.jdmk:jmxtools:jar:1.2.1
  • Solutions

    I recommend solution 4, below. After an hour or two of Googling, reading and learning, my final course of action (Solution 4) was to first delete all the troubled Sun dependencies, then painstakingly download the right JARs directly from Sun/Oracle and install them in the local repository. Below, I have listed all the useful solutions I found and tried during my journey to finding a complete repair.

    Solution 1 - Fastest, Easiest Fix

    Simplest solution: change just one character in the POM fille... use version 1.2.14 instead of 1.2.15. So the log4j dependency section
    changes FROM:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.15</version>
    </dependency>

    TO:

    <dependency>
    <groupid>log4j</groupid>
    <artifactid>log4j</artifactid>
    <version>1.2.14</version>
    </dependency>

    Solution 2 - Quick Fix

    Next simplest solution: exclude Sun jars by adding the following exclusions to the Log4j dependency within the pom.xml file:

    Solution 3 - Ideal Fix (didn't work for me)

    Best Solution (but doesn't work...or at least I can't get it to work): Use the special repositories provided by Sun: add to POM.xml

    Supposedly, this repository is provided by Sun and contains the missing jars. Each one has a "Reference Implementation" of the underlying API. Somehow, this allows for a looser license so the code can be redistributed without clicking through an SLA. When I tried this, it only successfully installed 1 of the JARs--javamail.

    Solution 4 - Thorough Repair (my choice)

    This is the longer, yet more complete solution--get the actual jars from Sun/Oracle. I kept track of all the little things I did and listed them below, keeping as many things "cut and pasteable" as possible. These are the steps I took and the commands I happened to run along the way:

    Delete the jars from the local repository:

      rm -rf ~/.m2/repository/javax/persistence/ejb/
      rm -rf ~/.m2/repository/javax/jms
      rm -rf ~/.m2/repository/javax/mail
      rm -rf ~/.m2/repository/com/sun/jdmk
      rm -rf ~/.m2/repository/com/sun/jmx

    run maven again (at least to the compile phase) to see exactly which jars fail.

    cd [top-level project directory with pom.xml]
    mvn assembly:directory -Dmaven.test.failure.ignore=true

    then download any remaining, missing JARs directly from SUN. Here are the detailed steps I took, grouped by each type of jar. The exact links may change over time but the basic steps should be the same. Note that the jdmk and jmx jars both come in one download.

    JMS

    1. click here to download the JMS jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. unpack the zip archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/jms1.1/lib/
    5. install the jms jar into the local maven repository, using the following command

    JDMK - JMX Tools and/or JMXRI

    1. click here to download the JDMK jar from Sun/Oracle, accept the Software License Agreement and download the jar
    2. (Found on Sun's Java SE page for the JDMK/JMX project by choosing Download" under the "BINARY DOWNLOAD" section under "JMX 1.2.1 Reference Implementation")
    3. This zip will include jars for both jmxtools and jmxri. Unpack the archive(automatic on my machine to directory ~/Downloads)
    4. cd to the lib directory
    5. cd ~/Downloads/jmx-1_2_1-bin/lib/
    6. install both jars into the local repository, using the following commands

    Persistence

    1. click here to access the javax.persistence jar from sourceforge
    2. unpack the archive (automatic on my machine to directory ~/Downloads)
    3. cd to the lib directory
    4. cd ~/Downloads/hibernate-annotations-3.1beta5/lib/
    5. install the javax persistence jar into the local maven repository, using the following command

    JavaMail

    Java mail is now open source so you shold be able to pull it from the default Maven repository. If not, try adding Sun's repository (Solution 3) and seeing if that will pull down the javamail jar. Be sure to completely delete the javamail directory (~/.m2/repository/javax/mail) before running this.


    Summary / Tradeoffs

    Each solution I found, I didn't quite like for different reasons. Solution 4 was the first satisfying choice. Each of the previous approaches involved tradeoffs. The first one downgrades to an earlier version of Log4j and, clearly, they moved to 1.2.15 for a reason.. Maybe there are security patches. Maybe the difference is negligable. Either way, I don't want to deal with figuring it out. So, Solution 1 would be the quick and dirty fix I'd use a coworker who needed to get their environment working in a hurry but it's not something I'd choose as a long-term fix. Solution falls into a similar boat. I like that it doesn't downgrade, but it cuts out dependences that are probably there for a reason. Most of what I read indicated that those libraries are virtually unused. Still, to me, there their for a reason so although I'd prefer solution 2 over solution 1, I wouldn't use it long-term, either. Solution 3 didn't work for me. The claim was that this repository had all the magic jars required but it didn't turn out that way. Upon download, two of them failed the checksum--I couldn't figure out why--and the other two jars didn't appear to be in the repository at all. In fact, it seemed that the only thing I could get, error-free, was the javamail jar. Not good enough.

    Finally, the fourth solution allowed Log4j to remain at the latest version and keep all it's dependencies. Admittedly, it was far more tedious and took me about 20 minutes to complete. Hopefully, this detailed post will greatly reduce that time for at least one person out there. If that person is you, I hope you can have your cake (a complete solution) and eat it too (a quick solution)! Celebrate.

    Linux Equivalent of ipconfig renew and ipconfig release on Windows

    I've looked this up 3 times so I finally decided to jot it down so I don't forget it.

    Problem

    Can't remember the Linux commands equivalent to:
    ipconfig renew
    ipconfig release

    Symptoms

    • Your IP is assigned via DHCP on a Linux box
    • You've unplugged from one network and plugged into another and the old IP address hasn't cleared out
    • Don't want to shutdown/restart the interface you just want to refresh the DHCP settings

    Solution

    sudo /sbin/dhclient -r is equivalent to ipconfig release
    sudo /sbin/dhclient is equivalent to ipconfig renew
    sudo /sbin/ifconfig is equivalent to ipconfig
    
    The dhclient command broadcasts a DHCP message to your DHCP server, resulting in a new lease. A slower way to achieve the same result is to shutdown the interface and bring it back up via (assuming your target interface is eth0):
    sudo /sbin/ifdown eth0
    sudo /sbin/ifup eth0
    
    This same, slower approach can also be done graphically on RedHat by clicking System > Administration > Network, choosing your interface (eth0) and clicking deactivate followed by activate.

    Jun 15, 2010

    Rollback Subclipse - Revert Subversion Changes

    Problem

    You need to rollback/revert subversion to a previous version and you're using the Subclipse plugin for Eclipse (or Flash Builder 4, etc.) to do it.

    Symptoms

    • There have been many changes to your project. You want to "undo" all those changes, restoring your project to its former glory.
    • Choosing "Revert" only blew away your local changes. That's not good enough.
    • There's a particular point in the past where everything "worked" and you need to reset everything back to that revision.

    Solution

    1. Right click your top level project folder and choose "Team" > "Show History"
    2. Find the point in the past where things worked
    3. TIP: click the play button on the top left to "show the next 25" revisions
    4. Highlight all revisions AFTER the target revision
    5. Right click and choose "Revert changes from revision # to revision #"
    6. That's it. Commit your changes

    For me, the revision that worked was revision 3690. The revision I was on was 3765. So, I highlighted revisions 3691 to 3765, right clicked and chose "Revert changes from revision 3765 to 3691."

    From there, I wanted to keep certain changes so I right clicked my project folder and chose "Compare With..." > "Latest From Repository". This opened a view of every single file in the project that was altered. I double-clicked the files with useful changes, copied the changes I wanted over and saved the compare editor.

    After everything looked correct, I committed. Worked great.

    May 20, 2010

    Debug BlazeDS Tomcat Server in Eclipse!!!

    Warning: this post is dripping with awesome. Once you're able to get this working, you might go dancing in the street (I know I did!). Consider yourself warned.

    Problem

    You need to debug java code running on Tomcat as part of BlazeDS. You want to do this in Eclipse.

    Symptoms

    • You're tired of using logs, system outs, or other tom-foolery to debug the server-side code for your Flex application!
    • You tried to set this up but received the following error:
    • java.lang.NoSuchMethodError: org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent.clearCache()V
    • You'd like to set a breakpoint and have server execution stop and jump to your breakpoint, even while executing RemoteObject code from Flex
    • Once you hit such a breakpoint, you want to be able to inspect variables and expressions and enjoy similar debugging pleasures

    Solution

    Note: In this process, I encountered the very common error:

    java.lang.NoSuchMethodError:

    org.eclipse.wst.common.componentcore.internal.resources
    .VirtualComponent.clearCache()V

    Fixing it simply required updating eclipse.

    I'll summarize the steps to getting debugging tomcat in eclipse to work as follows:

    1. Open the Server View, right click and create a New Server
    2. Point it to your /blazeds/tomcat folder (do not add any projects yet)
    3. Right Click the new server and choose "Open"
    4. Make sure your settings match this screenshot
    5. NOTE: if the "Sever Location" section is disabled, that means you added a project in step 2. Delete this sever and start over without adding any projects.


    Better yet, just follow this excellent and detailed blog titled Setting up your BlazeDS (tomcat) server on Eclipse ( local ). It worked flawlessly.

    I credit the FlashBandit blog with opening my eyes to the fact that Setting Up a Basic BlazeDS Server with Debugging was even possible.

    Uninstall MySQL on Mac OS X (Leopard 10.5 or Snow Leopard 10.6)

    Problem

    You need to completely remove mysql from your system as easily as possible.

    Symptoms

    You want to do a clean delete and a fresh install because you don't want to deal with errors such as:
    • MySQL [your version] for Mac OS X can't be installed in this disk. A newer version of this software already exists on this disk.
    • [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
    • [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist

    Solution

    Execute the following commands that I found here and here:
    sudo rm /usr/local/mysql
    sudo rm -rf /usr/local/mysql*
    sudo rm -rf /Library/StartupItems/MySQLCOM
    sudo rm -rf /Library/PreferencePanes/My*
    edit /etc/hostconfig and remove the line MYSQLCOM=-YES-
    sudo rm -rf /Library/Receipts/mysql*
    sudo rm -rf /Library/Receipts/MySQL*
    sudo rm -rf /var/db/receipts/com.mysql.*
    
    Maybe one day, if I'm feeling frisky, I'll come back and write a bash script to remove the MYSQLCOM line auto-magically. Maybe some magic involving sid or awk or something.

    May 7, 2010

    Fix Pixelbender Shader Compile Errors

    Today, I had a small pixelbender issue that I faced once before and forgot about it until I found the solution. Since this is the second time I've faced this, I decided to record the solution here.

    Problem

    Flex code, related to PixelBender, isn't compiling.

    Symptoms

    In Flex Builder / Flash Builder, I get the following errors:

    • 1046: Type was not found or was not a compile-time constant: Shader.
    • 1046: Type was not found or was not a compile-time constant: ShaderFilter.
    • 1172: Definition flash.display:Shader could not be found.
    • 1172: Definition flash.filters.ShaderFilter could not be found.
    • 1180: Call to a possibly undefined method Shader.
    • 1180: Call to a possibly undefined method ShaderFilter.

    Solution

    Clearly, these errors make no sense because both Shader and ShaderFilter are built-in classes distributed with Flash. Luckily, the solution is simple--you have to adjust your target Flash Player version. Make sure it's at least version 10:
    1. Right click your project and choose properties
    2. Go to the Flex Compiler section
    3. At the bottom, in the HTML wrapper section, check the Require Flash Player version box (which requires the Generate HTML wrapper file box to be checked)
    4. Enter at least version 10.0.0
    5. Celebrate!
    That's it. Here's a picture!

    May 4, 2010

    Install MySQL

    I just referenced this section of a file on my laptop because it has direct links and I was too lazy to think through installing mysql. Then, I decided to post it so I can link to it from another post I'm writing. Enjoy.

    Installation of MySQL v5.1

    1. Open the Safari browser then go to http://dev.mysql.com/downloads/mysql/5.1.html
    2. Download the latest version (today it's 5.1.46) either 32 or 64 bit (we use 32)
    3. Note: I recommend the DMG version, instead of the TAR archive because it has a handy pkg that, with one click, sets mysql server to run at startup.
      Snow Leopard (10.6):
      click the "Download" button under Mac OS X ver. 10.6 (x86, 32-bit), DMG Archive
      or
      Leopard (10.5):
      Mac OS X 10.5 (x86, 32-bit), Compressed DMG Archive
    4. On the next screen, you can ignore the login boxes by choosing

      "» No thanks, just take me to the downloads!"

      and select a mirror
    5. Double click on the mysql-5.1.46-osx10.6-x86.dmg file in the window opened by the download.
    6. Click the mysql-5.1.46-osx10.6-x86.pkg file to install mysql
    7. Optionally, once done, double click the "MySQLStartupItem.pkg" to automatically configure your Mac to launch the mysql server on startup
    8. Start the database by entering, /usr/local/mysql/bin/mysql –u root –p (no password needed).
    9. NOTE: if you get the error:
      “Can't connect to local MySQL server through socket '/tmp/mysql.sock'”
      Then, that means the mysql server is not running. One work-around to solve this problem is to enter a command similar to the following:
      sudo /usr/local/mysql/bin/mysqld_safe
      (enter your OS X login password, when prompted) Then, open a new terminal window and proceed
    10. List all databases by entering,
      SHOW DATABASES; 
    11. Create a new database,
      CREATE DATABASE myDatabase
    12. where myDatabase is the name of the new database.

    13. Use the database by entering, USE myDatabase
    14. Create a table in the new database by entering
      CREATE TABLE example_table (
               id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               data VARCHAR(100),
               cur_timestamp TIMESTAMP(8)
             );
    15. Display the table by entering
      SHOW TABLES;
    16. Add a value to the table by entering
      INSERT INTO example_table (data) VALUES (‘the current time is’)
    17. View the all data in the table by entering
      SELECT * FROM example_table;
    18. In order to create users, enter
      CREATE USER ‘userBob’@’localhost’ INDENTIFIED BY ‘s3kr1tP4$$W0RD’;
    19. In order to grant permissions to users for local and remote connections to the database, enter
      GRANT ALL PRIVILEGES on myDatabase.* TO 'userBob'@’%’

    Mar 16, 2010

    Eclipse - Run / Debug - The Fast Way

    Ok. This was so awesome, I had to stop everything and blog about it, simply because every Eclipse user on earth should hear about this.

    Problem

    So, in Eclipse, I got fed up always clicking through a thousand menus to run my application. I'm using maven, so to run our project, I have to mouse over to our POM.xml, right click on it, mouse ALL THE WAY down to "Run As" (of course, I always forgetfully mouse over "Maven," instead), then mouse ALL THE WAY down to "Maven build," then I have 6-8 run configurations to choose from so I have to mouse ALL THE WAY over to the middle of the screen and pick one!

    Clearly, I HATE MOUSING. So I hunted down a better way.

    Now all I have to do is hit COMMAND + SHIFT + F11 (ctrl + F11 on windows) to run my last-used configuration. This command already works by default on plain Java files but when you start getting fancy with the run configurations . . . and Maven . . . and things . . . it doesn't function the same.

    Solution

    1. Hit COMMAND + , to open preferences (without the stinkin' mouse!)
    2. Begin typing. Enter "Launching" in the filter box
    3. Open the Launching preferences
    4. In the bottom section, choose "Always launch the previously launched application"
    5. Click OK. Celebrate victory.

    This used to be the default behavior in Eclipse. A while ago, it changed so that it now makes a best guess based on your active resource and editor. That works perfectly . . . until you start doing things more complex. Now the CMD+SHFT+F11 shortcut key runs your last run/debug choice! That alone, will save BOATLOADS of time. Some days, I click "Maven Build" no less than 1 billion times!

    Mar 9, 2010

    Install Bugzilla on Mac Pro or MacBook Pro Running OS X 10.5 Leopard or 10.6 Snow Leopard

    NOTE: I've added a troubleshooting section at the very bottom to address additional problems I encounter. If you have trouble with installation, check there for great tips.

    Bugzilla on a Mac? Installing it shouldn't have been so hard. I guess it wasn't "hard," it was just really, really tedious. Almost, a "throw your laptop out the window" kind of tedious. I should know: I did it twice (installation, that is--not PC homicide). It felt like getting in line for the most crowded ride at Disney, waiting for hours to get to the front, only to arrive and realize it's NOT the front AT ALL--it's just a corner!! And once you turn it, 60 more minutes of wait time smack you in the face!

    I guess that's why they invented the "FastPass." Well, lucky for us, each time I installed Bugzilla (on a MacBook Pro and a Mac Pro), I took meticulous notes, which I've summarized, below. Enjoy your FastPass to Bugzilla on a mac:

    NOTE: I'd like to credit the blog I followed at Circles of Archimedes titled Installing Bugzilla on Mac OS X Server. It was, by far, the clearest, simplest, most accurate blog I could find on this topic. However, it is geared toward OS X Server and I have a Mac Pro running standard Leopard. Thereby, several steps were different. Much different.

    Bugzilla on a Mac/MacBook Pro
    (Leopard/Snow Leopard)

    These are the exact steps I took to get it to work (twice). Basically, I had to:

    then pass out from sleep deprivation. Exact details follow.

    Download & Unpack

    1. Download the latest stable release of Bugzilla here http://www.bugzilla.org/download/#stable
    2. Double click the archive file ("bugzilla-3.6.tar.gz" in my case) to unzip/untar it
    3. Move the resulting directory ("bugzilla-3.6" in my case) to /usr/local
    4. Create a symlink in /usr/local
      sudo ln -s bugzilla-3.6 bugzilla
    5. Create symlink in /usr/bin pointing to /usr/local/bugzilla
      cd /usr/bin; sudo ln -s /usr/local/bugzilla bugzilla
      
    6. Do the same in the Apache document root
      cd /Library/WebServer/Documents; sudo ln -s /usr/local/bugzilla bugzilla

    Perl

    Now it's time to get Perl situated. I'm not a perl guy, so I make no assumptions about your perl knowledge. Just do everything below and it should work.

    Identify What's Missing

    1. Run the Bugzilla script to check your Perl setup
    2. cd /Library/WebServer/Documents/bugzilla; sudo ./checksetup.pl --check-modules
    3. Scroll down until you get to a section that looks like this
    4. YOU MUST RUN ONE OF THE FOLLOWING COMMANDS (depending on which database you use): PostgreSQL: /usr/bin/perl install-module.pl DBD::Pg MySQL: /usr/bin/perl install-module.pl DBD::mysql Oracle: /usr/bin/perl install-module.pl DBD::Oracle COMMANDS TO INSTALL REQUIRED MODULES (You *must* run all these commands and then re-run checksetup.pl): /usr/bin/perl install-module.pl DateTime::TimeZone /usr/bin/perl install-module.pl Template /usr/bin/perl install-module.pl Email::Send /usr/bin/perl install-module.pl Email::MIME /usr/bin/perl install-module.pl Email::MIME::Encodings /usr/bin/perl install-module.pl Email::MIME::Modifier

    Essentially, these are all the problems (dependencies) you must fix before the bugzilla Perl code can function. I used CPAN to get that done. This is MUCH easier than typing the commands listed above because 1) CPAN exists, natively, on the Mac and 2) it takes care of all the stupid dependencies of dependencies for you! I'm not a Perl guy so maybe there are better ways to do this. All I know is, this worked (twice):

    Install Missing Modules

    1. Run CPAN (from an administrator account)
    2. sudo CPAN
    3. If this is your first time using CPAN on your machine, walk through all the configuration options.
    4. The defaults work well. So most times, you can just press enter to select the default option. Toward the end, they'll ask you questions and tell you what the "Typical frequently used setting" is. Generally, I went with their suggestion. For example, when it said:

      Parameters for the 'make install' command?
      
      Typical frequently used setting:
      
      UNINST=1         to always uninstall potentially conflicting files
      
      Your choice:  []

      I typed in "UNINST=1"

    5. When you reach the end, it will prompt the following:
    6. Please enter your CPAN site: []

      After some Googling, I chose a few sites from the mirror list at mirrors.cpan.org to accomplish that I...

      • chose my country and "Show Mirrors" on the side
      • searched for , -5 to find all instances of my timezone
      • grabbed a couple mirrors... used the HTTP sites too, for fun

      This was my output in that section:

      Please enter your CPAN site: [] http://cpan-du.viaverio.com/
      
      Enter another URL or RETURN to quit: [] http://mirrors.ccs.neu.edu/CPAN/
      
      Enter another URL or RETURN to quit: [] ftp://mirror.cogentco.com/pub/CPAN/
      
      Enter another URL or RETURN to quit: [] ftp://perl.secsup.org/pub/perl/
      
      Enter another URL or RETURN to quit: []
      
      New set of picks:
      
      http://cpan-du.viaverio.com/
      
      http://mirrors.ccs.neu.edu/CPAN/
      
      ftp://mirror.cogentco.com/pub/CPAN/
      
      ftp://perl.secsup.org/pub/perl/
    7. Once CPAN is ready to go, you can begin installing the Perl modules by executing the commands in the section titled, "COMMANDS TO INSTALL REQUIRED MODULES." For example, my commands were
    8. install DateTime::TimeZone
      
      install Template
      
      install Email::Send
      
      install Email::MIME
      

      Note that the last command took care of the other Email dependencies I needed!

    9. After those commands are done, choose a database (we use MySQL) and install it's module
    10. install DBD::mysql
    11. Exit CPAN and re-run the check setup script(step #7, above) to verify that you addressed all required commands
    12. Rejoice, you're almost done!

    Apache

    This is the part I was telling you about, where it feels like you're at the end of the line . . . only to realize, you've got a ways to go. Next up, is the Apache & MySQL stuff.

    One site I read somewhere mentioned that, briefly, Apache will be vulnerable while modifying some of these settings. Ideally, you should turn off your web server, first (sytem preferences -> sharing -> enable web sharing checkbox)--or better yet, disconnect from the internet entirely.

    Admittedly, I did neither. I guess I'm a rebel.

    1. Modify your bugzilla localconfig file *NOTE: it seems this file isn't created until checksetup.pl passes
    2. edit:
      
      /usr/local/bugzilla-3.6/localconfig
      
      - set $webservergoup = '_www'
      
      - set $db_pass = 'yourPassword'
      
      
      Obviously, replace 'yourPassword' with a valid password for the 'bugs' user.
    3. Change the owner on all your bugzilla files and symlinks
    4. sudo chown -R _www:_www /Library/WebServer/Documents/bugzilla
      
      sudo chown -R _www:_www /usr/local/bugzilla-3.6
      
      sudo chown -R _www:_www /usr/local/bugzilla
      
    5. Edit your Apache config file
    6. edit:
      
      /private/etc/apache2/httpd.conf
      
      add the following after the closing tag for <Directory "/Library/WebServer/Documents"> (after <Directory>):
      #
      
      # Bugzilla
      
      #
      
      <Directory "Library/WebServer/Documents/bugzilla">
      
      AddHandler cgi-script .cgi
      
      Options +Indexes +ExecCGI +FollowSymLinks
      
      DirectoryIndex index.cgi
      
      AllowOverride Limit
      
      </Directory>
      
    7. Note that the +FollowSymLinks option needs to be set for this to work.
    8. Also, I had to do something funky to get CGI pages to stop loading as text. I don't have that documented but I believe it's just the +ExecCGI Option, above. I may have needed to load this module in the "LoadModule" section near the top:
    9. LoadModule cgi_module libexec/apache2/mod_cgi.so

    MySQL

    Now comes the fun with MySQL. Basically, all you need to do is create the bugs database, create the bugs user (with the proper password). Of course, I assume you already have MySQL (if not, follow this post to install MySQL on Mac OS X). Then do the following to configure the bugzilla database:

    1. Run the following SQL (or copy it to a file named bugzilla.sql and run: mysql -u root -p < bugzilla.sql)
    2. use mysql;
      create database if not exists bugs;
      
      CREATE USER 'bugs'@'localhost' identified by 'yourPassword';
      
      CREATE USER 'bugs'@'127.0.0.1' identified by 'yourPassword';
      
      CREATE USER 'bugs'@'%' identified by 'yourPassword';
      
      
      
      GRANT ALL PRIVILEGES ON bugs.* TO 'bugs'@'localhost' WITH GRANT OPTION;
      
      GRANT ALL PRIVILEGES ON bugs.* TO 'bugs'@'127.0.0.1' WITH GRANT OPTION;
      
      GRANT SELECT, INSERT, UPDATE, DELETE, INDEX, ALTER, CREATE, LOCK TABLES, CREATE TEMPORARY TABLES, DROP, REFERENCES ON bugs.* TO 'bugs'@'%' WITH GRANT OPTION;
      FLUSH PRIVILEGES;

    Obviously, replace 'yourPassword' with a valid password for the 'bugs' user on the database. Also, granting ALL privileges is, of course, probably NOT the best thing to do . . . feel free to restrict the privilages on localhost if you like. I just wanted to be sure it would work. Plus, our DB is only connected to our intranet. Likewise, you don't need to grant privileges to all domains (i.e. the line containing 'bugs'@'%' could be omitted).

    Home Stretch

    Now that all this is set, and your bugs database has GRANT privileges, run the checksetup.pl script (as administrator) :

    sudo /usr/local/bugzilla/checksetup.pl

    Once Perl is completely setup, this script sets up your Database tables & data and applies a few other settings. There will be several prompts to respond to but all the answers are straight-forward. Be sure to TAKE NOTE OF WHAT YOU SET YOUR EMAIL/PASS TO! (I forgot mine and it was a hassle)

    Bugzilla Settings

    By now, all the difficult things are done. The only thing left is to run Bugzilla. So, fire up Apache (sytem preferences -> sharing -> enable web sharing checkbox) and visit the bugzilla directory on your server (for me it's, http://our.server.address/bugzilla) and celebrate!

    From there, login at the top and begin setting the required paramaters (namely, urlbase). Here's a quick list of some of the things I typically change on every installation:

    • Required Settings > urlbase > http://our.server.address/bugzilla
    • Bug Fields > usebugaliases > On
    • Bug Fields > defaultpriority > Normal
    • Bug Fields > defaultseverity > Normal
    • Bug Fields > defaultplatform > Macintosh
    • Bug Fields > defaultopsys > Mac OS
    • User Matching > confirmuniqueusermatch > Off

    Troubleshooting

    Ok. So we upgraded our server to Snow Leopard and, somehow, that impacted the Perl environment thereby messing up Bugzilla. In the process of fixing this issue, I hit SO MANY roadblocks that it prompted me to add this Troubleshooting section--just for my own sanity.

    Below, I will organize the bugzilla problems I encountered into Problem/Symptom/Solution sections and link each topic below:

    Topics:

    Problem

    Installation of Email::MIME module failed

    Symptom

    received the following error:

    make test had returned bad status, won't install without force

    Solution

    The suggestion at the bottom of this forum post recommended running
    force install Email::MIME
    which, in fact, did forcefully install the module. Whether that's good or bad, I can't say. I did continue looking for the root problem (which was, basically, to find and install all missing modules).

    Problem

    Problem description: Perl. That's it, just Perl. Perl + Bugzilla = headache

    Jokes aside, every issue I've had installing Bugzilla always boils down to deducing the missing Perl module and installing it. Installation is easy. It's the "figuring out which module" part that will get you, every time!

    Symptom

    received errors during Perl configuration such as:

    #   Failed test 'use Email::Send;'
    #   at t/foreign-mailer.t line 7.
    #     Tried to use 'Email::Send'.
    #    Error:  Can't locate Email/Simple.pm in @INC ... 
    or
    BEGIN failed--compilation aborted at ...
    or
    DIED. FAILED tests
    or
    #     Error:  Attempt to reload Email/MIME.pm aborted.
    #     Error:  Base class package "Email::Simple::Creator" is
    empty.
    

    Solution

    The best process I've found for solving most bugzilla installation errors is:
    1. Open a fresh terminal window
    2. Attempt to install every module required in the "checksetup.pl" script. (run the commands in step 4, above.)
    3. Execute every installation command once, ignoring any errors
    4. Copy all output into a file
    5. I used CPAN, which has it's own shell and thereby wouldn't let me pipe output into a file. So I just chose "Select All > Copy" in that fresh terminal window (in step 1) and pasted it into a temporary file
    6. Grep the file to sift out text related to missing modules
    7. They often generate errors along the lines of

      Error:  Can't locate Email/Simple.pm in @INC (@INC contains ...

      So I used some variation of the following:
      cat tempFile.txt | grep @INC | awk -F"@" '{ print $1 }' which takes the file, pulls out every line with "@INC" in it, then lazily uses awk to split each line around the "@" symbol and print the first segment. This produced crude information on missing modules such as:
      t/19local-win32......Can't locate Params/Validate.pm in 
      t/20local-subclass......Can't locate Params/Validate.pm in 
      t/abstract-msg.......Can't locate Email/Simple.pm in 
      #     Error:  Can't locate Email/Simple.pm in 
      t/classic............Can't locate Email/Simple.pm in 
      t/email-send-test....Can't locate Email/Simple.pm in 
      
    8. Identify statements in a form similar to:

      Params/Validate.pm
      Email/Simple.pm
      Email/Date/Format.pm
    9. Install the corresponding modules:
      sudo CPAN
      install Params::Validate
      install Email::Simple
      install Email::Date::Format
    10. Rerun the installation commands
    11. Run the checksetup.pl script again to verify that the required modules no longer appear in the list
    12. Celebrate!
    Typically, this process fixes the problem. I go over the initial output (the temp file created in step 3) with a fine-toothed comb and install everything that seems to be missing. The list above contains everything I installed this time, except YAML (for that just run: install YAML).

    Problem

    General errors that mention "DateTime" or "Locale"

    Symptom

    errors such as:

    Attempt to reload DateTime.pm aborted
    BEGIN failed--compilation aborted at /usr/local/share/perl/
    5.10.0/DateTime/Locale/Base.pm line 8.
    Compilation failed in require at /usr/local/share/perl/5.10.0/
    DateTime/Locale.pm line 10.
    BEGIN failed--compilation aborted at /usr/local/share/perl/
    5.10.0/DateTime/Locale.pm line 10.
    Compilation failed in require at lib/i486-linux-gnu-thread-
    multi/DateTime.pm line 46.
    BEGIN failed--compilation aborted at lib/i486-linux-gnu-thread
    -multi/DateTime.pm line 46.

    Solution

    Many users on this forum found it helpful to run

    install DateTime::Locale



    Problem

    install DBD::mysql fails

    Symptom

    running the command generates the following error:

    Running install for module 'DBD::mysql'
    Running make for C/CA/CAPTTOFU/DBD-mysql-4.014.tar.gz
      Has already been unwrapped into directory /Users/svn/.cpan/
      build/DBD-mysql-4.014-jZi5O8
      '/usr/bin/perl Makefile.PL' returned status 512, won't make
    Running make test
      Make had some problems, won't test
    Running make install
      Make had some problems, won't install
    

    Solution

    Verify that the command "mysql" works from the terminal. If not, install mysql. Verify that you can connect to mysql as user "root." If not, grant permissions to your root account.

    Problem

    You need to re-run the initial CPAN setup wizard, for whatever reason (maybe to reset your URL mirror sites)

    Symptom

    None the URLs you have seem to work, or maybe there's one that needs deleting (in my setup the first one would fail and take like 3 minutes to timeout).

    Perhaps, you don't trust your CPAN installation settings and you want to rule that out during troubleshooting (I wanted to rule this out)

    Solution

    Re-run the initial CPAN setup with the folowing command (note: the first character is an 'o' -- not a bullet):
    o conf init
    
    To choose new URLs (or edit existing ones) run:
    o conf init urllist
    Be sure to commit your configuration after making changes. I believe the command is:
    o conf commit


    Problem

    Need to reset bugzilla admin password

    Symptom

    The admin password is lost or forgotten

    The admin login credentials are lost or fogotten

    Another admin account needs to be added (but you can't login)

    Solution

    This forum post provides lots of help on recovering a forgotten admin password or account.

    There are several ways to address this issue

    • run checksetup.pl with the --make-admin option:
    • ./checksetup.pl --make-admin=yourEmail@domain.com
    • copy the profiles.cryptpassword for a known user account to the administrator account, OR add your account to the admin group:
    • SELECT @myusr := userid FROM profiles WHERE login_name="PUT YOUR EMAIL HERE"; 
      SELECT @admin := id FROM groups WHERE name="admin"; 
      INSERT INTO user_group_map (user_id,group_id,isbless,grant_type) VALUES 
      (@myusr,@admin,0,0);
    • Throw your computer out the window
    • That fixes everything.


    Problem

    Installing DateTime fails with an error mentioning "Singleton"

    Symptom

    Errors such as:
    • t/37local-add.t ......... Can't locate Class/Singleton.pm in @INC (@INC contains: /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/lib /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/arch /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at /Library/Perl/5.10.0/DateTime/TimeZone/America/Chicago.pm line 14.
    • BEGIN failed--compilation aborted at /Library/Perl/5.10.0/DateTime/TimeZone/America/Chicago.pm line 14.
    • t/38local-subtract.t .... Can't locate Class/Singleton.pm in @INC (@INC contains: /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/lib /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/arch /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at /Library/Perl/5.10.0/DateTime/TimeZone/America/Chicago.pm line 14.
    • BEGIN failed--compilation aborted at /Library/Perl/5.10.0/DateTime/TimeZone/America/Chicago.pm line 14.
    • Compilation failed in require at (eval 906) line 3.
    • t/41cldr_format.t ....... Can't locate Class/Singleton.pm in @INC (@INC contains: /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/lib /Users/svn/.cpan/build/DateTime-0.55-ilncRa/blib/arch /Library/Perl/Updates/5.10.0/darwin-thread-multi-2level /Library/Perl/Updates/5.10.0 /System/Library/Perl/5.10.0/darwin-thread-multi-2level /System/Library/Perl/5.10.0 /Library/Perl/5.10.0/darwin-thread-multi-2level /Library/Perl/5.10.0 /Network/Library/Perl/5.10.0/darwin-thread-multi-2level /Network/Library/Perl/5.10.0 /Network/Library/Perl /System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level /System/Library/Perl/Extras/5.10.0 .) at /Library/Perl/5.10.0/DateTime/TimeZone/America/Chicago.pm line 14.
    • Result: FAIL
    • Failed 11/43 test programs. 3/2864 subtests failed.

    Solution

    The Singleton module is missing. For me, this also meant that the DateTime::TimeZone module hadn't been installed (because it depends on Singleton). To solve this, either
    • execute install DateTime::TimeZone
    • and choose [yes] when prompted about the Unsatisfied dependency on Singleton. This will automatically install the missing Singleton module.

      OR

    • execute install Class::Singleton
    Whichever solution you use, make sure to run install DateTime and install DateTime::TimeZone to ensure that both of these modules are now installed properly.