Archive

Archive for the ‘Grimoire’ Category

Oracle: Paging Results

February 5th, 2010 No comments

Paging Oracle developers…

This will be a quick post, as the problem is small.  I will add, though, that setting up paging with database queries can be a major pain in the ass.  Setting up the consumer – usually jQuery, ExtJS, DWR, or some other AJAX client, is hard enough, but then you have to translate the client’s version of “start-limit” to the persistance-side’s language.  Sometimes it’s a simple start/limit pair, sometimes it’s a start/page pair, and then there’s Oracle, which decided to punt on the whole thing. Read more…

Categories: Grimoire, Oracle Tags: , , , ,

Frozen Explorer

January 21st, 2010 1 comment

A common problem, unfortunately…

This is a simple trick that will save you from having to restart your pc at inopportune times.  The setup – you are working along, minding your own business, writing your [insert invaluable document name] Word document, when out of the blue Windows Explorer freezes up.  You know the symptoms – you can’t click on anything on the desktop… you drag a window around and it leaves “trails”, which everyone will automatically cover the entire desktop in (because it’s fun!).  A few seconds later, you realize that you can’t get to your Word document as well, and you hadn’t saved it.  “That’s [x] hours of work!” you silently scream to yourself as you contemplate the glowing frozen tableau in front of you, dread slowing sinking down into the pit of your stomach.  Now what the hell do you do?

The answer is to try this trick.  It can’t hurt, and it just might recover your computer enough to save your document and restart.  It actually might allow you to keep working normally, but when I’m doing something important, I usually ere on the side of caution – the side where you save anything and restart just to make sure. Read more…

Categories: XP Tricks Tags: , ,

JSF: SelectOneComboBox

January 13th, 2010 5 comments
Post Technology Stack
  • MyFaces 1.1.7 (JSF 1.1 spec)
  • Java 1.5
  • MyFaces Tomahawk 1.1.9
  • ExtJS 3.1 *

Not Again…

JSF, that steaming pile of undocumented, developer-hating obfuscation has yet again soaked up about 16 hours of my time to do something that should have been a three second configuration. Just to reiterate, much like Randall Munroe’s hatred of velociraptors spurs him to evaluate houses based on their ability to repulse dinosauriod attacks, I find myself now evaluating jobs by how close the project requirements are to actually using the JSF framework.

That said, when you’re a contractor, you use the tools selected for you by the almighty architects. In my case, it’s JSF or my paycheck. Being the Alpha Geek that I am, I gratefully welcomed the paycheck an opportunity to learn more about JSF.

What did they do now???

The crux of the problem is right in the title of this post. Combo box. JSF doesn’t have one, and I needed one. Being the Jack of All Tech that I am, I figured it would be relatively simple to grab the ExtJS combobox and front the JSF selectOneMenu control with it. So long as the ExtJS code didn’t monkey with all the javascript and DOM that the JSF selectOneMenu control created, I’d have myself a nice little combobox that worked with JSF. Well, if you’ve been coding for any longer than two minutes, you know just how screwed up things can get right after you utter the words “That was easy!”.

In this case, the problem emerged as an inability to submit the form of which the combobox was a part. Weirder still, submitting was only a problem when I entered in a value that was not in the dropdown list. Armed with Eclipse and 18mg of ritilin, I spent a few hours tracing the problem down to validation which myfaces was perpetrating on the submitted combobox value – validation that was not implemented as an official Validator.

Here I give you a few lines in javax.faces.components.UISelectOne from where the problem stems. Line 69 is perfectly fine, setting off an execution chain that includes getting the list of validators that have been assigned to the component and executing them. That is not where our problem validation happens, and that’s the problem. Line 77, when parsed, creates an iterator for the list of options created for the drop-down. That iterator is then sent to the _SelectItemsUtil.matchValue method which then makes sure that the submitted value for the drop-down component is one of the available options… and there’s the reason I will never get hours of my life back. See, we’ve got code that runs all the validators assigned the UISelect descendant class, then we’ve got what amounts to a hardcoded validation right after that. Isn’t that great!

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
protected void validateValue(FacesContext context, Object value)
{
    super.validateValue(context, value);
 
    if (!isValid() || value == null)
    {
        return;
    }
 
    // selected value must match to one of the available options
    if (!_SelectItemsUtil.matchValue(value, new _SelectItemsIterator(this)))
    {
        _MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID,
                        new Object[] {getId()});
        setValid(false);
    }
}

