Impossible de créer une instance de Service via différé de liaison

J'ai essayé de construire un GWT /Google App Engine web app à l'aide de la mvp4g cadre.

Je reçois un message d'erreur à propos de ne parviennent pas à créer une instance de mon Service via différé de liaison.

Mon Acebankroll.gwt.xml fichier ressemble à ceci:

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='acebankroll'>
    <inherits name='com.google.gwt.user.User'/>
    <inherits name="com.google.gwt.i18n.I18N"/>
    <inherits name='com.google.gwt.user.theme.standard.Standard'/>  
    <inherits name='com.mvp4g.Mvp4gModule'/>
    <entry-point class='com.softamo.acebankroll.client.AceBankroll'/>
     <source path='client'/>  
</module>

Mon Module d'Entrée ressemble:

public class AceBankroll implements EntryPoint {
    public void onModuleLoad() {
        Mvp4gModule module = (Mvp4gModule)GWT.create( Mvp4gModule.class );
        module.createAndStartModule();
        RootPanel.get().add((Widget)module.getStartView());
    }
}

Trace De L'Erreur

Je post au complet trace de l'erreur comme une réponse.

FAQ et Essais

J'ai lu que la prochaine liste des erreurs les plus courantes qui peuvent causer cette erreur:

  • La ServiceAsync interfaces ont des méthodes avec les valeurs de retour. C'est mal, toutes les méthodes doivent retourner void.

  • Les interfaces de Service ne s'étendent pas à la RemoteService interface.

  • Les méthodes dans la ServiceAsync interfaces de manquer le dernier argument de AsyncCallback.

  • Les méthodes sur les deux interfacé, ExampleService et ExampleServiceAsync, ne correspondent pas exactement (autres que la valeur de retour et AsyncCallback argument)

J'ai vérifié toutes les conditions ci-dessus et n'a pas trouvé le problème.

Comment voulez-vous insérer vos services dans les présentateurs?

Voici un extrait illustrant comment je fais injecter le service dans mes classes presenter.

protected MainServiceAsync service = null;
@InjectService
public void setService( MainServiceAsync service ) {
    this.service = service;
}

Avez-vous les bibliothèques requises?

Oui, j'ai commons-configuration-1.6.jar, commons-lang-2.4.jar et mvp4g-1.1.0.jar dans mon répertoire lib.

Est-ce que votre projet se compile?

Oui, il fait de la compilation. J'utilise Eclipse avec GWT/Google App Engine plugin. Ensuite, j'ai poster mon .classpath

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
    <classpathentry kind="src" path="src"/>
    <classpathentry kind="src" output="test-classes" path="test"/>
    <classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/>
    <classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
    <classpathentry kind="lib" path="lib/commons-configuration-1.6.jar"/>
    <classpathentry kind="lib" path="lib/commons-lang-2.4.jar"/>
    <classpathentry kind="lib" path="lib/mvp4g-1.1.0.jar"/>
    <classpathentry kind="lib" path="test/lib/emma.jar"/>
    <classpathentry kind="lib" path="test/lib/junit-4.5.jar"/>
    <classpathentry kind="lib" path="C:/Users/sdelamo/Programms/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.1_1.3.1.v201002101412/appengine-java-sdk-1.3.1/lib/testing/appengine-testing.jar"/>
    <classpathentry kind="lib" path="C:/Users/sdelamo/Programms/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.1_1.3.1.v201002101412/appengine-java-sdk-1.3.1/lib/impl/appengine-api.jar"/>
    <classpathentry kind="lib" path="C:/Users/sdelamo/Programms/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.1_1.3.1.v201002101412/appengine-java-sdk-1.3.1/lib/impl/appengine-api-labs.jar"/>
    <classpathentry kind="lib" path="C:/Users/sdelamo/Programms/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.1_1.3.1.v201002101412/appengine-java-sdk-1.3.1/lib/impl/appengine-api-stubs.jar"/>
    <classpathentry kind="lib" path="C:/Users/sdelamo/Programms/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.1_1.3.1.v201002101412/appengine-java-sdk-1.3.1/lib/impl/appengine-local-runtime.jar"/>
    <classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>

Sont vos Haricots Sérialisable?

Oui, ils sont sérialisables. Ils implémente l'interface suivante:

public interface BasicBean extends Serializable  {
    public String getId();      
    public void copy(BasicBean ob); 
}

Ils ont tous un argument vide constructeur. Certains d'entre eux ont deux constructeurs. Sans arguments, et un avec des arguments.

Certains implémentent cette interface

public interface NameObject extends BasicBean, BaseOwnedObject, Comparable<NameObject>   { 
    public String getName();
    public void setName(String name);       
    public abstract int compareTo(NameObject ob);
}

Peut Comparables causer des problèmes?

Comment votre code de service ressemble?

Je poste mon code de service:

MainService

@RemoteServiceRelativePath( "main" )
public interface MainService extends RemoteService {
    public List<UserBean> getUsers();    
    public void deleteUser(UserBean user);    
    public void createUser(UserBean user);    
    public void updateUser( UserBean user );        
    public String authenticate(String username, String password);       
    public boolean isSessionIdStillLegal(String sessionId);     
    public void signOut();      
    public boolean userAlreadyExists(String email);     
    public UserBean getByEmail(String email);       
    public void confirmUser(String email);          
    public UserBean getUserById(String id);
}

MainServiceAsync

public interface MainServiceAsync {
    public void getUsers(AsyncCallback<List<UserBean>> callback);    
    public void deleteUser(UserBean user, AsyncCallback<Void> callback);    
    public void createUser(UserBean user, AsyncCallback<Void> callback);    
    public void updateUser( UserBean user, AsyncCallback<Void> callback);       
    public void authenticate(String username, String password, AsyncCallback<String> callback);     
    public void isSessionIdStillLegal(String sessionId, AsyncCallback<Boolean> callback);       
    public void signOut(AsyncCallback<Void> callback);      
    public void userAlreadyExists(String email, AsyncCallback<Boolean> callback);       
    public void getByEmail(String email, AsyncCallback<UserBean> callback );            
    public void confirmUser(String email, AsyncCallback<Void> callback );           
    public void getUserById(String id, AsyncCallback<UserBean> callback);
}

De Base De Haricots

import java.io.Serializable;    
public interface BasicBean extends Serializable  {
    public String getId();      
    public void copy(BasicBean ob); 
}

Utilisateur Bean

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class UserBean implements BasicBean {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    protected Long ident;       
    @Persistent
    private String name = null;     
    @Persistent
    private String email = null;        
    @Persistent
    private boolean confirmed = false;      
    @Persistent
    private String password = null;

    public UserBean() { }

    public String getId() {
        if( ident == null ) return null;
        return ident.toString();
    }
    public void setId(String id) {
        this.ident = Long.parseLong(id);
    }           
    public String getEmail( ) { return email; }
    public void setEmail(String email) { this. email = email; }     
    public String getName() { return name; }
    public void setName(String name) { this. name = name; }     
    public String getPassword() { return password; }    
    public void setPassword(String password) {  this.password = password;}      
    public boolean isConfirmed() { return confirmed;}
    public void setConfirmed(boolean confirmed) {this.confirmed = confirmed;}       
    public void copy(BasicBean ob) {
         UserBean user = (UserBean) ob;
        this.name = user.name;
        this.email = user.email;
        this.password = user.password;      
    }
}

Prochaine je poste un extrait de web.xml

Note. J'ai 7 autres services. Je suis en utilisant le module de la fonctionnalité de MVP4G. J'ai d'autres servlets définis pour chaque module web.xml

<servlet>
    <servlet-name>mainServlet</servlet-name>
    <servlet-class>com.softamo.acebankroll.server.MainServiceImpl</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>mainServlet</servlet-name>
    <url-pattern>/acebankroll/main</url-pattern>
</servlet-mapping>

Serveur

BaseServiceImpl

