miércoles may 31, 2006

Thanks all, it was fun all the time.

Leaving Sun is possibly the most difficult decision that a Sun employee may ever make. Sun is not just a great company, but "The Great Company".

Sun has changed the world. A few years ago the data centers at many customers were a nightmare to maintain. It's Sun technology and innovation that has changed that. Java has made things easier. So has N1. So has Solaris. So has dtrace. So have all the different technologies and standards Sun has created during all these years. And, wait, there's more to come. Don't ever doubt it. Now, possibly now more than ever, Sun is changing the world.

And I have been lucky enough to be able to see that change. To actively participate in that change. To help Sun customers build systems that remain years after release, and that are flexible enough to accept new technologies and standards.

And during this travel I have been lucky enough to enjoy working with Great People. People that changes the world with their daily work.

It has been my pleasure to work with you all, guys. Thanks all for making Sun the greatest place to work at (and the toughest place to leave).

It's time for me now to start new personal and professional projects. The best of it is that I may be collaborating with you all, so I'll still be able to work with the best professionals in the world.

Thanks all, for everything,
Antonio

lunes may 08, 2006

Wrap it around a (J)Tree!

I don't mean you have to wrap your car around a tree like this. I'm talking of JTrees and Drag and Drop support.

Inspired by the Swing Hack # 27 (drag and drop in JTrees), I've built a tiny library that automagically provides drag and drop support for those JTrees built using a DefaultTreeModel. As a plus this wrapper eases popup menu handling, performs autoscrolling, automagically expands nodes, does not require the JTree to be extended, cooks the breakfast for you in the mornings and, well, has many other interesting features you may find useful.

More at antonioshome

jueves mar 23, 2006

NetBeans Cookies API Secret Unveiled

NetBeans Cookies API secret unveiled

I've always been wondering what a Cookie means when you're developing NetBeans. There're two answers to this:

  • The Official Answer, which is quite good.
  • The real thing, the hidden secret, which I observed moments before Geertjan started his presentation on NetBeans module development. Here's a photo:

I'll try to post tomorrow, more seriously, about the NetBeans Day and the Java Expo. It was a great experience.

Happy NetBean-ing,
Antonio

miércoles mar 22, 2006

I've met Geertjan!

while( true )
  System.out.println("I've met Geertjan Wielenga!");

Oh my! I'm still recovering ;-)

Well, the fact is that I wanted to meet him. As you probably know we're currently holding the Java Expo, Sun Tech Days and the NetBeans World Tour in Madrid, so there's all sort of interesting people around.

Geertjan allowed me to take and post this photo of him:

Geertjan's live blogging

While blogging live from the Java Expo.

He's presenting tomorrow (NetBeans Day). I'm eager to talk to him about NetBeans Module Development. Let me know if you want me to ask him anything.

Cheers,
Antonio

P.S.:
Things to improve for the next Java Expo:

viernes feb 24, 2006

Playing with JDBM (I)

I must admit I like JDBM for desktop applications. It looks extremely strong. And it is very compact. It's runtime weights only 85Kb so it looks perfect for Java Web Start downloads. Since JDBM is based on a B-Tree, it allows only for one key for queries, but this is probably good enough for me. The fact is that JDBM allows for different B-Trees in the same database. It also allows for other indexing techniques, such as hashing, so you can use a JDBM database as a huge hashtable for storing stuff. In this entry I explore the basics of using JDBM, so that I can reference them in further entries. (In the future I'll aggregate all JDBM blog entries into my Links Room). read more

jueves feb 16, 2006

Insistence on desktop persistence

I'm afraid I'll insist in lightweight desktop persistence without RDBMS in this entry (and maybe in a few others). I've found some nice B-Tree based storage mechanisms, that seem to be widely used out there. They're being used in NetBeans, blojsom and OpenJMS, for instance.
read more

miércoles feb 15, 2006

Persistence in desktop applications

Will you bundle a full RDMBS with your GUI applications? How are you persisting the model in your desktop applications? What are the trends in this area? Well. If you build a Swing application that needs to persist your model then you don't probably want your users to download and install MySQL first. Right?

This is the problem I'm facing with the RSS feed reader I'm buildling. I want to store all the RSS feeds somewhere and be able to search them. Stuff there should be indexed. That easy. Easy? Or not?

read more

Moving... and furnishing!

I'm moving !!. I don't own five computers as Jonathan does, but I'm a traveller. So it's difficult (and heavy) to carry all my stuff around the country countries. Keeping in synch my office computer, my laptop and any other computer I use is too much a hassle.

I've decided to store everything in my my virtual home, antonioshome.net and try to carry with me as less as possible.

