Lady Java

This is video is quite recent, but already very popular. It's a parody of Lady Gaga songs, about Java. Looks like Oracle is gonna benefit of the Java wave even though they already declared themselves as bad asses, more interested on money and control than on technology.


Java rocks, and ever will. Despite Oracle.

JavaBeans to XML, with no libraries.

Converting JavaBeans to XML and viceversa is quite a common task, and there are tons of libraries around for this purpose.
But I always like to use what is already available in the JRE, avoiding dependencies as much as possible.
In the past I and Simone developed a rest API using the JSR57 serialization, that was already available in the Java 5. But Java 6 included JAXB in the standard libraries, which is more modern and flexible, and gives you a better control over the XML translation process.

Here I want to provide a couple of simple examples to show how those two API work.

Suppose we have some java beans "the model" as per following sources:


public class Book implements Serializable {
	String title;
	String author;
	Price price;
	public Book() {} //default constructor is mandatory for JavaBeans

	public Book(String title, String author, Price price) {
		this.title= title;
		this.author = author;
		this.price = price;
	}

	//... imagine the getter and setters boilerplate code here ...

	@Override
	public String toString() {
		return title + " by " + author + ", " + price;
	}

}

public class Price implements Serializable {
	Double amount;
	Currency currency;

	public Price() {}  // default constructor, as JavaBeans mandate...

	public Price(Double amount, Currency currency) {
		this.amount = amount;
		this.currency = currency;
	}

	//... imagine the getter and setters boilerplate code here ...

	@Override
	public String toString() {
		DecimalFormat fmt = new DecimalFormat("0.00");
		return fmt.format(amount) + currency;
	}
}

Two simple JavaBeans, a classical example: one models a book, with title author and price. And the price is composed by the amount and the currency. The Currency class with its hidden partner CurrencyData class are a funny couple in the JDK; if you look at the code you may find it quite amusing; I suggest to never use that. By the way, it is a good example here, because that class other than having such source code, doesn't have a public default constructor, and makes the XML marshaling fail. So it makes a good example for a not so trivial XML serialization.

The following code samples will instantiate a Book object, as per above class definitions, then transform that to an XML String, and after the XML String will be used to reconstruct another instance of the Book object.

JSR57 Serializer. Also known as "XMLDecoder/XMLEncoder"

Let's start from the JSR57 Serializer.

public class Jsr57Spike {
	public static void main(String[] args) throws Exception {
		Book book = new Book("Carrie", "Stephen King", new Price(17.25,
				Currency.getInstance("CHF")));

		String xml = encode(book);
		System.out.println(xml);

		Object o = decode(xml);
		System.out.println("decoded object: " + o);
	}

	private static String encode(Book book) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		XMLEncoder encoder = new XMLEncoder(out);

		fixCurrency(encoder);

		encoder.writeObject(book);
		encoder.close();
		return out.toString();
	}

	private static void fixCurrency(XMLEncoder encoder) {
		encoder.setPersistenceDelegate(Currency.class,
				new PersistenceDelegate() {
					@Override
					protected Expression instantiate(Object oldInstance,
							Encoder out) {
						return new Expression(Currency.class, "getInstance",
								new Object[] { oldInstance.toString() });
					}
				});
	}

	private static Object decode(String xml)
			throws UnsupportedEncodingException {
		XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(xml
				.getBytes("UTF-8")));
		return decoder.readObject();
	}
}

As you can see, I had to write a special handler to deal with the java.util.Currency class (lines 25..33), the PersistencyDelegate for the Currency class has to be set on the encoder before usage. If you don't do it, it will not throw any exception, but the decoder will be unable to deserialize the XML as it will fail to instantiate the Currency class. It will not throw any exception, it will just print on System.error some weird stuff like:

java.lang.InstantiationException: java.util.Currency
Continuing ...
java.lang.RuntimeException: failed to evaluate: =Class.new();
Continuing ...

And the decoded object will miss the currency instances. You can easily try that commenting the line number 17, where the "fix" is applied.

With the fix in place, everything should go fine and produce the following output:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.6.0_20" class="java.beans.XMLDecoder">
 <object class="it.newinstance.xml.spike.model.Book">
  <void property="author">
   <string>Stephen King</string>
  </void>
  <void property="price">
   <object class="it.newinstance.xml.spike.model.Price">
    <void property="amount">
     <double>17.25</double>
    </void>
    <void property="currency">
     <object class="java.util.Currency" method="getInstance">
      <string>CHF</string>
     </object>
    </void>
   </object>
  </void>
  <void property="title">
   <string>Carrie</string>
  </void>
 </object>
</java> 

decoded object: Carrie by Stephen King, 17.25CHF

We may find that the above XML representation is possibly too verbose and too Java-centric. So we may look forward to Jaxb...

But it's nice to notice here that in this case I didn't had to touch the model (Book and Price class) as the XMLDecoder/Encoder are really not intrusive and may be suitable for JavaBeans from which we do not have the source code or we can't easily change.

