Dear Java, I hate you – accessing the Facebook API with Java

So, I’m pretty open minded when it comes to technology, especially diving head-first into programming languages but for some reason I’ve always had a personal vendetta and hatred towards Java even though I’ve never touched the language. I think it comes from my line-of-work; clients ringing up complaining that this Java plugin isn’t working or their browser crashes because of a Java applet. Anyhow, vendettas aside I decided to dive in – fueled with wine gums and semi-naked…
The main reason for playing around with Java was because it’s an upcoming unit in the honours degree I’m studying but also the DLNA server I use, PS3 Media Server (PMS), for streaming movies to my PS3 implemented third-party plugin support – hello!
My aim was to allow users to automatically publish what they are watching/playing on their PlayStation3 via Facebook by creating a PMS plugin.
My first poision of a Java Facebook client was facebook-java-api as it seems to be the most stable, documented and actively developed. After playing around for over a day I couldn’t get a working application, the examples I found around the ‘net were all out of date – functions had been depreciated, Facebook changed it’s API and all sorts of headaches.
38 (thirty-eight!) imports later I had a working application and when I played a movie on my PlayStation it was published on my Facebook wall.

As I dove into the Facebook Java API more and more I decided I didn’t like it. It was crude, heavy, un-logical – something just wasn’t right. For example to simply get a list of friends I had to write 25-or-so lines of code, create a SECOND Facebook object but this time using the Jaxb client which, guess what, equaled more imports to handle Jaxb.
My bitching aside, I looked around a little more and came across RestFB. RestFB’s goals? Simple:
- Minimal public API
- Maximal extensibility
- Robustness in the face of frequent Facebook API changes
- Simple metadata-driven configuration
- A single dependency, Apache Log4j
Exactly what I’m looking for, perfect! I found RestFB a dream to work with putting aside my diminishing Java hatred. To get to the point below is some code to retrieve the user ID of the currently logged in user.
// I've removed the imports to keep the size down
public class Main {
// define our strings
private static final String FACEBOOK_API_KEY = "xxxxx";
private static final String FACEBOOK_APPLICATION_SECRET = "xxxxx";
private FacebookClient facebookClient;
private String facebookAuthToken = null;
private String facebookSessionKey = null;
public static void main(String[] args) throws FacebookException {
facebookClient = new DefaultFacebookClient(FACEBOOK_API_KEY, FACEBOOK_APPLICATION_SECRET);
// I always call facebookAuthorise
// First time users would click a button that calls facebookConnect() first to grab the session key.
facebookAuthorise();
}
private void facebookConnect() throws FacebookException {
// auth.createToken returns a string
// http://wiki.developers.facebook.com/index.php/Auth.createToken
facebookAuthToken = facebookClient.execute("auth.createToken", String.class);
String url = "http://www.facebook.com/login.php"
+ "?api_key=" + FACEBOOK_API_KEY
+ "&fbconnect=true" + "&v=1.0"
+ "&connect_display=page" + "&session_key_only=true"
+ "&req_perms=read_stream,publish_stream,offline_access"
+ "&auth_token=" + facebookAuthToken;
// Here we launch a browser with the above URL so the user can login to Facebook, grant our requested permissions and send our token for pickup later
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(new URI(url));
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(URISyntaxException use) {
use.printStackTrace();
}
}
}
}
private void facebookAuthorise() throws FacebookException {
// I saved my session key to a .properties file for future use so the user doesn't keep have to authorising my app!
// auth.getSession returns JSON so we need to decode it just to grab the session key
// http://wiki.developers.facebook.com/index.php/Auth.getSession
// Here we pickup the session key and define the authToken we used above in facebookConnect()
JSONObject json = new JSONObject(facebookClient.execute("auth.getSession", String.class, Parameter.with("auth_token", facebookAuthToken)));
facebookSessionKey = json.getString("session_key");
// An example call, you can literally use anything from the REST API
Long uid = facebookClient.execute("users.getLoggedInUser", facebookSessionKey, Long.class);
System.out.println("FB User ID: " + uid);
}
}
So, excluding the methods to get a session we managed to use one line of code, simples!
I still hate Java; it complains all the time, it needs dependency after dependency and it seems a little restrictive (like a women). I guess I’ll have to learn to get along with it. AS for the plugin, I’m still developing it and hope to publish it to the PMS community ASAP
Related posts:
29 Responses to “Dear Java, I hate you – accessing the Facebook API with Java”
Leave a Reply


