Я пытался создать GWT / веб-приложение Google App Engine с помощью mvp4g платформы.
Я продолжаю получать ошибку об Отказе создать экземпляр моего Сервиса через задержанную привязку.
Мой файл Acebankroll.gwt.xml похож:
Мой Модуль Записи похож:
public class AceBankroll implements EntryPoint {
public void onModuleLoad() {
Mvp4gModule module = (Mvp4gModule)GWT.create( Mvp4gModule.class );
module.createAndStartModule();
RootPanel.get().add((Widget)module.getStartView());
}
}
Я отправляю полную ошибочную трассировку как ответ.
Я считал, что следующий список частых ошибок может вызвать эту ошибку:
Интерфейсы ServiceAsync имеют методы с возвращаемыми значениями. Это неправильно, все методы должны возвратиться пусто.
Сервисные интерфейсы не расширяют интерфейс RemoteService.
Методы в интерфейсах ServiceAsync пропускают заключительный аргумент AsyncCallback.
Методы на этих двух, с которыми соединяют интерфейсом, ExampleService и ExampleServiceAsync, не совпадают точно (кроме возвращаемого значения и аргумента AsyncCallback)
Я проверил все вышеупомянутые условия и не нашел проблему.
Вот отрывок, иллюстрирующий, как я действительно ввожу сервис в своих классах предъявителя.
protected MainServiceAsync service = null;
@InjectService
public void setService( MainServiceAsync service ) {
this.service = service;
}
Да, у меня есть commons-configuration-1.6.jar, commons-lang-2.4.jar и mvp4g-1.1.0.jar в моем каталоге lib.
Да, это действительно компилирует. Я использую Eclipse с плагином Механизма Приложения GWT/Google. Затем я отправляю свой .classpath
Да, они являются сериализуемыми. Они реализуют следующий интерфейс:
public interface BasicBean extends Serializable {
public String getId();
public void copy(BasicBean ob);
}
У них всех есть конструктор пустого аргумента. У некоторых из них есть два конструктора. Один без аргументов и один с аргументами.
Некоторые из них реализуют этот интерфейс
public interface NameObject extends BasicBean, BaseOwnedObject, Comparable {
public String getName();
public void setName(String name);
public abstract int compareTo(NameObject ob);
}
Сопоставимое может вызвать проблемы?
Я отправляю свой служебный код:
@RemoteServiceRelativePath( "main" )
public interface MainService extends RemoteService {
public List 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);
}
public interface MainServiceAsync {
public void getUsers(AsyncCallback> callback);
public void deleteUser(UserBean user, AsyncCallback callback);
public void createUser(UserBean user, AsyncCallback callback);
public void updateUser( UserBean user, AsyncCallback callback);
public void authenticate(String username, String password, AsyncCallback callback);
public void isSessionIdStillLegal(String sessionId, AsyncCallback callback);
public void signOut(AsyncCallback callback);
public void userAlreadyExists(String email, AsyncCallback callback);
public void getByEmail(String email, AsyncCallback callback );
public void confirmUser(String email, AsyncCallback callback );
public void getUserById(String id, AsyncCallback callback);
}
import java.io.Serializable;
public interface BasicBean extends Serializable {
public String getId();
public void copy(BasicBean ob);
}
@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;
}
}
Затем я отправляю извлечение web.xml
Примечание. У меня есть 7 других сервисов. Я использую функциональность модуля MVP4G. Мне определили другие сервлеты для каждого модуля в web.xml
mainServlet
com.softamo.acebankroll.server.MainServiceImpl
mainServlet
/acebankroll/main
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();
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;
}
}
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 getUsers() {
PersistenceManager pm = JdoUtil.getPm();
pm.setDetachAllOnCommit(true);
Query q = pm.newQuery(UserBean.class);
if(q==null)
return new ArrayList();
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);
}
}
По-видимому, Google App Engine Annotations в моих Классах компонента вызывал проблему. Удаление аннотации из клиентского кода решило проблему. Что я действительно знаю, есть ли у меня классы с нотацией JDO в стороне сервера. То, что это должно сказать, что бобы являются простым объектом трансдруга данных, который клонирован в объект с аннотациями JDO в стороне сервера.
Я буквально сложен. Я не знаю, что попробовать. Любая справка действительно ценится!
Если ваши методы службы содержат POJO, они могут вызвать проблемы, они должны иметь конструктор с нулевым аргументом или конструктор не определен. Также они должны реализовать IsSerializable или Serializable.
Вы можете попытаться создать службу вручную с помощью:
MainServiceAsync service = GWT.create(MainService.class);
И, возможно, опубликовать классы MainService.
Отредактировано:
Это результат работы treelogger с ошибкой отложенного связывания, и он выводится в консоль, когда вы выполняете компиляцию gwt. Вы также можете увидеть этот вывод в консоли devmode, если вы работаете в размещенном режиме. Всегда проверяйте первую ошибку, потому что остальные чаще всего вызваны первой ошибкой.
Compiling module se.pathed.defa.DefaultGwtProject
Scanning for additional dependencies: file:/C:/Users/Patrik/workspace/skola-workspace/DefaultGwtProject/src/se/pathed/defa/client/DefaultGwtProject.java
Computing all possible rebind results for 'se.pathed.defa.client.GreetingService'
Rebinding se.pathed.defa.client.GreetingService
Invoking com.google.gwt.dev.javac.StandardGeneratorContext@16c6a55
Generating client proxy for remote service interface 'se.pathed.defa.client.GreetingService'
[ERROR] se.pathed.defa.shared.UserBean is not default instantiable (it must have a zero-argument constructor or no constructors at all) and has no custom serializer. (reached via se.pathed.defa.shared.UserBean)
[ERROR] se.pathed.defa.shared.UserBean has no available instantiable subtypes. (reached via se.pathed.defa.shared.UserBean)
[ERROR] subtype se.pathed.defa.shared.UserBean is not default instantiable (it must have a zero-argument constructor or no constructors at all) and has no custom serializer. (reached via se.pathed.defa.shared.UserBean)
[ERROR] Errors in 'file:/C:/Users/Patrik/workspace/skola-workspace/DefaultGwtProject/src/se/pathed/defa/client/DefaultGwtProject.java'
[ERROR] Line 37: Failed to resolve 'se.pathed.defa.client.GreetingService' via deferred binding
Scanning for additional dependencies: jar:file:/C:/eclipse/plugins/com.google.gwt.eclipse.sdkbundle.2.0.3_2.0.3.v201002191036/gwt-2.0.3/gwt-user.jar!/com/google/gwt/core/client/impl/SchedulerImpl.java
[WARN] The following resources will not be created because they were never committed (did you forget to call commit()?)
[WARN] C:\Users\Patrik\AppData\Local\Temp\gwtc301646733929273376.tmp\se.pathed.defa.DefaultGwtProject\compiler\se.pathed.defa.client.GreetingService.rpc.log
[WARN] For the following type(s), generated source was never committed (did you forget to call commit()?)
[WARN] se.pathed.defa.client.GreetingService_Proxy
[ERROR] Cannot proceed due to previous errors