Showing the code who’s boss

You’d think that would be the end of the combobox quest. I mean, if checking the submitted value against the options is hardcoded into a core-core API class, you’re basically screwed, right? No getting around that… If you answered yes, please stop reading here, turn in your geek badge, and go read yourself some FARK. If you answered by opening up firefox to the myfaces api and started looking for chinks in the API armour, then read on! …Oh – and if your answer was to break out your Wiha precision screwdriver set and pop the hood off your rig, it’s time to switch to decaf.

* A few important notes first. This solution uses an ExtJS combobox for the UI portion of the hack. ExtJS is, unfortunately, a semi-free library. The “semi” part comes in if you use the library for any public facing user-interfaces which are not open source. Of course, the licensing scheme is waaaay more complicated than that, so I suggest you visit ExtJS’s Licensing Overview page to figure out just what your options are. At the time of this writing, I don’t know of any completely open-source combobox solutions that can interact successfully with the underlying generated JSF DOM structures. If you do, leave a comment!!! Otherwise, the Java/JSF portion of this hack takes care of the application side of things and should be usable (or make usable) any UI combobox solution.

Let’s start with the html/jsp code to make the front end of our combobox work:

1
2
3
4
5
6
7
8
9
10
11
12
13
<f:view>
<h:form id="carCreatorForm">
    <t:selectOneMenu id="colourSelect"
                             value="#{car.Colour}"
                             binding="#{selectOneComboHelper.htmlSelectOneMenu}">
        <t:selectItems var="colour"
                             value="#{colourShelf.colours}"
                             itemLabel="#{colour}"
                             itemValue="#{colour}"/>
    </t:selectOneMenu>
...
</form>
</view>

A few assumptions:

  1. colourShelf is an object that holds available colors and is defined as a JSF managed bean, and it has a getColours method that returns a Java List collection of color names.
  2. car is also defined as a JSF managed bean, and has a setColour method.
  3. selectOneComboHelper is defined as a JSF managed bean, and will be discussed shortly.
  4. I dislike JSF immensely.

The above code is standard for creating a selectOneMenu component for MyFaces using the Tomahawk taglibs. The selectOneMenu tag has the value attribute tying the selected value to the “car” managed bean. The selectItems tag creates the option list. In short:

  1. The value attribute says to call the getColours method on the colourShelf managed bean, which in the example’s case returns a Java List collection of colour name strings.
  2. The var attribute states that “colour” will be the variable name in which the string colour names from the list will be stored.
  3. The selectItems tag iterates over the strings in the colour name list, creating new option elements for the select element created by the selectOneMenu tag.

Now that we have our list menu, here’s the code that makes it a combobox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html>
<head>
    <!-- Ext relies on its default css so include it here. -->
    <!-- This must come BEFORE javascript includes! -->
    <link rel="stylesheet" type="text/css" href="js/extjs/resources/css/ext-all.css">
 
    <!-- Include here your own css files if you have them. -->
 
    <!-- First of javascript includes must be an adapter... -->
    <script type="text/javascript" src="js/extjs/adapter/ext/ext-base.js"></script>
 
    <!-- ...then you need the Ext itself, either debug or production version. -->
    <script type="text/javascript" src="js/extjs/ext-all-debug.js"></script>
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
    <script type="text/javascript">
 
    // Path to the blank image must point to a valid location on your server
    Ext.BLANK_IMAGE_URL = 'js/extjs/resources/images/default/s.gif';
 
    // Main application entry point
    Ext.onReady(function() {
        var converted = new Ext.form.ComboBox({
            typeAhead: true,
            triggerAction: 'all',
            transform:'carCreatorForm:colourSelect',
            width:135
        });
    });
    </script>
</head>
<body>
...

