Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to connect to PostgreSQL server from java app engine. On my local machine code works perfectly, but when I deploy code to appengine, I get this exception:

Uncaught exception from servlet
java.lang.NullPointerException
    at com.google.appengine.runtime.Request.process-3a02a4d7b73299fa(Request.java)
    at java.util.Hashtable.put(Hashtable.java:432)
    at java.util.Properties.setProperty(Properties.java:161)
    at org.postgresql.Driver.loadDefaultProperties(Driver.java:121)
    at org.postgresql.Driver.access$000(Driver.java:46)
    at org.postgresql.Driver$1.run(Driver.java:88)
    at java.security.AccessController.doPrivileged(AccessController.java:63)
    at org.postgresql.Driver.getDefaultProperties(Driver.java:85)
    at org.postgresql.Driver.connect(Driver.java:231)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at guestbook.PostgreServlet.doGet(PostgreServlet.java:49)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.tools.appstats.AppstatsFilter.doFilter(AppstatsFilter.java:141)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:435)
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:442)
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:186)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:306)
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:298)
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:439)
    at java.lang.Thread.run(Thread.java:722)

I am using postgresql-9.2-1003.jdbc4.jar and I have this jdbc as library and also inside my "war/WEB-INF/lib" folder. My java code is here:

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class PostgreServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        resp.setContentType("text/html");
        PrintWriter pw = resp.getWriter();

        Connection conn = null;
        String result = "";
        try {
            conn = DriverManager.getConnection("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/xxxxx", "xxx", "xxxx");           
            if(conn == null){
                pw.println("Connection null");
                return;
            }
            ResultSet rs = conn.createStatement().executeQuery(
                    "SELECT * FROM pg_catalog.pg_tables");
            while (rs.next()) {
                result += rs.getString("tablename") + "<br>";
            }
            pw.println(result);

        } catch (SQLException e) {
            e.printStackTrace();
        } 
            finally {
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
        }
    }
}
share|improve this question

3 Answers 3

Google don't allow jdbc out, only http out.

Look at Google Secure Data Connector (which is deprecated, but works until 2015).

Connections out from the Google App Engine are only HTTP based!

Google Cloud SQL

There is some functionality in Google Cloud SQL that you might wanna look at: https://developers.google.com/cloud-sql/

JDBC over HTTP

There are solutions to reach databases over http (e.g. http://vjdbc.sourceforge.net/ http://sourceforge.net/projects/sqlgateway/ etc)

The URLFetch API

App Engine applications can communicate with other applications or access other resources on the web by fetching URLs. An app can use the URL Fetch service to issue HTTP and HTTPS requests and receive responses. The URL Fetch service uses Google's network infrastructure for efficiency and scaling purposes. https://developers.google.com/appengine/docs/python/urlfetch/

Socket API

App Engine supports regular outbound Java sockets such as java.net.Socket and java.net.DatagramSocket. There is currently no support for sockets via java.nio.SocketChannel or other java.nio classes. Sockets are only available for paid apps! (another way to use outbounds, mentioned by Peter Knego) https://developers.google.com/appengine/docs/java/sockets/

But I would not recommend (accessing external databases easily over internet, with public IPs) , this solution are no-no for me, it is a high security issue - my opinion!

share|improve this answer
    
what solution would you recommend for access to this database? I am developing web app that needs to access multiple databases (CloudSQL, MySQL and PostgreSQL). –  user2028394 Sep 12 '13 at 12:03
    
I would create web services, that I can access from my GAE application. (Could be REST. Could use UrlFetch). In this case I would have control over my database, and keep a low coupling and dependency between the systems. –  MrSimpleMind Sep 12 '13 at 12:13
1  
I have not looked at this in deep but it is a python demo that you can get inspired from bloing.net/2011/01/soap-webservice-gae-python-howto –  MrSimpleMind Sep 12 '13 at 12:18
1  
That is not entirely true: in addition to HTTP, GAE also allows outbound socket connections via Sockets API: developers.google.com/appengine/docs/java/sockets –  Peter Knego Sep 12 '13 at 13:27
    
+1 Peter, true! This one I have not seen. It is though for paid users :) I will add it to the answer, so it contains all suggestions in one. Thx –  MrSimpleMind Sep 12 '13 at 13:48
up vote 2 down vote accepted

Connecting to PostgreSQL from GAE Can be done!

You have to use this jdbc -

postgresql-8.3-607.jdbc2ee.jar

and you must have Sockets enabled

But still, thank you all for your suggestions and answers

share|improve this answer

You forgot to load the driverclass (org.postgresql.Driver). Please add the driver jar into your application lib folder.

    try {

           Class.forName("org.postgresql.Driver"); //You forgot to load the driver 
           conn = DriverManager.getConnection("jdbc:postgresql://xx.xxx.xxx.xxx:xxxx/xxxxx", "xxx", "xxxx");           
        if(conn == null){
            pw.println("Connection null");
            return;
        }
        ResultSet rs = conn.createStatement().executeQuery(
                "SELECT * FROM pg_catalog.pg_tables");
        while (rs.next()) {
            result += rs.getString("tablename") + "<br>";
        }
        pw.println(result);

      } catch (SQLException e) {
         e.printStackTrace();
     } 
share|improve this answer
    
I tried this before and it didn't solve the problem. Since jdbc4 you don't have to register driver (see DriverManager documentation), but thanks for help –  user2028394 Sep 12 '13 at 11:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.