So that's one of the reasons why I've been a little bit quiet lately. Another one is that I've been doing some research (more in this later) and, well, of course, overloaded with work. I hope you understand (and forgive me for not posting).

I'm still furnishing this virtual home (you know: I hate moving ;-)), so bear with me meanwhile.

I'll try to post here too, but I've a blog at home (quite cute, a PHP one!). And keeping two blogs in sync is too much overhead. So if you're interested in participating in my new blog please update your bookmarks.

And if you have any suggestions on new rooms for antonio's home, then please just let me know.

Thanks,
Antonio

viernes ene 20, 2006

NetBeans 5.0 RC2 is out!

I cannot believe it. I haven't had time to evaluate 5.0 RC1 but ... 5.0 RC2 is out!!

I wonder what the NetBeans team has for breakfast. Wow, this is impressive job, guys!!

Enjoy,
Antonio

jueves ene 19, 2006

Look, Ma: Running SwingWorkers...

See ma? They're running there...

Screenshot of test application

So continuing my last post I decided to build an easy-to-use SwingWorkerManager to monitor how my SwingWorkers run in the wild.

I've built a SwingWorkerManager.getInstance() singleton to which I "submit( SwingWorker )" for execution. The SwingWorkerManager has a little ListModel that keeps track of the last executed SwingWorkers (by adding PropertyChangeListeners to them) and monitors their activity.

Apart of this ListModel the SwingWorkerManager can create also a ListCellRenderer to better visualize SwingWorker progress.

Source code (LGPL'ed) is available. Of course you can also run this little Java WebStart demo (note: JDK 5.0 required). Instructions for using the SwingWorkerManager are included in the javadoc documentation.

Sizing the pool...

So as I said before this SwingWorkerManager uses an internal thread pool to execute SwingWorkers. As Jeffrey wisely pointed out in his comment, the size of the pool should depend on the number of available processors NCPU in the environment (that is, it should be a linear function of NCPU=Runtime.getRuntime().availableProcessors()). So, continuing our previous discussion:

M = F \* NCPU < N 

Where M is the number of threads in the pool, F is a constant, NCPU is the number of CPUs in the system and N is the number of scheduled tasks.

Since usually many threads are just waiting for I/O it would be a waste of time to set F=1 (since then many CPUs would be just hanging around waiting for I/O). So I think a good F value could be around 3. That way we'll kick those lazy CPUs. You know, CPU speeds are very high nowadays, and CPU cycles are probably cheaper than any other kind of resource.

So let's assume F=3 is a good bet. Are we missing something? Well, er.. what about those slow ones?

Come on, you lazy one, hurry up, get out of my way...

Assume you're downloading a 10 Gb file from somewhere. You, of course, want to use a SwingWorker for that. But that's gonna take quite some time. And we're using a fixed thread pool, right? So that task is going to reduce the size of our fixed thread pool (and, thus, reduce the responsiveness of our GUI).

How could we handle this? Well, two solutions come to mind...

  • a) Increase M slightly to make room for these slow ones.
  • b) Use another fixed thread pool to schedule these very long-running, very time-consuming slow processes.
  • c) Use one of the above and provide a timeout setting for scheduling tasks. That way those tasks that have not finished before the given timeout value would be automatically interrupted.

The two first ones are not difficult to implement...

Solution a) would require this value for M:

M = F \* NCPU + SLOW < N 

Where SLOW is a fixed value that approximates the number of simultaneous slow processes you think may be running in your application.

And solution b) would require adding a new fixed thread pool (of size, say, SLOW) and a new method (say "submitSlowTask( SwingWorker )") that schedules things into this new fixed thread pool.

The third solution won't be too difficult to implement, either (by slightly increasing M to allocate timeout watcher SwingWorkers).

What do you think? Which one do you like best? Come on, give me a hand here! ;-)

The wonderfully complex world of task scheduling

Many Task Scheduling algorithms are NP hard problems. The SwingWorkerManager presented here implements a simple FIFO (First In-First Out) solution to scheduling SwingWorkers in a set of threads.

SwingWorkerManager may be a good way to experiment different task scheduling algorithms (say, in a Computer Science classroom), but I think a FIFO is good enough for me. And, of course, I can watch my SwingWorkers running. See ma? I hope it's good for you too (and if not, then just complain here! ;-)).

Please let me know of any improvements or bugs.

Happy swinging,
Antonio

domingo ene 08, 2006

SwingWorker: Throttling and monitoring?

The problem

I have a lot of RSS feeds to read. And I want to read them in my Swing application without blocking the event dispatch thread.

So, of course, I want to use SwingWorkers to fetch and parse all RSS feeds.