The above is standard ExtJS – you include all the ExtJS scripts in the head element of the page, and then use the Ext.onReady function to initialise your ExtJS UI components. The secret to getting ExtJS to recognise and transform the JSF select box is to remember that the HTML form element IDs JSF generates are the name of the form first, a colon, and then the ID you assigned the element. In the case of the code above, our form name is “carCreatorForm”, and the ID of the select menu is “colourSelect”, hence “carCreatorForm:colourSelect”.

The ExtJS combobox transform attribute tells the component that it isn’t going to create a combobox from scratch, but will instead create one from an existing select element (I’ve gotta tell ya – I love those guys at ExtJS!). That means when the html page’s body’s “onLoad” event fires, ExtJS will seek out a DOM element with the name “carCreatorForm:colourSelect”, suck all the information out of it, remove it, and replace it with pod-person combobox version.

Managing JSF shortcomings

With the user-interface portion of our little hack done, we turn now to the underlying MyFaces code that so offends our idea of “How Things Should Work”. Honestly, I don’t have time to figure out if this same “bug” exists in other JSF implementations, or even later versions of MyFaces. If not, then you are already home free and the rest of this post only serves to show you how clever I am (I am extremely clever!). If you try the above and find that the page refreshes without any form elements getting bound to their backing beans, however, this next part my serve as a guide, if not an outright shortcut to getting a working combobox.

To recap (damn, this is a long post!), the symptoms of the problem is the lack of anything actually happening when you hit the form’s submit button. The screen refreshes, but none of the form values are bound to their associated backing beans. Another symptom is this nebulous entry in your log files:

DEBUG | 2010-01-12 15:19:18,550 | LifecycleImpl.java:178 | exiting from lifecycle.execute in PROCESS_VALIDATIONS(3) because getRenderResponse is true from one of the after listeners

According to the code, there should have been another error along the lines of:

javax.faces.component.UISelectOne.INVALID

…but no amount of fiddling with Log4j would make it appear.

Anyhoo, that debug log message is the clue to what is really happening. When the code decides that you are vainly trying to trick it by providing a value that wasn’t on the approved option list, it stops the bus at the third JSF lifecycle step of “Process Validations”, turns it around and leaves the way it drove in. Just so you know, the fourth lifecycle step is “Update Model Values”, which is where the form values would have been bound to the backing beans. It’s also where the bathroom was, which is why you get that bloated, unfulfilled feeling when you see the page refresh with no joy for the backing beans.

Giving JSF more “options”

I know this post is aging you where you sit, that your coffee is cold, and that you are starting to worry about deep vein thrombosis, but there’s only two parts to this hack and all the background’s been covered, so just stay with me a few more paragraphs!

I’ve seen very few APIs that were bullet proof – meaning that I couldn’t screw with them. The general rule is the more complex or less well-developed the API, the easier it is to screw with. That axiom in mind, JSF is extremely easy to screw with! Let’s start with a “helper” class, and when I say helper, I mean l33t h4x0r c0Dz:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.facets.examples;
 
import java.util.List;
import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.apache.commons.lang.StringUtils;
import org.apache.myfaces.component.html.ext.HtmlSelectOneMenu;
 
public class SelectOneComboBox {
 
    private HtmlSelectOneMenu component;
 
    public HtmlSelectOneMenu getHtmlSelectOneMenu() {
        return this.component;
    }
 
