Подтвердить что ты не робот

Почему я получаю ClassNotPersistableException при запуске приложения GWT App Engine в режиме размещения?

Я случайно получаю org.datanucleus.exceptions.ClassNotPersistableException, когда пытаюсь выполнить запрос в локальном хранилище JDO моего приложения GWT/App Engine. Это происходит только при запуске приложения в режиме Hosted. Когда я развертываю его в Google App Engine, все работает отлично.

Трассировка стека:

org.datanucleus.exceptions.ClassNotPersistableException: The class "com.wayd.server.beans.WinePost" is not persistable. This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found.
    at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:305)
    at org.datanucleus.ObjectManagerImpl.getExtent(ObjectManagerImpl.java:3700)
    at org.datanucleus.jdo.JDOPersistenceManager.getExtent(JDOPersistenceManager.java:1515)
    at com.wayd.server.WinePostServiceImpl.getPosts(WinePostServiceImpl.java:212)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:527)
    ... 25 more
Caused by: org.datanucleus.exceptions.ClassNotPersistableException: The class "com.wayd.server.beans.WinePost" is not persistable. This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found.
    at org.datanucleus.ObjectManagerImpl.assertClassPersistable(ObjectManagerImpl.java:3830)
    at org.datanucleus.ObjectManagerImpl.getExtent(ObjectManagerImpl.java:3693)
    ... 32 more)

Класс WinePost - это очень простой класс, поддерживающий JDO:

@PersistenceCapable (identityType = IdentityType.APPLICATION) открытый класс WinePost {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private User author;

@Persistent
private String grape;

@Persistent
private String comment;

public WinePost(final User author, final String grape,
        final String comment) {
    super();
    this.grape = grape;
    this.comment = comment;
}

public User getAuthor() {
    return author;
}

public void setAuthor(final User author) {
    this.author = author;
}

public Long getId() {
    return id;
}

public void setId(final Long id) {
    this.id = id;
}

public String getGrape() {
    return grape;
}

public void setGrape(final String grape) {
    this.grape = grape;
}

public String getComment() {
    return comment;
}

public void setComment(final String comment) {
    this.comment = comment;
}

public String getUserNickname() {
    String retVal = null;
    if (author != null) {
        retVal = author.getNickname();
    }
    return retVal;
}

public WinePostModel getWinePostModel() {
    final WinePostModel winePostModel = new WinePostModel(grape, vintage, getUserNickName());
    return winePostModel;
}

}

Запрос хранилища данных выполняется следующим способом:

public ArrayList<WinePostModel> getPosts() {
        final ArrayList<WinePostModel> posts = new ArrayList<WinePostModel>();
        final PersistenceManager persistenceManager = PMF.get()
        .getPersistenceManager();

        final Extent<WinePost> winePostExtent = persistenceManager.getExtent(
                WinePost.class, false);
        for (final WinePost winePost : winePostExtent) {
            posts.add(winePost.getWinePostModel());
        }
        winePostExtent.closeAll();

        return posts;
    }
4b9b3361

Ответ 1

Я уверен, что с вашим кодом нет ничего плохого. Причина, по которой вы получаете эту ошибку, связана с проблемой с энхансером Datanucleus.

Если вы видите эту ошибку, закройте Jetty и проверьте консоль внутри Eclipse (вам нужно будет выбрать нужную консоль на маленькой панели инструментов над консольным окном). Он должен сказать что-то вроде:

DataNucleus Enhancer (версия 1.1.4): Улучшение классов DataNucleus Enhancer завершил успешную работу в классах X. Сроки: вход = 547 мс, усиление = 76 мс, всего = 623 мс. Подробные сведения см. В журнале

... где X - количество обработанных классов. Число должно быть равно числу определяемых вами сущностей.

Но иногда по какой-то причине он скажет 0, поэтому вы получаете ошибку ClassNotPersistableException.

Чтобы исправить, откройте класс сущности и измените что-нибудь (добавьте пробел или что-то еще) и сохраните. Проверьте консоль, пока она не сообщит, что она расширила все классы сущностей. Затем перезапустите отладчик и повторите попытку.

Ответ 2

Публикация для будущих ссылок для тех, кто сталкивается с одной проблемой, несмотря на то, что это старый поток.

Я столкнулся с "той же" проблемой и обнаружил, что мой путь к классам имеет несколько экземпляров datanucleus-appengine-1.0.7.final.jar. Я узнал об этом из журнала, который был запрошен, когда я попытался создать мое рабочее пространство. Здесь содержимое журнала.

