Ok, so I decided that (a) a laptop without the "Suspend" / "Hibernate" was only marginally more useful than a door-stopper and (b) that I could do it, if I really wanted.
I'd also discovered that, out of the box, Ubuntu would not support an external monitor - which was a bit unsettling, as I was due to give a presentation the next day (to no less than Google folks!) and was planning to do so from the laptop.
Fire up Google, search for "Ubuntu dual head" and up pops HowTo: Dual Monitors a very well written article, with plenty of detail.
It turns out that the source of so much misery were the missing nVidia drivers - installing them following this How-To was a piece of cake and that also had the nice side effect to enable the external monitor.
One thing that still troubles me is that I have been thus far unable to find a way to make Ubuntu recognise the special function keys (you know, the ones that allow you to change brightness, volume, etc. and, critically, switch the LCD/External monitor) so to have the external monitor to work, one has to re-start (Ctrl-Alt-Backspace) the X server.
I have so far been unable to make Twinview work and I am using Xinerama instead - although, apparently, Twinview was designed exactly for nVidia cards, my (admittedly, feeble) attempts to make it work have miserably failed: I decided that life is too short and can live quite happily with Xinerama.
A more general consideration is that it took me the best part of a Sunday afternoon and several trial and errors (for God's sake, whatever you do, make a backup of xorg.conf at each and every step - trust me, you'll need them!) - to achieve something that Windows gives you straight out of the box (and, to be fair, most Linux distros): I am still quite unsure whether choosing Ubuntu was as clever as I thought it was.
On balance, I'd recommend Suse Linux: I have v. 10 installed on my other laptop (a much older one that I use as a staging server for my Tomcat Java apps) and it is much easier to manage, configure and, generally, use.
Also RedHat's Fedora Core felt a lot easier to use, although much less "flashy" than Ubuntu.
I used to run FC4 on yet another laptop as a development/testing box - had all sorts of servers and tools running on that one: despite years of abuse, I never really managed to crash it: the same, sadly, can't be said of my Windows dev PC, that recently enjoys crashing on me rather spectatularly): I can only assume that FC6 is even better (and FC7 is about to be released).
Now, if only I could get the little battery guy to see some sense ...
(although, I must admit it's got its amusement value: yesterday warned me of 5 remaining minutes of power as soon as I unplugged the power cable, after an entire day charging)
This blog was born as a means of annotating big and small discoveries in my use of Java, Ubuntu/Linux and Android that would be easy to access from anywhere, anytime. It does beat post-it's big time, and it also adds the benefit that others might, eventually, contribute with intelligent insights.
Saturday, May 19, 2007
Monday, May 7, 2007
Ubuntu, NetBeans and Sun's Application Server (Glassfish)
I have recently read that Sun and the folks behind the Ubuntu Linux distro are getting some sort of strategic partnership and closer cooperation.
Well, not one day too soon, say I.
For the poor souls like myself that have been struggling to get Ubuntu to be a bit more co-operative and let the Sun App Server (SJAS) do its stuff, it's been quite trying.
For a start, although I may intellectually agree with Ubuntu's desire not to let root roam free and cause havoc, that is hardly helpful when people like myself spend 90% of their time on a Linux box doing exactly the kind of stuff root is supposed to be doing (set-up the server, install and remove stuff, create/delete/fiddle endlessly with configuration options, firewall, user access rights, and other highly amusing stuff...)
The novelty of having to type endlessly sudo/gksudo sort of wears thing after the 900th time you've done it in two hours....
However, having decided to endure it for a while and see whether that would lead to a better world, I made a fundamental mistake...
I installed NetBeans, SJAS and MySQL (server) as root
Now, isn't this what you are supposed to do?
As root, you install the applications, and then create 'safe zones' for the users (or, equivalently, assign rights to mysql users) so that they won't mess up with the installation and other users' data.
Well, if you do that, NetBeans, SJAS and MySQL won't love each other, in fact they'll loathe each other, the world and, most critically, you!
For example, SJAS will start (well, sort of), but NetBeans won't be able to figure it and will sit there endlessly until it times out (and, by the way, whoever set the timeout value must have a Buddhist monk, as it takes forever to do so!)
MySQL for its part will install and start well enough, but then won't let you create new databases and/or new tables on existing ones - unless, that is, you go manually in /var/lib/mysql and change (chown) ownership to the user.
Something I don't particularly like, but let's face it, who else is going to fiddle with that dir?
Hackers? never!
So there you have it: if you want NB, SJAS and mysql to happily talk to each other, the only solution I have found is to create a /development folder in which to install them - whose ownership is for the 'users' group, and install them both as one of the 'users'
As per mysql, it would seem that by keeping mysql:mysql as the user:group for /var/lib/mysql location makes it all work.
However, to be totally, honest, I'm rather sick and tired of Ubuntu: I have installed it on a Sony Vaio laptop (not exactly a rare or exotic choice of hardware) and almost nothing seems to work as intended:
I mean, none of this is reason enough to go back to Microsoft Windows (one thing is not being able to hibernate, another is having to reboot every couple of hours or so, and having your server wide open to anyone who's bothering to hack into it) - so I've ordered Sun Solaris 10, one would hope that its integration with Sun's Application Server and NetBeans is slightly better.
Watch this space...
Well, not one day too soon, say I.
For the poor souls like myself that have been struggling to get Ubuntu to be a bit more co-operative and let the Sun App Server (SJAS) do its stuff, it's been quite trying.
For a start, although I may intellectually agree with Ubuntu's desire not to let root roam free and cause havoc, that is hardly helpful when people like myself spend 90% of their time on a Linux box doing exactly the kind of stuff root is supposed to be doing (set-up the server, install and remove stuff, create/delete/fiddle endlessly with configuration options, firewall, user access rights, and other highly amusing stuff...)
The novelty of having to type endlessly sudo/gksudo sort of wears thing after the 900th time you've done it in two hours....
However, having decided to endure it for a while and see whether that would lead to a better world, I made a fundamental mistake...
I installed NetBeans, SJAS and MySQL (server) as root
Now, isn't this what you are supposed to do?
As root, you install the applications, and then create 'safe zones' for the users (or, equivalently, assign rights to mysql users) so that they won't mess up with the installation and other users' data.
Well, if you do that, NetBeans, SJAS and MySQL won't love each other, in fact they'll loathe each other, the world and, most critically, you!
For example, SJAS will start (well, sort of), but NetBeans won't be able to figure it and will sit there endlessly until it times out (and, by the way, whoever set the timeout value must have a Buddhist monk, as it takes forever to do so!)
MySQL for its part will install and start well enough, but then won't let you create new databases and/or new tables on existing ones - unless, that is, you go manually in /var/lib/mysql and change (chown) ownership to the user.
Something I don't particularly like, but let's face it, who else is going to fiddle with that dir?
Hackers? never!
So there you have it: if you want NB, SJAS and mysql to happily talk to each other, the only solution I have found is to create a /development folder in which to install them - whose ownership is for the 'users' group, and install them both as one of the 'users'
As per mysql, it would seem that by keeping mysql:mysql as the user:group for /var/lib/mysql location makes it all work.
However, to be totally, honest, I'm rather sick and tired of Ubuntu: I have installed it on a Sony Vaio laptop (not exactly a rare or exotic choice of hardware) and almost nothing seems to work as intended:
- I can't get it to hibernate / standby, as the display won't come back;
- I can't get it to see the "special function" keys (brightness, function keys, external display, etc.);
- the battery meter is a confused little guy (how for a battery meter that tells you that there is 63% left - correctly - and then goes on to state that "only 5 minutes " are left?);
- sometimes, when the screen saver comes on, the display colours palette gets entirely messed up and the only way to get back a sembiance of normality is to log off and log back in (effectively, restarting the X server).
I mean, none of this is reason enough to go back to Microsoft Windows (one thing is not being able to hibernate, another is having to reboot every couple of hours or so, and having your server wide open to anyone who's bothering to hack into it) - so I've ordered Sun Solaris 10, one would hope that its integration with Sun's Application Server and NetBeans is slightly better.
Watch this space...
Dynamic Pages adds AJAX to your JSF pages
I was going through the "Adding Ajax to JavaServer Faces Technology With Dynamic Faces" tutorial, and it occurred to me that it would have been a much more AJAXy solution to have the check on the existence of the User ID to occur when the user moved to the next field (without the need to click on a button - which is so Web 1.0 !)
That is easily done, by removing the "Check for user ID availability" button altogether, and adding the Dynamic Faces action on the 'onblur' method for the user ID text field:
The
It is also worth noting that the installation instructions at the beginning of the article are particularly uninformative - in fact, it is NOT necessary to download and install the Sun Developer Web Pack (I found the idea particularly frightening, as apart from the installation process being particularly cumbersome, it also seemed like the shortest path to messing up my carefully crafted NetBeans / Tomcat / Sun App Server (GlassFish) settings).
In fact, jsf-extensions (Dynamic Faces) is likely to already be in your NetBeans installation (if you have installed the Visual Web component) or, equally simply, can be installed by downloading it from the Dynamic Faces Project page.
That is easily done, by removing the "Check for user ID availability" button altogether, and adding the Dynamic Faces action on the 'onblur' method for the user ID text field:
<!-- Dynamic Faces usage follows: -->
<h:inputText required="true" id="userid" autocomplete="off"
binding="#{Register_Backing.userid}"
valueChangeListener="#{Register_Backing.userIdChanged}"
onblur="DynaFaces.fireAjaxTransaction(this, {
execute: 'userid',
render: 'userIDAvailableMessage',
immediate: true});
return true;" />
<h:message for="userid" errorClass="ValidateError"/>
<br />
<!-- this is the element rendered by the AJAX request -->
<h:outputText style="{color: red}" id="userIDAvailableMessage"
value="#{requestScope.userIDAvailableMessage}" />
<br />
The
userIdChanged
method in the Register.java class simply calls the original checkUserIDAvailable
method:public void userIdChanged(ValueChangeEvent e) {
ActionEvent aev = new ActionEvent(e.getComponent());
checkUserIDAvailable(aev);
}
It is also worth noting that the installation instructions at the beginning of the article are particularly uninformative - in fact, it is NOT necessary to download and install the Sun Developer Web Pack (I found the idea particularly frightening, as apart from the installation process being particularly cumbersome, it also seemed like the shortest path to messing up my carefully crafted NetBeans / Tomcat / Sun App Server (GlassFish) settings).
In fact, jsf-extensions (Dynamic Faces) is likely to already be in your NetBeans installation (if you have installed the Visual Web component) or, equally simply, can be installed by downloading it from the Dynamic Faces Project page.
Sunday, May 6, 2007
J2ME Multi-Threading and HTTP (Part 2)
In part 1 of this series, I have explained how to implement a LongRunningTask.
All the magic, however is done in the ControllerThread class, which takes care of executing the task, keeping tabs on it and, eventually, terminating it if it overstays its welcome.
Before getting on to ControllerThread, it is worth, however, to briefly review the Observer interface that will have to be implemented by the calling class.
We need an Observer here mostly for three reasons:
Bear in mind that we cannot "wrap" the call to Thread.start() with a try/catch block, as no exception will ever be thrown by this code - catching the TaskException is a job for the ControllerThread (and the reason why LongRunningTask does not implement Runnable).
The Observer interface is defined as follows:
Once a
The constructor takes a reference to the
ControllerThread does implement
All the magic is done in the internal class ControllerRunnable that implements Runnable itself and inside its run() method actually executes the LongRunningTask, wrapped in a try/catch block to catch failures.
As you can see, it is
This is critically important in the very frequent case of real-life applications that have multiple tasks that may be executing at any one time (and, possibly, even concurrently) and hence are likely to have state variables to control what's going on: in this case, calling twice complete() is almost as bad as not calling it at all.
Note also the wait/notify mechanism (
From an application developer's point of view, however, all of the above can be treated as "magic."
All one has to do to use this framework is:
Update: I have uploaded the source code to BitBucket, you can easily download it using Mercurial (see here for an intro) by simply using:
All the magic, however is done in the ControllerThread class, which takes care of executing the task, keeping tabs on it and, eventually, terminating it if it overstays its welcome.
Before getting on to ControllerThread, it is worth, however, to briefly review the Observer interface that will have to be implemented by the calling class.
We need an Observer here mostly for three reasons:
- because of the asynchronous nature of the call, we need a way to communicate back when we are done with our task (if you look back at the last snippet of code in Part 1, you'll notice that startRecording() returns immediately: however the recording itself will last a few seconds, until either the user stops it, or the ControllerThread "expires" - in this case, after 10 seconds at most);
- we may also want to be notified of progress (eg, by showing a "progress bar" to the user);
- most importantly, we need to be notified when the task failed (that is, a TaskException was thrown).
Bear in mind that we cannot "wrap" the call to Thread.start() with a try/catch block, as no exception will ever be thrown by this code - catching the TaskException is a job for the ControllerThread (and the reason why LongRunningTask does not implement Runnable).
The Observer interface is defined as follows:
public interface Observer { /** * A simple logging ability, this has to be implemented in a * thread-safe manner, eg wrapping the logging with synchronized blocks * * @param msg a simple logging message */ public void addMsg(String msg); /** * callback for signaling progress of time-consuming process, provides * an opportunity to either allow stopping the background operation or * update an UI element providing visual indication that the application * is not 'stuck' */ public void idle(); /** time-consuming operation complete, results, if any, are available */ public void complete(); /** acknowledgement of interruption, optional */ public void interrupted(); /** * This is called by the LongRunningTask to signal progress, could * be used to update some UI element (eg a progress bar) * * @param progress a value (meaningful to the application's semantics) * that indicates progress. Most typically, a value between 0 * and 100, to indicate percentage progress towards completion. */ public void announceProgress(int progress); /** Called when the task fails */ public void fail(TaskException tex); }
Once a
LongRunningTask
is started, it will either complete()
or fail()
: these methods will be called by ControllerThread
(not LongRunningTask
); the latter will either complete the execute()
method normally, or throw a TaskException
to indicate failure.ControllerThread
is a pretty long class: the full source code can be found here, only snippets of code will be shown in the following.public ControllerThread(LongRunningTask task, long waitInterval, long timeout, Observer observer)
The constructor takes a reference to the
task
to execute, an (optional) reference to an Observer
and two numeric values that indicate, respectively, how often it should check on progress and how long the task is given to complete its work.ControllerThread does implement
Runnable
- it is executed in its very own thread and creates (and executes) in turn another thread: as I mentioned in the first part of this article, to execute a background thread, you need two threads, just one won't do!public void run() { long start = System.currentTimeMillis(); long elapsed; Thread t = new Thread(new ControllerRunnable()); t.start(); while (!task.isDone() && !task.isStopped() && !failed) { wait_state = THREAD_STATE_WAIT; elapsed = System.currentTimeMillis()-start; if (elapsed > totalTimeout){ task.cancel(); wait_state = THREAD_STATE_EXPIRED; getObserver().interrupted(); return; } synchronized (lock) { try { // double-check to avoid race conditions if (!task.isDone() && !task.isStopped()) lock.wait(waitTimeout); } catch (InterruptedException ex) { failed = true; failureMessage = "ControllerThread interrupted"; t.interrupt(); getObserver().interrupted(); return; } } } // while }
All the magic is done in the internal class ControllerRunnable that implements Runnable itself and inside its run() method actually executes the LongRunningTask, wrapped in a try/catch block to catch failures.
private class ControllerRunnable implements Runnable { public void run() { if(task == null) { failureMessage = "No task to execute"; failed = true; getObserver().fail(new TaskException("No task to execute")); return; } try { task.execute(getObserver()); synchronized (lock) { lock.notify(); } getObserver().complete(); } catch(TaskException ex) { failureMessage = new String(ex.getMessage()); failed = true; getObserver().fail(ex); } } }
As you can see, it is
ControllerRunnable.run()
that calls the Observer
's complete()
or fail()
methods, and ensures that:- one and only one of those methods will be called;
- that they will be called at most once.
This is critically important in the very frequent case of real-life applications that have multiple tasks that may be executing at any one time (and, possibly, even concurrently) and hence are likely to have state variables to control what's going on: in this case, calling twice complete() is almost as bad as not calling it at all.
Note also the wait/notify mechanism (
lock
is simply an Object
, private
to ControllerThread
, used to synchronize the two threads) to signal the controlling thread that we are done and that is no longer necessary to wait. If the notification fails to arrive within the timeout
value set when creating the controller thread, the task will be terminated (see ControllerThread.run()
).From an application developer's point of view, however, all of the above can be treated as "magic."
All one has to do to use this framework is:
- write a time-consuming task as a single execute() method;
- wrap the time-consuming task in a class that implements LongRunningTask (bearing in mind that most of its methods are optional - only execute() is, rather obviously, mandatory);
- implement Observer in the calling class (most likely, a Controller class in an MVC pattern) - this will also include, probably, adding a "Stop" command to the UI as well as some sort of progress indicator (eg, a Gauge);
- wrap the call to the time-consuming task in the following code:
public class Multimedia implements Observer { // Observer interface implementation omitted here // ref. source code & Part II of this article public void startRecording() { task = new RecordTask(); thread = new ControllerThread(task, 1000L, 10000L, this); new Thread(thread).start(); } // Other stuff goes here... }
Update: I have uploaded the source code to BitBucket, you can easily download it using Mercurial (see here for an intro) by simply using:
https://marco@bitbucket.org/marco/j2me_threads
Subscribe to:
Posts (Atom)