    public void setHtmlSelectOneMenu(HtmlSelectOneMenu component) {
        this.component = component;
        @SuppressWarnings("unchecked")
        // Get _ComponentChildrenList, with list of child components of the SelectOneMenu component.
        List children = component.getChildren();
        if(children==null || children.isEmpty()) {
            // If no children, page is probably just being rendered, not submitted, so nothing
            // needs to be (or can be) done.
            return;
        }
        // Tell myfaces to marshal the submitted values so we can get to them. 
        component.decode(FacesContext.getCurrentInstance());
        // This is the previous value of the component - the last value to be submitted.
        Object value = component.getValue();
        // This is the current value of the component - the value just submitted.
        Object subValue = component.getSubmittedValue();
        if(!(subValue instanceof String)) {
            component.setSubmittedValue(value);
            return;
        }
        String valueStr = (String)subValue;
        // Get the only child of the SelectOneMenu - the SelectItems component.
        UISelectItems itemsComp = (UISelectItems)children.get(0);
        // Get the array of values from the SelectOneMenu.
        SelectItem[] items = (SelectItem[])itemsComp.getValue();
        // Is the submitted value one of the listed option values?
        for(SelectItem item : items) {
            if(!StringUtils.isBlank((String)item.getValue()) && item.getValue().equals(valueStr)) {
                return; // Submitted value is a listed option - nothing needs to be done.
            }
        }
        // Create a new value for the written-in value of the combobox.
        SelectItem newValue = new SelectItem(valueStr,valueStr);
 
        // Create and fill a new array for the existing option values and the one written in value.
        SelectItem[] newItems = new SelectItem[items.length+1];
        for(int i=0;i<items.length; i++) {
            newItems[i] = items[i];
        }
        newItems[items.length] = (new SelectItem(valueStr));
        // Set the new value array on the SelectItems component so the backing list now includes
        // the written-in value.
        itemsComp.setValue(newItems);
        // Tell the component that the submitted value is an object from the backing list.
        component.setSubmittedValue(newValue);
    }
}

For the most part, everything you need to know about the class exists as inline comments in the code above. Regardless of whether the backing list for the SelectItems component contains strings or objects of your own design, the above should work because it is called between the second and third lifecycle steps (2=Apply Request Values, 3=Process Validations). Since the “Process Validations” step is where everything is converted to the underlying object model from the necessary string values for the front-end HTML UI, strings are all you really have to deal with. I would be careful if you are using Enums as your backing list objects, however, as you can’t just create a new Enum member on the fly from a new value.

To get this to work, you need two pieces of code. The first you saw in the jsp code above, specifically the “binding” attribute of the SelectOneMenu component. That snippet hands the select component object to the SelectOneComboBox.setHtmlSelectOneMenu method above. In order for the SelectOneComboBox object to exist, we need to add it as a managed bean to your faces-config file, like so:

<faces-config>
    <managed-bean>
        <managed-bean-name>selectOneComboHelper</managed-bean-name>
        <managed-bean-class>com.facets.examples.SelectOneComboBox</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    ...

Congratulations! Not only do you now have a working JSF combo box, but more importantly you have made it through my longest post yet!

JSF Tricks: Abstracted Actions

December 17th, 2009 2 comments

JavaServer Faces – Aw, crap…

I hate JavaServer Faces. I think JSF is a bloated abstraction-fest and just about any other framework makes it easier to write MVC applications – even Struts. That being said, I’ve had to recently work with the beast, and in doing so I had to figure out how to do some things that wouldn’t even be an issue in Spring MVC, but required a workaround in JSF. One of those things is abstracting out actions from the JSF tags, and what follows is how to do it.
Read more…

Categories: Grimoire, JSF Tags: , , , , ,

Spring ResourceBundle Property Configurer

December 4th, 2009 No comments

Spring Logo

I haz a problem!

I had a problem, as I often do with the frameworks I work on. I wanted to set properties in my spring context configuration file with externalized strings à la i18n. It seemed like a reasonable request at the time – and then I had several hours sucked out of my life by internet searches with terms like “propertyplaceholderconfigurer i18n”, “propertyplaceholderconfigurer externalized strings”, and near the end when my brain cells started committing seppuku out of loathing of whining forum posters and rage at bofh post answerers, “job openings mcdonalds”.
Read more…

Bashed!: Getting the function return as an array.

November 14th, 2009 2 comments
I want to:

You want to get an array back from a function (which exposes your underlying evil intentions)…

How the hell?
get_haxlog_types() {
    declare -a types
    types[0]="TRACE"
    types[1]="DEBUG"
    types[2]="INFO"
    types[3]="WARN"
    types[4]="ERROR"
    echo "${types[@]}"
}
logTypes=( `get_haxlog_types` )
echo "${logTypes[@]}"
echo "${logTypes[0]}"
echo "${logTypes[2]}"
WhaaaaaaAAAAA?

