将ObjectifyImpl转换为Ofy可以编译,但是在Eclipse / Java8中运行时失败

时间:2019-01-05 19:56:52

标签: java eclipse google-app-engine objectify

标题中的强制转换在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中本地运行。当我启动本地主机服务器时,主index.jsp页显示良好,其他从index.jsp静态链接的页也是如此。但是,按任何调用服务器处理的按钮(例如任务页面上的“开始”),就会弹出带有上述消息的弹出窗口。搜索代码声称唯一转换为(Ofy)的文件是com.strongbrain.db.OfyService.java,如下所示。

相关文件com.strongbrain.db.Ofy.java以及与Objectify相关的web.xml部分也在下面提供。

文件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 :(得分:0)

我怀疑您需要替换库存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);
  }
}