java.lang.RuntimeException: Неожиданное исключение   at com.google.appengine.tools.enhancer.Enhancer.execute(Enhancer.java:59)   в com.google.appengine.tools.enhancer.Enhance. (Enhance.java:60)   at com.google.appengine.tools.enhancer.Enhance.main(Enhance.java:41) Вызывается: java.lang.reflect.InvocationTargetException   at sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод)   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)   на sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)   в java.lang.reflect.Method.invoke(Method.java:597)   at com.google.appengine.tools.enhancer.Enhancer.execute(Enhancer.java:57)   ... еще 2 Вызывается: org.datanucleus.exceptions.NucleusException: плагин (Bundle) "org.datanucleus.store.appengine" уже зарегистрирован. Убедитесь, что у вас нет нескольких версий JAR одного и того же плагина в пути к классам. URL-адрес:/G:/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.4_1.3.4.v201005212032/appengine-java-sdk-1.3.4/lib/user/orm/datanucleus-appengine -1.0.7.final.jar "уже зарегистрирован, и вы пытаетесь зарегистрировать идентичный плагин, расположенный по адресу URL:/G:/WS_Quotemandu/quotemandu/war/WEB-INF/lib/datanucleus-appengine-1.0. 7.final.jar".   на org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:434)   на org.datanucleus.plugin.NonManagedPluginRegistry.registerBundle(NonManagedPluginRegistry.java:340)   на org.datanucleus.plugin.NonManagedPluginRegistry.registerExtensions(NonManagedPluginRegistry.java:222)   на org.datanucleus.plugin.NonManagedPluginRegistry.registerExtensionPoints(NonManagedPluginRegistry.java:153)   на org.datanucleus.plugin.PluginManager.registerExtensionPoints(PluginManager.java:82)   в org.datanucleus.OMFContext. (OMFContext.java:160)   at org.datanucleus.enhancer.DataNucleusEnhancer. (DataNucleusEnhancer.java:172)   at org.datanucleus.enhancer.DataNucleusEnhancer. (DataNucleusEnhancer.java:150)   at org.datanucleus.enhancer.DataNucleusEnhancer.main(DataNucleusEnhancer.java:1157)   ... еще 7

G:/eclipse/plugins/com.google.appengine.eclipse.sdkbundle.1.3.4_1.3.4.v201005212032/appengine-java-sdk-1.3.4/lib/user/orm/datanucleus-appengine-1.0. 7.final.jar

Файл:/G:/WS_Quotemandu/quotemandu/war/WEB-INF/lib/datanucleus-appengine-1.0.7.final.jar

Надеюсь, это поможет!

Ответ 3

Я видел что-то очень похожее раньше, и это было связано с тем, что persistantManager вызывается разными способами одновременно. Это происходит потому, что pm должен быть единственным экземпляром (который не является singleton, поэтому вам нужно самому управлять им).

Условия могут меняться между средой разработки и производственной средой, которая была развернута, чтобы это могло объяснить и то, что вы видите.

Проблема была решена с помощью synchronized в объявлениях методов, которые используют pm.

Возможно, это не ваше дело, но вы можете сделать снимок.

Ответ 4

У меня была та же проблема, вызванная установкой двух версий.

Сначала я установил Google App Engine Sdk 1.8.8, затем появилось обновление и затмение загрузилось Google App Engine Sdk 1.8.9.

Наличие двух версий вызвало эту ошибку. Несмотря на то, что все скомпилировано хорошо, я не понимал, что журнал консоли datanucleus enhancer предупреждает меня об этой ошибке во время компиляции, просто обнаружил, что консоль существует; -)

Решение, в моем случае, состояло в том, чтобы сохранить только более новую версию, удалив старый:

  • Щелкните правой кнопкой мыши на porject → Свойства
  • Перейдите к Google/App Engine
  • С правой стороны вы увидите ссылку на кнопку с именем Настроить SDK
  • Открывается новое окно с указанием всех установленных версий SDK.
  • Выберите нежелательные версии и нажмите кнопку Удалить

enter image description here

Чтобы полная версия (1.8.8) была полностью удалена:

  • Откройте файл-проводник C:\Users\XXX\.eclipse\org.eclipse.platform_4.3.0_1709980481_win32_win32_x86_64\plugins, где XXX - ваш пользователь Windows.
  • Если папка com.google.appengine.eclipse.sdkbundle_1.8.8 существует, удалите ее!

Теперь, если вы откроете консоль энхансера datanucleus, класс будет успешно расширен.

datanucleus enhancer console log

Ответ 5

Проверьте версию своего компилятора. Он должен быть 1,7 или менее. Это не должно быть 1,8. Я также получил то же самое, и я сменил компилятор, затем он сработал у меня.

Ответ 6

У меня была такая же проблема. В моем случае код был правильно обработан во время сборки через maven clean + install, см. Ниже выдержку из журнала:

ENHANCED (Постоянство): nl.jdoexample.model.Product ENHANCED (Постоянно): nl.jdoexample.model.Book

Пошло не так, что при выполнении (в Intellij) перед исполнением (см. для этой конфигурации Run/Debug) была выполнена команда make, тем самым удалив расширенные java файлы. Это вызвало появление ошибки.

Репарация проблемы в Intellij (но также может быть выполнена в Eclipse или Netbeans): - jdo-example   - Жизненный цикл:       - изменить конфигурацию (Run/Debug Configurations):           - jdo-example [установить]               Командная строка: чистая установка

  • Конфигурации запуска/отладки:  -Заявка:   - Удалить 'make'   - Определение нового исполнения:       - Имя: выполнить главный jdoExample       - Конфигурация:           - Основной класс: nl.jdoexample.main

Таким образом, приложение не будет скомпилировано перед выполнением, тем самым удалив расширенные java файлы. Это было успешным в моей ситуации. Надеюсь, это поможет.

Ответ 7

"Класс" com.wayd.server.beans.WinePost "не является устойчивым. Это означает, что он либо не был расширен, либо улучшенная версия файла не находится в CLASSPATH (или скрыта без помощи версия), или метаданные/аннотации для класса не найдены."

Так почему бы не проверить каждый из этих трех условий? Одно из них верно.