Container types

During a discussion with Konrad Malawski about typesystems.

Consider a Fruit.

class Fruit {}

There are different kinds of fruit. Explicitly:

Fruit<E> {}

So far so good.

Fruit<Apple> apple;  
Fruit<Orange> orange;

Which allows:

apple.compareTo(orange) 

Does this make sense? Well, no 🙂 What to do? Well, Types to the rescue.

Dear types, please make comparing Fruits of different kinds illegal.
The types listen, and respond. Or actually it’s already in the JDK.
java.lang.Enum, which does

class Enum<E extends Enum<E>>

Generalizing

class Container<Type extends Container<Type>>
	
Why? To save the types. Applied to the example:
class Fruit<E extends <Fruit<E>> {}  

now makes

orange.compareTo(apple)

illegal. As expected and while still in Java.

JavaONE, day zero

It’s the best JavaONE I’ve been to so far 🙂
Where to begin.. well, lots of friends and faces, even more people I don’t know. And since Oracle OpenWorld takes place at the same time,
city is redecorated to look like an Oracle stronghold (cabs, buses, streetposts have Oracle ads). It is an experience.

My and Konrad’s session went well, we had a full room with not a single chair to spare.
Slides are up on SlideShare or just below

More news after the event, there is SO MUCH happening in here all at once, I wish I could bi- or tri- locate. 🙂

ps. Apparently, if I link to OTN from my blog, I will get a t-shirt, the choice was obvious. 😀

Autumn = fun, fun, fun!

Yay, I’m going to JavaONE. But it’s actually a bit better, since I’m actually speaking there! (Together with Konrad) a session called Java 8: The Good Parts [UGF10520].
That’s a news of its own, but it gets better! So, altogether, there is:

Should be a lot of fun, see you there!

Git – push to multiple remotes

Once upon a time, there comes a need to push to multiple remotes.
This time.. it’s because of Jacek Laskowski.
Specifically, this tweet:

And well, let’s see.

