Posts Tagged ‘Java’

How to use and retain Twitter4J OAuth access token

March 1st, 2010

I  stuck in a problem that how to re use access token, once user has authenticated by Twitter (on call back URL). I got it working. There was problem in my understanding about request token vs access token. When user first time comes on call backed URL. I take request token and token secret from session and prepare the access token. Here the place where I was confused.

Now if user presses the refresh button or you want to get user information again from twitter any where in your application. You need to use the access token and this method twitter.setOAuthAccessToken(String1, String2). Because user has already been authenticated by Twitter. You can save this information in session.

HttpSession session = request.getSession();

twitter.setOAuthConsumer(Constants.CONSUMER_KEY,Constants.CONSUMER_SECRET);

if (session.getAttribute("aToken") == null){
	// request token
	String token = (String) session.getAttribute("token");
	String tokenSecret = (String)session.getAttribute("tokenSecret");
	AccessToken accessToken =
		twitter.getOAuthAccessToken(token, tokenSecret);
	twitter.setOAuthAccessToken(accessToken);

	// save the access token, that are different from request token
	session.setAttribute("aToken", accessToken.getToken());
	session.setAttribute("aTokenSecret", accessToken.getTokenSecret());

}else{
	// use the access token to authenticate user whenever you want
	twitter.setOAuthAccessToken((String)session.getAttribute("aToken"),
		(String)session.getAttribute("aTokenSecret"));
}
User user = twitter.verifyCredentials();

If you are also developing some app by using Twitter4J API on Google App Engine. Please give feedback on it.

Twitter4J Quick Tutorial: A quick tutorial on how to develop Twitter app by using Twitter4J on Google App Engine.

Sun.com is dead now

January 31st, 2010

Just found that sun.com is now redirecting to oracle.com. Some days back I visited Sun’s original website. But it didn’t took long by Oracle to make it red. Well I am a regular visitor of Sun forums. And with this change, I am trying to adjust myself with this transition. As I am having some issue in finding contents.

After some browsing Oracle’s website I found they were some thing to say to Java developers community about continuing Sun Developer Network.

Sun.com now redirects to Oracle.com

FAQs for Sun Java developer community:

What will happen to Sun Developer Network, java.sun.com, and BigAdmin?

For the near future, all these sites will remain in their current form. We know that these resources are important, so you can continue to access them just as you always have at the same URLs and bookmarks. At some time, we foresee an integration of these sites into a newly redesigned and re-architected Oracle Technology Network, and we welcome your feedback about this process. We will make sure that any changes are communicated well in advance so that you will continue to have access to the tools and resources that you need.

And there are some other promises too about continuing Sun things.

I also found a Sun blogger saying good bye to blog.sun.com. Due to some Oracle policies that they can host only those blogs that targets to their products only not personal topics. You can read that blog post here.

I have started preparing for SCJP

January 27th, 2010

Its been a year since I purchased the voucher for SCJP 5.0. But I cant concentrate to have time to prepare it. From last night I have taken the oath to finally make it done. I have started with the book SCJP Sun Certified Programmer for Java 5 Study Guide (Exam 310-055) by Kathy Sierra and Bert Bates.

A remarkable thing is I purchased the free retake voucher which is going to expire on June 2010. But I still didnt make even a single attempt. Ok thats all right. I am going to do it. I hope to appear for the successful first attempt in good marks.

I am not using any IDE for coding practice. I am using Notepad++ editor and command line Javac compilation. I want to get maximum of language fundamentals and want to think out of code completion feature.

Useful cheat sheets on Cloud Computing and Google App Engine for Java

January 12th, 2010

google_app_engine_javaJust read cheat sheets (Refcard) by Dzone on Cloud Computing and Google App Engine for Java. They contain a very jumped to the point and quick reference on these things. You can read to have a quick overview.

Read them here:

Got two books on Google App Engine for Java

December 28th, 2009

Recently I got two books on Google App Engine for Java. Programming Google App Engine by Oreilly and Beginning Google App Engine by Apress. There is less material and comprehensive online tutorials available on this. So its better that you read book on it. I started reading Oreilly’s book. I completed some of the basic components so quickly by given code examples in the book. Its always a good start on some new technology, if you have books in your pocket.

