Saturday, August 27, 2011

Chrome.gwt - Building Chrome Extensions using GWT

As some of you might already noticed before, I'm not a big fan of JavaScript. Although I'm impressed by what is possible with JavaScript I don't like the rest of JavaScript... (yet!) :)

Still, I'm getting more and more interested in developing web apps or Chrome extensions. Fortunately, there's GWT.


If you don't know GWT yet, I very much recommend you to read the documentation and try the samples yourself first. You need to understand at least the basics of GWT, like what it does, how you configure it and what you get from GWT...

Ok, let's start. I've put up a simple sample at GitHub. So, if you don't want to read through the whole post feel free to skip ahead to GitHub here, for the GWT part of the sample, and here, for the AppEngine part (which is actually not related to the "Building Chrome Extensions using GWT").

Start by creating a GWT project in Eclipse. To keep it simple, create a new "Web Application Project", put the usual stuff in there and uncheck "Use Google App Engine". All we need for now is the Google Web Toolkit.


If you told the New Project Wizard to create a sample code for you, you're almost done. Now you just need to put the usual manifest.json into your new project's "war" directory. You can tell Chrome using your manifest which files to use. For example, I told it to serve a html file within the "war" directory, which linked to the actual JavaScript created by GWT in "war/*/*.nocache.js" after you hit the "Compile GWT" button.

However, you could easily tell Chrome to use the generated *.nocache.js file as a contentscript.

If you still have no idea what I'm talking about, I suggest you to browse through the sample's repository. It's a really easy sample without too much extras.

That's it! You're almost done! Now open Chrome's extension page, unfold "Developer Tools" and "Load unpacked extension...". Navigate to your project and load the "war" folder.

Now... That's it (this time for real)!

Further improvements
So far this was a really basic usage of GWT's capabilities. If you want to expand this sample and take advantage of Chrome's APIs without writing JSNI I suggest you to take a look at gwt-chrome. Also, I'm sure you can find some interesting bits in the SpeedTracer source (yes, it's built using GWT, too!).

Friday, August 19, 2011

Bloki - Crowdsourced typo fixjng

One week after submitting my first ever news to HackerNews and enjoying the massive traffic it's generating I'm happy to announce the second iteration of Bloki. It's now, after skipping two versions internally, at v004, which is most probably a pretty stupid version numbering scheme. At least until we reach the 7th iteration... (007, get it?)

The first thing you'll notice: It doesn't use ugly JavaScript methods like alert(); and prompt(); anymore. Instead, it's now powered by GWT - which I can tell you is awesome sauce after playing with it for a few days.
Another change - in fact the most important - is that it's now possible for you to include Bloki on every website. It's really, really easy. Sign up and include a two easy lines of code into your HTML. That's it. Also, we have various designs up for you, made by Martin Baumgart. You can find all of them in the gallery. I'm using the UserVoice.com style on this blog...

If you experience any problems, or even better, have any suggestions, feel free to mail me or submit an issue at GitHub.

Enough blabla! Head over to bloki-engine.tomtasche.at and sign up for Bloki! It's free! Or read more about it, how it works, what it looks like and how to integrate it into your blog at bloki.tomtasche.at

Thursday, August 11, 2011

What's new in Java 7?

Besides Java 7 breaking huge projects like Apache Solr and others, Java 7 also brings a few little big features making it even easier and more comfortable to use.

Finally! Use strings in a switch
https://gist.github.com/1139335

Auto-close readers, streams, etc.
https://gist.github.com/1139442


Multi-catches
https://gist.github.com/1139447


Thanks Sebastian for introducing me to Java 7. :)


Further reading

Track your app's ranking in Android Market

If you want to keep track of your app's ranking in Android Market you should check out AndroidAppTracker.com. You can sign up for regular updates about your app's ranking and watch your apps slide the Market's ranking up and down every day.
Also, you'll receive updates about new comments and the like.

There's also a "Keyword tracker" for pro users, but I don't have a credit card so that's yet another product I can't purchase although it sounds pretty interesting and useful...

CSS Hackeria

Add text using CSS
https://gist.github.com/1139319

There's also an :after pseudo-class.

Read more about this nifty trick here.

Positioning in CSS for noobs (like me)
Another trick I needed to learn in order to build Bloki is positioning a div in a corner. I asked my friend, who's some kind of CSS / HTML / JavaScript expert, Thomas Jirout about some advice and here's what he told me how to do it: https://gist.github.com/1139321


Damn, that's simple!

Eclipse stuck while deploying to AppEngine

If Eclipse gets stuck in the middle of the deployment process open your command line and do this (in Ubuntu):
'.eclipse/org.eclipse.platform_WEIRD_NUMBERS/plugins/com.google.appengine.eclipse.sdkbundle_MORE_WEIRD_NUMBERS/appengine-java-sdk-VERSION/bin/appcfg.sh' rollback '/home/tom/PATH_TO_YOUR_PROJECT/war/'

