Saturday, November 03, 2007

The Leopard and Java 6 Issue

Everybody in the Java community kept their keyboards busy lately ranting either against the fact that Apple's latest Mac OS X version doesn't include Java 6, or against those ranting against Apple's decision.

I can't deny the issue is bugging me, but not because of the same reasons: I don't really care about using the very latest Java 6 APIs or using the nice splash screen or getting a slightly faster startup time. Here is the problem, the way I see it:

On one side we've got Microsoft's Vista, which is clearly going to be the future mainstream OS, despite the fact that today most people are unhappy with it. Now, if you search the web to find out about Java and Vista compatibility, you'll find that the version of Java designed to work with Vista is Java 6. Java 5 was reported to have a huge number of serious issues on Vista. Sun did a great job in fixing many of them in JDK 5.0u13, but one may wonder how many others have not yet been found. To make the story short, if you want to be sure your application works fine with Vista, you better build it with Java 6.

On the other hand Leopard doesn't have Java 6 yet - well it has it, but it's in Beta.

So if you develop a product in Java and want to target both Mac OS X and Windows clients, you must make two different releases: one that that is Java 6 based, for Windows, and one that is Java 5 based, for Mac OS. This is far from being the end of the world, but it is a little bit annoying.

Things would be so much more simple if either Sun would make a good Java 5 release for vista - which might just be the case with 5.0u13 or if Apple would finalize Java 6 for Mac OS X.

Labels: , , , , , ,

Monday, August 21, 2006

still alive?

Yup, still alive. Unfortunately didn't have time to write much - did have a few subjects, though. Hope to have a little bit more time starting with September.

Cheers,
Emil.

Wednesday, April 26, 2006

j2ee postings on server side

Whenever I have a minute I try to share some of my j2ee experience on the server side forums. Here are a links to a few threads of general interest I have participated in:



Enjoy.

Sunday, February 26, 2006

More on the Java IDE comparison

Important: you can read the entire article, as it builds up, at this URL

Code template expansion

Template expansion is another time saving feature mainstrem java IDEs support nowadays. The feature consists in a setting up an abbreviation which when typed and followed by a specific key combination expands to a full featured piece of code. For example, you could set up psf+TRIGGER to expand to public static final. Or sout+TRIGGER to expand to System.out.println. Once you get used to this feature you become addicted. Templates are written in a simpe language, which can do more or less advanced things, depending on the implementation.

IDEA's code template expansion feature is the most advanced, mainly because the template definition language takes advantege of the state of the art code querying mechanism that is built into this IDE. When defining templates in IDEA you can query variables of a certain type, or of certain types.

For example, the following template could expand into while (iterator.hasNext()) { Person person = (Person)iterator.next() } and the cursor will be placed where the END tag is.

while($ITER$.hasNext()){ $TYPE$ $VAR$ = $CAST$ $ITER$.next(); $END$ }

This is cool already, but it gets even better when you notice that you can ask IDEA to replace $ITER$ with variables of a certain type - in this case, Iterator. This can be done by specifying that $ITER$ is a variableOfType("java.util.Iterator"). After doing so, when the code is expanded, IDEA will ask you to choose one of iterators in scope. You can also specify that $TYPE$ should take the value rightSideType(). This takes effect with typed collections in jdk 1.5 - at expansion time TYPE will automatically be replaced with the type of the elements contained in the collection. Regarding $VAR, you can ask IDEA to suggest a variable name, by setting it to suggestVariableName(). If you do so IDEA will propose you variable names based on the contained type. For example, if the type is ImageDescriptor IDEA will propose descriptor and imageDescriptor. All you have to do is choose the name you like most or type your own if your not happy with any of the default ones. Choosing one of the proposed choices, however, tends to result in very readable code.

It's possible and very easy to write your own templates. I wrote one to help me initialize log4j loggers. This is the typical situation where template code expansion is very handy. Initializing a logger is an annoing, repetetive task which doesn't have anything to do with the business logic you write. Here is a small template that helps you deal with the problem:

private static final Logger log = Logger.getLogger($CLASS_NAME$.class);

Then you insruct IDEA to give $CLASS_NAME$ the value className(), register your template under the logdecl abbreviation and you're set. All you have to do from now on is type logdecl+TAB and that IDEA will declare that annoying logger for you.

Aparently Eclipse offers code template expansion too, but I haven't been able to make it work. Just couldn't find it. But apparently it's there. But if I can't find it it's just like it wouldn't be.... hmmm......

Netbeans offers code template expansion with almost the same features as IDEA - it's slightly less flexible though. You can define your templates, define shortcuts - I have the feeling there are less options then in IDEA. On the other hand, I've not been able to change the activation key - which is SPACE, by default. Also, the activation sequence is kinda weird: the template is only expanded if you press SPACE just after the abbreviation. If you type the abbreviation move your cursor, then comme back and try to expand, it doesn't work. Have to delete the last letter, retype it and quickly press SPACE . I haven't been able to change the activation key - the config dialog let's you change it, SPACE doesn't work any more, but the new key doesn't work either.

