Connecting to PostgreSQL in the java application engine

存储架构 2018-01-14 阅读原文

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") + "
"; } 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(); } } } } }

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!
Hello, buddy!

责编内容by:Hello, buddy!阅读原文】。感谢您的支持!

您可能感兴趣的

What happens behind the scenes for finalize() meth... One Java question typically asked at interviews is “What is the purpose of finalize() method?” While you can respon...
Java内存区域 线程私有。 一块较小的内存区域,当前线程所执行的字节码的行号指示器。 如果执行的是一个Java方法,计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是一个Native方法,计数器值为空。 此内存区域,是唯一一...
Java日志-SLF4J使用与源码分析 SLF4J全称The Simple Logging Facade for Java,Java简易日志门面,将接口抽象与实现隔离开,在不修改代码的情况下使用不同的日志实现。 SLF4J支持的日志实现有: log4j lo...
自己动手写把”锁”—LockSupport深入浅出... 本篇是《自己动手写把"锁"》系列技术铺垫的最后一个知识点。本篇主要讲解LockSupport工具类,它用来实现线程的挂起和唤醒。 LockSupport是Java6引入的一个工具类,它简单灵活,应用广泛。 一、简单 俗话说,没有...
eclipse 快捷键及使用技巧 一、程序的编译和运行的环境配置(一般不改)window -- Preferences -- Java 编译环境:Compiler 默认选中的就是最高版本。 运行环境:Installed JREs 默认会找你...