NoClassDefFoundError和Netty

时间:2011-01-01 11:21:17

标签: java memcached

首先说我是Java中的n00b。我能理解大多数概念,但在我的情况下,我希望有人帮助我。我正在使用JBoss Netty处理简单的http请求,并使用MemCachedClient检查memcached中是否存在客户端ip。

import org.jboss.netty.channel.ChannelHandler;
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
import static org.jboss.netty.handler.codec.http.HttpVersion.*;
import com.danga.MemCached.*;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.Cookie;
import org.jboss.netty.handler.codec.http.CookieDecoder;
import org.jboss.netty.handler.codec.http.CookieEncoder;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpChunk;
import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.jboss.netty.util.CharsetUtil;

/**
* @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
* @author Andy Taylor (andy.taylor@jboss.org)
* @author <a href="http://gleamynode.net/">Trustin Lee</a>
*
* @version $Rev: 2368 $, $Date: 2010-10-18 17:19:03 +0900 (Mon, 18 Oct 2010) $
*/
@SuppressWarnings({"ALL"})
public class HttpRequestHandler extends SimpleChannelUpstreamHandler {

    private HttpRequest request;
    private boolean readingChunks;
    /** Buffer that stores the response content */
    private final StringBuilder buf = new StringBuilder();
    protected MemCachedClient mcc = new MemCachedClient();
    private static SockIOPool poolInstance = null;

    static {

// server list and weights
        String[] servers =
                {
                        "lcalhost:11211"
                };

//Integer[] weights = { 3, 3, 2 };
        Integer[] weights = {1};

// grab an instance of our connection pool
        SockIOPool pool = SockIOPool.getInstance();

// set the servers and the weights
        pool.setServers(servers);
        pool.setWeights(weights);

// set some basic pool settings
// 5 initial, 5 min, and 250 max conns
// and set the max idle time for a conn
// to 6 hours
        pool.setInitConn(5);
        pool.setMinConn(5);
        pool.setMaxConn(250);
        pool.setMaxIdle(21600000); //1000 * 60 * 60 * 6

// set the sleep for the maint thread
// it will wake up every x seconds and
// maintain the pool size
        pool.setMaintSleep(30);

// set some TCP settings
// disable nagle
// set the read timeout to 3 secs
// and don't set a connect timeout
        pool.setNagle(false);
        pool.setSocketTO(3000);
        pool.setSocketConnectTO(0);

// initialize the connection pool
        pool.initialize();


// lets set some compression on for the client
// compress anything larger than 64k
        //mcc.setCompressEnable(true);
        //mcc.setCompressThreshold(64 * 1024);
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        HttpRequest request = this.request = (HttpRequest) e.getMessage();
        if(mcc.get(request.getHeader("X-Real-Ip")) != null)
        {
            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
            response.setHeader("X-Accel-Redirect", request.getUri());
            ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
        }
        else {
            sendError(ctx, NOT_FOUND);
        }

    }

    private void writeResponse(MessageEvent e) {
        // Decide whether to close the connection or not.
        boolean keepAlive = isKeepAlive(request);

        // Build the response object.
        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        response.setContent(ChannelBuffers.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
        response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");

        if (keepAlive) {
            // Add 'Content-Length' header only for a keep-alive connection.
            response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
        }

        // Encode the cookie.
        String cookieString = request.getHeader(COOKIE);
        if (cookieString != null) {
            CookieDecoder cookieDecoder = new CookieDecoder();
            Set<Cookie> cookies = cookieDecoder.decode(cookieString);
            if(!cookies.isEmpty()) {
                // Reset the cookies if necessary.
                CookieEncoder cookieEncoder = new CookieEncoder(true);
                for (Cookie cookie : cookies) {
                    cookieEncoder.addCookie(cookie);
                }
                response.addHeader(SET_COOKIE, cookieEncoder.encode());
            }
        }

        // Write the response.
        ChannelFuture future = e.getChannel().write(response);

        // Close the non-keep-alive connection after the write operation is done.
        if (!keepAlive) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
            throws Exception {
        e.getCause().printStackTrace();
        e.getChannel().close();
    }


    private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
         HttpResponse response = new DefaultHttpResponse(HTTP_1_1, status);
         response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
         response.setContent(ChannelBuffers.copiedBuffer(
                 "Failure: " + status.toString() + "\r\n",
                 CharsetUtil.UTF_8));

         // Close the connection as soon as the error message is sent.
         ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
    }

}

当我尝试发送http://127.0.0.1:8090/1/2/3之类的请求时 我正在

java.lang.NoClassDefFoundError: com/danga/MemCached/MemCachedClient
        at httpClientValidator.server.HttpRequestHandler.<clinit>(HttpRequestHandler.java:66)

我认为它与classpath无关。可能与mcc不存在的上下文有关。 任何帮助表示赞赏

编辑: 原始代码http://docs.jboss.org/netty/3.2/xref/org/jboss/netty/example/http/snoop/package-summary.html 我修改了一些零件以满足我的需求。

1 个答案:

答案 0 :(得分:1)

为什么你认为这不是类路径相关的?当你需要的jar不可用时,你会遇到这种错误。你如何开始你的应用程序?

修改

抱歉 - 我在eclipse中加载并尝试了java_memcached-release_2.5.2包,到目前为止没有发现任何问题。调试类加载显示没有异常。除了更多提示再仔细检查之外,我无法帮助:

  • 确保您的下载正确无误。再次下载并解压缩。 (com.schooner。*类可用吗?)
  • 确保使用&gt; java 1.5
  • 确保您的类路径正确且完整。您显示的示例不包括netty。在哪里。
  • 我不熟悉通过向清单添加类路径而产生的交互。也许还原为简单样式,将所有需要的jar(memcached,netty,yours)添加到类路径并引用主类来启动,而不是一个可启动的jar文件