The winner here is IDEA again, with Netbeans comming in second and Eclipse third.

Getter / Setter / Constructor generation

Getter / setter / constructor generation features are comparable in IDEA and Eclipse. Both products offer quite complete features and there is nothing much to say on this matter. Netbeans has a slightly different approach on getter / setter generation: the feature is not available under the "source" menu, but under "refactoring", and it's called "encapsulate fields". A little wierd - I wouldn't think about this as refactoring - but hey, the feature is there. If I had some trouble finding the getter setter generation feature, I was totally unable to find an action to let me generate constructors. This is not a very good point for Netbeans, as constructor generation is a very widely used feature. The feature may be there but if I need more the 5 minutes to find it, it's just like it's missing. So the winners in this category are IDEA and Eclipse with similar and equally easy to use features with Netbeans comming in third, offering hard to find, not so easy to use functionality.

Thursday, January 19, 2006

IDEA live templates for log4j

Live templates are a neat feature in modern IDEA - btw, I'll discuss it in the next episode of my IDE comparison article series. Meanwhile for all IDEA and Log4J users out there, this is a set of live templates I wrote to help me deal with Log4J logger declarations and inserting logging lines in my code:


<?xml version="1.0" encoding="UTF-8"?>
<templateSet group="logging">
<template name="ldeb" value="if ($LOGGER$.isDebugEnabled()) $LOGGER$.debug("$END$");" description="Loggs in debug mode" toReformat="false" toShortenFQNames="true">
<variable name="LOGGER" expression="variableOfType("org.apache.log4j.Logger")" defaultValue="log" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="true" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="false" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>
<template name="lerr" value="$LOGGER$.error("$END$");" description="Loggs in error mode" toReformat="false" toShortenFQNames="true">
<variable name="LOGGER" expression="variableOfType("org.apache.log4j.Logger")" defaultValue="log" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="true" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="false" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>
<template name="linf" value="if ($LOGGER$.isInfoEnabled()) $LOGGER$.info("$END$");" description="Loggs in info mode" toReformat="false" toShortenFQNames="true">
<variable name="LOGGER" expression="variableOfType("org.apache.log4j.Logger")" defaultValue="log" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="true" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="false" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>
<template name="logdec" value="private static final Logger $LOGGER$ = Logger.getLogger($CLASS_NAME$.class);$END$" description="Declares a log4J private static final logger" toReformat="true" toShortenFQNames="true">
<variable name="LOGGER" expression="" defaultValue=""log"" alwaysStopAt="true" />
<variable name="CLASS_NAME" expression="className()" defaultValue="" alwaysStopAt="false" />
<context>
<option name="JAVA_CODE" value="true" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="false" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>
<template name="lwarn" value="$LOGGER$.warn("$END$");" description="Loggs in error mode" toReformat="false" toShortenFQNames="true">
<variable name="LOGGER" expression="variableOfType("org.apache.log4j.Logger")" defaultValue="log" alwaysStopAt="true" />
<context>
<option name="JAVA_CODE" value="true" />
<option name="JAVA_COMMENT" value="false" />
<option name="JAVA_STRING" value="false" />
<option name="XML" value="false" />
<option name="HTML" value="false" />
<option name="JSP" value="false" />
<option name="COMPLETION" value="false" />
<option name="OTHER" value="false" />
</context>
</template>
</templateSet>


Just copy this content into a XML file (such as logging.xml), place it in ~/.IntelliJIdea50/config/templates/ and enjoy.

Wednesday, December 14, 2005

IDEA vs. Eclipse vs. NetBeans - which one to choose?

Introduction

Eclipse and IDEA are definitely the best java IDEs around, and nobody can deny that. Now about the two of them, a flame war is going on, similar to Unix vs. Windows, VI vs. Emacs, Java vs. .Net.... NetBeans on the other hand, wasn't a very bright product in the past, but version 5 (beta) has a decent set of features that makes it almost a serious competitor for Eclipse and IDEA. Which one is the best? Which one is the best for you? What's the value and the subtle differences between all those cryptic features that seem all the same on paper? Hope this articles will help clarify some of these questions and more importantly, help you choose.

Code writing assistance

Code writing assistance is one of the most important features in today's modern java IDEs. It's what helps you gain time, lets you concentrate on the logic instead of searching for the name of that method you need to call, helps you analyze the code, reorganize it, make it more readable and maintainable.

Code completion

Code completion has been around for many years, in many development environments, not just JAVA ones. So the obvious question is: what could possibly get better about this? Well, you'll be surprised...

