我的网络应用程序使用Resteasy和Infinispan Cache。
我们的设置在Jetty中运行良好,但现在我们需要在JBoss Wildfly 8.1.0中部署。
在Wildfly下,我们在一些请求后出现了间歇性错误:
java.lang.ClassCastException: org.jboss.resteasy.plugins.cache.server.InfinispanCache$CacheEntry cannot be cast to org.jboss.resteasy.plugins.cache.server.InfinispanCache$CacheEntry
at org.jboss.resteasy.plugins.cache.server.InfinispanCache.get(InfinispanCache.java:85)
at org.jboss.resteasy.plugins.cache.server.ServerCacheHitFilter.handleGET(ServerCacheHitFilter.java:53)
at org.jboss.resteasy.plugins.cache.server.ServerCacheHitFilter.filter(ServerCacheHitFilter.java:38)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:256)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:242)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:229)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
请注意,在Widlfly下,我们打包的唯一依赖是 resteasy-cache-core.jar ,其中ServerCacheFeature
属于,所有其他内容都是服务器提供的。在Jetty下我们需要打包一切。
以下是我们在Jetty工作的方式。
一些Rest方法使用注释org.jboss.resteasy.annotations.cache.Cache。 E.g:
@GET
@Path("/actions")
@Cache(maxAge = 3600)
@Produces(value = { APPLICATION_XML, APPLICATION_JSON })
public Action[] getActions() {
...
}
要启用缓存,我在Application对象中添加缓存功能:
@Inject
private CacheContainer cacheContainer;
@Override
public Set<Object> getSingletons() {
Set<Object> objects = getDefaultProviders();
Cache<Object, Object> cache = cacheContainer.getCache("rest");
objects.add(new ServerCacheFeature(new InfinispanCache(cache)));
return objects;
}
最后,我使用CDI注入org.infinispan.manager.CacheContainer
并获取CacheContainer
// There's a cache manager deployed in this JNDI name in standlone.xml/jetty.xml
public static final String CACHE_MANAGER_JNDI_NAME = "java:/application/cachemanager/MyCacheManager";
@Produces
@ApplicationScoped
public CacheContainer createCacheManager() {
return DependencyContext.getFromJndi(CACHE_MANAGER_JNDI_NAME, CacheContainer.class);
}
那么......在JBoss Widlfy下使用infinispan启用和处理Resteasy Cache的正确方法是什么?
更新:实际上我有两场战争,其缓存的部署配置相同。只有缓存管理器JNDI名称不同。
答案 0 :(得分:1)
我发现了问题:
我有两场战争,都有自己的缓存配置。
两场战争都包括resteasy-cache-core.jar。由于两个类加载器都是模块隔离的,我们最终会为每个类加载器提供两个InfinispanCache类定义。
解决方案是将resteasy-cache-core.jar部署为模块,并在战争MANIFEST.MF文件中将其声明为依赖。
创建给定jar的模块:
jboss-cli.sh --connect --command="module add --name=org.jboss.resteasy.cachecore --dependencies=org.infinispan,org.jboss.resteasy,org.jboss.resteasy.resteasy-jaxrs,javax.ws.rs.api --resources=resteasy-cache-core-3.0.8.Final.jar"
**更新:一段时间后,错误再次发生。我们将进一步研究。 Definitelly我们的方法适用于Jetty和Tomcat等容器。 我们将研究正确的Wildfly。
答案 1 :(得分:0)
我将以下内容用于EAP / Wildfly。不是:我还需要web.xml中的Restesy bootstrap条目
public class JaxRsActivator extends Application {
@Resource(lookup ="java:jboss/infinispan/container/web") private EmbeddedCacheManager manager;
@Override public Set<Object> getSingletons() {
Set<Object> objects = new HashSet<>();
Cache<Object, Object> cache = manager.getCache("rest");
objects.add(new ServerCacheFeature(new InfinispanCache(cache)));
return objects;
}
}