Developing a Java Application that uses an AppEngine database

374 views Asked by At

This might be a very trivial question, but I'm having trouble finding an answer:

Using the Google Plugin for Eclipse, I would like to develop a plain old Java application (not a web-app), that uses AppEngine for cloud storage.

For this, I could, of course, simply create two projects, one containing the AppEngine server and one containing the Java application.

But I'm wondering whether it is possible to set up a single project in Eclipse that contains both the server and the client code (like for a GWT project). To execute it for local debugging, I would then want Eclipse to launch Tomcat to make my servlets available and then launch my Main.java from the client directory of the project as if the project was just a simple Java application. Is this what the "Launch and deploy from this directory" checkbox is for in the "Google" -> "Web Application" settings? If so, how do I use it?

2

There are 2 answers

2
Markus A. On BEST ANSWER

I found one way to do it, but it's a bit cheesy.

First, add the following helper-class to the project:

// other imports
import com.google.appengine.tools.development.DevAppServerMain;

public class DevServer {
    public static void launch(final String[] args) {
        Logger logger = Logger.getLogger("");
        logger.info("Launching AppEngine server...");
        Thread server = new Thread() {
            @Override
            public void run() {
                try {
                    DevAppServerMain.main(args);  // run DevAppServer
                } catch (Exception e) { e.printStackTrace(); }
            }
        };
        server.setDaemon(true);  // shut down server when rest of app completes
        server.start();          // run server in separate thread
        URLConnection cxn;
        try {
            cxn = new URL("http://localhost:8888").openConnection();
        } catch (IOException e) { return; }  // should never happen
        boolean running = false;
        while (!running) {  // maybe add timeout in case server fails to load
            try {
                cxn.connect();  // try to connect to server
                running = true;
                // Maybe limit rate with a Thread.sleep(...) here
            } catch (Exception e) {}
        }
        logger.info("Server running.");
    }
}

Then, add the following line to the entry class:

public static void main(String[] args) {
    DevServer.launch(args);  // launch AppEngine Dev Server (blocks until ready)
    // Do everything else
}

Finally, create the appropriate Run Configuration:

  • Simply click "Run As" -> "Web Application". To create a default Run Configuration.
  • In the created Run Configuration, under the "Main"-tab select your own entry class as the "Main class" instead of the default "com.google.appengine.tools.development.DevAppServerMain".

Now, if you launch this Run Configuration, it will first bring up the AppEngine server and then continue with the rest of the main(...) method in the entry class. Since the server thread is marked as a daemon thread, once the other code in main(...) completes, the application quits normally, shutting down the server as well.

Not sure if this is the most elegant solution, but it works. If someone else has a way to achieve this without the DevServer helper-class, please do post it!

Also, there might be a more elegant way to check whether the AppEngine server is running, other than pinging it with a URL connection as I did above.

Note: The AppEngine Dev Server registers its own URLStreamHandlerFactory to automatically map Http(s)URLConnections onto AppEngine's URL-fetch infrastructure. This means that you get errors complaining about missing url-fetch capabilities if you then use HttpURLConnections in your client code. Luckily, this can be fixed in two way as described here: Getting a reference to Java's default http(s) URLStreamHandler.

0
Rakesh On

If you definitely want to use appengine, then you will end up creating two projects, one on appengine and another a standalone (no servlets). In this case you can take a look at appengine Remote API