The above is a slightly modified function from one of my open source bash projects. To see this work, you will need to put the above into a file, and then make that file executable (like chmod 777 [filename] or some such).

There are two parts to this solution – how the function returns and how you assign output of the function to a variable. Let’s start with how the function returns. I’m going to tell you something that will blow your mind here, so try not to utter primal screams and throw various innocent electronics devices around when the light shines. Ready? The return of the function has nothing to do with this.

Yeah – do you see a “return” statement anywhere in the code snippit above? No? That’s because we are not “returning” our array values – aaaand because functions return a numerical value specifying the success or lack thereof of the function execution. In simple terms, “0” = good. Anything else = “AAAAaaaaahhhhhrrrrg!” The secret sauce of the solution to your problem is something that you are probably already doing if you’ve spent any time working with shell scripting. It’s all in the “echo”.

In a function, as in a shell script, the echo command is your best friend. Most of the time you are just echoing the value of a variable in your script in an attempt to figure out at just what point your code decided to hate you. In this case you are using the fact that the backtick command substitution will take the function name string (get_haxlog_types) and run it as a script command, which then echos the contents of the array you created within that function.

The command substitution doesn’t finish the job, however. To see why, take away the subshell parenthesis and see what you’re left with. A little setup in the example script first:

logTypes=`get_haxlog_types` 
echo "${logTypes}"
echo ${logTypes}
echo "@ = ${logTypes[@]}"
echo "0 = ${logTypes[0]}"
echo "2 = ${logTypes[2]}"

… and then run the script. I’ve called my “test” because I have no imagination:

[root@vps tmp]# ./test
TRACE DEBUG INFO WARN ERROR
TRACE DEBUG INFO WARN ERROR
@ = TRACE DEBUG INFO WARN ERROR
0 = TRACE DEBUG INFO WARN ERROR
2 = 
[root@vps tmp]#

What you’re left with is the array getting echoed in the function (echo "${types[@]}") as one long string and being assigned to the logTypes variable, which is not what we are looking for. To get the echoed string assigned out as an array variable, we use ever useful subshell to get the string filtered through the IFS (internal field separator), which then breaks the string up by the spaces and assigns the now line break (LF) delimited string to the logTypes variable as an array, rather than a single string. Exempli gratia:

The set up, now with subshell secret sauce…

logTypes=(`get_haxlog_types`) 
echo "${logTypes}"
echo ${logTypes}
echo "@ = ${logTypes[@]}"
echo "0 = ${logTypes[0]}"
echo "2 = ${logTypes[2]}"

And the results we’ve wanted:

[root@vps tmp]# ./test
TRACE
TRACE
@ = TRACE DEBUG INFO WARN ERROR
0 = TRACE
2 = INFO
[root@vps tmp]#

That’s all there is to it.

Categories: bash Tags: , , , ,

Bashed!: Assigning a directory listing to a variable

November 8th, 2009 No comments
I want to:

You need to get a directory listing into a variable so you can iterate through it and do things (horrible, unspeakable things) to the child files and directories.

How the hell?
DIRECTORY="/root/example"
dirListing=(`ls ${DIRECTORY}`)
WhaaaaaaAAAAA?

We will go over this from the inside out. First, the variable expansion ${DIRECTORY} translates to whatever you have set the variable “DIRECTORY” to. In our example, we’ve set “DIRECTORY” to an example directory I created for this little tutorial:

[root@vps ~]# mkdir example
[root@vps ~]# touch example/one
[root@vps ~]# touch example/two
[root@vps ~]# touch example/three
[root@vps ~]# touch example/four

Next, the backticks (or backquotes), eg `…`, tell the processor to treat everything in them as command line text. This is called a command substitution. This means without the backticks, ls ${DIRECTORY} is a string. Inside the backticks, it is a command.

Once the command is run, the results are run through the IFS filter (internal field separator). Since one of the characters assigned by default to the IFS variable (${IFS}) is a space, the spaces in our directory listing become delimiters, and the resulting string is broken up.

So far, we’ve got the command:

dirListing=`ls ${DIRECTORY}`

… and that seems to treat us well. The directory listing is assigned to the dirListing variable, so you would see something like this:

