Приведение ObjectifyImpl к Ofy компилируется, но завершается неудачно во время выполнения в Eclipse / Java8 - PullRequest
0 голосов
/ 05 января 2019

Приведение в названии отлично работает в Objectify 5.0.3 (компилируется, запускается локально в Eclipse и запускается в GAE). При попытке обновить до Objectify 5.2.22 (наряду с другими обновлениями, подробности ниже), компилятор не возражает против приведения, но во время выполнения в Eclipse я получаю это сообщение во всплывающем окне:

com.googlecode.objectify.impl.ObjectifyImpl cannot be 
cast to com.strongbrain.db.Ofy

Код, связанный с Ofy / ObjectifyService / OfyFactory, не изменился с 5.0.3. (Ниже)

Подробнее: Я пытаюсь обновить бесплатный сайт (http://strong -brain.com / ), который уже пару лет работает без внимания на Google App Engine. Основные компоненты, оригинальные версии и новые целевые версии:

             Original     Target
appengine-api    1.9.25       1.0-sdk-1.9.71
GAE sdkbundle    1.9.25       Cloud SDK version 228.0.0
Eclipse          Luna         Neon.3 Release (4.6.3)
Java             1.7          1.8
Objectify        5.0.3        5.1.22
DWR              2.0.10       2.0.10

Пока что я только пытаюсь работать локально в Eclipse. Когда я запускаю сервер localhost, главная страница index.jsp отображается нормально, как и другие страницы, статически связанные с index.jsp. Однако нажатие любой кнопки, вызывающей обработку сервера (например, «Пуск» на странице задач), приводит к появлению всплывающего сообщения с приведенным выше сообщением. Поиск кода утверждает, что единственное приведение к (Ofy) находится в файле com.strongbrain.db.OfyService.java, показанном ниже.

Соответствующий файл com.strongbrain.db.Ofy.java и часть web.xml, относящаяся к Objectify, также представлены ниже.

Файл com.strongbrain.db.OfyService.java

package com.strongbrain.db;
import com.googlecode.objectify.ObjectifyService;

/**
 * Custom version of ObjectifyService which uses the custom Ofy and OfyFactory.
 * Sets up OfyFactory instead of the standard ObjectifyFactory.
 * Derived from Motomapia app.
 */
public class OfyService
{
    static {
        ObjectifyService.setFactory(new OfyFactory());
    }

    /**
     * @return Ofy extension to Objectify
     */
    public static Ofy ofy() {
        return (Ofy)ObjectifyService.ofy();
    }

    /**
     * @return OfyFactory extension to ObjectifyFactory
     */
    public static OfyFactory factory() {
        return (OfyFactory)ObjectifyService.factory();
    }
}

Файл com.strongbrain.db.Ofy.java

package com.strongbrain.db;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.impl.ObjectifyImpl;

/**
 * Basic data access interface wrapper. Extends the basic Objectify interface to add convenience methods.
 * Derived from Motomapia app.
 *  @see <a href="https://github.com/stickfigure/motomapia/blob/master/java/com/motomapia/Ofy.java">Motomapia Ofy.java</a> 
 */
public class Ofy extends ObjectifyImpl<Ofy>
{

    public Ofy(OfyFactory base) {
        super(base);
    }

     /** More wrappers, fun */
    @Override
    public OfyLoader load() {
            return new OfyLoader(this);
    }   

    /* Convenience methods using the OBT DBMgr naming scheme, but made generic. */

    public <T> Key<T> insertEntity(T e) {
        return updateEntity(e);
    }
    public <T> Key<T> updateEntity(T e)
    {
        return save().entity(e).now();
    }
    public @NonNull <T> T retrieveEntityByKey(Key<T> k)
    {
        @SuppressWarnings("null")
        @NonNull T e = load().key(k).safe();
        return e;
    }
    public @Nullable <T> T findEntityByKey(Key<T> k)
    {
        return load().key(k).now();
    }
    public <T> void deleteEntityByKey(Key<T> k)
    {
        delete().key(k).now();
    }
    public <T> void deleteEntity(T e)
    {
        delete().entity(e).now();
    }
    public <T> void deleteEntities(Iterable<?> entities)
    {
        delete().entity(entities).now();
    }
    public void deleteEntityKeys(Iterable<? extends Key<?>> keys)
    {
        delete().keys(keys).now();
    }
    public <T> Map<Key<T>, T> batchRetrieve(List<Key<T>> keys)
    {
        return load().keys(keys);
    }
}

фрагмент web.xml:

        <filter>
        <filter-name>ObjectifyFilter</filter-name>
        <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
        </filter>
        <filter-mapping>
        <filter-name>ObjectifyFilter</filter-name>
        <url-pattern>/*</url-pattern>
        </filter-mapping>

Ожидается: доступ к данным через Objectify
Факт: всплывающее окно, описанное выше.

1 Ответ

0 голосов
/ 14 января 2019

Я подозреваю, что вам нужно заменить набор com.googlecode.objectify.ObjectifyFilter: этот фильтр вызывает вызов ObjectifyService.begin() в начале запроса, который в свою очередь использует фабрику ObjectifyService для создания экземпляра Objectify. Это происходит до того, как статический инициализатор OfyService сможет установить фабрику ObjectifyService.

Я думаю, вам нужно предоставить свой собственный фильтр, который сначала устанавливает фабрику:

public class ObjectifyWebFilter extends ObjectifyFilter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain)
      throws IOException, ServletException {
    ObjectifyService.setFactory(new OfyFactory());

    super.doFilter(request, response, chain);
  }
}
...