# Tuesday, September 09, 2008

S60 Sucks, The phone rulez

S60 is a software platform for mobile phones, running on Symbian OS.
I have to work with it since I got my new Nokia E71.
Well I don't know if it's Symbian or S60, but I don't like it.

First, I can't save my laptop as a trusted bluetooth device. So it asks me on every single operation if my laptop is trusted. WTF? My previous phone could do that.
Second, I can't see my IP while in a wireless connection. No such option. This is important to me.
Third, I can't find the control panel which is for the keyboard layouts installed. WTF? I can't find the control panel for bluetooth. I can't find the control panel for anything.
Fourth, the Cyrillic language layout is really weird. Yea, ok, it's actually Russian, but still, it's weird.
   MTEL, YOU BASTARDOS, MAKE A BULGARIAN PHONE, YOU LAZY FUCKERS, FOR ONCE DO SOMETHING ON YOUR OWN AND DO IT RIGHT.
Fifth, I can't get the flash card and plug it in, the phone has to be restarted. WTF? My previous phone could do that.
Sixth, The phone crashes too often. At least it reboots fast and goes right in the menu where it crashed. This is nice.
Seventh, I can't use the Cyrillic capital characters of М, Н, О, П in my address book, since the Address book crashes. It cannot list them, but the quick search works. WTF? My previous phone worked perfectly with Cyrrilic.
   Now my whole Address Book is in Latin. I don't like that. I want to use Cyrrilic. I'm really dissapointed.
Eighth, The software for editing the address book sucks. It's slow. Opening a contact list - 3-4 seconds. Saving it - 4-5 seconds. WTF?


These are the bad things, and they are driving me crazy. I'm waiting for an update. This is an example how Nokia can skrew such a nice phone with such a stupid OS.Do
Don't get me wrong I don't regret bying this phone and I'll find a way around all those things.
# Saturday, September 06, 2008

My new Nokia E71 is finally here.

I'm using it to post this now

Unfortunately, I have to write html again. I'm using Opera Mini. There's no proofing, no copy/paste in Opera. The phone is amazing, the GPS is outstanding. I can't write more now, this interface sucks.

# Thursday, September 04, 2008

java.lang.Throwable, the "... 3 more" case, how to read it