[root@vps /]# DIRECTORY=/tmp
[root@vps /]# dirListing=`ls ${DIRECTORY}`
[root@vps /]# echo ${dirListing}
four one three two

Notice that the string looks still to be all one line? It isn’t really – try using double quotes and you’ll see how the string is now broken up by the IFS:

[root@vps ~]# echo "${dirListing}"
four
one
three
two
[root@vps ~]#

So why aren’t we happy yet? Well, if you knew a little bit more about variable expansion in bash, you’d then realize that with the echo command, we are technically asking the shell to print out either ${dirListing} or ${dirListing[0]}. The former means the entire string assigned to the dirListing variable, and the latter means the first element of the dirListing array. If we try echoing the first element of an array however, we get this:

[root@vps ~]# echo "${dirListing[0]}"
four
one
three
two
[root@vps ~]#

The string was broken up, but unless you use double quotes to print it out, you don’t see the LF line breaks, and the entire output was assigned as a long string again – not as the array we are looking for. To get an array, we need to use a subshell. Now the subshell does quite a bit, but we are only interested in one particular effect is has on the output of delimited strings when that output is assigned to a variable. Yes, that is a VERY specific use case of subshell parenthesis! Try this:

[root@vps ~]# (`ls ${DIRECTORY}`)
-bash: four: command not found
[root@vps ~]#

In my case, “four” is the name of the first file in my “/root/tmp” directory. The subshell tried to execute it, like it is supposed to. If that file had been executable, it would have been run, and then the next file name would have been executed. We aren’t looking for execution though – we want the broken up string assigned out as an array. Let’s run the same command and this time assign the output to our variable…

[root@vps ~]# DIRECTORY="/tmp"
[root@vps ~]# dirListing=(`ls ${DIRECTORY}`)
[root@vps ~]# echo $dirListing
four
[root@vps ~]# echo ${dirListing}
four
[root@vps ~]#

Remember that using the ${…} form of variable designation actually outputs either the value of the variable or the first element of the array (eg: ${…[0]})? Looks like the we got our array output! Let’s check the next few elements to make sure:

[root@vps ~]# echo ${dirListing[1]}
one
[root@vps ~]# echo ${dirListing[2]}
three
[root@vps ~]# echo ${dirListing[3]}
two
[root@vps ~]#

See? That wasn’t so hard, was it?

Categories: bash Tags: , , , ,

Adsense Nonsense

February 12th, 2009 No comments

If you look around my humble little blog here, you are probably noticing a dearth of content.  Given that I’ve just started out in my blogging phase, something possibly every true tech head goes through, the short list of posts so far is perfectly understandable.  What is also understandable is my wish to make some kind of money off all this effort I’m putting into my literary work of vanity, a wish I took to the web in an effort to find an advertiser that would share their earning with me in exchange for some small share of real estate in my posts and on my front page.

Advertising on blogs and the like is a break-even to small comfort proposition, unless your name is Ariana Huffington.  Apparently, because I did not know this before my mental spewing venture, once you start advertising on your site, your entire existence consists of clicking the refresh button on your webalizer or statpress log pages like a rabid chain-smoking day-trader.  Actually posting  contents becomes secondary.  Given that the need to make even the small amount necessary to cover your hosting costs for your site, finding an advertising company that will both treat you right and pay you well becomes very important.  Keep those two things in mind as we go on…

After much research on the internet machine, I settled on Google Adsense.  There was a lot of information out there on their Adsense service, and even more pixels dedicated to get-rich-quick schemes using the service.  Signing up for Adsense for free and adding some JavaScript to my site and then collecting money sounded pretty good to me.  Even though I’ve just started, I’m knowledgeable enough and definitely egotistical enough to be sure that I’m going to continue adding content for a while to come, assuring me a growing number of clicks and therefor a growing check from the guys who claim the motto “Do no Evil”.   I make money.  Google makes money.  Google’s advertisers make money.  Everyone wins.