You guys can share your feedback if you read any book or any material on it.

Apress_Beginning_Google_App_Engine

Oreilly_GoogleAppEngin

Spoken on Google App Engine at a conference in UET

December 19th, 2009

Today I had delivered a workshop on Developing Java Web Applications In Google App Engine. This workshop was the part of events of 3rd International Conference on Open Source Systems and Technologies. It was organized by Al-Khawarizmi Institute of Computer Science , University of Engineering and Technology, Lahore.

I have presented following slides there. Also coded a basic sample application to show how to create and deploy new Java project on GAE. Which can send emails, how to use authentication by Google, and how to do database interaction. It was a very intresting topic for me to present. Participants also liked it.

Comments and feedback is welcomed on the presentation material from you guys.

Tutorial: JPA on Google App Engine

December 13th, 2009

This project will create and delete an entity record. I have chosen JPA for datastore in app engine. You can also look JDO for this purpose. But my choice to go for JPA is due to Sun standardization on it.

I am using App Engine SDK version 1.2.18

Project name: engineplay
URL: http://engineplay.appspot.com

Project structure:

jpa_gae_project_structureUserPrefs.java: The entity class

package com.engineplay.datastore.pojos;
import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import com.engineplay.datastore.EMFService;
import com.google.appengine.api.users.User;

@Entity(name = "UserPrefs")
public class UserPrefs {
 @Id
 private String userId;
 private int donuts;
 @Basic
 private User user;

 public UserPrefs(String userId) {
 this.userId = userId;
 }

 /* TODO create getter and setters for above properties yourself */

 public static UserPrefs getPrefsForUser(User user) {
 UserPrefs userPrefs = null;
 EntityManager em = EMFService.get().createEntityManager();
 try {
 if (em.find(UserPrefs.class, user.getEmail()) == null) {

 userPrefs = new UserPrefs(user.getEmail());
 userPrefs.setUser(user);

 } else {
 userPrefs = em.find(UserPrefs.class, user.getEmail());
 }
 } finally {
 em.close();
 }
 return userPrefs;
 }

 public void save() {
 EntityManager em = EMFService.get().createEntityManager();
 try {
 em.persist(this);
 } finally {
 em.close();
 }
 }

 public void remove() {
 EntityManager em = EMFService.get().createEntityManager();
 try {
 UserPrefs userPrefs = em.find(UserPrefs.class, user.getEmail());
 em.remove(userPrefs);
 } finally {
 em.close();
 }
 }
}

EMFService.java: The class to create EntityManagerFactory instance.

package com.engineplay.datastore;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EMFService {
 private static final EntityManagerFactory emfInstance = Persistence
 .createEntityManagerFactory("transactions-optional");

 private EMFService() {
 }

 public static EntityManagerFactory get() {
 return emfInstance;
 }
}

LoginServlet.java

package com.engineplay.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.engineplay.datastore.pojos.UserPrefs;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class LoginServlet extends HttpServlet {

 public void doGet(HttpServletRequest req, HttpServletResponse resp)
 throws IOException {

 UserService userService = UserServiceFactory.getUserService();
 User user = userService.getCurrentUser();
 String navBar, form = null;
 int donuts = 0;
 if (user == null) {
 navBar = "<p>Welcome! <a href=\"" + userService.createLoginURL("/") +
 "\">Sign in or register</a> to customize.</p>";
 form = "";
 } else {
 UserPrefs userPrefs = UserPrefs.getPrefsForUser(user);

 if (userPrefs != null) {
 donuts = userPrefs.getDonuts();
 }
 navBar = "<p>Welcome, " + user.getEmail() + "! You can <a href=\"" +
 userService.createLogoutURL("/") +
 "\">sign out</a>.</p>";
 form = "<form action=\"/donuts\" method=\"post\">" +
 "<label for=\"donuts\">" +
 "Need more donuts?:" +
 "</label>" +
 "<input name=\"donuts\" id=\"donuts\" type=\"text\" size=\"4\" />" +
 " <input name=\"olddonuts\"  type=\"hidden\" value=\"" + donuts + "\" /> " +
 " <input name=\"userId\"  type=\"hidden\" value=\"" +user.getEmail()+ "\" /> " +
 "   <input type=\"submit\" value=\"  ADD  \" /><br><input type=\"submit\"  name =\"deleteBtn\" value=\"  DELETE ME!  \" />" +
 "</form>";

 }
 resp.setContentType("text/html");
 PrintWriter out = resp.getWriter();
 out.print("<html><head><title>Engine Play - Donuts</title</head><body>");
 out.println(navBar);
 if (donuts != 0)
 out.println("<p>Donuts you have: " + donuts + "</p>");
 else
 out.println("<p> No donuts you have :(  </p>");
 out.println(form);
 out.print("</body></html>");
 }
}