My first approach would be to create a SwingWorker for each of the RSS feed URLS. The SwingWorker would then download the RSS feed from the given URL (using a java.net.HttpURLConnection, for instance) and then parse it.

So I instantiate 200 SwingWorkers, each one holding a different URL, and "execute()" them. Cool.

But... wait a moment. 200 SwingWorkers? That's 200 threads, right?

Well, yes. That's 200 threads. And that's a problem too!

So, to summarize:

If you have a big number of tasks to execute asynchronously don't use a thread for each one.

Most operating systems won't complain directly if you create a big number of threads, but probably the system will be slow. There will be a lot of context switching between threads. And synchronization between them (if any) may be a problem.

Throttling

So in order to keep resource-consumption under control we would probably want to introduce some throttling. This is, we want to define a number M of simultaneous threads to execute those N tasks. And, of course, having M < N.

A pool of M threads seems a good idea to me. Building a pool of threads using Java 5 is a piece of cake:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
...
int M = 3;
ExecutorService threadPool = Executors.newFixedThreadPool( M );

And, well, executing SwingWorkers using that thread pool is also a piece of cake: we just need to invoke the "submit()" method on our Executor. Like this:

SwingWorker mySwingWorker = ...;
threadPool.submit( mySwingWorker );

Note that the SwingWorker can be cancelled as usual, this is, the SwingWorker semantics are not lost if you use your preferred ExecutorService. What I mean is that in order to cancel a SwingWorker you still can use the "cancel()" command as usual (and it's not necessary to handle the threadPool in any way). Like this:

mySwingWorker.cancel();

Having an ExecutorService is handy if you have a lot of things to do: you submit them all and that's all. The FixedThreadPool places all the pending tasks in an unbound queue. And then starts executing them in order. When one task finishes the thread is returned to the pool. If there are any pending tasks to be executed then the recently released thread starts executing one of those.

So, for instance, if we have N SwingWorkers to be executed stored in an ArrayList we can submit them all for execution with the following code:

ArrayList<SwingWorker> mySwingWorkers = ...
// This loops over all N workers to execute...
for( SwingWorker worker : mySwingWorkers )
  threadPool.submit( worker );

The Singleton Pattern

It may be interesting to have a reference to that ExecutorService handy in our application. We can achieve this by using the Singleton pattern. Something like this:

import ...;
public final class SwingWorkerExecutor
{
  /\*\* Number of threads in the pool. \*/
  private static final int M = 3;

  /\*\* The ExecutorService. \*/
  private static ExecutorService threadPool
    = Executors.newFixedThreadPool(M);

  /\*\*
   \* Schedules a SwingWorker for execution.
   \* @param aWorker a SwingWorker to execute.
   \*/
  public static <T,V> void execute( SwingWorker<T,V> aWorker )
  {
    threadPool.submit( aWorker );
  }
}

So we can say something like:

  SwingWorkerExecutor.submit( mySwingWorker );

What else? Monitoring?

We can also take advantage of this SingletonPattern in some other interesting ways. Monitoring, for instance. This is what I'm thinking of currently:

  • Make the SwingWorkerExecutor keep a ListModel with the list of the currently running SwingWorkers.
  • Or, even better, make the SwingWorkerExecutor keep a TableModel with the list of the currently running SwingWorkers, and their current progress.
  • Keep statistics inside the SwingWorkerExecutor about the average wait time (in the unbounded queue) and the average run time. This may be interesting to fine-tune an appropriate value for M (the number of threads) for different scenarios.
  • Build a mechanism for allowing time-out on execution of SwingWorkers

So I was wondering what you think. Do you see any other uses for such an hypothetical "SwingWorkerExecutor"? Any ideas or suggestions?

Cheers,
Antonio

UPDATE:

As Vaidya points out the SwingWorker implementation in JDK 6 has a pool of 10 threads, so it won't ever fire 200 threads.

miércoles dic 28, 2005

Happy New Year

Happy New Year!! I wish you all a Happy New Year 2006. I'll be unplugged for some days (Xmas break :-)), but couldn't resist wishing you a Happy New Year!!!

I would also like to thank all people that have contributed comments. It's these people that are making this an interesting place. Thanks everybody!!

As a new year resolution, I'll try to make this blog a little more active. By the way, would you like to see something in particular addressed here, then please just let me know.

My best wishes,
Antonio

lunes dic 19, 2005

2927 JNLP applications, wow!!

I've seen at JavaHispano that somebody has grouped a total of 2927 JNLP applications in a single page for you to run. Check it yourself. (lots of games, too). Impressive!!!

RSS: One stylesheet to rule them all?

Bloglines and RSS parsing

As you probably know I've been exploring Bloglines services to easily build just another RSS reader. The fact is that I have found no services to handle channels. This is, you cannot programmatically add/remove/update channels. Too bad. :-(

So, unless I'm completely wrong, we'll have to parse RSS ourselves.

First approach: Rome

The very first approach is, of course, Rome, Sun's open source project for RSS parsing.

But, to be honest, Rome is too big for my liking, too powerful for my modest needs. It depends on JDOM (which, luckily, seems to depend on nothing else). Rome is very good to parse in detail all sort of RSS flavors. All I want it to have a least common denominator of different RSS flavors. RSS 0.91, RSS 0.92, RSS 1.0, RSS 2.0 and Atom 1.0 would be good enough, I think.

Furthermore, I'd like to do it myself so as to exercise Java XML APIs. After all I need to keep up with those things, it's some sort of hobby of mine ;-).

