Reputation: 510
My web application uses Resteasy and Infinispan Cache.
Our setup works fine in Jetty but now we need to deploy in JBoss Wildfly 8.1.0.
Under Wildfly we have an intermitent error after some requests:
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)
Note that under Widlfly the only dependency we pack inside war is resteasy-cache-core.jar , where ServerCacheFeature
belongs, all other stuff are server provided. Under Jetty we need to pack everything.
Below is what we do to work in Jetty.
Some Rest methods uses annotation org.jboss.resteasy.annotations.cache.Cache. E.g:
@GET
@Path("/actions")
@Cache(maxAge = 3600)
@Produces(value = { APPLICATION_XML, APPLICATION_JSON })
public Action[] getActions() {
...
}
To enable cache I add Cache Feature at Application object:
@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;
}
Finally I inject org.infinispan.manager.CacheContainer
using CDI and get 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);
}
So... what's the correct way to enable and handle Resteasy Cache using infinispan under JBoss Widlfy?
update: In fact I have two wars with the same deployment configuration regarding cache. Only The Cache Manager JNDI names are different.
Upvotes: 1
Views: 1866
Reputation: 572
I used the following for EAP / Wildfly. Not: I also needed the Restesy bootstrap entry in web.xml
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;
}
}
Upvotes: 1
Reputation: 510
I found the problem:
I have two wars, both with their own Cache Configurations.
Both wars package resteasy-cache-core.jar. Since both classloaders are module isolated we end up with two InfinispanCache class definition, onde for each classloader.
The solution is to deploy resteasy-cache-core.jar as a module and declare it as dependency in wars MANIFEST.MF files.
To create the module given the 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"
** Update: After some time the error happens again. We are going to look further. Definitelly our approach is suitable for containers like Jetty and Tomcat. We are going to research the correct for Wildfly.
Upvotes: 1