JAXB: Java Architecture for XML Binding

Following code does again the same stuff: from a JavaBean to XML and the way back.

public class JaxbSpike {
	@XmlRootElement
	private static class XMLBook extends Book {
		@SuppressWarnings("unused")
		public XMLBook() {} // default constructor is mandated by JavaBeans spec

		public XMLBook(String title, String author, Price price) {
			super(title, author, price);
		}
	}

	public static void main(String[] args) throws JAXBException {
		JAXBContext jc = JAXBContext.newInstance(XMLBook.class);
		Book book = new XMLBook("Carrie", "Stephen King", new Price(17.25,
				Currency.getInstance("EUR")));

		String xml = marshall(jc, book);
		System.out.println(xml);

		Book unmashalledBook = unmarshall(jc, xml);
		System.out.println("Last book I read: " + unmashalledBook);
	}

	private static Book unmarshall(JAXBContext jc, String xml)
			throws JAXBException {
		Unmarshaller u = jc.createUnmarshaller();
		return (Book) u.unmarshal(new StringReader(xml));
	}

	private static String marshall(JAXBContext jc, Book book)
			throws JAXBException, PropertyException {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		Marshaller m = jc.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.marshal(book, out);
		return out.toString();
	}
}

Jaxb requires that the object which represents the XML root has to be annotated with the @XmlRootElement. As I don't like to change my model just to transform it, I preferred in this example to subclass Book and apply the XML serialization to the inner class XMLBook where I can add the annotation without any problem.

At line 34 I set the JAXB_FORMATTED_OUTPUT property to true to produce a formatted XML. This is helpful for human reading, but it is good to have the ability to produce an XML on a single line to optimize the fruition by machines.

The rest of the code is quite self explanatory.

Here, I didn't had to add any handler for the Currency class in the marshaller/unmarshaller code... But I had to declare the converter with an annotation applied to the package. To annotate the package containing the model classes you need to create a special file named "package-info.java" with following source:

@XmlJavaTypeAdapter(value=CurrencyAdapter.class,type=Currency.class)
package it.newinstance.xml.spike.model;
import java.util.Currency;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

The marshaller/unmarshaller will check the annotations applied to the classes, the fields, and the packages, and apply the specified rules. JAXB has a rich set of annotations that can be applied to your JavaBeans and the packages themselves. The problem is that annotations are, under all aspects, interface elements. Annotating a class means introducing dependencies and changing the interfaces of your domain model. Also take in mind that sometime you just don't own the source code of the JavaBeans you want to serialize or you cannot change them. Subclassing may help, as I showed in the above example, introducing the XMLBook inner class, but it may be not enough. Further investigation of the JAXB API may show solutions to this issue, but at the moment, I don't know...

Then I had also to create a very simple CurrencyAdapter class, which will be used by JAXB to handle the translations Java <-> XML

public class CurrencyAdapter extends XmlAdapter<String, Currency>{

	@Override
	public String marshal(Currency v) throws Exception {
		return v.toString();
	}

	@Override
	public Currency unmarshal(String v) throws Exception {
		return Currency.getInstance(v);
	}
}

If you don't set up the CurrencyAdapter, the Exception that you will get is the following:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.util.Currency does not have a no-arg default constructor.
	this problem is related to the following location:
		at java.util.Currency
		at public java.util.Currency it.newinstance.xml.spike.model.Price.getCurrency()
		at it.newinstance.xml.spike.model.Price
		at public it.newinstance.xml.spike.model.Price it.newinstance.xml.spike.model.Book.getPrice()
		at it.newinstance.xml.spike.model.Book
		at it.newinstance.xml.spike.jaxb.JaxbSpike$XMLBook

	at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:277)
	at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
	at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
	at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
	at javax.xml.bind.ContextFinder.find(ContextFinder.java:376)
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
	at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
	at it.newinstance.xml.spike.jaxb.JaxbSpike.main(JaxbSpike.java:32)

I have to say that the exception is very descriptive of the problem. JAXB, for the little I had the chance to see, is a very well made API.

So, now that we have all in place, let's see what's the output of our JaxbSpike:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlBook>
    <author>Stephen King</author>
    <price>
        <amount>17.25</amount>
        <currency>EUR</currency>
    </price>
    <title>Carrie</title>
</xmlBook>

Last book I read: Carrie by Stephen King, 17.25EUR

For sure a better, simpler and non-Java-centric representation of the Book object, if we compare this with the output given using the XMLEncoder.

But, we have to notice that we have introduced the annotation on the package, so we changed the original domain. It is possible that, learning better the JAXB APIs, this change may be avoided, but I am really not confident in that. For sure JAXB is the best choice when you have some flexibility in changing the code of your JavaBeans.

Want to try by yourself?

Here you find the source code: JavaBeansToXml.tar.gz

Good luck!