SAX Parsing: the cost of speed

So my very first approach was to go for speed, using SAX parsers. I've built a SAX handler that is chained with other different SAX handlers for every different flavor of RSS.

And, to be honest, the thing works quite fast. SAX parsers consume little memory and run really fast.

But after all the experiment those SAX handlers looked to me quite similar to AWK scripts. This is: they're difficult to maintain. I don't think I'll be able to modify those RSS handlers myself within, say, one month from now.

XSL to the rescue?

So I thought, why not use an XSLT stylesheet to extract information from those different RSS flavors (RSS 0.91, 0.92, 1.0, 2.0, Atom 1.0) and transform those different flavors in a least common XML file? Then with a single SAX parser I'd be able to parse all sort of RSS flavor.

And, since all transformation is handled in a XML file (the XSLT stylesheet) it should be easier to maintain. Of course there's a cost for this ease of mainteinance: we're loosing speed.

I'm sort of tired now (it's difficult to write coherently, sorry by that), but I think a small diagram could explain things better. There we are:

I've been doing some tests and, well, there's some lack of speed. But I think it's worth the effort. Simpler, smaller, easier to maintain, no dependencies... I like it.

What do you think? Any suggestions? Any way to improve the XSLT stylesheet? (By the way, the XSLT stylesheet can be found here).

Cheers,
Antonio

viernes dic 16, 2005

Mozilla, Paulo Coelho and customer bases

Mozilla

It seems Mozilla and Firefox are the most used browsers hitting the place. This is a graph of the last 100 browsers used to see this blog:

Last 100 browsers

That's a total of 39+12+9+1+1 mozilla (or mozilla firefox) browsers hitting the place. A total of 62% of browsers. Wow.

Paulo Coelho

It happened by accident. While at the bookstore I happened to meet a portuguese version of Paulo Coelho's "O Diário de um Mago" ("Diary of a Wizard"). I think the english translation is entitled as "The Pilgrimage: A Contemporary Quest for Ancient Wisdom" although I'm not sure. (It talks about a pilgrimage to Santiago de Compostela, the city were I was born).

It's a great book. After that I've met "O Alquimista" and "Brida". All three in portuguese. Nice read indeed. I highly recommend them. These Paulo's books are easy to read (at least in portuguese ;-)) and they talk about the really important things in life.

So what does mozilla have to do with Paulo Coelho?

Well, nothing at all, of course. The fact is that I'd like to learn some portuguese (a very difficult language, from my point of view) and I was told about this virtual school of portuguese. The fact is that the site does not work with Mozilla nor firefox (the browsers I own).

That is, put simply, just stupid. Making a web site that accepts only Internet Explorer and Microsoft users is not a good idea. If my site statistics are right you'll probably loose 64% of your potential readers. So, by making things Internet Explorer specific, you're loosing 64% of your potential clients.

And, well, loosing 64% of your potential clients in your very first page in your web site is just stupid, isn't it?

But, wait, there's even more. You can't visit "Santiago's Way" official site either! Xacobeo (which means "from Jacob" in english, you know, Santiago means "Saint Jacob", actually).

Who selects who?

And this is more food for thought. Trying to select your customer base by rejecting users that don't use your tools is not a good idea. Because it may become against you. After all, who selects who? Who rejects who? Is it web sites selecting and rejecting readers just for the browsers they use, or is it the other way round? The answer is obvious to me: I reject sites not accepting firefox. Full stop.

So, since I cannot learn portuguese using Escola Virtual maybe I can learn it anywhere else. Any ideas, anyone?

Thanks!
Antonio

Update: Escola Virtual is working now in Mozilla right now. Damn it! I've already written this blog entry!

About

swinger

Search

Archives
« julio 2014
lunmarmiéjueviesábdom
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   
       
Hoy