Question

So I think I'm a little confused on how memcached works. I'm in the process of developing the same API using different frameworks all of which incorporate memcached (the java version spymemcached). When I set up memcached on my first framework it worked as expected. Now that I'm trying to incorporate it on the second framework I'm using I keep getting a ClassNotFoundException where it tries to find a class in the first framework I used and thus doesn't cache anything. Maybe someone can enlighten me to the flaw in my logic. Here are the two classes (they're identical since I'm building the same API in different platforms), the core.Party class is in the first one (that works when running the respective application) the pojo.PojoParty is the one and the second framework I'm using that doesn't seem to be connecting to the memcached.

Here's the constructor of the class where it occurs:

    package resources;

import health.TemplateHealthCheck;

import java.net.InetSocketAddress;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.ResultSetMetaData;
import java.util.HashMap; 

import com.codahale.metrics.Gauge;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Counter;
import com.codahale.metrics.RatioGauge;

import contextListener.MyAdminServletContextListener;

import pojo.PartyPojo;

import net.spy.memcached.MemcachedClient;

    public class DBConnection {

        public static Connection con;
        private static ResultSet resultSet;
        private static PreparedStatement ps;
        private static ResultSetMetaData meta;
        private static HashMap<String,PartyPojo> map;
        private static DBConnection connection;
        private static PartyPojo party;
        private static final InetSocketAddress isa= new InetSocketAddress("atom1.cisco.com",11211);
        private static MemcachedClient memcache;
        private static Meter hits = MyAdminServletContextListener.registry.meter(MetricRegistry.name("Meter",
                "get-hits")); 
        private static Meter calls = MyAdminServletContextListener.registry.meter(MetricRegistry.name("Meter",
                "get-calls"));
        private static Counter evictions = MyAdminServletContextListener.registry.counter(MetricRegistry.name("Counter",
                "Memcache-Evictions"));
        private static int getHits,getCalls;
        private final static int MAX_MEMCACHED_EXPIRATION=2505600;

        private DBConnection()
        {
            try 
            {
                map = new HashMap<String,PartyPojo>();
                Class.forName("com.mysql.jdbc.Driver");
                con = DriverManager.getConnection(
                        "jdbc:mysql://atom3.cisco.com:3306/reddb", "redteam",
                        "redteam");     
                //initialize memcache
                memcache   = new MemcachedClient(isa); //this line produces error
                //this is just a integer variable I was using to make sure my Meters were measuring correctly
                getHits = Integer.valueOf(DBConnection.memcache.getStats().get(DBConnection.isa).
                        get("get_hits"));
                getCalls = Integer.valueOf(DBConnection.memcache.getStats().get(DBConnection.isa).
                        get("cmd_get"));
                metricsRegistry();      
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

Here's the class it's trying to reach that's not part of the second framework (this is the pojo class from the first framework):

    package core;

import java.io.Serializable;
import java.util.HashMap;

public class Party implements Serializable {


    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    HashMap <String,String> partyInfo = new HashMap<String,String>();

    public HashMap<String,String> getPartyInfo() throws Exception
    {
        return partyInfo;
    }
 }

Here's the identical class but in the project I'm trying to run

    package pojo;

import java.io.Serializable;
import java.util.HashMap;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.eclipse.persistence.oxm.annotations.XmlPath;


@XmlRootElement(name="Party") 
@XmlAccessorType(XmlAccessType.FIELD)
public class PartyPojo implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -4892745279086305480L;
    /**
     * 
     */
    /**
     * 
     */
    @XmlPath(".")
    @XmlJavaTypeAdapter(MapAdapter.class)

    HashMap <String,String> partyInfo = new HashMap<String,String>();

    public HashMap<String,String> getPartyInfo() throws Exception
    {
        return partyInfo;
    }
 }

Here's the stacktrace:

 2013-08-05 15:54:39.810 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=atom1.cisco.com/173.36.62.251:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2013-08-05 15:54:39.847 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@529762a
2013-08-05 15:54:40.120 WARN net.spy.memcached.transcoders.SerializingTranscoder:  Caught CNFE decoding 434 bytes of data
java.lang.ClassNotFoundException: core.Party
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at java.io.ObjectInputStream.resolveClass(Unknown Source)
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
    at java.io.ObjectInputStream.readClassDesc(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at net.spy.memcached.transcoders.BaseSerializingTranscoder.deserialize(BaseSerializingTranscoder.java:129)
    at net.spy.memcached.transcoders.SerializingTranscoder.decode(SerializingTranscoder.java:88)
    at net.spy.memcached.transcoders.TranscodeService$1.call(TranscodeService.java:63)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at net.spy.memcached.transcoders.TranscodeService$Task.run(TranscodeService.java:110)
    at net.spy.memcached.transcoders.TranscodeService$Task.get(TranscodeService.java:96)
    at net.spy.memcached.internal.GetFuture.get(GetFuture.java:63)
    at net.spy.memcached.MemcachedClient.get(MemcachedClient.java:997)
    at net.spy.memcached.MemcachedClient.get(MemcachedClient.java:1018)
    at resources.DBConnection.readOneParty(DBConnection.java:114)
    at resources.OnePartyResource.getParty(OnePartyResource.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:134)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:505)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:211)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1094)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:432)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1028)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
    at org.eclipse.jetty.server.Server.handle(Server.java:445)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:267)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:224)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532)
    at java.lang.Thread.run(Unknown Source)
Was it helpful?

Solution

I figured it out and the answer is quite embarrassing. So because I was rushing to complete the code on different frameworks I essentially copy and pasted the code from one to the other. Essentially what was happening was it was storing the values from the first API fine; however, when I tried to query those same values using the other API it was attempting to store those values in memcache at the same key location. Thus why it couldn't find the object, it was in the wrong project! So I basically appended the string key for one program so that it would return correctly.

Obviously an embarrassing error to make but I'll chalk it up to being my first time using any sort of caching system across multiple programs.

OTHER TIPS

When memcached (or any serializer) tries to reconstitute your object from serialized form, it has to have access to the appropriate class. You don't have core.Party available on the deserializing side, and so memcached has no Java representation for the incoming data stream.

When you talk about "different platforms", you appear to be misunderstanding how Java libraries work. Since you're using Java on both sides, you shouldn't have two "copies" of the class, you should just have the one single class available on both. If there is some shared code (such as Party) but some other code that shouldn't be shared between the two distributions, put Party in a library jar included by both projects. Maven and other build-management systems make this easy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top