Yesterday I was at Joe Cocker's concert and the day before at a concert from the Gospel Institut to celebrate the end of their courses... and the late arrival of summer (even though we had a few drops during the concert).
There was no security to take my camera at that concert and I could grab a few pictures before it was too dark. My 18-200mm lens needs lots of light and the D60 does not give great pictures when pushing in the ISO. I wish I had a 50mm f/1.4 to take pictures late in the concert when the raw emotion was more palpable on the singers' faces.
I particularly enjoyed a beautiful interpretation of Eric Clapton's Tears In Heaven. One of my favourites songs makes for a great gospel full of soul and emotions.
I had a great time at that concert listening to all the singers and musicians and taking pictures but I am disappointed by their low quality. I need to practice more on low light settings and invest in the Nikon 50mm f/1.4 to get better results. The photograph would still be to blame for the unoriginal compositions :)
Yesterday, Joe Cocker was at Jazz a Vienne and it was thrilling to listen to him:
I love going to Jazz a Vienne: the location is spectacular, the sound is great and the artists are always top notch!
I was annoyed that the security did not let me keep my camera. I wanted to take some nice pictures with my 70-300mm and all I had was my iPhone and some low-quality HDR snapshots...
I just spent one week at Lanzarote in the Canary Islands to learn surfing, do some sightseeing and take some pictures.
It was my first surf experience and I managed to ride some waves at the end of the week (no, it's not me on the picture above, my waves were smaller) and loved the feeling. Once up on the board, it reminded me of snowboard but even more intense and more lively as I have to adapt to the wave, its shape, its speed and direction. However I was also surprised by the amount of paddling which was required, I must have paddled 10 minutes against the waves for every 10 seconds up on the board. But every one of these 10 seconds was worth it :)
If you want to learn surfing at Lanzarote, I recommend Volcano Surf School. Sabine and Seb are very friendly, passionate about surf and Nico is a great teacher. Tell'em hi from me!
Just before going to Lanzarote, I bought a new zoom lens: a Nikon 70-300mm /4.5 AF-S VR which was great to shoot surfers and birds. Unfortunately I did not have a lot of time to get used to it and learnt on the fly how to use it properly. The surfer picture above is one of the last I took when I finally started to get a handle on the lens.
Lanzarote's landscape is spectacular with many volcanoes of different heights and shapes. The volcano below was the main location of the greatest recorded eruptions which occurred between 1730 and 1736:
The wineyards are also spectacular: they are buried in the volcanic soil and protected from the wind by small stone walls:
This week was lots of fun, lots of sport and lots of good food and wine! I made some good new friends and I am looking forward to surfing again. Next time won't come soon enough!
I just received my copy of Cocoa Programming. At first glance, the book seems a good update for Mac OS X development.
It has been quite a few months since I did Mac (and iPhone) programming. I have not looked deeply at Core Data and Grand Central Dispatch yet. I also want to experiment with Objective-C blocks.
I need to find a suitable idea for a Mac application to prototype and experiment. Any idea or suggestion is welcome!
Exchanging messages directly between a Web browser and a messaging server is an interesting use case. There are many ways to do this (AJAX, Comet, etc.). The most recent way is to use Web Sockets.
What are Web Sockets?
Web Sockets are "TCP for the Web". A Web Socket is a bi-directional communication between a browser and a server that follows the HTTP same-origin model (you can only connect to a server on the same origin than the HTTP request that served the page).
Web Sockets support has been checked in HornetQ Subversion repository. Since Web Sockets are like TCP sockets, we needed to add a protocol on top of it with messaging semantic. A perfect candidate for this was Stomp, a text-base messaging protocol. I have created a JavaScript library, stomp-websocket, which makes it very simple to send and receive Stomp messages over Web Sockets.
How do you send a message from the browser to a Stomp broker? The steps are always the same:
create a Stomp.client with the broker endpoint URL
connect to the broker with user credentials
register a callback to be notified when the client is connected and authenticated
send a message to the broker on a given destination
var client = Stomp.client("ws://blackbook.local:61614/stomp");
client.connect("guest", "guest", function() {
// called back after the client is connected and authenticated to the Stomp server
client.send("/queue/test", {priority: 9}, "Hello, from the browser");
});
Receiving messages from the broker involves an additional step where the client subscribes to a destination:
client.subscribe("/queue/test", function(message)
{
// called back every time the client receives a message from the broker for the destination
$("#messages").append("<p>" + message.body + "</p>\n");
};
stomp-websocket documentation explains in more details how to use the library. The project is hosted on GitHub and ships with a chat example where browser clients sends and receives messages from a topic.
HornetQ Implementation
Web Socket and Stomp support in HornetQ are quite new and a bit rough around the edges (e.g. no implicit mapping between Stomp message and JMS messages, destinations mapping to addresses and queues). Do not hesitate to report issues in HornetQ bug tracker and contribute patches.
To accept Web Sockets connection from port 61614, add a <acceptor> to hornetq-configuration.xml:
Web Sockets can then connect to ws://localhost:61614/stomp endpoint.
Web Sockets Status
Web Sockets is a recent Web technology and few browsers support it (only WebKit nightly builds and Google Chrome at the moment). The protocol is a moving target (at the time of this writing, the handshake specification is changing significantely) and applications using Web Sockets may break until browsers and servers agree on the protocol.
Besides, the specification status is a bit unclear. The protocol is at the IETF but the revised draft is at WHATWG, while the browser API is at W3C. Mozilla is cautious (with reasons) to add it to Firefox and I have not seen any indication that Internet Explorer will support it. It is likely that its use on the desktop will not be widespread soon. However it may really shine on mobile platforms.
Both the iPhone and Android Web browsers are based on WebKit. Future releases of the platforms will likely add support for Web Sockets (but I did not find any roadmap for it...). With Web Sockets, browsers on Android, iPhone, iPad will be able to send and receive messages in a simple and efficient fashion. Combining that with offline support, Web developers have great tools to build Web applications.
I am looking forward to seeing what they will come up with!
The user proposed to have jmx4r objects implement [] and work like a Hash to support dotted names. I am not convinced that such edge cases are worth supporting [] but if you think otherwise, do not hesitate to vote for this feature and I will add it to jmx4r.
HornetQ is an open source project to build a multi-protocol, embeddable, very high performance, clustered, asynchronous messaging system
Yesterday, we released HornetQ 2.0.0 which supports 2 messaging APIs, JMS and HornetQ's own Core messaging API. However, we already have users who wants to use HornetQ in non-Java environments.
One solution is to use Stomp with HornetQ so that any Stomp clients can communicate with HornetQ.
To show how to setup HornetQ and Stomp together, I created a project with the source code and all the required jars on GitHub:
The source code consists in a single class which configures and starts a fully functional standalone HornetQ server and connects it to Stomp:
public class HornetQStompServer {
public static void main(String[] args) throws Exception {
Configuration configuration = new ConfigurationImpl();
// to keep things simple, we disable security. In real use, we'd setup authentication properly
configuration.setSecurityEnabled(false);
// we add a In-VM acceptor to HornetQ as the server will be accessible outside using Stomp
configuration.getAcceptorConfigurations().add(
new TransportConfiguration(InVMAcceptorFactory.class.getName()));
// we add a Queue which will be available to Stomp under /queue/a
configuration.getQueueConfigurations().add(
new QueueConfiguration("jms.queue.a", "jms.queue.a",null, true));
// we create the HornetQ server using this config
HornetQServer hornetqServer = HornetQServers.newHornetQServer(configuration);
// we also create a JMS server manager as Stomp is using the JMS API
JMSServerManager jmsServer = new JMSServerManagerImpl(hornetqServer);
// starting the JMS server will also start theHornetQ server underneath
jmsServer.start();
// We create directly a JMS ConnectionFactory which will be
// connected to the HornetQ server using In-VM connection
ConnectionFactory connectionFactory = HornetQJMSClient.createConnectionFactory(
new TransportConfiguration(InVMConnectorFactory.class.getName()));
// We inject the connection factory in Stomp
StompConnect stompConnect = new StompConnect(connectionFactory);
// and start it using default Stomp config
stompConnect.start();
}
}
As both HornetQ server and clients are in the same Virtual Machine, we use in-vm connections. There will be only one port opened: the port used by Stomp (61613 by default)
$ ant server
...
server:
[java] 14 janv. 2010 10:57:30 org.hornetq.core.logging.impl.JULLogDelegate info
[java] INFO: live server is starting..
[java] 14 janv. 2010 10:57:30 org.hornetq.core.logging.impl.JULLogDelegate warn
[java] ATTENTION: Security risk! It has been detected that the cluster admin user and password have not been changed from the installation default. Please see the HornetQ user guide, cluster chapter, for instructions on how to do this.
[java] 14 janv. 2010 10:57:30 org.hornetq.core.logging.impl.JULLogDelegate info
[java] INFO: HornetQ Server version 2.0.0.GA (Hornet Queen, 113) started
[java] 14 janv. 2010 10:57:30 org.codehaus.stomp.tcp.TcpTransportServer doStart
[java] INFO: Listening for connections at: tcp://BlackBook.local:61613
That's all you need to have a fully functional messaging server accessible to any Stomp clients.
To check that it works properly, we will use telnet as our Stomp client:
$ telnet localhost 61613
First, we connect to the server. To keep things simple, we have disabled security from the server so that we can connect to it anonymously:
CONNECT
login:
passcode:
^@
(^@ is Ctl-@)
The server replies that we are connected:
CONNECTED
session:null
We send a message to the destination /queue/a:
SEND
destination:/queue/a
hello, hornetq!
^@
To make things more interesting, you can now kill the server and restart it. The message that was sent to the queue is persisted and will be consumed after the server is restarted.
Once the server is restarted, we open a new Stomp client and connect to the server:
By leveraging HornetQ & Stomp, you can use messaging queues in your applications regardless on the platform you use.
One key decision of HornetQ was to make it simple to embed and integrate with other projects. This simple example shows that we reach our goal with Stomp.
jmx4r 0.1.0 has just been released (jmx4r is a JRuby library which makes it super easy to write simple Ruby scripts to manage Java applications using JMX).
fixed dynamic mbean issues where attributes and methods were added to all the dynamic mbeans in the thread (thanks Munesse!)
There is also two new features:
support for Java CamelCase style in addition to Ruby snake_case (thanks again to Dan)
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging"
# Ruby syntax works
logging.set_logger_level "global", "FINEST"
# Java syntax works too
logging.setLoggerLevel "global", "FINEST"
Connection to a local JVM (thanks to Mr ohtsuka). You can now connect to a JVM running on the same machine without adding the com.sun.management.jmxremote system properties.
For example, start an instance of jconsole without any additional system properties:
$ jconsole &
You can now manage this Java application locally:
require 'rubygems'
require 'jmx4r'
# :command is a regexp corresponding to the Java process to connect to
JMX::MBean.establish_connection :command => /JConsole/
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
memory.gc
In addition to the previous :host, :port and :url arguments that you can pass to establish a JMX connection, there is now :command which must be a regular expression corresponding to the local Java process you want to connect to. You can find the name of the process using jps:
$ jps
4255 JConsole
4395 Jps
You can connect to a local Java application running on Java 5 or 6. Is someone interested to contribute support for JDK7 too?
Once again, thanks to all the contributors and users who help make jmx4r even more useful!
As usual, to get this new release, just update the rubygem:
I created an Automator Service to create a Gist from a text selection. This service will create the gist and copy the corresponding URL to the clipboard so that it can be pasted in IRC or in a web browser
Since it can take a few seconds to create a Gist, I added a Grow notification: drag and drop Utilities → Show Growl Notification
Save service as "Gist Code"
You will end up with this service:
Gist Code
Now, you can select any text1, right-click and select Gist Code:
Mate
It also works from the Terminal using the application menu Terminal → Services → Gist Code
Once the gist has been created, you will be notified by Growl when the gist URL is copied to the clipboard. You can then paste this on IRC or in a web browser: http://gist.github.com/213301
By default, the gist will be saved as plain text (you will need to change the type from the gist page directly). This service also uses Git to retrieve GitHub credentials so that the gist is added to your Gists (rather than anonymously).
This is a screencast showing how to create and use this service:
Enjoy!
It only works for Cocoa text widget. At first, I wanted to use it with Eclipse but unfortunately Eclipse does not support Apple Services... ↩
These books are not necessarily the most complete references and they do not cover all features offered by the languages but I found that they gave me the best insight to understand and think with these languages.
One language I did not list is Java. I have used Java for so long that the last introduction book I read was for version 1.2. Which book would you recommend to learn Java?
This is more than just Objective-C but I found that learning Cocoa stuff really make the language shine. ↩
I have not read Dive into Python 3 yet but I bet it is as good or even better than Dive into Python ↩