Well – no they don’t.  Let Me Explain — No, There Is Too Much.  Let Me Summarize.  I signed up for their service, got my account, created a few ads and even dared a channel.  I put the ads on my site using a WordPress plugin called Smart Ads.  After a day, the ads started matching the content on my site.  I told people about my new blog – friends, family, etc… After a week, I had about $18.00 in my account, spurring dreams of the blog actually paying for itself and possibly providing a little extra with which I could buy new tech.  I was very happy.  And then it happened.  I logged into my account one morning about a week after I opened it and I got the dreaded message:

Account Disabled

Your AdSense account for this login is currently disabled. We recommend checking your email inboxes for any messages we may have sent you regarding your account status. Sometimes our messages can be caught by email filters, so please be sure to check the Bulk/Spam folders of your email accounts as well. If your account was disabled for invalid click activity, please visit our Disabled Account FAQ for more information.

Well.  That sucks.

I Did What?

After the initial shock, my brain kicked into overdrive to asses the situation, running through hundreds – nay, thousands of options which streamed in front of me terminator HUD style, each being evaluated against a laundry list of variables to determine the exact cause of my embarrassment.  Only one conclusion rose to the top of my full statistical analysis of all the possible vectors.  That conclusion: “What the hell!?!”

Next stop was my email account, in which I found this wonderfully helpful missive…

While going through our records recently, we found that your AdSense account has posed a significant risk to our AdWords advertisers. Since keeping your account in our publisher network may financially damage our advertisers in the future, we’ve decided to disable your account.

Please understand that we consider this a necessary step to protect the interests of both our advertisers and our other AdSense publishers. We realize the inconvenience this may cause you, and we thank you in advance for your understanding and cooperation.

If you have any questions about your account or the actions we’ve taken, please do not reply to this email. You can find more information by visiting https://www.google.com/adsense/support/bin/answer.py?answer=57153&hl=en_US.

Sincerely,

The Google AdSense Team

You’re kidding me…  This site?  MyTechHell.com?  What was the significant risk? – that they might learn something about hardware?  Is the Java language anathema to the advertisers?  To quote one great American cartoon character – “What did I did wrong?”

Having exhausted my almost non-existent knowledge on the subject of getting rejected by online advertising companies, I turned once again to the internet machine to find solace and an answer as to how to remove the scarlet “R” from my account.  On my first page of results, however, I found a whole different story.  Go ahead – do a search with the words “adsense account disabled” and see what comes up.  You’ll find exactly what I did: Google seems to be running a grift of epic proportions.

They’re Doing What?!?

For the most part, you can figure out a lot by taking a look at the information on adsenseaccountdisabled.com.  The gist of that site and other sites, blog entries, and forums is that Google will suddenly and without warning cancel people’s accounts in what seems to be a completely arbitrary fashion.  In my case, this website was approved for an account, and a week later they suddenly found that it violated their T&C (Terms and Conditions).  The difference between when they approved my site and disapproved of it?  One post.  A post reviewing a Logitech Mouse.  I already knew that Google uses pidgeons to rank web pages,   but could it be that they are using cats to manage their Adsense business?

cat-on-computer funny_cat_pictures_pc_2

It is a sad fact that by all accounts, only about one percent of those so ejected from Adsense are ever allowed to return.  Using the link included in your rejection letter to get the appeal form is almost worthless given this statistic.  Even worse, most people have no idea what they did to incur Google’s wrath.  Oh, I’m sure there are a lot of people who say they didn’t do anything while they shut down their auto-click applications, but it is statistically improbably that the number of site owners having this problem would all turn out to be click fraudsters or porn magnates, and the only answer anyone has ever gotten from Google is this:

Because we have a need to protect our proprietary detection system, we’re unable to provide our publishers with any information about their account activity, including any web pages, users, or third-party services that may have been involved.

Riiiiggggghhhht…  So Google thinks my website is somehow harmful to their advertisers (even though they approved my site only a week before), but they can’t tell me exactly what they found that was considered harmful, and whatever it was was so egregious an affront to their terms of service that no warning was given before termination.  Oh – wait… I forgot.  There’s no evidence anywhere on the ‘net that warnings are ever given.  It’s the equivalent of telling someone out of the blue that they’ve broken the law and sending them directly to death row.

