Thursday, November 30, 2006

New certificate on the horizon?

I've just received ordered book "Sun Certified Enterprise Architect for J2EE Technology Study Guide" and I'm slowly starting to learn to Sun Certified Enterprise Architect exam. I'll shortly see whether this book is good or not - the success indicator for me is passed exam by the end of June 2007.

Friday, November 24, 2006

WebServices Hell

There are many open-source WebService frameworks like:


All of them base on StAX (Streaming API for XML) but have different set of other useful features. Some of them support asynchronous calls, some of them support more WS-* standards some of them less (is WS-* really what we need? see http://www.tbray.org/talks/php.de.pdf especially slides no. 15 and 16) but which to choose? Maybe you should buy something e.g. IONA Arix?

Our team uses XFire at this moment but will have to support also Axis2, maybe XINS. Decision is not easy - if you choose one it can eventually turn out that that features set is not enough or some implementation details break your code, or something is impossible to achieve, or..., etc., etc. Unfortunately it can be too late for you and your project and you will stick somewhere and the only workable solution will be to change open-source code in order to get it worked.

Commercial products are not better. More so you have to pay for them...

Maybe WS frameworks will be mature enough soon but who is able to define soon?

Sunday, November 19, 2006

Bugs in Eclipse Java compiler (part II)

Version: 3.2.1; Build id: M20060921-0945

Try this:

package iface;

interface DefaultInterface {
String INVISIBLE_CONST = "Invisible string";
}
, this:

package iface;

public interface PublicInterface extends DefaultInterface {
String VISIBLE_CONST = "Visible String";
}
and this:

package test;

import static iface.PublicInterface.INVISIBLE_CONST;
import static iface.PublicInterface.VISIBLE_CONST;
import iface.PublicInterface;

public class Test {
public static void main(String[] args) {
System.out.println(PublicInterface.INVISIBLE_CONST);
System.out.println(PublicInterface.VISIBLE_CONST);
System.out.println(INVISIBLE_CONST);
System.out.println(VISIBLE_CONST);
}
}

Of course Eclipse will compile three classes above without any warning, but when you try to compile this with Sun's compiler (javac 1.5.0_05 in my case - this is the command: javac iface\*.java test\*.java) you will get such error message:

test\Test.java:11: INVISIBLE_CONST in iface.DefaultInterface
is defined in an inaccessible class or interface
System.out.println(INVISIBLE_CONST);
^
1 error

Malicious line is static import of const string from interface which is invisible from within test package:

import static iface.PublicInterface.INVISIBLE_CONST;

Although this const belongs to PublicInterface it is not defined there.

It looks like Java bug not Eclipse bug. Why can I access constant from inaccessible interface and cannot import it statically at the same time? It's nonsense - I should be able neither import it statically nor access it through accessible interface.
Having known this bug it is possible to expose all methods and constants from inaccessible/package-default interfaces just by extending them by public interfaces.

PS. (2008-11-24) This is already fixed - it was a Sun's Java compiler problem (and mine) - everything that is defined in an interface is public (there is no default scope).

National Geographic day

Today is my NG day - I'm reading all postponed articles in all put off NG editions (since June 2006 ;) Don't expect any post today...

Saturday, November 18, 2006

Bugs in Eclipse Java compiler (part I)

Version: 3.2.1; Build id: M20060921-0945

Try this one:

public abstract class AbstractClass<T> {
AbstractClass(T obj) {
System.out.println(obj.toString());
}

AbstractClass(String string) {
System.out.println(string);
}
}

and this:

public class Implementation extends AbstractClass<String> {
public Implementation(String obj) {
super(obj);
}
}

Eclipse' compiler will compile two above classes without any warning but when you try to compile this with Sun's original Java compiler (javac 1.5.0_05 in my case - this is the command: javac *.java) you will get such error message:

Implementation.java:3: reference to AbstractClass is ambiguous,
both method AbstractClass(T) in generics.AbstractClass and method
AbstractClass(java.lang.String) in generics.AbstractClass
match
super(obj);
^
1 error

I don't have much time for reporting this bug to Eclipse bugzilla, so if you have some time please do so (if it is not already reported).

BTW. I had to solve this problem because I wanted implementing classes to have both constructors. The solution is to change one of the constructors in AbstractClass that it looks like this one:

AbstractClass(String string, boolean fakeFlag) {
System.out.println(string);
}

This way you get rid of ambiguity.

PS. (2008-11-24) It is already fixed - it was indeed an Eclipse compiler bug but don't ask about any dates and versions - I don't have them.

Thursday, November 16, 2006

TAGRI (They Aren't Gonna Read It)

Today I read interesting article about the TAGRI (They Aren't Gonna Read It) Principle of Software Development. If you comply with agile everything (which is good for you) you should read this article.

I totally agree with the author as far documentation is concerned. I've wrote with my colleagues System Architecture Specification recently. Document was rather low-level specification (should be high-level ;) and I must confess that I have never ever look at this document again after we base-lined it (BTW. we wrote this document for ourselves - that was the idea). On the other hand what we wrote on our Wiki pages and in Maven-generated documentation is great, fantastic, splendid, etc. Why? Because it is concise, precise and USEFUL.

As the example of WRONG documentation I would recommend you looking at the IBM products documentation e.g. WebSphere MQ. You can find tons of pages of so-called "documentation" on their help pages. Unfortunately when I wanted to install and run their MQ I had no f****ing idea how to do this!!! I spent one whole day on that - it's terrible!!! On the contrary when you want to run ActiveMQ (or TIBCO MQ, or Sonic MQ) it will take you 5 to 30 minutes. That's the difference I think.

Anyway - what I mentioned above are only my modest experiences with documentation. I STRONGLY recommend you reading the article linked at the beginning of this post.

Tuesday, November 14, 2006

Again: equals() confusions

I was wrong and everyone is wrong who claims that such construct:

if (getClass() != obj.getClass()) {
return false;
}
is more efficient than this one:

if (!(obj instanceof ExampleBean)) {
return false;
}
It wasn't difficult to check the performance and I must say that instanceof is slightly FASTER!!! than != operator in this case. I invoked 10.000.000 time equals() method on my simple bean and the result were very similar but equals() using instanceof operator was faster every time at about 50 millis (it's not much BUT...). I checked it even with small hierarchy i.e. I created class A, class B extends A and class C extends B and checked it again - still instanceof is faster.

I also checked third possibility, namely:

if (!getClass().isAssignableFrom(obj.getClass())) {
return false;
}
but it was three times slower than two other constructs.

Once again: REMEMBER to use instanceof operator in all persistent objects when you use Hibernate (see hibernate docs), but also keep in mind that this operator breaks the equals() method contract - it is not SYMMETRICAL.

Sun Certified Java Developer's logo

I finally received it and am very proud of it. Look and admire :)



NOTE: Logo above belongs to Sun Microsystems and you are not allowed to use it for any purpose. For details refer to: Sun Trademark and Logo Usage Requirements.

Monday, November 13, 2006

Developer's laziness

Today evening I wanted to find some places I visited in Asia through GoogleEarth (GE), match them to my pictures and publish them on my website. I want to match GE location either for single picture (if it makes sense) or for the whole chapter (e.g. Luang Prabang - ancient Lao capital). Steps I have to proceed are:
1. Find place in GE (it's pleasure)
2. Save GE's placemark as KMZ in local disk
3. Copy KMZ(s) to remote server
4. Update MySQL databse (using SQL - not PHPMyAdmin)
5. Say "%$&*($A@#^*" if I have to repeat this operation many times.

I created simple framework in PHP for browsing SQL database and display my pictures (I did it in PHP because I didn't know JSP at that time :) Unfortunately now I am very lazy person and don't want to loose time at home improving this to support DnD (drag'n drop) - but I think I should. It would save my precious time ;) Maybe I will implement such web framework in the future - maybe there is existing one? But how many picture publishing frameworks support GoogleEarth placemarks?

Anyway I know that I write gibberish but I just wanted to say that even if people (like me in this example) have many interesting ideas (I consider my idea interesting and useful - what is more important ;) they don't have time to put these ideas in life. How many great engineers passed away without doing great things they had in mind? That's pathetic how our life is restraining us - we only shop, vote, get cancer and die (like Americans say :)

Sunday, November 12, 2006

IAdaptable - Design Pattern or philosophy?

Can IAdaptable inspire Java developers to create better and more maintainable applications? Russian colleagues from my team claim that they worship this pattern and extensively use it. Can extending class features in runtime be achieved easily? Check it out:
What is IAdaptable?
FAQ How do I use IAdaptable and IAdapterFactory?

Thursday, November 09, 2006

The "I" Thing

Java naming convention is something developers like to talk and argue about ;) Why it is so important? Let's have a look at the following example. Should we use "I"-for-interface convention? The answer is not easy. One can say (I'm among those) that this makes code more readable because you always know whether you are looking at interface or not. It not so important when you have javadoc and IDE (like Eclipse) because you can just press F3 or any other significant shortcut ;) and you see whether it is interface, class, abstract class, enum or whatever else. The readability issue is more confusing when you have to browse repository using web browser. It is really annoying when you enter the class and it turns out to be an interface without content (I mean implementation).

On the other hand it shouldn't be the case whether you use interface or the class - in fact in ideal world you should use only interfaces (it's not my thought but I think I can borrow it :). Unfortunately ideal world is only our imagination and it is not so beautiful. I agree that all developers (in OOP) should program to interfaces. For us as users of any API the implementation is not important (it's interchangeable) and we shouldn't worry whether we use interfaces or classes.
But there is one thing more which gives "I" prefix advantage over non-"I" convention. If you are a good developer you know that you should use interface and if you see the whole package you can easily choose interfaces and code it. If there is no "I" prefix at the beginning how should you know which class you have to use? Of course it is feasible in reasonable time but it is confusing that first of all you have to dig into the package details in order to find out what is an interface and how should you obtain the implementing object.

Some people say that if we decide to use "I" prefix for interfaces we should use the same notation for abstract classes ("A"), enums ("E"), etc. I don't agree - the only instance that does not have any implementation details is interface. Either enums and abstract classes are implemented (if abstract class consist of only abstract methods and attributes it should be an interface). If enums and abstract classes have any contents developers are likely to view them - unlike the interfaces which are not interesting in such context :) BTW: I know that it is rather against Sun's convention but I try to add "Abstract" prefix for abstract classes and "Enum" postfix for enums - note that every exception has "Exception" postfix - but this is ordinary Java class, isn't it?. For me browsing packages is more convenient with such notation. Of course neither of notation mentioned by me is more helpful that puritan Sun's one if we use javadoc. All types are enumerated in categories: interfaces, classes, enums and exceptions.

Developers can argue (and they do so :) their whole life whether one notation is better that another. What force us to use one of those is our custom. The good thing about developers is that they sometimes can change their habits and they accept changes (sometimes they get back to their old customs when they change their job or department ;). What I wanted to write is that I prefer "I" as an interface prefix, "Abstract" prefix for abstract classes, "Enum" postfix for enums and "Exception" postfix for exceptions - I specifically like the last one :D

If you want to know more about different coding notations and conventions please visit links below:
Java Coding Conventions
Java Code Conventions (PDF)
Eclipse Platform Naming Conventions
Java Coding Standard (Doug Lea)
Chimu Inc Coding Standards
Scott Ambler's Coding Conventions
Naming Conventions in C++ and Java

Wednesday, November 08, 2006

I don't like Sun's policy...

I don't like Sun's policy regarding sharing Java certification information. I asked them yesterday whether I can share Sun Certified Java Developer's assignment given to me in order to implement: "I want to ask whether it is legal for me to publish such information (I mean assignment instruction and my solution including source code) on e.g. my public blog? I want to share my knowledge with other people who want to take this exam but I don't want to break the law.". I received response today in which they state: "It is against Sun policy for you or any other candidate to share his or her assignment with others. Sun Certification assignments are considered Sun's intellectual property.".

Well I generally understand Sun and I support such policy because I think that everybody who wants to take this exam has to do this by her/himself. On the other hand everyone who takes this exam receives different assignment - why shouldn't I publish my design problem and my solution?

What do you think?

Tuesday, November 07, 2006

Dangerous equals(Object) template in Eclipse

Problem statement


I found it very nice where I discovered that new Eclipse 3.x allows developers to automatically generate equals(Object) method. "This is great!" I thought that time. Unfortunately when I developed simple GUI application utilizing SWT and JFace as a front-end and Hibernate as a database access framework I found that something does not work. It took me some time to find this stupid bug. It was equals method of course. Look at this example (I added { to the originally generated code cause I hate when Java developers do not add curly braces for blocks with only one operation - it's just ugly and in my view disallowed - how could Eclipse.org release such shitty code!?):

public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}

if (getClass() != obj.getClass()) {
return false;
}

// omitted - checking selected attributes
}
The code looks fine but it consist one subtle bug (BTW. I found that authors of let's say Java bible namely Core Java use the same notation and the same equals template). It is in line:
if (getClass() != obj.getClass())

I agree that checking class objects is faster but it simply does not work when you operate not on classes you created but on their proxies. Hibernate wraps your domain (or persistent) objects into proxies generated supposedly by ASM library. In case of Hibernate you almost (is almost necessary in this sentence?) never operate on your classes but on runtime generated proxies. This way this buggy line stressed above will always return false unless you use instanceof operator.

Solution


I will repeat what Josh Bloch wrote in his great book "Effective Java" that you should not optimize your code if you are not 100% sure it will work in every situation. My solution (at least for Hibernate) is to replace this piece of code:

if (getClass() != obj.getClass()) {
return false;
}
with this one:

if (!(obj instanceof NameOfYourClass)) {
return false;
}
Of course instanceof operation is less effective that != but it is not so fragile. If you suppose that your classes can be used (and created) by dynamic proxies you should use instanceof operator instead of !=.

Conclusions


Generally equals method template presented by me as buggy is correct in many cases. Unfortunately we as developers never know how our classes will be used and that's why we should protect them as well as possible. Nowadays many frameworks grill our classes and use dynamic proxies (with added logging, security and whatever else) and we should be aware of this. My proposal is to use instanceof operator when you are almost sure that your classes will be instantiated by dynamic proxies or use ==, != operators otherwise. In such case you should clearly state in JavaDoc that you use such and such operator and, if your class will be wrapped by dynamic proxy, equals method will not work properly even if two comparing objects will be equal (not same) in terms of business logic.

Breaking the ice (who ordered this iceberg?)

This is my first post and I hope not the last one. I really want to write something useful for Java developers (including those from JEE world) and I hope I'll bring some good ideas for them.

I am not very prolific blogger, so don't expect tons of posts - I'll do my best :)

That's all for now (not very much indeed :)