Enter your mail address + password and you're good to go.

Wednesday, August 10, 2011

Ads, mobs and a fox - AdMob vs. MobFox

I'm now running MobFox ads in Announcify for less than a week, but I think I already know all you need to know about this service. Let's look at the facts:
MobFox is a one-man-company dedicated to mobile advertising. Also, it's based in Vienna. That's a big plus because I prefer things that come from Austria. But the plus doesn't seem to be big enough for MobFox...

Size
Talking about jar-sizes they're almost head on head. AdMob: ~50kB, MobFox: ~30kB. I don't care much about that 20kB. Do you?

Implementation
MobFox's instructions for how to implement their ads on Android are faulty. Really.

If you're an experienced developer that's definitely not a problem for you, but I guess some beginners could despair at this point. AdMob on the other hand offers docs, READMEs, FAQs and step-by-step guides too. AdMob.score++

Web Interface
MobFox's web interface looks... like... erm... AdMob's. Ok, there's nothing really bad about that. Most websites look identically. I'm just saying...

MobFox eCPMcontrol
"Only serve CPC ads that pay a minimum of $ X per click." and "Only serve CPM ads that pay a minimum of $ X per thousand impressions.". Do I need to explain that any further?

MobFox Backfill
The idea about MobFox Backfill is simple: If they don't have any ads to show which meet your requirements (eCPMcontrol...), they fetch one from AdMob or a few other ad networks. Sounds like a good idea, but it isn't.

MobFox eCPMcontrol + Backfill != money++
My experience was like that: I enabled eCPMcontrol and set it to the average recommended values. $0.10 CPC, $1 CPM. Until then I had a few thousand impressions and something like $0.30 a day. The next day I reviewed the statistics eCPMcontrol already took traction: 500 impressions and $0 a day. Cool! Er, wait!? That's actually pretty bad. Ok, no problem. MobFox Backfill and therefore AdMob to the rescue! Nope. No rescue for you. MobFox does indeed fetch ads from AdMob, but displays only the ad's text. No graphics. Why should users click on boring plain text ads (like I do have here on my blog! ;))? Also, they display a little "MobFox" at the right side. Is this legal?

Update: After some more fiddling with both AdMob and MobFox at work I think MobFox is better than it sounds in the paragraph above. For example, AdMob's fill rate is at something like 40% lately. It was as high as 90% before. If I used MobFox the chance for actually receiving an ad would be a lot higher. However, remember how MobFox displays AdMob's ads...

Money
So, MobFox didn't make me sing "A Milli" like Lil' Wayne did after he earned his first million dollars. Did AdMob? No. Announcify is an app you open once or twice a month (or even less!) and forget about the rest of your time. It's very unlikely you click ads in this app. However, running AdMob brought me $0.20 a day. That's at least something if you earn it everyday without doing anything for it.

Conclusion
I'm sure this post sounds a little confusing, but it really depends on your situation which ad network fits your needs better. If your app's audience is mainly from Austria you're definitely good to go with MobFox.
Also, if MobFox didn't display AdMob's so strange I would recommend it to everyone. Maybe Mr. MobFox reads this post and considers changing this part of MobFox?

