AbstractAppEngineAuthorizationCodeServlet.getUserId(...) throws nullpointer

2 views
Skip to first unread message

why_vincent via StackOverflow

unread,
Jan 12, 2017, 7:34:04 AM1/12/17
to google-appengin...@googlegroups.com

I'm trying to run a sample that I took from Google to see if I could access Google+ from App Engine. I added the following files to my project and set up the servlet mapping so that they are available on the paths they are expected to be at. I deployed it to app engine and tried accessing the application. Going to https://mydomain.appspot.com/ gives me Error: NOT_FOUND. Accessing the urls of the sampleservlet gives me the exception mentioned below. Samples are taken from https://github.com/google/google-api-java-client-samples/tree/master/plus-appengine-sample

These samples might not be up to date, but they are the newest I can find from Google. Any clue to what I should do to get this working would be helpful.

My classes look like this:

BasicServlet:

public class PlusBasicServlet extends HttpServlet {

    /**
     * Enter your API key here from https://code.google.com/apis/console/?api=plus under "API Access".
     */
    private static final String API_KEY = "AIzaSyB9NEc2yQRisoj-rIqgg35yeZXReASMRCI";

    private static final long serialVersionUID = 1;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        HttpTransport httpTransport = new UrlFetchTransport();
        JsonFactory jsonFactory = new JacksonFactory();

        Plus plus = new Plus.Builder(httpTransport, jsonFactory, null).setApplicationName("")
                .setGoogleClientRequestInitializer(new PlusRequestInitializer(API_KEY)).build();

        ActivityFeed myActivityFeed = plus.activities().search("Google").execute();
        List<Activity> myActivities = myActivityFeed.getItems();

        resp.setContentType("text/html");
        resp.setStatus(200);
        Writer writer = resp.getWriter();
        writer.write("<ul>");
        for (Activity a : myActivities) {
            writer.write("<li>" + a.getTitle() + "</li>");
        }
        writer.write("</ul>");
    }

}

Callback:

public class PlusSampleAuthCallbackServlet
        extends AbstractAppEngineAuthorizationCodeCallbackServlet {

    private static final long serialVersionUID = 1L;

    @Override
    protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
            throws ServletException, IOException {
        resp.sendRedirect(Utils.MAIN_SERVLET_PATH);
    }

    @Override
    protected void onError(
            HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
            throws ServletException, IOException {
        String nickname = UserServiceFactory.getUserService().getCurrentUser().getNickname();
        resp.getWriter().print("<h3>Hey " + nickname + ", why don't you want to play with me?</h1>");
        resp.setStatus(200);
        resp.addHeader("Content-Type", "text/html");
        return;
    }

    @Override
    protected AuthorizationCodeFlow initializeFlow() throws ServletException, IOException {
        return Utils.initializeFlow();
    }

    @Override
    protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
        return Utils.getRedirectUri(req);
    }

}

Util:

class Utils {

    /**
     * Global instance of the {@link DataStoreFactory}. The best practice is to make it a single
     * globally shared instance across your application.
     */
    private static final AppEngineDataStoreFactory DATA_STORE_FACTORY =
            AppEngineDataStoreFactory.getDefaultInstance();

    private static GoogleClientSecrets clientSecrets = null;
    private static final Set<String> SCOPES = Collections.singleton(PlusScopes.PLUS_ME);
    static final String MAIN_SERVLET_PATH = "/plussampleservlet";
    static final String AUTH_CALLBACK_SERVLET_PATH = "/oauth2callback";
    static final UrlFetchTransport HTTP_TRANSPORT = new UrlFetchTransport();
    static final JacksonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    private static GoogleClientSecrets getClientSecrets() throws IOException {
        if (clientSecrets == null) {
            clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
                    new InputStreamReader(Utils.class.getResourceAsStream("/plus_secret.json")));
            Preconditions.checkArgument(!clientSecrets.getDetails().getClientId().startsWith("Enter ")
                            && !clientSecrets.getDetails().getClientSecret().startsWith("Enter "),
                    "Download client_secrets.json file from https://code.google.com/apis/console/?api=plus "
                            + "into plus-appengine-sample/src/main/resources/client_secrets.json");
        }
        return clientSecrets;
    }

    static GoogleAuthorizationCodeFlow initializeFlow() throws IOException {
        return new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, getClientSecrets(), SCOPES).setDataStoreFactory(
                DATA_STORE_FACTORY).setAccessType("offline").build();
    }

    static String getRedirectUri(HttpServletRequest req) {
        GenericUrl requestUrl = new GenericUrl(req.getRequestURL().toString());
        requestUrl.setRawPath(AUTH_CALLBACK_SERVLET_PATH);
        return requestUrl.build();
    }
}

SampleServlet:

public class PlusSampleServlet extends AbstractAppEngineAuthorizationCodeServlet {

    private static final long serialVersionUID = 1L;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException, ServletException {
        // Get the stored credentials using the Authorization Flow
        AuthorizationCodeFlow authFlow = initializeFlow();
        Credential credential = authFlow.loadCredential(getUserId(req));
        // Build the Plus object using the credentials
        Plus plus = new Plus.Builder(
                Utils.HTTP_TRANSPORT, Utils.JSON_FACTORY, credential).setApplicationName("").build();
        // Make the API call
        Person profile = plus.people().get("me").execute();
        // Send the results as the response
        PrintWriter respWriter = resp.getWriter();
        resp.setStatus(200);
        resp.setContentType("text/html");
        respWriter.println("<img src='" + profile.getImage().getUrl() + "'>");
        respWriter.println("<a href='" + profile.getUrl() + "'>" + profile.getDisplayName() + "</a>");
    }

    @Override
    protected AuthorizationCodeFlow initializeFlow() throws ServletException, IOException {
        return Utils.initializeFlow();
    }

    @Override
    protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
        return Utils.getRedirectUri(req);
    }
}

Exception when accessing sample servlet:

Uncaught exception from servlet
java.lang.NullPointerException
    at com.google.api.client.extensions.appengine.auth.oauth2.AbstractAppEngineAuthorizationCodeServlet.getUserId(AbstractAppEngineAuthorizationCodeServlet.java:92)
    at com.google.api.client.extensions.servlet.auth.oauth2.AbstractAuthorizationCodeServlet.service(AbstractAuthorizationCodeServlet.java:122)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)


Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/41613174/abstractappengineauthorizationcodeservlet-getuserid-throws-nullpointer

why_vincent via StackOverflow

unread,
Jan 12, 2017, 9:34:07 AM1/12/17
to google-appengin...@googlegroups.com

This had to be added in web.xml under the tag:

  <security-constraint>
        <web-resource-collection>
            <web-resource-name>any</web-resource-name>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>


Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/41613174/abstractappengineauthorizationcodeservlet-getuserid-throws-nullpointer/41615607#41615607
Reply all
Reply to author
Forward
0 new messages