[00:48][ags@ags-mbpro:~/temp/git_for_jacek]
$ git init repo1 --bare
Initialized empty Git repository in /Users/ags/temp/git_for_jacek/repo1/
$ git init repo2 --bare
Initialized empty Git repository in /Users/ags/temp/git_for_jacek/repo2/
$ git init repo_base
Initialized empty Git repository in /Users/ags/temp/git_for_jacek/repo_base/.git/
$ cd repo_base/
[00:48][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git remote add dla_jacka file:///Users/ags/temp/git_for_jacek/repo1
$ git remote help
error: Unknown subcommand: help
usage: git remote [-v | --verbose]
   or: git remote add [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url>
   or: git remote set-url [--push] <name> <newurl> [<oldurl>]
   or: git remote set-url --add <name> <newurl>
   or: git remote set-url --delete <name> <url>
[00:49][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git remote show dla_jacka 
* remote dla_jacka
  Fetch URL: file:///Users/ags/temp/git_for_jacek/repo1
  Push  URL: file:///Users/ags/temp/git_for_jacek/repo1
  HEAD branch: (unknown)
[00:50][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git remote set-url dla_jacka --push --add file:///Users/ags/temp/git_for_jacek/repo2
$ git remote -v show
dla_jacka	file:///Users/ags/temp/git_for_jacek/repo1 (fetch)
dla_jacka	file:///Users/ags/temp/git_for_jacek/repo2 (push)

Not exactly right, again.

[00:51][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git remote set-url dla_jacka --push --add file:///Users/ags/temp/git_for_jacek/repo1
[00:52][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git remote -v show
dla_jacka	file:///Users/ags/temp/git_for_jacek/repo1 (fetch)
dla_jacka	file:///Users/ags/temp/git_for_jacek/repo2 (push)
dla_jacka	file:///Users/ags/temp/git_for_jacek/repo1 (push)

Hmm, seems like it’s what I need. Let’s try!

[00:52][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ touch test
[00:52][ags@ags-mbpro:~/temp/git_for_jacek/repo_base]
$ git add test
$ git commit -m "first commit, to check things"
[master (root-commit) 39d428d] first commit, to check things
 0 files changed
 create mode 100644 test

Empty file ready, let’s push!

[00:52][ags@ags-mbpro:~/temp/git_for_jacek/repo_base(master)]
$ git push dla_jacka master
Counting objects: 3, done.
Writing objects: 100% (3/3), 224 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To file:///Users/ags/temp/git_for_jacek/repo2
 * [new branch]      master -> master
Counting objects: 3, done.
Writing objects: 100% (3/3), 224 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To file:///Users/ags/temp/git_for_jacek/repo1
 * [new branch]      master -> master

Bang, works 🙂

Proguard, jdk7 and OS X

[INFO] ------------------------------------------------------------------------
[INFO] Building XClient 1.2.34-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ xclient ---
[INFO] Deleting /Users/ags/vcs/paysforblogging/XClient/target
[INFO] 
[INFO] (...)
[INFO] (...)
[INFO] (...)
[INFO] (...)
[INFO] --- android-maven-plugin:3.3.2:proguard (default-proguard) @ xclient ---
[INFO] (...)
[INFO] java.io.IOException: Can't read [/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home/Classes/classes.jar] (No such file or directory)

No such? I’m using Oracle JDK, should work. Let’s see.

cd /Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home
cd Classes/: No such file or directory

Ah, ok, seems we’re not going the old OSX way of putting things inside JDK anymore.

mkdir Classes
cd Classes
sudo ln -s ../jre/lib/rt.jar classes.jar
sudo ln -s ../jre/lib/jsse.jar 
sudo ln -s ../jre/lib/jce.jar 
[03:18][ags@ags-mbpro:/Library/Java/JavaVirtualMachines/jdk1.7.0_09.jdk/Contents/Home/Classes]
$ ls -al
total 24
drwxr-xr-x   5 root  wheel  170 Nov  2 17:42 ./
drwxrwxr-x  16 root  wheel  544 Nov  2 17:19 ../
lrwxr-xr-x   1 root  wheel   17 Nov  2 17:38 classes.jar@ -> ../jre/lib/rt.jar
lrwxr-xr-x   1 root  wheel   18 Nov  2 17:42 jce.jar@ -> ../jre/lib/jce.jar
lrwxr-xr-x   1 root  wheel   19 Nov  2 17:40 jsse.jar@ -> ../jre/lib/jsse.jar

And.. works!

After jdd 2k12

Once again, I’ve been to JDD.
Sixth time out of seven (I like saying I’ve been to all Krakow editions, since 2nd took place far from the city centre).
This year’s event started with mine and Marcin Sawicki‘s Jenkins and Continuous Delivery workshop. We wanted to show how and where to use Jenkins for the greater good and world peace.
Judging from feedback, we succeeded. Even though faulty network forced us to change plans and improvise a bit.

On Thursday, I’ve visited almost all the lectures I wanted. “Catcher in the Code” by Paweł Badeński, a noteworthy talk about telling a story with code. I really admire the way in which Paweł talks from such a huge perspective. Before that was Jarek Pałka’s “Deconstruction of Architecture”. It’s obvious Jarek experiences the same
pain I express as “I hate computers”. Another good thing to see.

I also enjoyed MetaYoda‘s Meta Cloud Architecture talk.
As much as it contained more than a few buzzwords, it didn’t put me off, especially as I had a conversation
with the speaker on the next day.

Then came Friday, day during which I talked in the lobby more and visited talks less.
The only talk I’ve seen in full was “Git Happens” by Jessica Kerr.
I’ve presented Git the previous year (together with Konrad Malawski),
but IMHO Jessica’s way was a bit more interesting, even though it explained basics. In a lively (jumping!), colourful way,
which maybe is what a git talk should include.

It was a good conference. Lots of interesting people met, some very solid talks, all very inspiring.
I definitely enjoyed it and will try to come next year as well. 🙂

I just put Jelly Bean on my Nexus on Ubuntu

Here’s how. First, you need Android SDK installed and maybe this
Warning, this WILL clear your data.


wget http://dl.google.com/android/android-sdk_r20.0.3-linux.tgz
tar xvf  android-sdk_r20.0.3-linux.tgz
mkdir -p ~/opt/sdk
mv android-sdk-linux ~/opt/sdk/android-sdk
export PATH= /home/abc/opt/sdk/android-sdk/platform-tools
fastboot devices

Your device, connected via USB and with debugging enabled, should be listed.

cd ~/downloads/
wget https://dl.google.com/dl/android/aosp/yakju-imm76i-factory-8001e72f.tgz
tar -xzf yakju-imm76i-factory-8001e72f.tgz
cd yakju-imm76i
sudo fastboot oem unlock
sudo ./flash-all.sh

wait, wait, boom, works 😀

sudo fastboot oem lock

Debugging NetBeans RCP from IntelliJ

Netbeans rocks, especially as it becomes more and more like IntelliJ 😉

The story: NB RCP app, converted to use maven, developed mostly in IntelliJ (with the exception of GUI screens, which go through Matisse).
It’s runnable, it works, but there’s one glitch: debugging only seems to work from inside NetBeans. Should be easy, nbm plugin manual tells what to do here.
Let’s create a Run Configuration, add params, should work, right?

 and 

And it works! Well, almost, or up to the point where VM complains and quits.

1
2
3
4
5
6
7
8
[INFO] --- nbm-maven-plugin:3.7:run-platform (default-cli) @ application ---
[INFO] Executing:
/bin/sh -c /Users/ags/vcs/work/trololo-code/client/application/target/trololo_client/bin/trololo_client
--userdir /Users/ags/vcs/work/trololo-code/client/application/target/userdir
-J-Dnetbeans.logger.console=true -J-ea --branding trololo_client
-J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=n,server=n,address=8888
[INFO] Invalid memory access of location 0x0 rip=0x7fff958af540
[INFO] ERROR: transport error 202: connect failed: Connection refused

But it works under NetBeans, and it uses the same parameters and it’s Java and.. WTF?!
What does netbeans exactly do for debugging?


NetBeans: JPDA Listening Start...
JPDA Address: ags-mbpro.local:54019
Port:54019
cd /Users/ags/vcs/work/trololo-code/client/application;
JAVA_HOME=/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
"/Applications/NetBeans/NetBeans 7.2.app/Contents/Resources/NetBeans/java/maven/bin/mvn"
-Djpda.listen=true
"-Dnetbeans.run.params.ide=-J-Xdebug -J-Xrunjdwp:transport=dt_socket,suspend=n,server=n,address=54019"
-Djpda.address=54019 nbm:cluster-app nbm:run-platform

Of course our parameters are correct, running the same command from the command line doesn’t give anything. So the glitch must somewhere else… or. It’s right here, in the very beginning!

NetBeans: JPDA Listening Start...
JPDA Address: ags-mbpro.local:54019
Port:54019

NetBeans starts listening on for debugger BEFORE it runs RCP. Idea can do that too, but by default it wants to connect to a socket. So the easiest way it change it to Listen and start before running the app (meh).

Or change server to y. That’s my preferred way (at least since quite some time).

-J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=n,server=y,address=8888

ubuntu 12.04 android sdk fun

Jenkins says:
[INFO] /bin/sh: 1: /home/jenkins/opt/sdk/android-sdk/platform-tools/aapt: not found
[ERROR] Error when generating sources.
org.apache.maven.plugin.MojoExecutionException:

Ehm.. ok.

cd /home/jenkins/opt/sdk/android-sdk/platform-tools/
root@javaone:/home/jenkins/opt/sdk/android-sdk/platform-tools# ls -al
total 23204
drwxrwxr-x 5 jenkins jenkins 4096 Jul 4 13:39 .
drwxr-x--- 12 jenkins jenkins 4096 Jul 4 13:41 ..
-rw-rw-r-- 1 jenkins jenkins 401602 Jul 4 13:39 NOTICE.txt
-rwxrwxr-x 1 jenkins jenkins 929144 Jul 4 13:39 aapt
-rwxrwxr-x 1 jenkins jenkins 204436 Jul 4 13:39 adb
-rwxrwxr-x 1 jenkins jenkins 226004 Jul 4 13:39 aidl
(...)
root@javaone:/home/jenkins/opt/sdk/android-sdk/platform-tools# ./aapt
bash: ./aapt: No such file or directory
root@javaone:/home/jenkins/opt/sdk/android-sdk/platform-tools#

Ok, now WTF?!

root@javaone:/home/jenkins/opt/sdk/android-sdk/platform-tools# file aapt
aapt: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped

Gotcha! 32bit. ia32-libs does this, right?

root@javaone:~# apt-get install ia32-libs
Some packages could not be installed. (...)

The following packages have unmet dependencies:
 ia32-libs : Depends: ia32-libs-multiarch
E: Unable to correct problems, you have held broken packages.

Oh no, you don't!

root@javaone:~# apt-get install ia32-libs-multiarch
Some packages could not be installed. (..)
The following packages have unmet dependencies:
 ia32-libs-multiarch:i386 : Depends: libgphoto2-2:i386 but it is not going to be installed
 Depends: libsane:i386 but it is not going to be installed
 E: Unable to correct problems, you have held broken packages.
 root@javaone:~# apt-get install libgphoto2-2:i386 libsane:i386

 Some packages could not be installed. (..)

The following packages have unmet dependencies:
 libgphoto2-2:i386 : Depends: libgd2-xpm:i386 (>= 2.0.36~rc1~dfsg) but it is not going to be installed
 E: Unable to correct problems, you have held broken packages.
 root@javaone:~# apt-get install libgd2-xpm:i386

 The following extra packages will be installed:
 gcc-4.6-base:i386 libc6:i386 libexpat1:i386 libfontconfig1:i386 libfreetype6:i386 libgcc1:i386 libgd2-xpm libjpeg-turbo8:i386 libjpeg8:i386 libpng12-0:i386 libx11-6:i386 libxau6:i386 libxcb1:i386
 libxdmcp6:i386 libxpm4:i386 zlib1g:i386
 Suggested packages:
 glibc-doc:i386 locales:i386 libgd-tools libgd-tools:i386
 The following NEW packages will be installed:
 gcc-4.6-base:i386 libc6:i386 libexpat1:i386 libfontconfig1:i386 libfreetype6:i386 libgcc1:i386 libgd2-xpm libgd2-xpm:i386 libjpeg-turbo8:i386 libjpeg8:i386 libpng12-0:i386 libx11-6:i386
 libxau6:i386 libxcb1:i386 libxdmcp6:i386 libxpm4:i386 zlib1g:i386
 0 upgraded, 17 newly installed, 3 to remove and 3 not upgraded.

Ok, a few minutes later I could do a:

apt-get --no-install-recommends install ia32-libs-multiarch

And..

root@javaone:/home/jenkins/opt/sdk/android-sdk/platform-tools# ./aapt
<pre><pre>Android Asset Packaging Tool

Usage:
 aapt l[ist] [-v] [-a] file.{zip,jar,apk}
 List contents of Zip-compatible archive.

It works. Let's make a chef out of it and be happy 🙂