Oh, and if you want to sign up for MobFox (I guess it's always worth a try) please sign up using this link so I get some cookies for free. :)

Alternatives
Here's a pretty extensive comparison of ad networks out there, compiled by the company I'm working for, customLBS. Keep in mind that values like CPC and eCPM vary depending on time, location and your application itself.

An essay written by Google's server.

At first let me clarify that this is not a fake. I didn't write this essay. It was Google's almighty brain. You know, the one which knows everything about you, your interests and so on...
All I did is helping Google find a good beginning (I thought introducing himself would be a good beginning so I told me to start with "Hello, my name is") and giving him a helping hand when he hangs himself. The rest originates from Google's very own scribe...

Please forgive Google any mistakes. It's still learning from the bazillion queries you send him every day.
Also, it seems like Google's keyboard lags a little bit. It doesn't get that space thing right every now and then. Forgive him, please.

(Read more about how this was done and how you can get more of it after Google's dramatic essay...)

Here's what Google has to say:

"Hello, my name is not only annoying but also their own personality and style of their own and others working in their own rights and their protection from the elements and their compounds are not available for these purposes is the same assumptions as in theorem 1 is that there isn'ta single person in their lifetimes and their families into their own hands and feet and then they will become more apparent from the following descriptions of these two types of databases and their associated costs and benefits often are not aware of anything that is not there anymore and I'm really nothing to do without them and I'm really nothing to do without them and I'm really nothing to do without them and I'm not really sure what to download and installed them into their own hands and feet and then they will become more apparent from the following descriptions of these two types of databases and their associated costs and benefits often are not aware of anything that is not there anymore and I'm for sure that they arent going to be able toprovide and then they will become more apparent from the following descriptions of these two types of databases and their associated costs and benefits often are not aware of anything that is not there anymore and I'm always looking for news on their websites and blogs which mention or quote Davidenkov and then they will become more apparent from the following descriptions of these two types of databases and their associated costs and benefits often are not aware of anything that is not there anymore and I'm hanging out with friends and family.It is found in their study of these two types of databases and their associated costs and benefits often are not aware of anything that is not there anymore and I'm done with them and they are nothing but another form of therapy for these patients is not known whether these are the only ones whose names are not case sensitive and must be able to getting them to work within their own communities and their membership in their own rights and their protection from the elements and their compounds are not available for these purposes is the same assumptions as in theorem 1 is that there isn'ta..."

Ok, let's stop here. That's an A+ for sure, Google! :)

You want Google to write an essay for you too? No problem! Get yours at essayfromgoogle.tomtasche.at. Hurry up before Google bans me.

Source code is available at GitHub, including a desktop version.

PS: Congratulations for graduating from Google Labs, Google Scribe!

Saturday, August 6, 2011

GWT - Little big things you should know

This week I rewrote Bloki from scratch. Instead of using JavaScript like before, I'm now using pure GWT and AppEngine power. That's a really, really powerful combination, but you need to invest some time in order to get used to it.

Renaming files in GWT is a dangerous task
I already faced the first big problem after renaming the sample code. I didn't have a clue how *.gwt.xml and my code were linked to each other and what that file did. Also, Eclipse seems not to recognize renaming of these files properly. ("[ERROR] Unable to find '*.gwt.xml' on your classpath; could be a typo, or maybe you forgot to include a classpath entry for source?") You need to delete the project's run configuration everytime you renamed your *.gwt.xml. Annoying, but not a big problem if you know that trick. You don't rename your *.gwt.xml every now and then anyway...

Accessing the page's body
When searching for a solution for this problem I discovered another really cool feature of GWT: native methods. JavaScript in your Java files! It looks like this: https://gist.github.com/1129229

That's a powerful tool you should keep in mind when developing with GWT.

However, today I came across a cleaner solution, without any native methods: https://gist.github.com/1129232

Yet another method to access a page's body I just came across: https://gist.github.com/1131533
Including your GWT widget in a foreign website
That's something inevitable for Bloki, since it's meant to be integrated easily into whatever website you want. So, what's the problem here? GWT blocks access from foreign websites to your compiled JavaScript. I'm not sure why, but fixing it is easy. All you need to do is to insert this line into your *.gwt.xml:
<add-linker name="xs"></add-linker>

Now you're able to link to your JavaScript from foreign websites like this: https://gist.github.com/1123625

GWT overrides my stylesheets
This immediately lead me to the next problem (ugh, sounds like working with GWT is only about solving such problems). GWT insists to override your website's CSS, no matter at which point you insert GWT's script. Working around this issue isn't that easy...

Assuming you used GWT's chrome theme before, delete the line applying the theme and insert this line instead:
<inherits name="com.google.gwt.user.theme.chrome.ChromeResources></inherits>

Now you need to include the needed GWT stylesheet yourself, before (!) you apply your own styles...

<link href="http://bloki-engine.appspot.com/submit/gwt/chrome/chrome.css" rel="stylesheet" type="text/css"></link>

Autohide DialogBox
One more tip Bartinger told me about: new DialogBox(true); and it'll hide itself when you click outside the dialog. Handy!

Finished! :D I hope to continue this kind of blog post on a regular base...

Friday, August 5, 2011

Ubuntu: /home doesn't mount at boot anymore

Yesterday was a usual day: I went to work, turned on my laptop, typed in my password and Ubuntu rejected to mount /home. Err...?

After fiddling around with /etc/fstab and the like my boss suggested to try fsck.
sudo fsck /dev/sda5

"Fix file Y?", yes. "Fix file Z", yes. This went on for a few dozen files and finally I rebooted my laptop and everything was fine again.
However, beware of this operation! In my case a few installers, like Plants vs. Zombies, went missing ( :( !). If you care about all your files, do a backup first.

Oh, I hear some of you asking "How the hell is that possible when the /home partition isn't mounted?"...
sudo mkdir /media/home; sudo mount /dev/sdaX /media/home

And how to find out the partition's number (sdaX)? Either use gparted or sudo fdisk -l

Oh, and if you aren't able to start your terminal with a keyboard shortcut (like CTRL+ALT+T) press CTRL+ALT+F1 and you're in. Good luck!