DonutsServlet.java

package com.engineplay.servlet;

import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.engineplay.datastore.pojos.UserPrefs;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public class DonutsServlet extends HttpServlet {

 public void doPost(HttpServletRequest req, HttpServletResponse resp)
 throws IOException {
 UserService userService = UserServiceFactory.getUserService();
 User user = userService.getCurrentUser();
 UserPrefs userPrefs = UserPrefs.getPrefsForUser(user);
 try {

 String deleteOpt = req.getParameter("deleteBtn");
 if (deleteOpt == null){
 int donuts = new Integer(req.getParameter("donuts")).intValue();
 int oldDonuts = new Integer(req.getParameter("olddonuts")).intValue();

 userPrefs.setDonuts(donuts + oldDonuts);
 userPrefs.save();
 }else{
 String userId = req.getParameter("userId");
 userPrefs.setUserId(userId);
 userPrefs.remove();
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 resp.sendRedirect("/Login");
 }
}

persistence.xml: Configuration file required for JPA

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence

http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"

 version="1.0">
 <persistence-unit name="transactions-optional">
 <provider>
 org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider
 </provider>
 <properties>
 <property name="datanucleus.NontransactionalRead"
 value="true" />
 <property name="datanucleus.NontransactionalWrite"
 value="true" />
 <property name="datanucleus.ConnectionURL"
 value="appengine" />
 </properties>
 </persistence-unit>
</persistence>

web.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">

 <servlet>
 <servlet-name>LoginServlet</servlet-name>
 <servlet-class>com.engineplay.servlet.LoginServlet</servlet-class>
 </servlet>
 <servlet>
 <servlet-name>DonutsServlet</servlet-name>
 <servlet-class>com.engineplay.servlet.DonutsServlet</servlet-class>
 </servlet>

 <servlet-mapping>
 <servlet-name>LoginServlet</servlet-name>
 <url-pattern>/Login</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
 <servlet-name>DonutsServlet</servlet-name>
 <url-pattern>/donuts</url-pattern>
 </servlet-mapping>

 <welcome-file-list>
 <welcome-file>Login</welcome-file>
 </welcome-file-list>
</web-app>

Access the project here: http://engineplay.appspot.com

run_gae_project

Upgrading to Google App Engine Java SDK 1.2.8

December 7th, 2009

I was getting following exception while trying to code my first interaction with JPA in Google App Engine.

org.datanucleus.metadata.InvalidMetaDataException:
Error in MetaData for field "user" in class "com.engineplay.datastore.pojos.UserPrefs" : this is declared as com.google.appengine.api.users.User with "persistence-modifier=none" yet has either "default-fetch-group=true" or "primary-key=true" specified! These should be false.

After some searching I came to know that I should upgrade my App Engine SDK. To get datanucleus-enhancer-1.1.4.jar. But when I upgraded my SDK from 1.2.0 to 1.2.8. I got following exception.

java.lang.RuntimeException: Unable to locate the App Engine agent. Please use dev_appserver, KickStart,  or set the jvm flag: "-javaagent:<sdk_root>/lib/agent/appengine-agent.jar"
at com.google.appengine.tools.development.DevAppServerFactory.testAgentIsInstalled(DevAppServerFactory.java:102)
at com.google.appengine.tools.development.DevAppServerFactory.createDevAppServer(DevAppServerFactory.java:77)
at com.google.appengine.tools.development.DevAppServerFactory.createDevAppServer(DevAppServerFactory.java:38)
Caused by: java.lang.NoClassDefFoundError: com/google/appengine/tools/development/agent/AppEngineDevAgent
at com.google.appengine.tools.development.DevAppServerFactory.testAgentIsInstalled(DevAppServerFactory.java:98)
... 6 more
Caused by: java.lang.ClassNotFoundException: com.google.appengine.tools.development.agent.AppEngineDevAgent
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
... 7 more

I got two problems to fix. First the JPA enhancer was not working and second I was unable to start my server through Eclipse.

Running the server was looking straight forward from the exception that I need to add extra VM arguments for all of my applications. Remember this, your previous application will not work unless you add these VM arguments seprately in their launcher configurations.

Following are the steps to do that.

1. Right click the project and select Run As –> Open Run Dialog.

gae-add-vm-arguments

2. Copy the message which you are getting in exception. This is exactly the same that we need to add in VM arguments section. The only addition we need to do is to add our SDK path.

gae-added-vm-arguments

3. Now if you run or debug your project. You server will run perfectly.

gae-server-run-success

Determine whether application is running on local server or App Engine

December 1st, 2009

If you are working on developing some application on Google App Engine. You may come up with such situation to switch your production code with your local dev code. Following is my solution for this problem. I have initialized a servlet from web.xml. That set appropriate value in a static boolean. I will use this boolean in whole of my application. I used getServletContext().getServerInfo().

Note: You must read App Engine docs about how they take load-on-startup.

App Engine supports the <load-on-startup> element for servlet declarations. However, the load actually occurs during the first request handled by the web server instance, not prior to it.

Following is my code snippet.

StartupServlet.java: A generic servlet. Which will be initialized when server starts.

public class StartupServlet extends GenericServlet {

public void init() {
String serverInfo = getServletContext().getServerInfo();
/* ServletContext.getServerInfo() will return "Google App Engine Development/x.x.x"
* if will run locally, and "Google App Engine/x.x.x" if run on production envoirnment */
if (serverInfo.contains("Development")) {
Constants.DEV_MODE = true;
}else {
Constants.DEV_MODE = false;
}
}

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub

}
}

web.xml: Add following contents in it

  <servlet>
    <servlet-name>StartupServlet</servlet-name>
    <servlet-class>com.servlet.StartupServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

    <servlet-mapping>
    <servlet-name>StartupServlet</servlet-name>
    <url-pattern>/Startup</url-pattern>
  </servlet-mapping>

Now you can use Constants.DEV_MODE anywhere in your application. It will be true if you are on local server. And false if you are on GAE. For this constant you can make a class with name Constant and declare a static boolean with name DEV_MODE.

If you have anyother idea to implement this solution or you can help me to improve my one. Please drop your comments.

How to avoid DeadlineExceededException in Google App Engine

October 3rd, 2009

If you are developing web application on Google App Engine for Java. And you dont know what this exception is. You can be in trouble. The container throws this exception for those requests which take time more than 30 seconds. In other words GAE wants every requests to be fullfilled within 30 seconds.

Case
I am developing a Twitter application and I got this exception when I login my Twitter user name. I have some 120 friends and 170 followers. So I need to fill two lists of Twitter users with their name and image URL. It was a bad practice from my side that I started populating lists in a loop which contain external service lookup overhead (Twitter) and also big in iteration. So I got following exception.
This request (670f658c2bf64b44) started at 2009/10/02 23:18:23.902 UTC and was still executing at 2009/10/02 23:18:52.605 UTC.

Possible solution
As for those users who have friends and followers in thousands, this problem will persist. So what I am thinking is to put lists in session. Populate the page with first 30 users. And give a link to next 30 (paginate). I will keep updating two variables in session which will tell start and end to pick the users from the list. I will use DWR for this. By this my every request will be responded by container with in 30 seconds.

If you guys have some more optimum solution for it, please share me. Another solution has been discussed here too.