title: com.google.api.server.spi.auth.EspAuthenticator not found
body: <p>I am working on google endpoints api 2.0 and was trying to integrate firebase authentication using <a href="https://cloud.google.com/endpoints/docs/frameworks/java/authenticating-users" rel="nofollow noreferrer">this</a></p>
  
  <p>Part of documentation. I encountered a peculiar problem that with the dependencies that I have added to pom.xml com.google.api.server.spi.auth.EspAuthenticator.class doesn't show up. There are other authenticators available such as GoogleJwtAuthenticator and  GoogleOAuth2Authenticator, but EspAuthenticator is not available for import. It is not recognised. Here is my pom.xml </p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
  
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
      &lt;packaging&gt;war&lt;/packaging&gt;
      &lt;version&gt;1.0&lt;/version&gt;
  
      &lt;groupId&gt;com.google.devrel.training.conference&lt;/groupId&gt;
      &lt;artifactId&gt;conference&lt;/artifactId&gt;
  
      &lt;properties&gt;
          &lt;appengine.app.version&gt;1&lt;/appengine.app.version&gt;
          &lt;appengine.target.version&gt;1.9.53&lt;/appengine.target.version&gt;
          &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
      &lt;/properties&gt;
  
      &lt;dependencies&gt;
          &lt;!-- Compile/runtime dependencies --&gt;
          &lt;dependency&gt;
      &lt;groupId&gt;com.google.endpoints&lt;/groupId&gt;
      &lt;artifactId&gt;endpoints-framework&lt;/artifactId&gt;
      &lt;version&gt;2.0.7&lt;/version&gt;
  &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.google.appengine&lt;/groupId&gt;
              &lt;artifactId&gt;appengine-api-1.0-sdk&lt;/artifactId&gt;
              &lt;version&gt;${appengine.target.version}&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.google.appengine&lt;/groupId&gt;
              &lt;artifactId&gt;appengine-endpoints&lt;/artifactId&gt;
              &lt;version&gt;${appengine.target.version}&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
              &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
              &lt;version&gt;2.5&lt;/version&gt;
              &lt;scope&gt;provided&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;javax.inject&lt;/groupId&gt;
              &lt;artifactId&gt;javax.inject&lt;/artifactId&gt;
              &lt;version&gt;1&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.googlecode.objectify&lt;/groupId&gt;
              &lt;artifactId&gt;objectify&lt;/artifactId&gt;
              &lt;version&gt;5.0&lt;/version&gt;
          &lt;/dependency&gt;
  
          &lt;!-- Test Dependencies --&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.google.appengine&lt;/groupId&gt;
              &lt;artifactId&gt;appengine-testing&lt;/artifactId&gt;
              &lt;version&gt;${appengine.target.version}&lt;/version&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;com.google.appengine&lt;/groupId&gt;
              &lt;artifactId&gt;appengine-api-stubs&lt;/artifactId&gt;
              &lt;version&gt;${appengine.target.version}&lt;/version&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;junit&lt;/groupId&gt;
              &lt;artifactId&gt;junit&lt;/artifactId&gt;
              &lt;version&gt;4.11&lt;/version&gt;
          &lt;/dependency&gt;
  
  
  
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;outputDirectory&gt;target/${project.artifactId}-${project.version}/WEB-INF/classes&lt;/outputDirectory&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                  &lt;version&gt;2.5.1&lt;/version&gt;
                  &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                  &lt;configuration&gt;
                      &lt;source&gt;1.7&lt;/source&gt;
                      &lt;target&gt;1.7&lt;/target&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
              &lt;plugin&gt;
      &lt;groupId&gt;com.google.cloud.tools&lt;/groupId&gt;
      &lt;artifactId&gt;endpoints-framework-maven-plugin&lt;/artifactId&gt;
      &lt;version&gt;1.0.0-beta5&lt;/version&gt;
      &lt;configuration&gt;
          &lt;!-- plugin configuration --&gt;
      &lt;/configuration&gt;
  &lt;/plugin&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                  &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt;
                  &lt;version&gt;2.3&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;webXml&gt;${project.build.directory}/generated-sources/appengine-endpoints/WEB-INF/web.xml&lt;/webXml&gt;
                      &lt;webResources&gt;
                          &lt;resource&gt;
                              &lt;!-- this is relative to the pom.xml directory --&gt;
                              &lt;directory&gt;${project.build.directory}/generated-sources/appengine-endpoints&lt;/directory&gt;
                              &lt;!-- the list has a default value of ** --&gt;
                              &lt;includes&gt;
                                  &lt;include&gt;WEB-INF/*.discovery&lt;/include&gt;
                                  &lt;include&gt;WEB-INF/*.api&lt;/include&gt;
                              &lt;/includes&gt;
                          &lt;/resource&gt;
                      &lt;/webResources&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;com.google.appengine&lt;/groupId&gt;
                  &lt;artifactId&gt;appengine-maven-plugin&lt;/artifactId&gt;
                  &lt;version&gt;${appengine.target.version}&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;enableJarClasses&gt;false&lt;/enableJarClasses&gt;
                  &lt;/configuration&gt;
                  &lt;executions&gt;
                      &lt;execution&gt;
                          &lt;goals&gt;
                              &lt;goal&gt;endpoints_get_discovery_doc&lt;/goal&gt;
                          &lt;/goals&gt;
                      &lt;/execution&gt;
                  &lt;/executions&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
          &lt;pluginManagement&gt;
              &lt;plugins&gt;
                  &lt;!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;org.eclipse.m2e&lt;/groupId&gt;
                      &lt;artifactId&gt;lifecycle-mapping&lt;/artifactId&gt;
                      &lt;version&gt;1.0.0&lt;/version&gt;
                      &lt;configuration&gt;
                          &lt;lifecycleMappingMetadata&gt;
                              &lt;pluginExecutions&gt;
                                  &lt;pluginExecution&gt;
                                      &lt;pluginExecutionFilter&gt;
                                          &lt;groupId&gt;
                                              com.google.appengine
                                          &lt;/groupId&gt;
                                          &lt;artifactId&gt;
                                              appengine-maven-plugin
                                          &lt;/artifactId&gt;
                                          &lt;versionRange&gt;
                                              [1.9.3,)
                                          &lt;/versionRange&gt;
                                          &lt;goals&gt;
                                              &lt;goal&gt;
                                                  endpoints_get_discovery_doc
                                              &lt;/goal&gt;
                                          &lt;/goals&gt;
                                      &lt;/pluginExecutionFilter&gt;
                                      &lt;action&gt;
                                          &lt;ignore&gt;&lt;/ignore&gt;
                                      &lt;/action&gt;
                                  &lt;/pluginExecution&gt;
                              &lt;/pluginExecutions&gt;
                          &lt;/lifecycleMappingMetadata&gt;
                      &lt;/configuration&gt;
                  &lt;/plugin&gt;
              &lt;/plugins&gt;
          &lt;/pluginManagement&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>And here is my ConferenceApi Code, that I developed from udacity course building scalable apps with java and later migrated to 2.0 version using the migration guide.</p>
  
  <pre><code>package com.google.devrel.training.conference.spi;
  
  import static com.google.devrel.training.conference.service.OfyService.ofy;
  
  import java.util.List;
  import com.google.api.server.spi.auth.GoogleOAuth2Authenticator;
  import com.google.api.server.spi.auth.EspAuthenticator; // not available
  
  
  import com.google.api.server.spi.config.Api;
  import com.google.api.server.spi.config.ApiIssuer;
  import com.google.api.server.spi.config.ApiIssuerAudience;
  import com.google.api.server.spi.config.ApiMethod;
  import com.google.api.server.spi.config.ApiMethod.HttpMethod;
  import com.google.api.server.spi.response.UnauthorizedException;
  import com.google.appengine.api.users.User;
  import com.google.devrel.training.conference.Constants;
  import com.google.devrel.training.conference.domain.Conference;
  import com.google.devrel.training.conference.domain.Profile;
  import com.google.devrel.training.conference.form.ConferenceForm;
  import com.google.devrel.training.conference.form.ConferenceQueryForm;
  import com.google.devrel.training.conference.form.ProfileForm;
  import com.google.devrel.training.conference.form.ProfileForm.TeeShirtSize;
  import com.google.devrel.training.conference.service.OfyService;
  import com.googlecode.objectify.Key;
  import com.googlecode.objectify.cmd.Query;
  
  /**
   * Defines conference APIs.
   */
  @Api(name = "conference", version = "v1", scopes = { Constants.EMAIL_SCOPE }, 
  authenticators = {com.google.api.server.spi.auth.EspAuthenticator.class},
  //EspAuthenticator not available
  issuers = {
          @ApiIssuer(
                  name = "firebase",
                  issuer = "https://securetoken.google.com/***PROJECT ID***",
                  jwksUri = "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com")
       },
  issuerAudiences = {
          @ApiIssuerAudience(name = "firebase", audiences = "***PROJECT ID***")
      },
  clientIds = {
          Constants.WEB_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID }, description = "API for the Conference Central Backend application.")
  public class ConferenceApi {
  
      /*
       * Get the display name from the user's email. For example, if the email is
       * lemoncake@example.com, then the display name becomes "lemoncake."
       */
      private static String extractDefaultDisplayNameFromEmail(String email) {
          return email == null ? null : email.substring(0, email.indexOf("@"));
      }
  
      /**
       * Creates or updates a Profile object associated with the given user
       * object.
       *
       * @param user
       *            A User object injected by the cloud endpoints.
       * @param profileForm
       *            A ProfileForm object sent from the client form.
       * @return Profile object just created.
       * @throws UnauthorizedException
       *             when the User object is null.
       */
  
      // Declare this method as a method available externally through Endpoints
      @ApiMethod(name = "saveProfile", path = "profile", httpMethod = HttpMethod.POST)
      // The request that invokes this method should provide data that
      // conforms to the fields defined in ProfileForm
  
      // TODO 1 Pass the ProfileForm parameter
      // TODO 2 Pass the User parameter
      public Profile saveProfile(final User user,ProfileForm profileForm) throws UnauthorizedException {
  
          String userId = null;
          String mainEmail = null;
          String displayName = "Your name will go here";
          TeeShirtSize teeShirtSize = TeeShirtSize.NOT_SPECIFIED;
  
          // TODO 2
          // If the user is not logged in, throw an UnauthorizedException
          if(user==null){
              throw new UnauthorizedException("Unauthorized Exception");
          }
  
          // TODO 1
          // Set the teeShirtSize to the value sent by the ProfileForm, if sent
          // otherwise leave it as the default value
  
  
  
          // TODO 1
          // Set the displayName to the value sent by the ProfileForm, if sent
          // otherwise set it to null
  //        displayName=profileForm.getDisplayName();
  
          // TODO 2
          // Get the userId and mainEmail
          userId=user.getUserId();
          mainEmail=user.getEmail();
  
          // TODO 2
          // If the displayName is null, set it to default value based on the user's email
          // by calling extractDefaultDisplayNameFromEmail(...)
  //        if(displayName==null){
  //          displayName=extractDefaultDisplayNameFromEmail(mainEmail);
  //        }
  
  
          // Create a new Profile entity from the
          // userId, displayName, mainEmail and teeShirtSize
          Key&lt;Profile&gt; key=Key.create(Profile.class,userId);
          Profile profile = ofy().load().key(key).now();
  
          if(profile==null){
  
               if(profileForm.getTeeShirtSize()!=null){
                  teeShirtSize=profileForm.getTeeShirtSize();
               }else{
                   teeShirtSize=TeeShirtSize.NOT_SPECIFIED;
               }
  
               if(profileForm.getDisplayName()!=null){
                   displayName=profileForm.getDisplayName();
               }else{
                   displayName=extractDefaultDisplayNameFromEmail(mainEmail);
               }
               profile=new Profile(userId,displayName, mainEmail, teeShirtSize);
          }else{
              profile.update(profileForm.getDisplayName(), profileForm.getTeeShirtSize());
          }
  
          // TODO 3 (In Lesson 3)
          // Save the Profile entity in the datastore
          ofy().save().entity(profile).now();
  
          // Return the profile
          return profile;
      }
  
      /**
       * Returns a Profile object associated with the given user object. The cloud
       * endpoints system automatically inject the User object.
       *
       * @param user
       *            A User object injected by the cloud endpoints.
       * @return Profile object.
       * @throws UnauthorizedException
       *             when the User object is null.
       */
      @ApiMethod(name = "getProfile", path = "profile", httpMethod = HttpMethod.GET)
      public Profile getProfile(final User user) throws UnauthorizedException {
          if (user == null) {
              throw new UnauthorizedException("Authorization required");
          }
  
          // TODO
          // load the Profile Entity
          String userId = user.getUserId(); // TODO
          Key&lt;Profile&gt; key = Key.create(Profile.class,userId); // TODO
          Profile profile=(Profile) ofy().load().key(key).now(); // TODO load the Profile entity
          return profile;
      }
  
      /**
       * Gets the Profile entity for the current user
       * or creates it if it doesn't exist
       * @param user
       * @return user's Profile
       */
      private static Profile getProfileFromUser(User user) {
          // First fetch the user's Profile from the datastore.
          Profile profile = ofy().load().key(
                  Key.create(Profile.class, user.getUserId())).now();
          if (profile == null) {
              // Create a new Profile if it doesn't exist.
              // Use default displayName and teeShirtSize
              String email = user.getEmail();
              profile = new Profile(user.getUserId(),
                      extractDefaultDisplayNameFromEmail(email), email, TeeShirtSize.NOT_SPECIFIED);
          }
          return profile;
      }
  
  /**
       * Creates a new Conference object and stores it to the datastore.
       *
       * @param user A user who invokes this method, null when the user is not signed in.
       * @param conferenceForm A ConferenceForm object representing user's inputs.
       * @return A newly created Conference Object.
       * @throws UnauthorizedException when the user is not signed in.
       */
      @ApiMethod(name = "createConference", path = "conference", httpMethod = HttpMethod.POST)
      public Conference createConference(final User user, final ConferenceForm conferenceForm)
          throws UnauthorizedException {
          if (user == null) {
              throw new UnauthorizedException("Authorization required");
          }
  
          // TODO (Lesson 4)
          // Get the userId of the logged in User
          String userId = user.getUserId();
  
          // TODO (Lesson 4)
          // Get the key for the User's Profile
          Key&lt;Profile&gt; profileKey = Key.create(Profile.class,userId);
  
          // TODO (Lesson 4)
          // Allocate a key for the conference -- let App Engine allocate the ID
          // Don't forget to include the parent Profile in the allocated ID
          final Key&lt;Conference&gt; conferenceKey = OfyService.factory().allocateId(profileKey, Conference.class);
  
          // TODO (Lesson 4)
          // Get the Conference Id from the Key
          final long conferenceId = conferenceKey.getId();
  
          // TODO (Lesson 4)
          // Get the existing Profile entity for the current user if there is one
          // Otherwise create a new Profile entity with default values
          Profile profile = ofy().load().key(profileKey).now();
          if(profile==null){
              profile=new Profile(user.getUserId(),user.getEmail(),extractDefaultDisplayNameFromEmail(user.getEmail()),TeeShirtSize.NOT_SPECIFIED);
  
  
          }
  
          // TODO (Lesson 4)
          // Create a new Conference Entity, specifying the user's Profile entity
          // as the parent of the conference
          Conference conference = new Conference(conferenceId,user.getUserId(),conferenceForm);
  
          // TODO (Lesson 4)
          // Save Conference and Profile Entities
           ofy().save().entities(profile,conference).now();
  
           return conference;
           }
      @ApiMethod(name="queryConferences",
              path="queryConferences",
              httpMethod=HttpMethod.POST)
      public List&lt;Conference&gt; queryConferences(ConferenceQueryForm cqf){
  
          return cqf.getQuery().list();
      }
  
      @ApiMethod(name="getConferencesCreated",
              path="getConferencesCreated",
              httpMethod=HttpMethod.POST)
      public List&lt;Conference&gt; getConferencesCreated(User user) throws UnauthorizedException{
          if (user == null) {
              throw new UnauthorizedException("Authorization required");
          }
          Query&lt;Conference&gt; query= ofy().load().type(Conference.class).ancestor(Key.create(Profile.class,user.getUserId())).order("name");
          return query.list();
      }
  
  //    @ApiMethod(name="filterPlayground",
  //          path="filterPlayground",
  //          httpMethod=HttpMethod.POST)
      public List&lt;Conference&gt; filterPlayground(){
          Query&lt;Conference&gt; query= ofy().load().type(Conference.class);
  //      query=query.filter("topics=", "Movie Making");
  //      query=query.filter("month=",6);
          query=query.filter("city","London");
          query=query.filter("maxAttendees &gt;",10).order("maxAttendees").order("name");
          return query.list();
      }
  
  
  
  }
  </code></pre>
  
  <p>Please tell me if there is something wrong with pom.xml or there are some other issues that are making EspAuthenticator.class not available. </p>