Traroth on April 8th, 2010
I don’t really understand here what’s the matter with Java.
You seem to have a problem with a Facebook API, but that’s third-party code…
Paul Price on April 8th, 2010
Traroth, you’re right. I tried to keep this post mostly Facebook API orientated to keep away the Java fan boys because I know they’re brutal – heh.
I think, as I mentioned, the reason I dislike Java is from end-user experience rather then development. I’ve never, ever touched Java before and coming from a PHP background I just found things to be a little crude. For example, adding an import to handle most basic things such as Arrays – I can see this is a benefit in some ways as there’s no point loading the lib into memory if you’re not going to use it.
Anyhow, I guess it’s a learning curve and the more I use it the more I’m liking it so we’ll see..
Traroth on April 9th, 2010
Hi Paul,
Yeah, if by end-user experience, you mean “applets”, even if I could be considered as a “Java fan-boy”, I’m ok to say it’s simply awful (at least for the century long loading times), but with Swing, it’s possible to make really great GUIs. Check out the new default look&feel, Nimbus, and the skinnable Synth look&feel…
funny_with_java on October 1st, 2010
I am tired of people bringing up applets. NO ONE uses them and NO ONE likes them. They were cool in 1997 because it was the only way to have any sort of dynamic app in a browser. I hate it when people bring this old shitty API up that NO ONE uses anymore.
max on March 31st, 2011
i think its more of the fb api problem than java itself..lol,if u r from php background(just a scripting lang),u still need to know a powerful system level programming language like .net,java or python.u simply cant hate java for another api mistake .:-)
Hass on April 9th, 2010
Hey Paul
First of all, thank u so much for this info.
And, you’re right about “the examples I found around the ‘net were all out of date – functions had been depreciated”…
im having problem with Java too but i need to get it over it since i need to get my project done..
here are my question to you rdg your codes
1. the FacebookClient : is that a class or from the API itself coz in the API, it has FacebookJsonRestClient, FacebookJaxbRestClient and FacebookXMLRestClient?
2. the DefaultFacebookClient : can you explain abt this too.
do need your help to survive Java
Thank you again
Paul Price on April 9th, 2010
Hey Hass, I feel your pain! It seems ever since Facebook dropped official support for their Java API it’s been downhill.
The code examples use RestFB (http://restfb.com) which is a third-party library, just like Facebook-Java-API but I found it easier to use.
I’d recommend visiting the RestFB website and just having a little play with the code, it really is simple and in my opinion wipes the floor with Facebook-Java-API.
I’d be glad to help!
Traroth on April 14th, 2010
I tried your code, and instead of the Facebook login page (for the browser part), I get a Facebook page with “An invalid next parameter was specified.” and an com.restfb.FacebookResponseStatusException saying “Received Facebook error response (code 100): Invalid parameter”. Do you have any clue?
Paul Price on April 16th, 2010
Hi Traroth, usually “Invalid parameter” means that the you haven’t created an Auth Token via auth.createToken and passed it in the login URL (&auth_token) – could you share your code and I’ll take a look for you…
Traroth on April 16th, 2010
Ok, here is my code. It’s actually only a dummy app, just to see how things work. I slightly modified yours:
public final static void main(String [] args) {
String sessionKey = null;
FacebookClient facebookClient = new DefaultFacebookClient(MY_API_KEY, MY_SECRET_KEY);
String facebookAuthToken = null;
try {
facebookAuthToken = facebookClient.execute(“auth.createToken”, String.class);
System.out.println(“facebookAuthToken : “+facebookAuthToken);
if (FIRST) {
String url = “http://www.facebook.com/login.php”
+ “?api_key=” + MY_API_KEY
+ “&fbconnect=true” + “&v=1.0″
//+ “&return_session=true”
+ “&connect_display=page” + “&session_key_only=true”
+ “&req_perms=read_stream,publish_stream,offline_access”
+ “&auth_token=” + facebookAuthToken;
System.out.println(“step 1″);
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
if (desktop.isSupported(Desktop.Action.BROWSE)) {
try {
desktop.browse(new URI(url));
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(URISyntaxException use) {
use.printStackTrace();
}
}
}
System.out.println(“step 2″);
JSONObject json = new JSONObject(facebookClient.execute(“auth.getSession”, String.class, Parameter.with(“auth_token”, facebookAuthToken)));
System.out.println(“step 3″);
sessionKey = json.getString(“session_key”);
System.out.println(“sessionKey : “+sessionKey);
} else {
JSONObject json = new JSONObject(facebookClient.execute(“auth.getSession”, String.class, Parameter.with(“auth_token”, facebookAuthToken)));
sessionKey = json.getString(“session_key”);
Long uid = facebookClient.execute(“users.getLoggedInUser”, sessionKey, Long.class);
System.out.println(“uid : “+uid);
}
} catch (FacebookResponseStatusException e) {
System.err.println(“code : “+e.getErrorCode()+” message : “+e.getErrorMessage());
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
static final public boolean FIRST = true;
Traroth on April 16th, 2010
One more thing: my code is stopping a between step 2 and step 3, and I get the folowing stack:
com.restfb.FacebookResponseStatusException: Received Facebook error response (code 100): Invalid parameter
at com.restfb.DefaultFacebookClient.throwFacebookResponseStatusExceptionIfNecessary(DefaultFacebookClient.java:357)
at com.restfb.DefaultFacebookClient.makeRequest(DefaultFacebookClient.java:320)
at com.restfb.DefaultFacebookClient.execute(DefaultFacebookClient.java:188)
at com.restfb.DefaultFacebookClient.execute(DefaultFacebookClient.java:178)
at com.kizoa.facebook.FBTester.main(FBTester.java:54)
Paul Price on April 16th, 2010
Hmmm, I think I found the problem. If you take a look after
System.out.println(“step 2″);
you pretty much request the infinitie session key straight away, not giving time for the user to login to Facebook and grant permissions to your application. For example, your application flow is as so;
1. Request an AUTH TOKEN from Facebooks server
2. Pass the AUTH TOKEN to /login.php and open in a browser for the user to login/request permissions manually and generate a SESSION KEY
3. Straight away we attempt to get the SESSION KEY created from step 2 but because we haven’t gave the user enough time to login and generate a session key the Facebook server sends the “Invalid parameter” response.
So, what we would need to change is just give time for a user to login to facebook. In my example I open the URL in the browser and then WAIT for the user to push a button which then triggers my auth.getSession()
I hope this make sense!
Traroth on April 19th, 2010
Yeah, I did this in the meantime. I don’t get the exception anymore. But I still have the message on Facebook.
Traroth on April 19th, 2010
Actually I added the following line to my parameters :
+ “&next=http://www.facebook.com/connect/login_success.html”
and now, it works.
Paul Price on April 19th, 2010
Glad you got it working. It’s strange that you have to include NEXT in the URI for it to work.
Raibaz on April 16th, 2010
Hi, i’ve been struggling with the Facebook API to get a session key to use with RestFB all day, then i found your post and it saved my day…thnks a lot!
bruno on May 3rd, 2010
Cool tip
worked perfectly with me. But you tell me how do I get the AUTH_TOKEN user with the login and password it?
Paul Price on May 4th, 2010
Hi Bruno, if I read your comment right you want to get the Facebook username after sending your AUTH_TOKEN but before you call auth.getSession? Unfortunately you can’t do this and you need to be authenticated..
Bruno Oliveira de Alcântara on May 4th, 2010
Yes, I understand I need to be logged in to facebook to post a photo, but I have some way to authenticate the user at all on facebook backend?
Example:
I get the login and password and submit to facebook and get the auth_token to configure my application and send the photo.
In the API eg twitpic this is possible with just calling a method, but on facebook I need the user to allow my application facebook collect the data from it to post the photo. What I was wondering is if it is somehow easier for me to do this in the backend (background) with no views?
Paul Price on May 4th, 2010
I don’t think there is. The user HAS to authorize your application for it to use it which involves them physically clicking “allow” on the authorize button – if you can do this transparently (in the background) then I believe Facebook has a huge security flaw…
If you’re developing a Java web-app it’s probably wiser to use Facebook Connect; http://wiki.developers.facebook.com/index.php/Facebook_Connect
Bruno Oliveira de Alcântara on May 4th, 2010
Okay, thanks for the replies, actually I need to do is send in the same background, no web interface, or any view, because I get the image on my server that uses Java and I have to send it to my facebook through this server.
Thank you for the posts so far, and congratulations on your tip restFB really all I have researched this is the best tip.
Regards,
Bruno.
Jagdeep on September 17th, 2010
This is a great link to start with the facebook apis.
I want to ligin to a facebook and save the Wall/Home page as a image on my machine. I need to refresh the image every 5 mins so I dont need any windoe prompt.
Someone pleas help.
maling on November 12th, 2010
Your code doesn;t work
saqs on January 3rd, 2011
Would be nice if U could update this
guna on April 7th, 2011
Hi Paul
Thank u so much for this info.
here are my question to you rdg your codes
1. is it possible getting friends facebook account?
2. if we get friends list, is it possible to get friends phone number and email?
do need your help to survive android
Thank you again and regrards
sekar
summu on April 29th, 2011
Hi Paul,
Do u have any idea regarding this exception “Managing advertisements requires the extended permission ads_management”
Chetan6033 on July 11th, 2011
i was able to connect to the fb by using the above code but i need to retrieve my friend’s(user’s on fb) comments. Is this possible by my application??
matthias on November 6th, 2011
Hello Paul,
it seems that “facebookClient.execute” does not exist anymore in the latest version of the restfb library.
How can I make the example working with the newest version of restfb ?
Thanks very much in advance!
BR,
Matthias
Craig on December 21st, 2011
Great article Paul. Best example of doing this I have been able to find.
Funnily enough, I did the same thing in C# in about 5 minutes, but Java on the other hand….phew, but like you I am about to take a Java course and was determined to do it this way.