P.S. This is all I know about Jaxb and JSR57 XML serialization; if you have a specific problem it's better to refer to some community forum. But feel free to leave a comment, I will be happy to help if I know the answer.

Maven Local Repository Modules

Local repository modules are useful when your project depends on some jars that cannot be found in any public or proprietary repository. In such cases, you have two choices: importing the jar in your local repository manually before running the build, as suggested in the mvn faq, or make your build process do it for you automatically; this is how: A Maven-friendly Pattern for Storing Dependencies in Version Control.
I learned this "pattern" time ago working with Greg in a company that was not using maven, so didn't had any repository for proprietary libraries. The solution was working great automating the process of installing the proprietary jars into the local repositories, and was saving developers to execute many maven esoteric command lines to import jars one by one.

To deploy files in a local repository module, it's possible to use the goal "deploy:deploy-file" as indicated in the example here:

mvn deploy:deploy-file -Durl=file://C:\m2-repo \
                       -Dfile=your-artifact-1.0.jar \
                       -DgroupId=org.some.group \
                       -DartifactId=your-artifact \
                       -Dversion=1.0 \
                       -Dpackaging=jar \
                       -DgeneratePom=true

I promised to myself to write an howto about this interesting topic, as it may be useful to myself in future and I need an online reference to this procedure. But recently I don't have much time to blog, so I have to reference an existing article.

Another reference: a feature request opened by Greg to Maven team MNG-3989.

A super funny video about a young and rebel Java developer grown in a Microsoft family.


Hope you'll enjoy as I did.

I think the original source of the video is here.

I've been working in Düsseldorf for some years and now I am leaving because I got job elsewhere. But before I want to share my experience and some tips that could be useful to people working (or planning to work) abroad, and in particular in this geographical area.

About Düsseldorf

Düsseldorf is a wonderful place, I loved it since the beginning. The city is awesome, tidy and safe. You can survive pretty well without speaking a single word of German: in the center of the city (the "Altstadt" = "the old city" ) almost everyone speaks English. People are warm and hospitable, food is great and there are many options for trying different cooking cultures.

There are many activities during the year: from carnivals, art exhibitions, concerts, fairs, sports, etc. For ordinary evening pubs and music clubs are open till late everyday, and the streets of the center are filled with people normally until 1:00am.

The weather is quite cold but it is OK during Summer, and if you are lucky also on springtime you can enjoy some sunny days. If you have a car there are plenty of cities and parks in the surrounding that deserve to be visited.

Mercer HR firm makes a survey about best city where to live, and they placed Düsseldorf at 6th position for the quality of living. I don't know if Düsseldorf is so great to deserve that placement, but for sure I enjoyed living here in the past years and, given my limited knowledge of the world, this is for sure the best place where I have been living.

Now, let me go in detail and make an analysis on some key points about living and working here.

Job

I start from the job topic, because it was the driving reason that lead me here, and for sure it is important to anyone to get a job in the place where he's going to move.
The reason why you may consider to work in Germany are several: from the working culture to the higher salaries, that are competitive with the UK job market (double, if compared to Italy). With Switzerland Holland and UK, Germany can probably offer the highest salaries for workers of the IT industry.

Firms. There are several international firms that establishing their headquarters in Düsseldorf. Strongest industries that lead the local economy focus in telecommunication, finance, fashion and trade. Some well known names are Vodafone (that was my employer), Nokia, Ericcson, Metro Group, Henkel, Tissen Krupp.

I saw also that Google has offices in Graf Adolf Platz 15 in the "GAP 15" tower, but afaik they are marketing division. In the same building you find other well known companies like Ernst & Young and Harvey Nash.

The "GAP 15" tower in Graf-Adolf-Platz 15

Vodafone. I've been working for Vodafone Global for some years trough a recruiting company. The "global" Vodafone has not be confused with the German OpCo, which is totally a different company, and of which I don't know much about. My experience with Vodafone Global is pretty positive: the work was interesting, the people I met there was great. Vodafone Global from the internal looks like a UK company: official language is English, result oriented, international teams. Work pressure is sustainable, as consultant you cannot benefit of the facilities offered to employees and the difference of treatment is quite evident, as well as infrastructures offered to consultants sometime give some headache, but everything in the norm considering the size of the organization.
The offices are positioned in the center of the city near a beautiful lake, in Berger Allee at the corner with Horionplatz. In the sunny day, lunch time it's a good chance to visit the Altstadt (old city) and some of the local restaurants where, at reasonable prices, you can get very good meals.

Vodafone Tower

Vodafone hires direct employees through this website: Opportunities at Vodafone. For contractors there are many companies doing staffing and recruiting, but the prime contractor is AMS, afaik they publish job offers on http://www.jobsite.co.uk and other job sites.

Job Hunting. Recently I've been looking for job offers in several sites and recruitment agency. For the ones interested in finding a job in Europe, following links are my bookmarks. I'm not recommending, taking responsibility or providing referees to those agencies: I'm just listing some possibly useful links.