All three IDEs I'm examining here offer some form of code completion. If you type a few letters and then you press CTRL+SPACE, the IDE will offer you a set of choices: class names or variable names. The most advanced code completion features are offered by IDEA. The big difference when compared to the others is that IDEA's code completion is context aware. This means that options that are offered to you when you initiate code completion are filtered with respect to the code fragment where the cursor is located. Indeed, instead of proposing you all the classes of the universe - the universe being your project class path :-) - IDEA will only offer you a reduced, less confusing, set of choices which in 95% of the situations will result in compiling code and in 85% of the cases they'll promote on top of the suggestions list the entity that you're actually looking for. They call it smart code completion and it's not an exaggeration.

How does smart code completion work? For example, if you have int variables a, b, c, d and double x, y, z and you type a = CTRL+SHIFT+SPACE, IDEA will only propose you only b, c and d. Definitely not x, y or z and definitely not class names or other entities. For return statements: if your method returns Person, if you type return CTRL+SHIFT+SPACE IDEA will only propose you variables of type Person or its specializations and methods that return instances of Person. Same thing goes for throws statements: when activating code completion after a throw statement IDEA will only propose you instances of the exceptions that are declared to be thrown by the method which you edit.

Smart code completion also works very well when instantiating objects: in assignments, return statements or throw statements, when you activate code completion after the new keyword IDEA will propose you only suitable constructors, as previously explained. The detail level is pushed to limits never seen anywhere else. For example, suppose you have a variable called count and you want to initialize it by calling a method on a class. If that class has a getter that contains "count" in its name - such as getCount() or getObjectCount() - that returns the type of the variable, IDEA's smart code completion will preselect that method for you. All you have to do is press ENTER t select it.

One of the most important features regarding smart code completion in IDEA is that it can be activated without typing the first letters of he text you want to complete. This is very time saving features as in most cases it prevents you from having to scroll to the beginning or the end of the class to remember how that variable or method is named. IDEA will efficiently look up all variables and methods that match the type of the assignment or of the parameter you're looking for and propose only those. Same thing when you want to cast a reference to an object. Type ( CRTL+SHIFT+SPACE in front of the object you want to cast and IDEA will automatically insert the REQUIRED class name.

IDEA expands the concept of code completion by transforming it into an efficient code querying mechanism, which is ready to serve the right variable, parameter, method or class names whenever you need it, with respect to the context in which you invoke the functionality. And it also does a very satisfactory job in guessing which variable, parameter or method you wish use and preselecting it for you. Plus, it's extremely easy to use. You don't have to learn many keyboard shortcuts. Whenever you need assistance when writing code, press CTRL+SHIFT+SPACE and you'll be surprised how well it works.

Code completion and parameter guessing in Eclipse are disappointing, which is a shame, because I consider ECLIPSE to otherwise be a fairly good product. Compared to IDEA, what you get in Eclipse is a joke. It's as primitive as it can get. This may seem harsh, but its reality. You type int i = CTRL+SPACE and it will propose you huge list of entities containing all the classes in the class path, all variables, all methods.... After scrolling in that list for a while you will eventually find the entity you need. Smart code completion doesn't exist. It's just raw code completion without any context filtering. This is very frustrating because there are signs that the knowledge to implement smart code completion in Eclipse is there. You can see it with the javadoc code completion feature: if you type @throws CTRL+SPACE it will only propose exceptions that are declared by the method for which you write the comment. If I would be to designate a functionality in Eclipse that needs urgent improvements, this would be it. Code completion is one of the first features a new user comes in contact with. If Eclipse wants to attract IDEA users, the primitive code completion features now in place are a huge barrier. It's the main reason that kept me from adopting it.

Netbeans 5 (beta) offers about the same level of code completion functionality as Eclipse does, but slightly better and easier to use. You get class and local variables on top of the list and classes and packages at the end. That's a small detail but an important improvement already.

Well, the winner in this category is - you must have guessed - IDEA. By far. Netbeans comes in second, followed by Eclipse. Both offer very basic code completion but the functionality in Netbeans is slightly more usable.

Sunday, October 23, 2005

TESTARE - junit integration

I've started to work on JUnit integration for TESTARE, my java testing framework. My approach for this integration effort is to enable projects that have already invested a great deal into a JUnit based test development effort to easily implement in container testing. Apart from that, there are a few other advantages coming out of this, like TESTARE test cases will be automatically discovered and executed by JUnit test case/suite runners, like those in IDEA and Eclipse - this is already starting to work, the code is in CVS and you can do a checkout at java.net

The goal is also to support at least one other mainstream testing framework, like TestNG. This is because I don't want to discriminate TestNG users over JUnit users. I see TESTARE as a new layer, that enables in container testing for regular testing frameworks.

I would like to use this opportunity to notice the lack of support JUnit offers for writing extensions. In order to properly integrate TESTARE, I absolutely need the following:
* receive an event before the execution of the first test in the suite
* receive an event after the execution of the last test in the suite
* enable extension writers to register a factory to instantiate tests present in a class

Right now I don't have any of these. It would be really great if the JUnit team would rethink their approach on how to handle extensions. This would make the life much more easier for many extension projects. But I promise I'll write more in details about this and approach the JUnit team about it.