一个ClassCastException引发的思考

一个ClassCastException引发的思考,在做一个简单的功能试验时,代码抛出了下面的异常


明明类的完全限定名是一样的,竟然会转换失败。。。

完整的项目代码如下所示

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.SessionManager;

public class SessionTestServlet extends HttpServlet {

    Map<String, HttpSession> allSessions = new HashMap<String, HttpSession>();

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        if (request instanceof org.eclipse.jetty.server.Request) {
            Request req = (Request) request;
            SessionManager sessionManager = req.getSessionManager();
            System.out.println("session manager:" + sessionManager.getClass().getName());
        }

        System.out.println("request class:" + request.getClass().getName());
        System.out.println("response class:" + response.getClass().getName());
        System.out.println("session class:" + session.getClass().getName());

        if (null != session) {
            System.out.println(session.getId());
            if (!allSessions.containsKey(session.getId())) {
                allSessions.put(session.getId(), session);
            } else {
                HttpSession existSession = allSessions.get(session.getId());
                System.out.println(session == existSession);
            }
        }
        session.setAttribute("testSetting", "value");
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            System.out.println(cookie.getName() + ":" + cookie.getValue());
        }
    }
}

项目背景:maven项目,使用eclipse IDE来做的开发,在pom中配置的jetty来作为服务器运行项目
               < plugin >
                       < groupId  > org.mortbay.jetty  </ groupId >
                       < artifactId  > jetty-maven- plugin </  artifactId >
                       < version  > 8.1.4.v20120524  </ version >
                       < configuration  >
                             < webAppConfig  >
                                  < contextPath  > /${project.artifactId}  </ contextPath >
                             </ webAppConfig >
                             < connectors  >
                                  < connector  implementation = "org.eclipse.jetty.server.bio.SocketConnector"  >
                                       < port  > 8097  </ port >
                                       < maxIdleTime  > 60000  </ maxIdleTime >
                                  </ connector >
                             </ connectors >
                            < scanIntervalSeconds  > 10  </ scanIntervalSeconds >
                       </ configuration >
                  </ plugin >

运行方式:直接通过eclipse来运行jetty,启动项目

有请求到达时程序的输出如下
request class:org.eclipse.jetty.server.Request
response class:org.eclipse.jetty.server.Response
session class:org.eclipse.jetty.server.session.HashedSession
16dzhskpd3is2ahcw57bfl2dn

问题:从程序的输出来看,request对象其实是一个 org.eclipse.jetty.server.Request实例,但这里的这个if语句条件 if (request instanceof org.eclipse.jetty.server.Request) ,判断结果为false。这里的原因是什么?


这里涉及到类加载的一些内容,大致可以解释为,我们使用 org.eclipse.jetty.server.Request类时,项目加载这个类使用的ClassLoader和加载request、response所属的类对象的ClassLoader不是同一个。不同的ClassLoader加载的类之间,是不能进行转换的。所以这里的if语句条件判断为false。
下面是修改了输出代码,以及某次运行过程中的输出结果
       System.  out .println( "org.eclipse.jetty.server.Request,loaded by "
                + org.eclipse.jetty.server.Request.  class .getClassLoader());
        System.  out .println( "request class:"  + request.getClass().getName () +  ",loaded by "
                + request.getClass().getClassLoader());
        System.  out .println( "response class:"  + response.getClass().getName () +  ",loaded by "
                + response.getClass().getClassLoader());
        System.  out .println( "session class:"  + session.getClass().getName () +  ",loaded by "
                + session.getClass().getClassLoader());


org.eclipse.jetty.server.Request,loaded by WebAppClassLoader=32261531@1ec459b
request class:org.eclipse.jetty.server.Request,loaded by org.codehaus.classworlds.RealmClassLoader@15253d5
response class:org.eclipse.jetty.server.Response,loaded by org.codehaus.classworlds.RealmClassLoader@15253d5
session class:org.eclipse.jetty.server.session.HashedSession,loaded by org.codehaus.classworlds.RealmClassLoader@15253d5
pxdj253ehd4l10i83lcd7cfi8
JSESSIONID:8c8nfkgiflfsrnv51wehpd6i


参考资料
http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值