Job sites:
JobServe, JobSite, JobSearch, CWJobs, Jobs.ch

International IT Recruitment Agencies:
Hays IT, Alexander Mann Solutions, Huxley, Elan-IT, Novate IT, Computer People, Computer Futures, Kingstone Consulting, Randstad Technologies, Hurst UK, Spring Technology, MDA Resources, Venn Group, Capita Resourcing, Access DE, Absolventa (Germany)

Professional social networks can be also very helpful in finding a job. LinkedIn is a must, I've many friends using Plaxo, but in Germany Xing is for sure one of the most popular.

Everyday life

Public transportation. Public transportation in Düsseldorf is very efficient but quite expensive. If you choose to live far from the city, let's say in the country, you may discover that after 8pm there are no more bus to bring you at home. Taxi are not very expensive.
I've not used public transportation very much. But I strongly suggest you to get a bike, as the city is very bike friendly.

Accommodation. In the country houses are cheaper, you can have a park in the backyard and live surrounded by the green. Very beautiful and quiet (take in mind that cities like Meerbusch and Lörick are near the Airport) , but not very convenient if you are young and you need flexibility on working hours, or if you simply like to be in the city for the evening.

My preferred option is to find a flat at 5 minute distance from the work place; if it is also near the hearth of the city is even better. So, for Düsseldorf, after some tries, I chosen a little studio in the very center of the city, and was perfect for my needs.
There are many company that can help you in finding an accommodation in Düsseldorf, I've used Home Company (very good), MWZ 24 (they just arranged an appointment with the landlord, never met them in person... just payed for the service), E-Rent. Those company fees are quite expensive, but they can be very helpful also if you have any complaint about the flat. My experience with very positive with Home Company, so I'd suggest you them: but be aware, they'll try to make you get the flat they are showing and you can never trust 100% the word of any seller. To pay those agencies you need a credit card, be prepared that sometime the credit limit may not cover the fees...
In Düsseldorf, rent costs are quite high, especially for furnished apartments , while the cost for buying a flat may be convenient; depends on how long you plan to stay, and the stability of your work/contracts. For a little furnished studio (25-30sq.m.) in the center of the city you may spend around 550-600 euro/month. Bigger and nicely furnished apartment can cost up to 1000-1500 eu per month.

Parking. Finding a park for your car could be a pain: in the city you have to pay for parking, almost everywhere, unless you get a park permit for residents (ask the landlord). But there are some special hidden places in the very center of Düsseldorf where you can park without paying.

Here's my map about the free parking places near Vodafone and GAP15.


View Duesseldorf Free Parking in a larger map

Language. In Düsseldorf you don't need to speak German for living... as a foreigner. In the center of the city, and also outside, people can speak a quite good English. But speaking German gives you much more freedom. Understanding the letters you receive without using translation tools or asking friends makes a real difference. If you work in an international firm, it may be not necessary to speak any German, as the official language in the company may be English. But, in times of financial crisis, it is much better to be able to work not just for the international companies, but also for littler firms. And here you find that a good level of German is required. Well, actually job ads ask for fluent English and German.
So I started to learn German. The bad news is that German is very difficult. The pronunciation is much simpler than English, but the grammar and the vocabulary is really hard. Simply, you cannot learn without a pragmatic training, possibly with a teacher.
To learn German it is possible to subscribe a German class in the Volkshochschule which is a public school organizing courses in several subjects, included German for the foreigners.
There are many other German school for business people moving to Düsseldorf for job, but they may be very expensive.
I found a great German class in GermaService, Friedrich-Ebert-Straße 45 D-40210 Düsseldorf. The cost is OK and the people are simply fantastic. WARMLY suggested.

Food. Düsseldorf offers a lot of restaurants that can satisfy any taste. There are good Italian restarants, as well Chinese, Turkish, Japanese, Korean etc.
Since the canteen in Vodafone is nothing special and quite expensive for the contractors, I got the chance to try many places.
In the Altstadt I suggest the "Enzo's Trattoria" in the market (Carlsplatz) for a good pasta with fish as side dish (ask for the Dorade). Good pasta can be found also at the restaurant "A Tavola". It looks like all my Italian colleagues agree that for the pizza "Di Napoli", is the best you can get in Düsseldorf; it is even better than many pizzerie in Italy. Also pizzeria "Matteo", just next to Di Napoli is good as well.
For steaks and meat, I suggest you to take a visit at Casa Picasso.
If you want to try some German food, try Zum Schiffchen.
For special occasions, or more classic dinners, some good italian food can be found at La Lampada or La Piazzetta di Positano.
Back to the altstadt, you can find good sushi for a lunch in Roppongi, and fantastic fish in Fischhaus.
For Chinese/Korean food I suggest Chop Chop, in Bolkerstraße, which is also very cheap; if you like spicy and hot food, I strongly suggest to try the Tom-Ka-Kay soup.
I tried also some Indian restaurants, and the best one is by far the Chanakya in Oberkassel.
For vegetarian and healthy food, Sattgrün is a good choice.
For a coffee, a drink or a snack, Bahara is a nice place where to talk with some friends. But if you need a place where you can also use WIFI for free, Woyton in Bolkerstraße near the tube entrance (in front of the McDonald's) is perfect; for quite a long period I've used this place as my office :)
If you are in Medienhafen, a nice place to visit is Tucan's Brazilian restaurant, where you can enjoy meat or a delicious buffet "all you can eat" at a reasonable price.
For a brunch in the weekend or delicious German soups during the lunch try Zicke Bistro.