So here I am, a user of a great many of Google’s wares including Chrome, gmail, search engine (of course!), etc…  and yet as far as their advertising department is concerned, I’m a depraved villain trying to take their money.  Well, I’ve got three questions for them that they will probably never answer.

  1. If you can detect fraudulent clicks, why aren’t you just filtering them out?
  2. How in the name of all that is good and pure does one click on an ad on your own site constitute enough click fraud to dole out the same punishment you apply to people who spend years creating systems to hide thousands of fraudulent clicks a day from you to scam you out of thousands of dollars a month?
  3. I know you want to protect your “algorithm” (who’s name is probably Mrs. Whiskers) from the world at large, but what the hell did you find so offensive on a site about technology???

Keep in mind that I did not fall into the “click fraud” category.  I was summarily accused of posing “a significant risk to [Google’s] AdWords advertisers.”  Even if the risk was that I did not have enough content yet, I’d be fine with that (and very busy for the next few weeks), but there’s no way to tell what the problem could possibly be.

Where’s My Check?

And people are loosing major money because of this problem.  I lost $18.xx dollars.  Not enough for me to cry over, but there are stories on the ‘net about people loosing their accounts with thousands of dollars in them, and suspiciously, they almost without fail seem to have their account yanked only a day or two before a check is supposed to be cut.  Even more suspiciously is where that money supposedly goes.  Let’s go back to Google’s “You’re Screwed” FAQ:

According to our Terms and Conditions, publishers disabled for invalid click activity may not receive any further payment. The earnings on your account will be properly returned to the affected advertisers.

Please also note that we place stop payments on any outstanding checks for accounts that have been disabled for invalid click activity. We ask that you refrain from depositing any checks you may receive in the future, as your bank may charge fees for depositing a stopped check.

I challenge anyone reading this to find one advertiser that actually got a refund check or had their fees reduced due to click fraud.  It would seem no one on the ‘net can find one, with several helpful Adclick users chiming in that they’ve never seen a penny returned to them for anything.  What’s more, if Google can determine click fraud so swiftly that the advertisers are never charged for invalid clicks, then what’s the deal with disabling accounts where one or two misplaced clicks occurred?  I have two cats that live with me that love walking over keyboards, and sometimes I’d like to verify what the ads placed on my site are linking to, and several other reasons why canceling for even a click or two a day is absolutely ludicrous.

I Has A Sad…

This whole post may constitute a long, drawn-out rant, but considering the sheer number of people having the same problem, I feel that adding my voice to theirs can only help to keep bubbling this problem up to the top of the general consciousness, and hopefully spur someone who can actually do something about it (Lawyers? Start your class action lawsuit engines!), to call Google Adsense what it’s starting to look like – a major scam.

In the end, for me at least, what really galls me is that I have been accused of doing “wrong” when I do my very best to be a good netizen.  Even given all the evidence that Google is doing this to thousands of people and by all maths, making a LOT of money off of it, I still get a twinge thinking that just maybe I really did do something wrong.  Hopefully this “problem” with Adsense will be corrected in the near future and give me a little vindication, but then again, the posts on the ‘net go back as early as 2006, so I’m not going to hold my breath.  If you are reading this, I’d think long and hard before I signed up for Adsense, because there’s a good chance you’ll get that apologetic email and most likely right when you’re about to collect a check you were really counting on.

And now, for your clicking pleasure, here are a list of links to the sites I found most informative on this subject:

Addendum

I foolishly tried to get reinstated.  Google says to expect a reply up to 48 hours from when you submit your “I did what?” query.  I got mine a little under the 72 hour mark, and what a surprise:

Hello,

Thanks for providing us with additional information. However, after thoroughly reviewing your account data and taking your feedback into consideration, we’ve re-confirmed that your account poses a significant risk to our advertisers. For this reason, we’re unable to reinstate your account. Thank you for your understanding.

As a reminder, if you have any questions about your account or the actions we’ve taken, please do not reply to this email. You can find more information by visiting https://www.google.com/adsense/support/bin/answer.py?answer=57153.

Do they realise what kind of animosity they are engendering on the ‘net with whatever secret policy they are using to cancel our accounts?

Categories: Blogging Tags: , , ,