We have the following:
(The code is taken from here http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Throwable.html#printStackTrace())
HighLevelException: MidLevelException: LowLevelException
    at Junk.a(Junk.java:14)
    at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
    at Junk.c(Junk.java:24)
    at Junk.b(Junk.java:18)
    at Junk.a(Junk.java:12)
    ... 1 more
Caused by: LowLevelException
    at Junk.e(Junk.java:31)
    at Junk.d(Junk.java:28)
    at Junk.c(Junk.java:22)
    ... 3 more

What does ... 1 more or ... 3 more means?

This is what it means:

HighLevelException: MidLevelException: LowLevelException
    at Junk.a(Junk.java:14)
    at Junk.main(Junk.java:4)

Caused by: MidLevelException: LowLevelException
    at Junk.c(Junk.java:24)
    at Junk.b(Junk.java:18)
    at Junk.a(Junk.java:12)
    ... 1 more =
(take the last line from the upper stack)
=> at Junk.main(Junk.java:4)

Caused by: LowLevelException
    at Junk.e(Junk.java:31)
    at Junk.d(Junk.java:28)
    at Junk.c(Junk.java:22)
    ... 3 more
= (take the last 3 lines from the upper stack)
=>  at Junk.b(Junk.java:18)
    at Junk.a(Junk.java:12)
    at Junk.main(Junk.java:4) (taken from the upper upper stack)

Berbatov rulez

"One of the best on the planet"
~Alex Ferguson

Chrome's "Create Application Shortcut" feature

Go to a web page -> context menu -> Create App Shortcut:

Then:


Then you have:

Even the icon is there, clicking it opens:


Note: It's not offline:


My opinion: not very useful, but nice.

Michael Moore

Michael Moore is a kind-of-a journalist, a filmmaker and a writer in the US. I have read and watched almost anything he did, going back even to "Roger and Me" (please search them up, I can't constantly write target="_blank"). He caught my attention with "Bowling for Columbine", a movie for some kids that armed themselves and killed some co-students and teachers in school. Especially the interview with Marylin Manson and the part where he mocks the locals claims that it was the bowling that put these kids to the idea.

Since then he got an Oscar, written a lot of stuff. He is not always absolutely objective, lets himself carried away sometimes but the personal touch makes him so likable.

He's in my blogroll now.

Chrome's EULA and Spying

Galcho commented out in a previous post of mine that Google Chrome's EULA said something like whatever I do with Chrome is property of Google. They of course revoked that and said it was a mistake. If it wasn't I would, obviously, have stopped using it.

Later on I read on the history of the browser and how A browser is very important to Google.
This brings me to another topic. How much info does any corp have about me? Google has a lot - mail, calendar, reader, search.....(there are claims that Google is misusing cookies so they can track anyone - gmail cookie used in search). I don't like the idea that a single entity has so much info about me. As much as I don't like my Government spying on me via the ISPs (an ongoing issue here). I don't trust my Government and I don't trust Google. But until now there's not much I can do. Google's services are really good and free. Maybe if I have some free time, I'll spend it on finding ways to make collection my private info a lot harder, especially for Google. I'll share the experience, of course.

Google Chrome, part II, processes

Here's how browser looks process wise:

They really do have multiple processes as they promised.

Update: Chrome just can't play cacao.fm

Update2: Firefox's new super-duper-nice search in history feature...

...is not in Chrome, too bad, it's a great feature.

Actually I don't see history in Chrome. I don't use it too often, but it's nice to have it.

Ctrl+Shift+T is working in Chrome, great

# Wednesday, September 03, 2008

Google Chrome

The new browser from Google - Google Chrome - is out.
First impressions: the html editor in the blog is NOT working, no idea why. I have to write html, it's really annoying.
It's fast. I don't see anything that's that much different from firefox.
The plug-ins are missing, I miss them.

Update: It's really fast, but so was firefox before all the pages and plug-ins.
Drag and drop works really nice:

Writing html really sucks.

Update2: It has something like the Firebug plug-in:

It has a javascript debugger, or at least it says so - I couldn't see what it can do.
The interface is really minimalistic, Google Talk style, I enjoy it. I could browse through all the options in a single minute.
It has the firefox shortcuts, downloads (Ctrl+J).

Update3: In maximized mode it uses even the title bar for the tabs. Cool. The tab text is too short to show the full title bar :-(
I REALLY HATE WRITING HTML, I'm going to post to the blog with firefox :((((((((((((
This thing is really fast.

Update4: The dream is over - it crashed (while opening an online radio):


Still, it's a great piece of software, especially the interface.

Did you know what 'Klaatu barada nikto' is?

I'm starting a new section "Did you know" where I'd share stuff I find interesting.

So, do you know what "Gort, Klaatu barada nikto" is?

It is considered the most famous science-fiction phrase ever. It has been quoted in almost all important science-fiction movies and not only.

It's from the 1951 movie called The Day the Earth Stood Still. It was said as a safe word to stop a robot from destroying the earth.
Gort was the name of the robot.

More on the subject: http://en.wikipedia.org/wiki/Klaatu_barada_nikto

# Tuesday, September 02, 2008

Copyright policy: no rights reserved

I've just changed my copyright policy to: no rights reserved.
Not that I have something useful here.

I find it really annoying that every body has some rights reserved on the things they produce - from coca-cola to a newborn blogger. This is my humble protest on the subject.

It's always better to ask than to enforce, so "if you mention my name, thank you".

Версия 2 на фонетичната: Shift + ь = ѝ

Направих една малка оптимизацийка на фонетичната.
Ето го постинга по темата:
http://mihail.stoynov.com/blog/2007/08/29/PhoneticKeyboardForWindowsVista.aspx

MS Word 2007 shortcuts listing

When one presses Alt key while in MS Word 2007 the shortcuts for all the commands are listed:



When one enters one of the tabs with the given shortcut, a next level of shortcuts are displayed:



I first saw this feature in Joel's FogBugz:

http://www.fogcreek.com/FogBugz/docs/60/topics/basics/KeyboardShortcuts.html

It's a really nice feature for the Ribbon (the new MS Office interface) to have. Great stuff, guys at MS.
Cons
for Word 2007 Shortcut feature: some of the shortcuts are with really strange letters, some of the things don't display shortcuts, for example, some stuff in the status bar.

MS Paint can open EMF files

Microsoft Paint tool can open EMF files. But cannot scale them (zoom) and cannot edit them.

Flex, Silverlight, Java what-ever and how Google sees it

There's Adobe Flex. There's Microsoft's Silverlight. There's Java's JavaFX. Maybe there are others.
These are platforms that would allow developers to put real applications in the browser. And not just the request-response model (http) and the async calls that javascript allows (ajax) and the modification of the DOM tree - SPI (Single Page Inteface - no wikipedia page for it). Or another way to put it - allow real applications to the user, while the browser is only the transport. The code is compiled, object-oriented, which makes is most-importantly much faster.
Pros: faster, a lot faster. developers write in real languages (javascript is a developer hell) - Silverlight is managed, Adobe's ActionScript is ECMA (which is not very promising, I don't know it in much detail, so I can't say), JavaFX is Java. The GUI definition is largely XML in most platforms.
Cons: plug-ins. Not standard. Different user interface and different rules for every platform. Compatibility issues with browsers, operating systems, elevation of rights (admin rights for install, elevated rights for execution).

Most modern web apps (gmail, youtube) exploit the browser to it's limits, my firefox just can't keep up (here and here).

What google thinks: make a browser that fixes all of the problems with the current browsers: most importantly speed, malware issues. Unfortunately developers will still have to write javascript. Fortunately, I'm not one of them. Fortunately, the model will stay open (html, javascript are no one's). Fortunately, the well-known rules of html/javascript pages will stay the same.

Their presentation of their new browser, called Chrome, is very ambitious:
http://books.google.com/books?id=8UsqHohwwVYC&printsec=frontcover#PPP1,M1
If they can do what they promise, I'm going to use it, I promise.
They hit exactly where current browsers fail (or at least with me) - speed, saparation of different pages (for some time I've been wanting to create multiple firefox processes, but don't know how), separation of plug-ins (to know who's fault it is), sandboxes, minimized rights, incognito mode.

I don't know much about Google Gears, but for offline reading of my feeds, it dissapointed me all the times I tried to do it.

# Monday, September 01, 2008

JAX-WS wsgen tool

Now, fix this one:
...>wsgen SomeInterface -wsdl -cp .;more.jar
Problem encountered during annotation processing;
see stacktrace below for more information.
java.lang.NullPointerException

        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP.isSubtype(WebServiceAP.java:418)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP.isRemote(WebServiceAP.java:413)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.isLegalType(WebServiceVisitor.java:8
13)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.isLegalMethod(WebServiceVisitor.java
:644)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.methodsAreLegal(WebServiceVisitor.ja
va:624)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.isLegalImplementation(WebServiceVisi
tor.java:542)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.shouldProcessWebService(WebServiceVi
sitor.java:352)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceVisitor.visitClassDeclaration(WebServiceVisi
tor.java:145)
        at com.sun.tools.apt.mirror.declaration.ClassDeclarationImpl.accept(ClassDeclarationImpl.java:95)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP.buildModel(WebServiceAP.java:347)
        at com.sun.tools.internal.ws.processor.modeler.annotation.WebServiceAP.process(WebServiceAP.java:232)
        at com.sun.mirror.apt.AnnotationProcessors$CompositeAnnotationProcessor.process(AnnotationProcessors.java:60)
        at com.sun.tools.apt.comp.Apt.main(Apt.java:454)
        at com.sun.tools.apt.main.JavaCompiler.compile(JavaCompiler.java:258)
        at com.sun.tools.apt.main.Main.compile(Main.java:1102)
        at com.sun.tools.apt.main.Main.compile(Main.java:964)
        at com.sun.tools.apt.Main.processing(Main.java:95)
        at com.sun.tools.apt.Main.process(Main.java:85)
        at com.sun.tools.apt.Main.process(Main.java:67)
        at com.sun.tools.internal.ws.wscompile.CompileTool.buildModel(CompileTool.java:605)
        at com.sun.tools.internal.ws.wscompile.CompileTool.run(CompileTool.java:538)
        at com.sun.tools.internal.ws.util.ToolBase.run(ToolBase.java:56)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.tools.internal.ws.Invoker.main(Invoker.java:63)
        at com.sun.tools.internal.ws.WsGen.main(WsGen.java:30)
error: compilation failed, errors should have been reported

A NullPointerException from a tool bundled in the JDK, how serious is this? Too bad for the 150 000+ test the guys at Sun did.

"errors should have been reported"?, yea they have been, but SO WHAT?
# Friday, August 29, 2008

Michael Phelps multi-angle camera

Multi-angle camera of his freestyle swimming:
http://uk.youtube.com/watch?v=ax77_hHq9Dc
(Michael Phelps, american swimmer, born 1985, won 8 golds in Beijing)

# Monday, August 25, 2008

Win + T, a great new shortcut

It's pretty nice - navigates through the tabs in the task bar.

A great day

As opposed to the previous gloomy post, here I'll tell you (my dear single reader :) about a great day I had a few days ago.

It all started at 8 in the morning: the phone call confirmed - the weather was great. Then a drive from Varna to Russalka (one of the best resorts on our seaside ever) - the trip was great - village roads light on traffic. I arrived in a sexy small bay with a motor boat (I don't know what that's called) on it and a really small island 10 meters from the shore. After a two-hour wait (I was late) I got on the wet suit and the oxygen bottle and my coach and I made a really nice trip around the island - up to 8-meter dives.

I tried to schedule a 25 meter dive - no luck. I had to have a special certificate.

Then with the pass for the diving I was free to do anything inside the resort. Now is the time to say that Russalka is a closed resort. Once inside everything is free - I had three cokes. It's very beautiful. (No camera sorry, I swam with my phone). I almost read Truman Capote's Summer Crossing.

Then on the way back I decided to go check out cape Shabla. Pretty nice place. Pretty close to the border with Romania. No more than 20 minutes there.

On the way there I stopped at Kamen Bryag and checked the ancient Tracian fortress Ajla. An amazing elevated view towards the sea. So pretty. Again 20 minutes there only.

Finally I arrived at Kaliakra - this is by far the most beautiful place I have ever seen in my life. Especially on sunset. The sea looked so powerful and mighty.

The day finished at Slunchev Bryag after a two hour drive at a Roger Sanchez's party. My car got towed and they gave it back for the humble price of 60 leva :( and a 800-meter, 15-leva taxi trip.

I got to bed at 6:30 after the same 2-hour drive after the party.

A great day.

About killing

Few days ago I accidentally hit a sparrow with my car. The poor creature did not survive. There's a really heavy feeling that grabs you right after that moment. Anger, frustration, trying to exonerate one's self. Sadness.

And if that's not enough, yesterday I hit a fox on the highway. I did not even stop to see what happened for which I kinda feel guilty. Again the sadness and thinking about life, the universe and everything else.

Damn bad luck. I have never hit anything before. And from the feeling of it - I'm no good for taking lives - I just can't bare the thought of it.

# Wednesday, August 20, 2008

Blogs that supply part of the content in the RSS/Atom feeds

There are blogs that only supply a resume or part of the content in the RSS. And the reason, I guess, is that they want you to leave the comfort of your own RSS reader and visit their site and maybe see some ads or who-cares-else what.

Well, FUCK THEM. The best I know are not doing it. Actually the best I know have no ads and have minimalistic web sites (I understand it as only content and unobtrusive navigation buttons/links).... and..... provide outstanding content.

Blogs that do that:
http://www.karieri.bg/blog/
http://www.nova-rabota.com/

I decided to stop reading them.


Other things that turn me down - copyright footer, a lot of links like "vote for me in ...." and guys that start taking themselves too seriously. For the latter I'm ready to make an exception, because some of them have an amazing style.

Operation Chicago

I just got the video from the paintball game "Operation Chicago".
I appear in 0:28 and 0:34 (the skinhead guy with the light green camouflage). In 0:34 I get my ass kicked by cross-firing machine guns (I'm behind a pretty thin tree).

  

I should name my blog "Complaining about stuff"

The "sucks" category is flourishing.

But it's damn easier to complain about stuff, than to write something meaningful.

I have to change that.

My blog in Internet Explorer

I just noticed it. It sucks. It's ugly, the font is ugly. How did I not notice that.
OOO, man, I have to fix it :(

In firefox it looks fine. Damn.

SonyEricsson K750i. SonyEricsson people, THANK YOU

Sony Ericsson K750i was my phone for quite a while. This is a thank-you note to the creators of that amazing machine.
Yesterday the latest accident finished it. This time for sure. It doesn't want to switch on. It's not showing any sign of life.

This phone made amazing pictures, most of my public images are made with it. It was the best of its time. There are still phone that can't match that. The iPhone's camera, for example, sucks. With a really steady hand one could make night shots too. I had a 2GB flash card of the awful sony format - memory stick.

The opera mini made it a decent browser. I could read mobi.capital.bg and mobi.dnevnik.bg in the restroom. BTW mobi.dnevnik.bg is boring as opposed to mobi.capital.bg.
Opera mini, BTW, is an example of a perfect minimalistic software. It's amazing. Great job.

I could use the phone with a bluetooth GPS until I lost the GPS in Amsterdam. The software choice wasn't that great, because I only had Java and no operating system. Here's the place to mention Nav4All - an amazing map software with routing (navigation) maps for Bulgaria. Once I ended up in a construction site in Sofia, but I hear these things happen to every map software. Nav4All used internet for downloading maps, and that made it quite a drag.

ReaderManiac made the phone an electronic book reader. Again an amazing software - I was planning to write an article about it, but maybe some other time. I read like 10 books on it. See the read books section (phone pages state that I read this on the phone). Navigation was amazing. Different font and sizes, great software. It even told you when to rest your eyes. I could supply Cyrillic fonts.

Lacking an OS made the phone very stable and pretty fast. It crashed only once a few months. I hate the so called organizers - Windows Mobile sucks big time.

The 2GB flash made the phone an excellent mp3 player. While snowboarding at -20 degrees Celsius it was working flawlessly. The earpieces weren't that well attached but the quality was quite satisfying.

A business phone: when it said that the battery was depleted it could work for at least a day at heavy use.

Negative sides: the jacks got pretty dirty and the earpieces and the usb connection got interferences. The screen wasn't as bright as the new phones. The inside of the protective glass (plastic) in front of the screen got full with sand and dirt and it was quite hard to clean it up. Thanks, Steen. Ugly flash card jack (memory stick duo), ugly earphones jack (something SonyEricsson). Nokia beats it here..

Update: I'd like to thank the mobile-review site for the outstanding reviews they make. Here's the one for K750i. Surely, I'll consult them for my next phone too. Also, their news page looks quite deserted, I really hope, they would continue to write good reviews.

So chronologically:

First while free-riding (snowboarding outside the track in fresh snow) I dropped it. After 80 minutes of heavy ringing I found it pretty wet under 20cm of snow still working and most importantly ringing so I could find it.

Second, I swam with it in a pool for at least half a minute. After a complete drying it continued to work but with a few minor quirks. Battery swelled up few days later and nearly blew up the whole phone. The new battery didn't charge correctly. The quality of the talks went significantly lower.

Third, yesterday I was with the phone in the sea for around 10 minutes. This was the end of it. It didn't show any signs of life after that. I did everything I can.

It's over.

Thank you, SonyEricsson people. This is was an amazing example of equipment.

Unfortunately SonyEricsson does not have a decent model with GPS. And that's what I'm looking for. I'm planning to have an iPhone (my roommate has one, it's a decent thing, but not for a primary phone) and maybe a Nokia with a GPS. My friends say E71, although ugly, is a pretty good one for business purposes. Both suck at pictures.
Maybe N82 too. We'll see.
Update2: BTW, mobile-review guys give a pretty bad review of the iPhone. They're right, I also strongly dislike Apple and its "closed" approach, but the article seems a little prejudiced. It seems personal. A red (bad) point for them.

Any other suggestions? I'm looking for a GPS, decent mapping software with maps and routing/navigation, wireless, a decent camera, fast interaction, no Windows Mobile, a lot of space, decent mp3 player, sturdy....

Vital equipment dying

I think I'm having a bad dream.
Most of the most important technical equipment around me is failing:

First the phone: SonyEricsson K750i. An amazing machine. Very sturdy, survived a swimming pool, being lost in the snow while snowboarding, numerous hits, is now dead.

The laptop's battery completely fucked up, it's constantly overheating. The laptop itself is scaring me up - not to die one day - it's a DELL, so....

My car is on the end of its usable life. Although I'm so thankful to it for saving my life after all the stupid things I did when I was younger, I have to change it.

I'm planning to buy a motorcycle.

It's partly my fault - most of the equipment was showing dreadful signs for a long time, but I constantly postpone to take measures.

So now to be able to buy all that I'm thinking of finding a second job or sell a kidney.

# Friday, August 15, 2008

I hate CDs/DVDs

I really do. Windows doesn't seem to understand them - the whole system stops and waits for a single DVD. The laptop is shaking.

Read/write times are really slow. Burning them with the windows's ATAPI service is hell.

When used to working with 3-5 MB/sec without worm-up times and spin times and whatever else times, it's really annoying.

But DVDs are the only reasonable way to give someone 15 GB even though you'll have to spend 2 hours to burn them.

P.S. I want to remove my laptop's DVD combo whatever bullshit, but I can't :( It's such a waste of weight and space.

Vista doesn't want to update to SP1

I don't know why. The update just does not want to come.
There are always other updates.

I'm too afraid to update to SP1 manually. Who knows what will happen.

And I want to stress that this is a legal copy.

Firefox is slow and youtube fails

Firefox is getting really slow. I don't know why, it may be due to too many plug-ins - I have 4 or 5.

And if working for sometime it stops playing flash streaming videos (youtube, google video....).

It has to be restarted. I'm disappointed.

Vista/XP can't burn a single CD/DVD without infuriating you

This is part of the series 'Vista sucks'. Although XP sucks as much as Vista in this case.

There was a feature first introduced in XP for burning CDs. In Xp the service was called something like ATAPI burning or whatever. Couldn't burn DVDs. In Vista the same software could burn DVDs. I couldn't find the service name. I may have missed it somehow.

So this software was a nice feature - simple, fairly stable.

But it's so darn slow and requires twice as much space as the burned data. Here's why:

First you copy the files on the CD/DVD with Windows Explorer. This copies the files in a cache of some kind. Trying to burn 4.5 GB requires 4-5 minutes of copying - and the machine is unusable  - copying utilizes the HDD. If you do something else it could take up to 20 min.

Then to burn them, the wizard should be started - this again copies the files to another cache I guess. Again 5 to 20 minutes.

This means 9 GB of space needed + the actual 4.5 GB. And a lot of time.

Vista/XP you messed up a good idea again. Vista/XP you suck.

As far as I can remember Nero was a lot faster, no cache needed, or at least no that much. Is Nero still good? Is there a light version of it?

# Monday, July 21, 2008

Adding columns to join tables (in the context of JPA/Hibernate)

At some point in a @ManyToMany relationship I had to add some extra columns in the join table (the middle table).

Here's what Gavin King says in Java Persistence with Hibernate (a notable book on the subject):

Adding columns to join tables
You can use two common strategies to map such a structure to Java classes. The first strategy requires an intermediate entity class for the join table and is mapped with one-to-many associations. The second strategy utilizes a collection of components, with a value-type class for the join table.

Later in that chapter for the first approach (the extra entity for the middle table):
The primary advantage of this strategy is the possibility for bidirectional navigation: You can get all items in a category {...} and the also navigate from the opposite direction {...}. A disadvantage is the more complex code needed to manage {...} entity instances to create and remove associations—they have to be saved and deleted independently, and you need some infrastructure, such as the composite identifier. However, you can enable transitive persistence with cascading options on the
collections {...}, as explained {...}, “Transitive persistence.”

Later in that chapter for the second approach (the collection of components approach):
That’s it: You’ve mapped a ternary association with annotations. What looked
incredibly complex at the beginning has been reduced to a few lines of annota-
tion metadata, most of it optional.

Naively enough I chose the second approach. Who cares that there's a hibernate dependency in my JPA data access layer. I already have a few (a hibernate interceptor).

In this approach I had to use the @CollectionOfElements annotation. @CollectionOfElements works like that: it maps a collection (set, map, list) of something to a table. This table has no entity attached to it. It can work with value types, Strings and @Embeddables. In my case it had to be the @Embeddable.

Let me give you an example - it will clear things up: there are classes and there are students - two entities. There can be two classes with many students some of which are the same - so the relationship is @ManyToMany. The extra column in the join table would the grade of the student in that class.

So the approach with the @CollectionOfElements works like that: one of the entities holds the relationship - let it be the class entity - so it has something like that:

@Entity
public class Class {
    @Version
    private int version;
    ...
    @org.hibernate.annotations.CollectionOfElements
    private Set<GradedStudent> students;
    ...
}


Student is a simple entity, no code needed. Let's call the student with the grade an GradedStudent:
@Embeddable
public class GradedStudent {
    ...
    @OneToOne(..., cascade = {MERGE, PERSIST, REFRESH})
    private Student student;
    ...
    @Column( nullable = false, ... )
    private int grade;
    ...
}

That's pretty much it. Seems simple, you would think and straightforward.

BUT IT DOESN'T WORK.

Here's what gets wrong:
  1. Everytime a class entity gets queried, it's version gets incremented. This makes updating a disconnected entity far more difficult and makes the @Version kind of obsolete.
    Solution: none, I couldn't find anything remotely connected to this problem on the net.
  2. The primary key in the join table (with a name like 'class_gradedstudent') is not the [class_id, student_id] but is [class_id, student_id, grade]. If you put extra columns in the join table and they are nullable = false, they would become part of the primary key.
  3. Cascading fails. You have to create and persist a Student first in order it to become a part of a certain class entity. Even though a GradedStudent is said to cascade a Student.
    Solution: none, I tried everything I could think of - no luck. I couldn't find anything remotely connected to this problem on the net.

Regarding 2: a quotation from the same book:
There is only
one change to the database tables: The {...} table now has a primary
key that is a composite of all columns, not only the ids of the two object, as in
the previous section. Hence, all properties should never be nullable—otherwise
you can’t identify a row in the join table.
Well, what if I don't want that? It doesn't say.

So, actually the second approach is not an option.
# Friday, July 18, 2008

@CollectionOfElements, JPA, the documentation and the problems it raises

In a project that I mention a lot there's an persistent model using JPA as an interface to Hibernate.

There was case where I wanted to put extra columns in a @ManyToMany relationship. JPA cannot do that.

So I had to use the Hibernate's @CollectionOfElements.
It works like that: if there are the objects Class and Student, the extra columns go to the wrapper class EnhancedStudent. The EnhancedStudent has a property of type Student.

Now I have a few bugs related to it:
  1. Causes the @Version of the containing object (Class) to increment on EntityManager.html#find(java.lang.Class, java.lang.Object)
  2. The creation of an ExtraStudent cannot propagate (cascade) the inner Student - no matter what.
The funniest thing is that the documentation of the @CollectionOfElements is a single line:

Annotation used to mark a collection as a collection of elements or a collection of embedded objects

http://www.hibernate.org/hib_docs/annotations/api/org/hibernate/annotations/CollectionOfElements.html

:(

Gotcha MTEL, YOU CHEATING BASTARDS

From some time I noticed that Mtel (my mobile service operation) is using VoIP when I'm calling an Mtel number while roaming.
When I'm calling another operator's number while still roaming, there's no VoIP.

CHEAP BASTARDS. For these prices you can at least provide a decent service - a VoIP call is with bad quality and the callee cannot see who's calling, he sees some service number.

BUT THATS NOT ALL.

The top of the cherry is that when Mtel is using VoIP they clearly cannot see whether the other side answers or not, so no matter whether you make a successful call or not - while you're ringing you get billed. That's not right, is it?!

I found out all that today while checking my bill. Two months ago while in Brno I made a call and was quite sure that I would get billed for that call even though nobody answered.

GOTCHA, YOU CHEAP BASTARDOs


Update: other case of proved cheating:
Mtel made me pay 200 bucks for half a megabyte of internet while roaming. Before that I explicitly asked for the price. It came out that the price is 10 times more and they charge every GPRS session for a full megabyte (with 10 times the prices) without saying it.

Few months ago I caught them billing me for an international call to a friend I haven't spoken with for at least a couple of years.

# Thursday, July 17, 2008

Ctrl+Shift+T in Firefox = reopen last closed tab (window)

Ctrl+Shift+T is a popular shortcut in Eclipse.

Ctrl+T is a popular shortcut in Firefox - opens an empty tab.

Once by mistake I pressed the former by mistake and found out that Ctrl+Shift+T makes an undo for the last closed window (tab). And not only for the last tab.

Cool

Mocking an EJB Container

There are a lot of tests for some EJBs.

Starting an J2EE server is slow. I wanted to test the business logic faster.

Most of the beans reference only each other and a persistence context.

So what should the mock worry about - transaction demarcation and dependency injection. And... exception wrapping and unwrapping.

  1. First just add some setters or change the access level modifiers (from private to protected for example).
  2. Know your transaction authority.
  3. Count started transactions. If 0, begin. If 0, commit. Rollback when necessary.
  4. Listen for all the exceptions and wrap and unwrap them.
  5. Reuse as much as possible of the code.
If I have some spare time left, I'll write some code.


Serialization, cyclic references (via hashmaps) and overriding hashCode()

I'll try to simplify it.
There's an object model. In it there are cyclic references (one object references a second one, the second one - a third one, the third one - the first one).
Some of the cyclic references are through aggregations - one object has a map of other objects.
Some of the objects have a meaningful hashCode() and equals() overridden. These two depend on some properties in the object itself.

Some of the objects get serizalized/deserialized (travel through a stream).

Now here comes the problem - the deserialization first sees the cyclic reference, makes instances of all the objects, initializes all the primitive fileds, does not initialize the other fields, then links the objects.

Here comes the problem, linking two objects (one of which has a map of the other) requires hashCode(). This requires some specific properties in that object that are not initialized - this causes NullPointerException (or in my case an AssertionError).

If the hashCode returns a default value if the properties are not there - another serious problem si caused - there are objects in the map in the wrong buckets - they entered the map with the default hash, but when they got completely initialized - they now have a different hash. I think that is really bad - the map has to be rehashed.

Here's a bug detail:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4957674

Here's what some of the guys say on the subject:

The problem is that HashMap's readObject() implementation , in order to re-hash the map, invokes the hashCode() method of some of its keys, regardless of whether those keys have been fully deserialized.

And:

The fix for this is actually quite easy: Modify the readObject() and writeObject() of HashMap so that it also saves the original hash code. (I am currently using this fix in production code for a large web site.) That way, when the map is reconstructed, you don't have to recompute the hashcode----the problem is caused by recomputing the hashcode at a moment when it is not computable.

What you *give up* with this fix is that HashMaps containing Objects that don't override hashCode() and equals() will not be deserialized properly.

So basically, you have a choice: either it will be robust for classes that implement hashCode(), or it will work for bare Objects(). One or the other. I prefer the former, because people are supposed to implement hashCode().

But, not all my object have a rewritten equals (of course I can check with reflection which ones do and which ones don't, but...). This would also mean that I'm using a customized collection.


There's another proposition - to hash the hashcode.

The fix for this is actually quite easy:  Modify the readObject() and writeObject() of HashMap so that it also saves the original hash code.  (I am currently using this fix in production code for a large web site.)

The hashcode is a primitive type, so it would get initialized first and the problem would be solved. This would mean to have an hashCode() and equals() which check which one is available - the cached hash or the properties - isn't that UGLY.

I'll investigate more.
# Monday, July 14, 2008

73 meters from the ground

This is 73 meters from the ground. It is scary and physically intensive. I did this route twice, the first time without the special gloves. My fingers still hurt.



On the top the second time (on the verge of not making it).


It's over, let's have something to eat.


More pictures when I get them.

MySQL, I hate you so much [Installing mysql as a service]

The first idea was to have the DB (MySQL) start as part of the script that launched the tests. Google couldn't find anything good. MySQL is one of the most unintuitive things I have ever seen, so the decision was to not try to figure it out on my own.

The next thing was to install MySQL as a service. That turned out to be difficult.

I tried to install MySQL as a service:

/>mysqld --install

As easy as that. The problem is IT DID NOT WORK. The service did not want to start.

After some reading it came out that the RIGHT way was to do it like that:

__correct dir__/><<path>>\mysqld.exe --install MySQL --defaults-file="<<path>>\my.ini"

Why do I have to supply the mysql directory explicitly?
Why do I have to supply the my.ini directory explicitly?

Why doesn't mysqld give me an error message when I install it without the needed parameters?
Why doesn't mysqld give me an error message when I install it without the needed explicit paths?

...is beyond my inderstanding.

MySQL, you are a disgrace.
MySQL, not only are you not a real RDBMS but you can't even start without making your users' life misserable.


Google mail servers fail?! All of them?

Connection timed out on all their servers?!

Technical details of temporary failure:
TEMP_FAILURE: The recipient server did not accept our requests to connect.
[ASPMX.L.GOOGLE.com. (1): Connection timed out]
[ALT1.ASPMX.L.GOOGLE.com. (5): Connection timed out]
[ALT2.ASPMX.L.GOOGLE.com. (5): Connection timed out]
[ASPMX3.GOOGLEMAIL.com. (10): Connection timed out]
[ASPMX5.GOOGLEMAIL.com. (10): Connection timed out]
[ASPMX2.GOOGLEMAIL.com. (10): Connection timed out]
[ASPMX4.GOOGLEMAIL.com. (10): Connection timed out]

# Friday, July 11, 2008

The sources for hibernate-entitymanager.jar, version 3.2.1GA

Yea, it was difficult. So difficult that I had to extract the sources from a zipped project file, put them into archive and rename to jar file. And hope that the versions I'm using are mathing....

The JBoss jar says it's implemented by JBoss.
JBoss/hibernate-entitymanager.jar/META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Product: Hibernate EntityManager
Specification-Title: JBoss
Created-By: 1.5.0_09-b03 (Sun Microsystems Inc.)
Specification-Version: 4.2.2.GA
Implementation-Vendor-Id: http://www.jboss.org/   WTF?
Version: 3.2.1.GA
Implementation-URL: http://www.jboss.org/
Ant-Version: Apache Ant 1.6.5
Implementation-Title: JBoss [Trinity]
Specification-Vendor: JBoss (http://www.jboss.org/)
Implementation-Version: 4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=20
 0710221139)
Implementation-Vendor: JBoss Inc.

However, the JBoss source does not have the sources.
http://repository.jboss.org/hibernate-entitymanager/3.2.1.GA/
WTF number 2?


In the hibernate downloads the source is missing as a separate download
http://sourceforge.net/project/showfiles.php?group_id=40712&package_id=156160
WTF number 3?

Finally, found it in the zip file in the last link. I was desparate, thinking of using the repositories here:
http://anonsvn.jboss.org/repos/hibernate/entitymanager/tags/
Had to extract it, re-zip it and hope the versions match. So far so good.

Why does it have to be so difficult?!

# Thursday, July 10, 2008

Overriding a method with a raw type, want to use generics in the override

I want to override that api.org.hibernate.Interceptor#postFlush(java.util.Iterator)
I want to do it like that:
@Override
public void postFlush( Iterator<?> entities ) throws CallbackException {...}
Does not work - the method is not with the same signature ?!

Then:
@Override
public void postFlush( Iterator<Object> entities ) throws CallbackException {...}
Does not work - the method is not with the same signature ?! WTF?

The only thing that does work (without a silly warning) is that:
@Override
public void postFlush( @SuppressWarnings( "unchecked" ) Iterator entities ) throws CallbackException {


Why?!!

Iterating over iterator contents with a for loop

How an iterator works:

Iterator i = collection.iterator();
while( i.hasNext() ) {
 Object o = i.next();
 //do stuff
}

Well, I want to move the red line in the loop init, so it would not mingle with the loop body where only business logic would reside.

Unfortunately that cannot happen. A for loop first inits the data, then checks the condition. With an iterator one has to first check if there are elements, then to get them.

And why would someone give you an iterator instead of a collection, my mind cannot understand. (org.hibernate.Interceptor#postFlush(java.util.Iterator))
# Tuesday, July 08, 2008

JUnit, exceptions in @Before and @After methods

JUnit spec (not very easy to find) states, that if there's an exception in the @Before method, the test is not called. True. BUT

JUnit spec does not state that in this case the @After method is called.

JUnit spec also does not state that if there's an exception in both the @Before and @After methods, the second exception (guess which one) overrides the first one. In my case the first one causes the second one (the first one is ConnectionClosed or similar, the second one is a NullPointerException because the resource is not initialized).

So the real reason for the problem is lost. One will say - avoid exceptions in the @After method - that's what I just did (and the real exception was printed), but finding the reason for that was not easy and straightforward.

I'm using junit 4.4, the default runner is JUnit4ClassRunner, JUnit4ClassRunner is calling ClassRoadie.runProtected():

public void runProtected() {
    try {
        runBefores();
        runUnprotected();
    } catch (FailedBefore e) {
    } finally {
        runAfters();
    }
}

This is the reason for the mentioned override. I hate when finally does that.

There's no such thing as a natural

There's no such thing as a natural. A natural is someone who practices so much it looks like they don't need to.
# Monday, June 30, 2008

blogging from an iphone

It's not very easy, this is the first phone that is sophisticated enough to support the editing page and easy enough to be usable for that purpose. Uploading does not work. Rich editing does not work. But typing is fast enough and easy enough.

# Tuesday, June 24, 2008

Hibernate, AuditLogging, cannot configure listeners in persistence.xml

First, what's my goal
I want to do an audit log. I read the http://www.hibernate.org/318.html and there two different approaches were mentioned.
The first is using a Listener.
The second is using the new eventing model in Hibernate3.
The author said that he couldn't make the eventing approach work for an unknown reason.

I'm using Hibernate via JPA. I'm using it in an EJB. So the problem with the first approach is that it is difficult (if possilbe) to supply the same transaction to the interceptor so that it can write an entry in the audit log. There is a solution with a static field holding a session or an EM, but that seems ugly.

So I chose the second approach. I created a class, inherited few eventhandlers (PreInsertEventListener, PostUpdateEventListener ) and tried to add the class as a listener.

Using the API, it worked (the callback methods in the listeners were called):

AnnotationConfiguration configuration = new AnnotationConfiguration();

configuration.setListener( "post-update", new Test1() );


configuration.addProperties( hibernateProperties );
EntityManagerFactory factory = new EntityManagerFactoryImpl( configuration.buildSessionFactory(),
   PersistenceUnitTransactionType.RESOURCE_LOCAL, true );
EntityManager result = factory.createEntityManager();


Using properties (as if using persistence.xml) failed(the callback methods in the listeners were NOT called):

Properties hibernateProperties = new Properties();
...

hibernateProperties.put( "hibernate.ejb.event.pre-update", "package.Test1" );
hibernateProperties.put( "hibernate.ejb.event.pre-insert", "package.Test1" );
 
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.addProperties( hibernateProperties );
EntityManagerFactory factory = new EntityManagerFactoryImpl( configuration.buildSessionFactory(),
   PersistenceUnitTransactionType.RESOURCE_LOCAL, true );
EntityManager result = factory.createEntityManager();


Ideas why?
# Saturday, June 21, 2008

A new challenge - a dog

I have to keep it alive for 24 hours. It's gonna be hard




Update: It's done - I successfully returned the dog alive, unharmed and in good condition.
# Friday, June 20, 2008

Category A in my driving license

Today I passed the exam for category A (motorcycles above 50cc). Very happy.