Amusement. The "Düsseldorf CineStar" runs latest movies in original language, and it is great for foreigners. In Bottrop-Kirchhellen, there is the "Movie Park" where you can spend a great day on the amusement rides.
In the surrounding area there are many cities, zoo, castles and natural parks to visit. The one I visited (and that I suggest to you) are the Duisburg Zoo, Düsseldorf AcquaZoo, Maastrict, Schloss Benrath, Schloss Dyck in Mönchengladbach (strongly suggested), Xanten city and its Roman museum.

To meet new friends you can attend the meetings at the Düsseldorf expat meetup (also on facebook), and if you can speak italian you can partecipate to italiansonline activities.
For geeks there are many occasions to discuss about technology: the local Google Technology User Group, the RheinJUG, and the Mobile Monday will keep you up to date on the cutting edge technologies. In November you cannot miss the Devoxx in Belgium, not very far from Düsseldorf.

Services. Requesting internet at home from T-Online requires from 15 days to 1 month. The proverbial German efficiency is revealed to be a Myth when you enter in an T-online shop. Expensive, unreliable, poor service, and you cannot cancel the contract before two years. In a couple of occasion I had internet outage for weeks and I had to go into the shop EVERY day to complain, before to receive the visit of a specialist for fixing the problem (that of course, was on the wires and not in my router). And when I quit the contract they told me that it is impossible to quit it before two years...
Since I moved in Germany I got 3 mobile numbers. The first from Vodafone: expensive (I'm sorry to say that for the company I worked for). The second from Ortel Mobile, cheap for calling abroad but no GPRS mobile internet and no way to disable the voicemail. And it's almost impossible to use the "number portability" when you decide to use another service provider. Last, and best... O2: they have been excellent, reasonable prices, good GPRS mobile internet connection, great support (on the shop in Karlplatz) and very flexible: when I decided to quit the contract because I was leaving, I had absolutely no problem, they made everything and I just had to sign a paper, with no additional cost or penalty. They also sell "multicards" contracts which means you can have a sim in your phone ad another sim to use in your computer with an USB stick; with additional cost of 25 euro. It has been always excellent.

One day I started to receive payment requests from a company called Unitymedia, without ever subscribing any contract, I ignored them since I finally received a complain letter from a credit repair firm. I had to answer that I was ready to pursue legal actions against them for the fraud they was attempting to me, for the stress caused and privacy violation... and other legal amenities, just to get them stop it. So, beware of Unitymedia (and don't pay).

There is much more to say, and more topics to cover, for example the bureaucracy you have to deal when moving abroad. Maybe on another post; this is becoming too long.
By the way, if you have questions or you want add something, leave a comment.

There are a couple of cool features in GIT that may not be well known by everyone, depending on which platform you are using. For example on Linux it is quite common to have the bash completion working, while in Windows msysgit comes with a cool prompt which displays the current branch and some status information on the command line, as well as with the bash completion.
Git (version 1.7.0, and probably 1.7.1) on OS X comes with nothing, so here I show how to enable the command line completion and the git enhanced prompt. You can use the same tip on Linux to get the GIT enhanced prompt.

Here you can see how my prompt looks like:
Git Prompt and Completition

"luigi@hal9000:~/bin" is my usual prompt (username@hostname:folder), the red part indicates current branch, and the asterisk means that I have some modified files to commit.
In the above sample, also you see what happens when I type "git cl[tab-key]". The tab key triggers command line completion, and I can see available git commands starting with "cl"; in this case clone and clean.
The completion works not only on the command names, but also on file names and git object names, for example on branch names: if you type "git checkout mas[tab-key]" you should get it expaended to "git checkout master".

To enable the GIT bash completion, on OSX, you need to execute the script located at /usr/local/git/contrib/completion/git-completion.bash. This script is installed together with GIT utilities on OSX. To have its features enabled when you open a terminal session you should add following lines to your .profile:

# Set git autocompletion and PS1 integration
if [ -f /usr/local/git/contrib/completion/git-completion.bash ]; then
  . /usr/local/git/contrib/completion/git-completion.bash
fi
GIT_PS1_SHOWDIRTYSTATE=true

if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi

PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '

The GIT_PS1_SHOWDIRTYSTATE variable is used to indicate that the prompt should display the asterisk or other characters to indicate that the state of the working tree is "dirty" (something is changed and it has not yet been committed).
The script git-completion.bash enables bash completion and contains also some functions that can be executed when the prompt (defined in the PS1 variable) is shown. In this case the function displayed is named __git_ps1 and it displayes the current branch; the rest of the PS1 text is to display a nice prompt with colors.
For Linux user (at least for Ubuntu ones), it is just necessary to define the PS1 variable in the ~/.bashrc file, as the git completion script is usually included by default when installing git.

Another nice trick, that is not enabled by default, is the coloring for the following git commands: branch, status and diff. Having colors enabled helps to faster and easier understand the output. To enable colors issue the following commands:

$ git config --global color.branch auto
$ git config --global color.diff auto
$ git config --global color.status auto

Configuring above git properties will affect color display as in following examples:

Branch:
git branch

Status:

Diff:
git diff

Hope you find those tricks as useful as I do find them.

Google Font API

Google just announced the Google Font API. This allows to include quality fonts in HTML pages, as easy as you were doing before with the "web-safe" fonts.

You specify a css link, and the Google Font API will produce on the fly the CSS for your browser. Then you are ready to use any font from the Google Font Directory, that currently is very little but it is easy to predict it will grow up very fast. Nevertheless, the few available Fonts looks pretty good!

Here an example:

<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>

<div style="font-family: 'Lobster', arial, serif; font-size: xx-large; text-shadow: 4px 4px 4px rgb(170, 170, 170); text-align: center">
The quick brown fox jumps over the lazy dog.
</div>

And here, what you get:

The quick brown fox jumps over the lazy dog.

Beautiful uh?

To make things even easier, the Google Font Directory also includes a code generator that produces samples that can be grabbed and included in your HTML pages.

Android.jar sources

Yesterday I wrote a post to explain how to link Android sources in Eclipse. If you use a different IDE, probably you can't have Eclipse facilities but it may be easier to have the sources "in line" with the android library.

For myself usage I packed the android sources into some jar files. To have them linked properly in Eclipse, you need to download them and unpack in the proper directory under the Android SDK.

Here the files and the folder where they should be unpacked.

  1. android-sdk-1.5_r3-src.jar unpack to ANDROID_SDK_HOME/platforms/android-3/sources
  2. android-sdk-1.6_r2-src.jar unpack to ANDROID_SDK_HOME/platforms/android-4/sources
  3. android-sdk-2.0.1_r1-src.jar unpack to ANDROID_SDK_HOME/platforms/android-6/sources
  4. android-sdk-2.1_r1-src.jar unpack to ANDROID_SDK_HOME/platforms/android-7/sources

You don't need to unpack the files if you don't use Eclipse, as probably your IDE is able to reference source-jars for libraries in the CLASSPATH.

Very soon Android 2.2 will be released, you can build the source-jar with the utility I published yesterday, that is a bash script which runs in OSX and hopefully on Linux as well (the "find" utility may differ a little bit on Linux). Drop me a comment here, if you have problems, and I will pack it for you.

If you are working with the Android Development Toolkit (ADT) for Eclipse you may have noticed that the sources for android.jar are missing.
The Android SDK comes without the sources, and even if you manage to download the source code for the Android library, the ADT does not allow you to attach the sources to the library in the IDE. When debugging or navigating into the sources of android classes this may be similar to what you'll get:

Class File Editor

The trick, how explained here, is to download the sources and copy them into android-sdk/platforms/android-X/sources folder (where X is the API version).

For example, supposing I've installed the SDK into ~/opt/android-sdk-mac_86 on my Mac, and I am developing an application with Android 1.5 (API level 3). I should download the source files from Android website using git. Then I need to checkout the sources with tag name "android-sdk-1.5_r3", collect all the source files and move them into the directory ~/opt/android-sdk-mac_86/platforms/android-3/sources.

Here's my source tree under android-sdk-mac_86/platforms; in red color the directory where to put the sources:

luigi@hal9000:~/opt/android-sdk-mac_86$ tree -L 2  platforms
platforms/
|-- android-3
|   |-- android.jar
|   |-- build.prop
|   |-- data
|   |-- framework.aidl
|   |-- images
|   |-- samples
|   |-- skins
|   |-- source.properties
|   |-- sources
|   |-- templates
|   `-- tools
|-- android-4
|   `-- ...
|-- android-6
|   `-- ...
`-- android-7
    `-- ...

Creating a directory and copy some files inside it's not much complicate. But once you downloaded the sources, you'll discover that they are spread in several sub-directories. Also you need some practice with git command line utility to download the sources check available tags, switch to the proper source tree, then package all the source files into a folder or an archive.

I created following script, which runs on OSX (and hopefully on Linux as well).

luigi@hal9000:~$ cat bin/android-src-build.sh

#!/bin/sh 

SRC_DIR=/tmp/android-api

print_syntax() {
   echo "Syntax:\\n\\t$(basename $0) [option]"
   echo "\\nOptions:"
   echo "\\t-l prints available versions"
   echo "\\t-v builds jar file with sources of specified version"
   echo "\\t-c cleans up the sources from the temp directory\\n"
   exit 1
}

error() {
   echo "Error:" $1
   exit 1
}

download_sources() {
    if [[ ! -d $SRC_DIR ]]; then
        git clone git://git.source.android.com/platform/frameworks/base $SRC_DIR
    fi
}

if ! which git > /dev/null ; then
    error "git not installed (or not in the PATH)"
fi

if ! which jar > /dev/null ; then
    error "jar not installed (or not in the PATH)"
fi

if [[ "$1" == "-l" ]]; then
    download_sources
    cd $SRC_DIR
    git tag -l
    exit 0;
fi

if [[ "$1" == "-c" ]]; then
    rm -rf $SRC_DIR
    exit 0;
fi

if [[ "$1" == "-v"  && ! -z "$2"  ]]; then
    JAR_FILE=$(pwd)/$2-src.jar
    download_sources
    cd $SRC_DIR
    if ! git tag -l | grep $2 ; then
        echo "Version \\"$2\\" not found"
        exit 1;
    fi
    git checkout $2
    touch $JAR_FILE
    find . -depth 2 -name "java" -type d -exec jar uf $JAR_FILE -C {} . \\;
    exit 0
fi

print_syntax

You can download it here: android-src-build.sh.gz. (It's a bash script: download and execute it at your own risk!)

The script, is able to download the sources from the Android git repository, and, given the version number it packs it into a jar file, that can be lately be unpacked into the sources folder of the Android SDK, where indicated above.

When you run it without parameters it gives you following help:

luigi@hal9000:~$ android-src-build.sh 
Syntax:
        android-src-build.sh [option]

Options:
        -l prints available versions
        -v builds jar file with sources of specified version
        -c cleans up the sources from the temp directory

The -l parameter prints the list of available versions. If the sources have not been already downloaded, the -l will also download them. So the first time, it will take some minutes before displaying the available releases:

luigi@hal9000:~$ android-src-build.sh -l
Initialized empty Git repository in /private/tmp/android-api/.git/
remote: Counting objects: 106183, done.
remote: Compressing objects: 100% (35592/35592), done.
remote: Total 106183 (delta 61793), reused 104978 (delta 60893)
Receiving objects: 100% (106183/106183), 128.07 MiB | 1.52 MiB/s, done.
Resolving deltas: 100% (61793/61793), done.
Checking out files: 100% (8431/8431), done.
android-1.0
android-1.5
android-1.5r2
android-1.5r3
android-1.5r4
android-1.6_r1
android-1.6_r1.1
android-1.6_r1.2
android-1.6_r1.3
android-1.6_r1.4
android-1.6_r1.5
android-1.6_r2
android-2.0.1_r1
android-2.0_r1
android-2.1_r1
android-2.1_r2
android-2.1_r2.1p
android-2.1_r2.1p2
android-2.1_r2.1s
android-sdk-1.5-pre
android-sdk-1.5_r1
android-sdk-1.5_r3
android-sdk-1.6-docs_r1
android-sdk-1.6_r1
android-sdk-1.6_r2
android-sdk-2.0.1-docs_r1
android-sdk-2.0.1_r1
android-sdk-2.0_r1
android-sdk-2.1_r1
android-sdk-tools_r2
android-sdk-tools_r3
android-sdk-tools_r4
android-sdk-tools_r5

Now, let's say that we are developing on Android 1.5, we may want to create a jar file containing all the java sources for that version with:

luigi@hal9000:~$ android-src-build.sh -v android-sdk-1.5_r3
android-sdk-1.5_r3
Note: moving to 'android-sdk-1.5_r3' which isn't a local branch
If you want to create a new branch from this checkout, you may do so
(now or later) by using -b with the checkout command again. Example:
  git checkout -b 
HEAD is now at b69bed1... AI 150122: Merge from donut.   Fix permissions issue for uninstall of updated system applications.   If an existing update for a system application is uninstalled, when reverting back to the existing   version in system partition, permissions have to be granted again.   BUG=1893639
luigi@hal9000:~$ ls -l *.jar
-rw-r--r--  1 luigi  staff  4766477 May 17 15:59 android-sdk-1.5_r3-src.jar

As shown above, after issuing the command a file called android-sdk-1.5_r3-src.jar will be generated into the current directory.
Now the only thing remaining is to expand this file into the folder ~/opt/android-sdk-mac_86/platforms/android-3/sources:

luigi@hal9000:~$ rm -rf /Users/luigi/opt/android-sdk-mac_86/platforms/android-3/sources/
luigi@hal9000:~$ mkdir ~/opt/android-sdk-mac_86/platforms/android-3/sources
luigi@hal9000:~$ cd ~/opt/android-sdk-mac_86/platforms/android-3/sources
luigi@hal9000:~/opt/android-sdk-mac_86/platforms/android-3/sources$ jar xf ~/android-sdk-1.5_r3-src.jar

At this point, restarting eclipse should be enough to have the ADT linked with the source files.

About the platforms available into the Android SDK, under the platform directory, there are following folders: android-3, android-4, android-6, and adroid-7.
I am not 100% sure, but they should correspond to the source code identified respectively by following table:

android-3 = android-sdk-1.5_r3
android-4 = android-sdk-1.6_r2
android-6 = android-sdk-2.0.1_r1
android-7 = android-sdk-2.1_r1

Finally, if you want to remove the sources downloaded you can run the script with the -c (clean) option: it will remove the sources stored temporarily into the folder /tmp/android-api:

luigi@hal9000:~$ android-src-build.sh -c
(no output returned)

Alternatively, you may want to remove the files manually.

Now, after a refresh (or a restart) from Eclipse, the sources from Android classes should look much better:

Sample Android Source

Check the referenced articles for further information on how to download the android sources, and how the ADT plugin for Eclipse locates the sources for the Android SDK.

I really think that Google should release the sources nicely packed as per the android.jar and make sure they are properly referenced by the ADT. Since then, this is my way.

For questions, mistakes, etc. leave a comment.

References

- Browsing Android Source in Eclipse
- Android sources

If you have more than one laptop/computer on your desktop, you may find yourself jumping from a keyboard to another to make use of them. In this article I explain how I configured my laptops to share keyboard and mouse using synergy.

It is always a good thing to have a second monitor, for example to read documentation while doing some development, or for listening to music or watching videos while doing things that do not require full attention.
I have an ancient (10 years old) Dell Inspiron 8600 laptop on which the keyboard and the touchpad are starting to lose efficiency, but still it has a great display and an unrivaled audio system. The keyboard is pretty different from the macbook I am using daily, and dealing with different keyboards may not be so enjoyable. Also being an old generation laptop, the keyboard it's not very pleasant to the touch, and sometime it loses some key press.

With Synergy, it is possible to control remote computers with a single keyboard and mouse. So now, I can work on my MacBook running OSX Snow Leopard and control also the second laptop, the ancient Dell on my desk running Ubuntu 10.4, without switching keyboard or mouse. A second thing that comes for free with Synergy is the clipboard sharing; this means that you can cut-and-paste across the computers you are using: it is very helpful.
You can find more information about synergy at the official site.

First of all, you need to install synergy executable files on all the computers you need to control. Download it from here. Then, ensure that the computer can see each others on the network, using ip address or dns names. If they can ping each others, usually it should be enough.
On ubuntu you can install synergy using apt-get, while on the mac you can download the executables packed into a tarball and unpack them in a any folder you like, in my case I used ~/opt/synergy-1.3.1.

I want to use my mac's keyboard and mouse to control the dell laptop. You can have a single controller computer and many controlled computers. The controller will need the synergy server, while the controlled computers will run the client.
So on my macbook I created a configuration file which describes computers I want to control and what edge of the screen is the "border" from which the mouse will jump on the other computers. I placed it under ~/etc/synergy.conf :

section: screens
    dell:
    macbook:
end

section: links
    dell:
        left = macbook
    macbook:
        right = dell
end

The above configuration describe my screens configuration and the links between the laptops. Basicallly I am telling that I have two screens, the dell one and the macbook. And for the dell I have a macbook on the left, and for the macbook I have the dell on the right. There are many other options, but here I am just using the defaults. The full documentation on the configuration options can be found here.

Then I have to start the Synergy server on the macbook using the command:

$ synergys --config ~/etc/synergy.conf

On the dell computer then I need to run the client, who will connect to the macbook (the controller laptop) and act consequently. To do so, I can connect the client launching one of the following commands


// supposing 192.168.1.123 is the ip of my macbook
$ synergyc 192.168.1.123

// in my network I can refer the server as macbook.local or just macbook.
$ synergyc macbook.local
// or
$ synergyc macbook

After doing so, you should be able to move your mouse from one computer to the other(s) just passing through the edges of the screens, and control all the computers on your desk.

If something goes wrong, you can use the -f option to run the client and the server in foreground, and the -d to enable debug tracing.

If you still have troubles with command line tools, you may want to try QSynergy, which is a graphical user interface over synergy.

Yet it is missing some "file sharing" feature; it would be very good if synergy was able to copy files dragging and dropping files from a desk to another, but at the moment, this is missing. Installing OpenSSH can do what is missing: file transfers (scp) and remote ssh logins should be enough to complete synergy desktop integration.

Here there is a video that visually explains what you can do with Synergy:

It looks like in the video she forgot to start the client; btw it is just needed to launch the synergyc executable as I explained above.

And here, a guy shared his mouse and keyboard over 7 computers using synergy:

Have fun.




About

Luigi Viggiano

"Thoughts about technology, code, life and diverse and occasionally related matters"
A blog by Luigi R. Viggiano

Follow me

twitter facebook LinkedIn feed email

Enter your email address:

Archives


Categories

Tag Cloud