public abstract class BaseServiceImpl extends RemoteServiceServlet {
    protected Map users = new HashMap();
    protected static final MemcacheService memcache = MemcacheServiceFactory.getMemcacheService();
    protected static final Logger log = Logger.getLogger(BaseServiceImpl.class.getName());    
    protected String getSessionId() {
        return getThreadLocalRequest().getSession().getId();
    }    
    protected String getCurrentUserId() {
        String id = getSessionId();
        UserBean user = (UserBean) users.get(id);
        if(user!=null) 
            return user.getId();
        return null;
    }    
    protected void saveBaseObject(BasicBean ob) {
        PersistenceManager pm = JdoUtil.getPm();
        String sessionId = getSessionId();      
        UserBean user = (UserBean) users.get(sessionId);
        if(user!=null) {
            String user_id = user.getId();
            ((BaseOwnedObject)ob).setUserId(user_id);
            pm.makePersistent(ob);
        }           
    }    
    protected void deleteBaseObject(Class classname, String id) {
        PersistenceManager pm = JdoUtil.getPm();                
        pm.deletePersistent( pm.getObjectById(classname, Long.parseLong(id) ));     
    }    
    protected List getAll(Class class_name) {
        PersistenceManager pm = JdoUtil.getPm();
        pm.setDetachAllOnCommit(true);

        Query q = pm.newQuery(class_name);          
        if(q==null) 
            return new ArrayList<BasicBean>();
        q.setFilter("userId == userIdParam");
        q.declareParameters("String userIdParam");          
        String userId = getCurrentUserId();
        return (List) q.execute(userId);
    }    
    public boolean isSessionIdStillLegal(String sessionId) {
        return (users.containsKey(sessionId))? true : false;
    }    
    public void signOut() {
        String id = getSessionId();
        synchronized(this) {
            users.remove(id);
        }
    }    
    public BasicBean getObjectById(Class classname, String id) {
        BasicBean result = null;
        PersistenceManager pm = JdoUtil.getPm();
        pm.setDetachAllOnCommit(true);
        result = pm.getObjectById(classname, Long.parseLong(id) );
        return result;
    }
}

MainServiceImpl

public class MainServiceImpl extends BaseServiceImpl implements MainService {       
    public MainServiceImpl() {}     
    public String authenticate(String username, String password) {
        PersistenceManager pm = JdoUtil.getPm();

        UserBean user = getByEmail(username);
        if(user==null || !user.isConfirmed())
            return null;
        String hashFromDB = user.getPassword();
        boolean valid = BCrypt.checkpw(password, hashFromDB);
        if(valid) { 
            String id = getSessionId();
            synchronized( this ) {
                users.put(id, user) ;
            }
            return id;  
        }
        return null;
    }    
    public void deleteUser(UserBean user) {
        deleteBaseObject(UserBean.class, user.getId());
    }
    public List<UserBean> getUsers() {
        PersistenceManager pm = JdoUtil.getPm();
        pm.setDetachAllOnCommit(true);
        Query q = pm.newQuery(UserBean.class);          
        if(q==null) 
            return new ArrayList<UserBean>();           
        return (List) q.execute();      
    }    
    public boolean userAlreadyExists(String email) {
        return (getByEmail(email)!=null) ? true : false;        
    }    
    public void updateUser(UserBean object) {
        saveBaseObject(object);
    }    
    public void confirmUser(String email) {
        PersistenceManager pm = JdoUtil.getPm();        
        UserBean user = getByEmail(email);
        if(user!=null) {
            user.setConfirmed(true);
            pm.makePersistent(user);
        }   
    }    
    public void createUser(UserBean user) {
        PersistenceManager pm = JdoUtil.getPm();
        String sessionId = getSessionId();
        //Only store it if it does not exists
        if( (getByEmail(user.getEmail()))==null) {
            String hash = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt());
            user.setPassword(hash);
            pm.makePersistent(user);
            synchronized( this ) {
                users.put(sessionId, user);              
            }           
        }       
    }    
    public UserBean getByEmail(String email) {
        return new MyAccountServiceImpl().getByEmail(email);
    }    
    public UserBean getUserById(String id) {
        return new MyAccountServiceImpl().getUserById(id);
    }
}

SOLUTION

Apparemment le Google App Engine Annotations dans mes classes de Haricots ont été à l'origine du problème. Retrait de l'annotation du côté client code résolu le problème. Ce que je sais, si j'ai le cours avec les JDO notation dans le côté serveur. Que c'est-à-dire les haricots sont de simples données transfère objet qui se cloné dans un objet avec JDO annotations dans le côté serveur.

Je suis littéralement empilés. Je ne sais pas quoi essayer. Toute aide est vraiment apprécié!

OriginalL'auteur Sergio del Amo | 2010-07-28