??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品成人无限看,亚洲人精品亚洲人成在线,久久亚洲AV无码精品色午夜麻http://m.tkk7.com/boluobn/大江东去,淘?..zh-cnThu, 15 May 2025 12:36:22 GMTThu, 15 May 2025 12:36:22 GMT60用instsrv与srvany在windows 建立服务http://m.tkk7.com/boluobn/archive/2009/04/19/266420.html菠萝菠萝Sun, 19 Apr 2009 06:44:00 GMThttp://m.tkk7.com/boluobn/archive/2009/04/19/266420.htmlhttp://m.tkk7.com/boluobn/comments/266420.htmlhttp://m.tkk7.com/boluobn/archive/2009/04/19/266420.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/266420.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/266420.html用instsrv与srvany在windows 建立服务

instsrv.exe  srvany.exe

q两个文件是MS扚w生的,|上应该能烂下蝲?/p>

首先这两个文g攑ֈ自定的\径中。例如放在C:\根目录下

在CMD对话框中输入 c:\instsrv.exe  servername c:\ srvany.exe 回R

其中servername是你所需要的服务名?/p>

之后你需要进入注册表q行相应的设|,在注册表的:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\servername

中简历Parameters子项Q然后在其中建立一个字W串ApplicationQ双击该字符Ԍ输入如下格式的语句:

C:\ABC\DEF\XXX.exe +Xms256M +Xmx256M -nodbcheck -minspan60 -retry1000

其中?56M与服务占用内存大有养Iq就要看机器的配|了?/p>

修改l束后推出,使用命oservices.mscq入服务界面Q找C刚刚定制的服务,双击q入Q之后选择“登陆”Q再选中“本地登陆”q确定。之后手动启动服务即可?br />
C:\service\instsrv.exe adslSrv "C:\service\srvany.exe"



菠萝 2009-04-19 14:44 发表评论
]]>
|上在线字典词典大全http://m.tkk7.com/boluobn/archive/2008/04/07/191226.html菠萝菠萝Mon, 07 Apr 2008 04:26:00 GMThttp://m.tkk7.com/boluobn/archive/2008/04/07/191226.htmlhttp://m.tkk7.com/boluobn/comments/191226.htmlhttp://m.tkk7.com/boluobn/archive/2008/04/07/191226.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/191226.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/191226.html译cd典词?

菠萝 2008-04-07 12:26 发表评论
]]>
XP/2003讉KXP的用户验证问? http://m.tkk7.com/boluobn/archive/2008/03/07/184590.html菠萝菠萝Fri, 07 Mar 2008 12:43:00 GMThttp://m.tkk7.com/boluobn/archive/2008/03/07/184590.htmlhttp://m.tkk7.com/boluobn/comments/184590.htmlhttp://m.tkk7.com/boluobn/archive/2008/03/07/184590.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/184590.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/184590.html   首先关于启用GuestZ么不能访问的问题Q? 
   
  1、默认情况下QXP   用Guest帐户  
  2、默认情况下QXP的本地安全策略禁止Guest用户从网l访? 
  3、默认情况下QXP?  本地安全{略   ->   安全选项   里,"帐户Q用空密码用户只能q行控制台登?是启用的Q也是_I密码的M帐户都不能从|络讉K只能本地登陆QGuest默认I密?.....  
   
  所以,如果需要用Guest用户讉KXP的话Q要q行上面的三个设|:启用Guest、修改安全策略允许Guest从网l访问、禁?里面的安全策略或者给Guest加个密码? 
   
  有时q会遇到另外一U情况:讉KXP的时候,d对话框中的用户名是灰?始终是Guest用户Q不能输入别的用户帐受? 
   
  原因是这个安全策略在作怪。默认情况下QXP的访问方式是"仅来?的方式,那么你访问它Q当然就固定为Guest不能输入其他用户帐号了? 
   
  所以,讉KXP最单的Ҏ(gu)是Q不用启用GuestQ仅修改上面的安全策略ؓ"l典"p了。别的系l访问XP可以自p入帐户信息? 
   
  至于讉K2003Q默认情况下2003用GuestQ但是没?  XP   那个讨厌的默认自相矛盄来宾方式׃nQ所以可以直接输入用户名密码讉K?

菠萝 2008-03-07 20:43 发表评论
]]>
RSS的格式及解释(?http://m.tkk7.com/boluobn/archive/2008/01/30/178454.html菠萝菠萝Wed, 30 Jan 2008 01:27:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/30/178454.htmlhttp://m.tkk7.com/boluobn/comments/178454.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/30/178454.html#Feedback1http://m.tkk7.com/boluobn/comments/commentRss/178454.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/178454.html阅读全文

菠萝 2008-01-30 09:27 发表评论
]]>
AJAXdrss的代??http://m.tkk7.com/boluobn/archive/2008/01/29/178418.html菠萝菠萝Tue, 29 Jan 2008 14:49:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/29/178418.htmlhttp://m.tkk7.com/boluobn/comments/178418.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/29/178418.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/178418.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/178418.html 
2007-02-02 15:48

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  " <html xmlns=" <head>
<title>this is test</title>

<script type="text/javascript">
var xmlHttp;

function createXMLHttpRequest() {
    if (window.ActiveXObject) {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } 
    else if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest();
    }
}

function readRSS(url) {
    createXMLHttpRequest();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("GET", url, true);
    xmlHttp.send(null);
  
  
}
    
function handleStateChange() {
    if(xmlHttp.readyState == 4) {
        if(xmlHttp.status == 200) {
            ResultSet();
        }
    }
}

function ResultSet() {
    var results = xmlHttp.responseXML;
    var title = null;
    var item = null;
    var link=null;
    //得到channel
    var ccc=results.getElementsByTagName("channel");
     var headtitle=ccc[0].getElementsByTagName("title")[0].firstChild.nodeValue;
     var headlink=ccc[0].getElementsByTagName("link")[0].firstChild.nodeValue;
     var cell = document.createElement("div");
        cell.innerHTML="<h1><a href="+headlink+" target=_blank>"+headtitle+"</a></h1><br>";
        document.getElementById("result").appendChild(cell);
       //得到items
    var items = results.getElementsByTagName("item");
    for(var i = 0; i < items.length; i++) {
        item = items[i];
        link=item.getElementsByTagName("link")[0].firstChild.nodeValue;
        title = item.getElementsByTagName("title")[0].firstChild.nodeValue;
        var cell = document.createElement("div");
        cell.innerHTML="<a href="+link+" target=_blank>"+title+"</a><br>";
       document.getElementById("result").appendChild(cell);
    }

}
function readrss1()
{
    var url=document.getElementById("txturl").value;
    if(url=="")
    {
        alert("误入RSS地址");
        }
    else
        {
            readRSS(url);
            }
    }

</script>
</head>

<body">
  <h1>ajax读rssCZ</h1>
  <form >
      
  <a href="javascript:readRSS('http://m.tkk7.com/rss.aspx')">blogjava原创?nbsp;</a>&nbsp     
   <a href="javascript:readRSS('http://beginner.blogjava.net/rss.aspx')">blogjava新手?nbsp;</a> &nbsp 
    <a href="javascript:readRSS('http://life.blogjava.net/rss.aspx')">blogjava非技术区 </a> &nbsp 
     <a href="javascript:readRSS('http://general.blogjava.net/rss.aspx')">l合?nbsp;</a>
     <br>
     输入一个RSS地址:<input type="text" value="
http://m.tkk7.com/wujun/rss.aspx" size=50 id="txturl">
     <input type="button" value="?nbsp;? onclick="readrss1()">
     
  </form>
    <div id="result"></div>
</body>
</html>



菠萝 2008-01-29 22:49 发表评论
]]>
Session机制http://m.tkk7.com/boluobn/archive/2008/01/26/177873.html菠萝菠萝Sat, 26 Jan 2008 01:53:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/26/177873.htmlhttp://m.tkk7.com/boluobn/comments/177873.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/26/177873.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/177873.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/177873.html

摘要:

虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/div>
 
一、术语session
在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?br />
sessionQ中文经常翻译ؓ会话Q其本来的含义是指有始有l的一pd动作/消息Q比如打?sh)话时从拿v?sh)话拨号到挂断?sh)话这中间的一pdq程可以UCZ?session。有时候我们可以看到这L?#8220;在一个浏览器会话期间Q?..”Q这里的会话一词用的就是其本义Q是指从一个浏览器H口打开到关闭这个期?①。最混ؕ的是“用户Q客LQ在一ơ会话期?#8221;q样一句话Q它可能指用L一pd动作Q一般情况下是同某个具体目的相关的一pd动作Q比如从d到选购商品到结账登样一个网上购物的q程Q有时候也被称Z个transactionQ,然而有时候也可能仅仅是指一ơ连接,也有可能是指含义①,其中的差别只能靠上下文来推断②?br />
然而当session一词与|络协议相关联时Q它又往往隐含?#8220;面向q接”??#8220;保持状?#8221;q样两个含义Q?“面向q接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电(sh)话,直到Ҏ(gu)接了?sh)话通信才能开始,与此相对的是写信Q在你把信发出去的时候你q不能确认对方的地址是否正确Q通信渠道不一定能建立Q但对发信h来说Q通信已经开始了?#8220;保持状?#8221;则是指通信的一方能够把一pd的消息关联v来,使得消息之间可以互相依赖Q比如一个服务员能够认出再次光的老顾客ƈ且记得上ơ这个顾客还Ơ店里一块钱。这一cȝ例子?#8220;一个TCP session”或?“一个POP3 session”③?br />
而到了web服务器蓬勃发展的时代Qsession在web开发语境下的语义又有了新的扩展Q它的含义是指一cȝ来在客户端与服务器之间保持状态的解决Ҏ(gu)④。有时候session也用来指q种解决Ҏ(gu)的存储结构,?#8220;把xxx保存在session ?#8221;⑤。由于各U用于web开发的语言在一定程度上都提供了对这U解x案的支持Q所以在某种特定语言的语境下Qsession也被用来指代该语a的解x案,比如l常把Java里提供的javax.servlet.http.HttpSessionUCؓsession⑥?br />
鉴于q种混ؕ已不可改变,本文中session一词的q用也会Ҏ(gu)上下文有不同的含义,请大家注意分辨?br /> 在本文中Q用中?#8220;览器会话期?#8221;来表辑֐义①Q?#8220;session机制”来表辑֐义④Q?#8220;session”表达含义⑤,使用具体?#8220;HttpSession”来表辑֐义⑥

二、HTTP协议与状态保?/strong>
HTTP 协议本n是无状态的Q这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器h下蝲某些文gQ无论是客户端还是服务器都没有必要纪录彼此过ȝ行ؓQ每一ơ请求之间都是独立的Q好比一个顾客和一个自动售货机或者一个普通的Q非会员Ӟ大卖Z间的关系一栗?br />
然而聪明(或者贪心?Q的Z很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用Q就像给有线?sh)视加上?gu)功能一栗这U需求一斚wqHTML逐步d了表单、脚本、DOM{客L行ؓQ另一斚w在服务器端则出现了CGI规范以响应客L的动态请求,作ؓ传输载体的HTTP协议也添加了文g上蝲?cookieq些Ҏ(gu)。其中cookie的作用就是ؓ了解决HTTP协议无状态的~陷所作出的努力。至于后来出现的session机制则是又一U在客户端与服务器之间保持状态的解决Ҏ(gu)?br />
让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ(gu)量。想象一下其实也无外乎下面的几种Ҏ(gu)Q?br /> 1、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待了。这U做法就是协议本w支持状态?br /> 2、发l顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每ơ消Ҏ(gu)Q如果顾客出C张卡片,则此ơ消费就会与以前或以后的消费相联pv来。这U做法就是在客户端保持状态?br /> 3、发l顾客一张会员卡Q除了卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的U录d一些消费信息。这U做法就是在服务器端保持状态?br />
׃HTTP协议是无状态的Q而出于种U考虑也不希望使之成ؓ有状态的Q因此,后面两种Ҏ(gu)成为现实的选择。具体来说cookie机制采用的是在客L保持状态的Ҏ(gu)Q而session机制采用的是在服务器端保持状态的Ҏ(gu)。同时我们也看到Q由于采用服务器端保持状态的Ҏ(gu)在客L也需要保存一个标识,所以session机制可能需要借助于cookie机制来达C存标识的目的Q但实际上它q有其他选择?br />
三、理解cookie机制
cookie机制的基本原理就如上面的例子一L单,但是q有几个问题需要解冻I“会员?#8221;如何分发Q?#8220;会员?#8221;的内容;以及客户如何使用“会员?#8221;?br />
正统的cookie分发是通过扩展HTTP协议来实现的Q服务器通过在HTTP的响应头中加上一行特D的指示以提C浏览器按照指示生成相应的cookie。然而纯_的客户端脚本如JavaScript或者VBScript也可以生成cookie?br />
而cookie 的用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器查所有存储的cookieQ如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置Q则把该cookie附在h资源的HTTPh头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示Q如果某家分店还发行了自q会员卡,那么q这家店的时候除了要出示麦当劳的会员卡,q要出示q家店的会员卡?br />
cookie的内容主要包括:名字Q|q期旉Q\径和域?br /> 其中域可以指定某一个域比如.google.comQ相当于d招牌Q比如宝z公司,也可以指定一个域下的具体某台机器比如www.google.com或者f(xi)roogle.google.comQ可以用飘柔来做比?br /> 路径是跟在域名后面的URL路径Q比?或?foo{等Q可以用某飘柔专柜做比?br /> 路径与域合在一起就构成了cookie的作用范围?br /> 如果不设|过期时_则表C个cookie的生命期为浏览器会话期间Q只要关闭浏览器H口Qcookie消׃。这U生命期为浏览器会话期的 cookie被称Z话cookie。会话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了q期旉Q浏览器׃把cookie保存到硬盘上Q关闭后再次打开览器,q些cookie仍然有效直到过讑֮的过期时间?br />
存储在硬盘上的cookie 可以在不同的览器进E间׃nQ比如两个IEH口。而对于保存在内存里的cookieQ不同的览器有不同的处理方式。对于IEQ在一个打开的窗口上?Ctrl-NQ或者从文g菜单Q打开的窗口可以与原窗口共享,而用其他方式新开的IEq程则不能共享已l打开的窗口的内存cookieQ对?Mozilla Firefox0.8Q所有的q程和标{N都可以共享同Lcookie。一般来说是用javascript的window.open打开的窗口会与原H口׃n内存cookie。浏览器对于会话cookie的这U只认cookie不认人的处理方式l常l采用session机制的web应用E序开发者造成很大的困扰?br />
下面是一个goolge讄cookie的响应头的例?br />
HTTP/1.1 302 Found
Location: http://www.google.com/intl/zh-CN/
Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html


image
q是使用HTTPLookq个HTTP Sniffer软g来俘LHTTP通讯U录的一部分

image
览器在再次讉Kgoolge的资源时自动向外发送cookie

image
用Firefox可以很容易的观察现有的cookie的?br /> 使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理?br />
image
IE也可以设|在接受cookie前询?br />
四、理解session机制

session机制是一U服务器端的机制Q服务器使用一U类g散列表的l构Q也可能是使用散列表)来保存信息?br />
当程序需要ؓ某个客户端的h创徏一个session的时候,服务器首先检查这个客L的请求里是否已包含了一个session标识 - UCؓ session idQ如果已包含一个session id则说明以前已lؓ此客L创徏qsessionQ服务器按照session id把这?session索出来用(如果索不刎ͼ可能会新Z个)Q如果客Lh不包含session idQ则为此客户端创Z个sessionq且生成一个与此session相关联的session idQsession id的值应该是一个既不会重复Q又不容易被扑ֈ规律以仿造的字符Ԍq个 session id被在本ơ响应中q回l客L保存?br />
保存q个session id的方式可以采用cookieQ这样在交互q程中浏览器可以自动的按照规则把q个标识发挥l服务器。一般这个cookie的名字都是类gSEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764Q它的名字就?JSESSIONID?br />
׃cookie可以被h为的止Q必L其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一U技术叫做URL重写Q就是把session id直接附加在URL路径的后面,附加方式也有两种Q一U是作ؓURL路径的附加信息,表现形式为http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一U是作ؓ查询字符串附加在URL后面Q表现Ş式ؓhttp://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
q两U方式对于用h说是没有区别的,只是服务器在解析的时候处理的方式不同Q采用第一U方式也有利于把session id的信息和正常E序参数区分开来?br /> Z在整个交互过E中始终保持状态,必d每个客户端可能请求的路径后面都包含这个session id?br />
另一U技术叫做表单隐藏字Dc就是服务器会自动修改表单,d一个隐藏字D,以便在表单提交时能够把session id传递回服务器。比如下面的表单
<form name="testform" action="/xxx">
<input type="text">
</form>


在被传递给客户端之前将被改写成
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>


q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6(SunONE应用服务器的前n)׃用了q种技术?br /> 实际上这U技术可以简单的用对action应用URL重写来代ѝ?br />
在谈论session机制的时候,常常听到q样一U误?#8220;只要关闭览器,session消׃”。其实可以想象一下会员卡的例子,除非֮d对店家提出销卡,否则店家l对不会L删除֮的资料。对session来说也是一LQ除非程序通知服务器删除一个sessionQ否则服务器会一直保留,E序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会d在关闭之前通知服务器它?yu)要关闭Q因此服务器Ҏ(gu)不会有机会知道浏览器已经关闭Q之所以会有这U错觉,是大部分session机制都用会话cookie来保存session idQ而关闭浏览器后这?session id消׃Q再ơ连接服务器时也无法找到原来的session。如果服务器讄的cookie被保存到盘上,或者用某U手D|写浏览器发出的HTTPh_把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session?br />
恰恰是由于关闭浏览器不会Dsession被删除,q服务器ؓseesion讄了一个失效时_当距dL上一ơ用session的时间超q这个失效时间时Q服务器可以认为客L已经停止了活动,才会把session删除以节省存储空间?br />
五、理解javax.servlet.http.HttpSession
HttpSession是Javaq_对session机制的实现规范,因ؓ它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作ؓ例子来演C?br />
首先QWeblogic Server提供了一pd的参数来控制它的HttpSession的实玎ͼ包括使用cookie的开关选项Q用URL重写的开关选项Qsession持久化的讄Qsession失效旉的设|,以及针对cookie的各U设|,比如讄cookie的名字、\径、域Q?cookie的生存时间等?br />
一般情况下Qsession都是存储在内存里Q当服务器进E被停止或者重启的时候,内存里的session也会被清I,如果讄了session的持久化Ҏ(gu),服务器就会把session保存到硬盘上Q当服务器进E重新启动或q些信息能够被再次使用Q?Weblogic Server支持的持久性方式包括文件、数据库、客Lcookie保存和复制?br />
复制严格说来不算持久化保存,因ؓsession实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进E中Q这样即使某个服务器q程停止工作也仍然可以从其他q程中取得session?br />
cookie生存旉的设|则会媄响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解?br />
cookie的\径对于web应用E序来说是一个非帔R要的选项QWeblogic Server对这个选项的默认处理方式得它与其他服务器有明昄区别。后面我们会专题讨论?br />
关于session的设|参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

六、HttpSession常见问题
Q在本小节中session的含义ؓ⑤和⑥的混合Q?br />
1、session在何时被创徏
一个常见的误解是以为session在有客户端访问时p创徏Q然而事实是直到某server端程序调?HttpServletRequest.getSession(true)q样的语句时才被创徏Q注意如果JSP没有昄的?<% @page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将会自动加上这样一条语?HttpSession session = HttpServletRequest.getSession(true);q也是JSP中隐含的 session对象的来历?br />
׃session会消耗内存资源,因此Q如果不打算使用sessionQ应该在所有的JSP中关闭它?br />
2、session何时被删?br /> l合前面的讨论,session在下列情况下被删除a.E序调用HttpSession.invalidate();或b.距离上一ơ收到客L发送的session id旉间隔过了session的超时设|?或c.服务器进E被停止Q非持久sessionQ?br />
3、如何做到在览器关闭时删除session
严格的讲Q做不到q一炏V可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进E这些非常规手段仍然无能为力?br />
4、有个HttpSessionListener是怎么回事
你可以创Llistenerȝ控session的创建和销毁事Ӟ使得在发生这L事g时你可以做一些相应的工作。注意是session的创建和销毁动作触发listenerQ而不是相反。类似的与HttpSession有关的listenerq有 HttpSessionBindingListenerQHttpSessionActivationListener?HttpSessionAttributeListener?br />
5、存攑֜session中的对象必须是可序列化的?br /> 不是必需的。要求对象可序列化只是ؓ了session能够在集中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在 Weblogic Server的session中放|一个不可序列化的对象在控制C会收C个警告。我所用过的某个iPlanet版本如果 session中有不可序列化的对象Q在session销毁时会有一个ExceptionQ很奇怪?br />
6、如何才能正的应付客户端禁止cookie的可能?br /> Ҏ(gu)有的URL使用URL重写Q包括超链接Qform的actionQ和重定向的URLQ具体做法参见[6]
http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

7、开两个览器窗口访问应用程序会使用同一个sessionq是不同的session
参见W三节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器Q不同的H口打开方式以及不同的cookie存储方式都会对这个问题的{案有媄响?br />
8、如何防止用h开两个览器窗口操作导致的session混ؕ
q个问题与防止表单多ơ提交是cM的,可以通过讄客户端的令牌来解冟뀂就是在服务器每ơ生成一个不同的idq回l客LQ同时保存在session里,客户端提交表单时必须把这个id也返回服务器Q程序首先比较返回的id与保存在session里的值是否一_如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表C层模式的部分。需要注意的是对于用javascript window.open打开的窗口,一般不讄q个idQ或者用单独的idQ以防主H口无法操作Q徏议不要再window.open打开的窗口里做修Ҏ(gu)作,q样可以不用设|?br />
9、ؓ什么在Weblogic Server中改变session的值后要重新调用一ơsession.setValue
做这个动作主要是Z在集环境中提示Weblogic Server session中的值发生了改变Q需要向其他服务器进E复制新的session倹{?br />
10、ؓ什么session不见?br /> 排除session正常失效的因素之外,服务器本w的可能性应该是微乎其微的,虽然W者在iPlanet6SP1加若q补丁的Solaris版本上倒也遇到q;览器插件的可能性次之,W者也遇到q?721插g造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题?br /> 出现q一问题的大部分原因都是E序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨个问题?br />
七、跨应用E序的session׃n

常常有这L情况Q一个大目被分割成若干项目开发,Z能够互不q扰Q要求每个小目作ؓ一个单独的web应用E序开发,可是C最后突然发现某几个项目之间需要共享一些信息,或者想使用session来实现SSO(single sign on)Q在session中保存login的用户信息,最自然的要求是应用E序间能够访问彼此的session?br />
然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ(gu)的session的。各个应用服务器从实际效果上都遵守了q一规范Q但是实现的l节却可能各有不同,因此解决跨应用程序session׃n的方法也各不相同?br />
首先来看一下Tomcat是如何实现web应用E序之间session的隔ȝQ从 Tomcat讄的cookie路径来看Q它对不同的应用E序讄的cookie路径是不同的Q这样不同的应用E序所用的session id是不同的Q因此即使在同一个浏览器H口里访问不同的应用E序Q发送给服务器的session id也可以是不同的?br />
image
image

Ҏ(gu)q个Ҏ(gu),我们可以推测Tomcat中session的内存结构大致如下?br /> image

W者以前用q的iPlanet也采用的是同L方式Q估计SunONE与iPlanet之间不会有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id?br />
iPlanet中有一U很单的Ҏ(gu)来实现共享一个session idQ那是把各个应用程序的cookie路径都设?Q实际上应该?NASAppQ对于应用程序来讲它的作用相当于根)?br />
<session-info>
<path>/NASApp</path>
</session-info>


需要注意的是,操作׃n的session应该遵@一些编E约定,比如在session attribute名字的前面加上应用程序的前缀Q?setAttribute("name", "neo")变成setAttribute("app1.name", "neo")Q以防止命名I间冲突Q导致互相覆盖?br />
在Tomcat中则没有q么方便的选择。在Tomcat版本3上,我们q可以有一些手D|׃nsession。对于版?以上的TomcatQ目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文g、数据库、JMS或者客LcookieQURL参数或者隐藏字D늭手段?br />
我们再看一下Weblogic Server是如何处理session的?br /> image
image

从截屏画面上可以看到Weblogic ServerҎ(gu)有的应用E序讄的cookie的\径都?Q这是不是意味着在Weblogic Server中默认的可以共享session了呢Q然而一个小实验卛_证明即不同的应用程序用的是同一个sessionQ各个应用程序仍然只能访问自己所讄的那些属性。这说明Weblogic Server中的session的内存结构可能如?br /> image

对于q样一U结构,?session机制本n上来解决session׃n的问题应该是不可能的了。除了借助于第三方的力量,比如使用文g、数据库、JMS或者客L cookieQURL参数或者隐藏字D늭手段Q还有一U较为方便的做法Q就是把一个应用程序的session攑ֈServletContext中,q样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下,

应用E序A
context.setAttribute("appA", session);


应用E序B
contextA = context.getContext("/appA");
HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");


值得注意的是q种用法不可ULQ因为根据ServletContext的JavaDocQ应用服务器可以处于安全的原因对于context.getContext("/appA");q回I|以上做法在Weblogic Server 8.1中通过?br />
那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ了SSOQ凡是共享这个session的应用程序都可以׃n认证的信息。一个简单的实验可以证明这一点,修改首先d的那个应用程序的描述Wweblogic.xmlQ把cookie路径修改?appA 讉K另外一个应用程序会重新要求dQ即使是反过来,先访问cookie路径?的应用程序,再访问修改过路径的这个,虽然不再提示dQ但是登录的用户信息也会丢失。注意做q个实验时认证方式应该用FORMQ因为浏览器和web服务器对basic认证方式有其他的处理方式Q第二次h的认证不是通过 session来实现的。具体请参看[7] secion 14.8 AuthorizationQ你可以修改所附的CZE序来做q些试验?br />
八、ȝ
session机制本nq不复杂Q然而其实现和配|上的灵zL却使得具体情况复杂多变。这也要求我们不能把仅仅某一ơ的l验或者某一个浏览器Q服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析?br /> 摘要Q虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/div>

菠萝 2008-01-26 09:53 发表评论
]]>URLClassLoader加蝲class到当前线E类加蝲器(转)http://m.tkk7.com/boluobn/archive/2008/01/26/177872.html菠萝菠萝Sat, 26 Jan 2008 01:51:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/26/177872.htmlhttp://m.tkk7.com/boluobn/comments/177872.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/26/177872.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/177872.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/177872.html 下面来看一个例子,在该例子中,我们要完成的工作是利用URLClassLoader加蝲jarq运行其中的cȝ某个Ҏ(gu)?

首先我们定义一个接口,使所有承它的类都必d现actionҎ(gu)Q如下:

  public   interface  ActionInterface  {
     public  String action();
}
完成后将其打包ؓtestInterface.jar文g?/p>

接下来新Z工程Qؓ了编译通过Q引入之前打好的testInterface.jar包。ƈ创徏TestActionc,使它实现ActionInterface接口。如下:


  public   class  TestAction  implements  ActionInterface  {
     public  String action()  {
         return   " com.mxjava.TestAction.action " ;
    }
}
 
完成后将其打包ؓtest.jarQ放在c盘根目录下。下面要做的是利用URLClassLoader加蝲q运行TestAction的actionҎ(gu)Qƈ返回的值打印在控制C?/p>

新徏一工程Q引入testInterface.jar包。ƈ创徏一可执行类QmainҎ(gu)Q,在其中加入如下代码:

 URL url  =   new  URL(“file:C: / test.jar”);
URLClassLoader myClassLoader  =   new  URLClassLoader( new  URL[]  { url } );
Class myClass  =  myClassLoader.loadClass(“com.mxjava.TestAction”);
ActionInterface action  =  (ActionInterface)myClass.newInstance();
System.out.println(action.action());
  在上面的例子中,首先利用URLClassLoader加蝲了C:\test.jar包,其中的com.mxjava.TestActionc蝲入内存,其强制转型为testInterface包中的ActionInterfacecdQ最后调用其actionҎ(gu)Qƈ打印到控制台中?/p>

  执行E序后,在控制台上如期打印出我们惌的内宏V但是,事情q没有那么简单,当我们将该代码移动web应用中时Q就会抛出异常。原来,Java为我们提供了三种可选择的ClassLoaderQ?br /> 1. pȝcd载器或叫作应用类加蝲?(system classloader or application classloader)
2. 当前cd载器
3. 当前U程cd载器

  在上例中我们使用javac命o来运行该E序Q这时候用的是系l类加蝲?(system classloader)。这个类加蝲器处?-classpath下的cd载工作,可以通过ClassLoader.getSystemClassLoader()Ҏ(gu)调用?ClassLoader 下所有的 getSystemXXX()的静态方法都是通过q个Ҏ(gu)定义的。在代码中,应该量地调用q个Ҏ(gu)Q以其它的类加蝲器作Z理。否则代码将只能工作在简单的命o行应用中。当在web应用中时Q服务器也是利用ClassLoader来加载class的,׃ClassLoader的不同,所以在强制转型时JVM认定不是同一cd。(在JAVA中,一个类用其完全匚wcd(fully qualified class name)作ؓ标识Q这里指的完全匹配类名包括包名和cd。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类Q被cd载器KlassLoader的一个实例kl1加蝲QCl的实例,即C1.class在JVM中表CZؓ(Cl, Pg, kl1)。这意味着两个cd载器的实?Cl, Pg, kl1) ?(Cl, Pg, kl2)是不同的Q被它们所加蝲的类也因此完全不同,互不兼容的。)Z能够使程序正运行,我们首要解决的问题就是,如何URLClassLoader加蝲的类Q同当前ClassLoader保持在同一cd载器中。解x法很单,利用java提供的第三种ClassLoader—当前线E类加蝲器即可。jdk api文档׃发现QURLClassLoader提供了三U构造方式:

 // 使用默认的委托父 ClassLoader 为指定的 URL 构造一个新 URLClassLoader?nbsp;
 URLClassLoader(URL[] urls)
// 为给定的 URL 构造新 URLClassLoader?nbsp;
URLClassLoader(URL[] urls, ClassLoader parent)
// 为指定的 URL、父cd载器?URLStreamHandlerFactory 创徏?URLClassLoader?
 URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) 
接下来要做的是Q在构造URLClassLoaderӞ当前线E类加蝲器置入即可。如下:

URLClassLoader myClassLoader  =   new  URLClassLoader( new  URL[]  { url } , Thread.currentThread().getContextClassLoader());
ȝQ?br />   Java是利用ClassLoader来加载类到内存的QClassLoader本n是用java语言写的Q所以我们可以扩展自qClassLoader。利用URLClassLoader可以加蝲指定jar包中的类到内存。在命行上利用URLClassLoader加蝲jarӞ是用系l类加蝲器来加蝲class的,所以在web环境下,׃出错。这是因为JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识的。我们只要利用URLClassLoader的第二种构造方法ƈ传入当前U程cd载器卛_解决?/p>

菠萝 2008-01-26 09:51 发表评论
]]>
了解Java ClassLoaderhttp://m.tkk7.com/boluobn/archive/2008/01/25/177748.html菠萝菠萝Fri, 25 Jan 2008 05:52:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/25/177748.htmlhttp://m.tkk7.com/boluobn/comments/177748.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/25/177748.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/177748.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/177748.html 
【原文地址Qhttps://www6.software.ibm.com/developerworks/cn/education/java/j-classloader/tutorial/?br /> 1.介绍
2.ClassLoader的结?br /> 3.Compiling ClassLoader
4.java2 中ClassLoader的变?br /> 5.源代?br /> ---------------------------------------------------------------------------

W一?介绍

什么是 ClassLoader

在流行的商业化编E语a中,Java 语言׃?Java 虚拟?(JVM) 上运行而显得与众不同。这意味着已编译的E序是一U特D的、独立于q_的格式,q依赖于它们所q行的机器。在很大E度上,q种格式不同于传l的可执行程序格式?

?C ?C++ ~写的程序不同,Java E序q不是一个可执行文gQ而是p多独立的cL件组成,每一个文件对应于一?Java cR?

此外Q这些类文gq立即全部都装入内存,而是Ҏ(gu)E序需要装入内存。ClassLoader ?JVM 中将c装入内存的那部分?

而且QJava ClassLoader 是?Java 语言~写的。这意味着创徏(zhn)自q ClassLoader 非常Ҏ(gu)Q不必了?JVM 的微细节?

Z么编?ClassLoader?

如果 JVM 已经有一?ClassLoaderQ那么ؓ什么还要编写另一个呢Q问得好。缺省的 ClassLoader 只知道如何从本地文gpȝ装入cL件。不q这只适合于常规情况,卛_全部~译?Java E序Qƈ且计机处于{待状态?

?Java 语言最h意的事就?JVM 可以非常Ҏ(gu)C那些非本地硬盘或从网l上获取cR例如,览者可以用定制的 ClassLoader ?Web 站点装入可执行内宏V?

有许多其它方式可以获取类文g。除了简单地从本地或|络装入文g以外Q可以用定制的 ClassLoader 完成以下dQ?

  • 在执行非|信代码之前Q自动验证数字签?
  • 使用用户提供的密码透明地解密代?
  • 动态地创徏W合用户特定需要的定制化构建类
M(zhn)认为可以生?Java 字节码的内容都可以集成到应用E序中?/font>

定制 ClassLoader CZ

如果使用q?JDK 或Q何基?Java 览器中?Applet 查看器,那么(zhn)差不多肯定使用q定制的 ClassLoader?

Sun 最初发?Java 语言Ӟ其中最令h兴奋的一件事是观看这Ҏ(gu)技术是如何执行在运行时从远E的 Web 服务器装入的代码。(此外Q还有更令h兴奋的事 -- Java 技术提供了一U便于编写代码的强大语言。)更一些o人激动的是它可以执行从远E?Web 服务器通过 HTTP q接发送过来的字节码?

此项功能归功?Java 语言可以安装定制 ClassLoader。Applet 查看器包含一?ClassLoaderQ它不在本地文gpȝ中寻扄Q而是讉Kq程服务器上?Web 站点Q经q?HTTP 装入原始的字节码文gQƈ把它们{换成 JVM 内的cR?

览器和 Applet 查看器中?ClassLoaders q可以做其它事情Q它们支持安全性以及不同?Applet 在不同的面上运行而互不干扰?

Luke Gorrie ~写?Echidna 是一个开放源码包Q它可以使?zhn)在单个虚拟机上运行多?Java 应用E序。(请参?a >q一步了解和参考资?/a>。)它用定制的 ClassLoaderQ通过向每个应用程序提供该cL件的自n副本Q以防止应用E序互相q扰?


我们?ClassLoader CZ

了解?ClassLoader 如何工作以及如何~写 ClassLoader 之后Q我们将创徏UC CompilingClassLoader (CCL) ?Classloader。CCL 为我们编?Java 代码Q而无需要我们干涉这个过E。它基本上就cM于直接构建到q行时系l中?"make" E序?

注:q一步了解之前,应注意在 JDK 版本 1.2 中已改进?ClassLoader pȝ的某些方面(?Java 2 q_Q。本教程是按 JDK 版本 1.0 ?1.1 写的Q但也可以在以后的版本中q行?/p>

Java 2 ?ClassLoader 的变?/a>描述?Java 版本 1.2 中的变动Qƈ提供了一些详l信息,以便修改 ClassLoader 来利用这些变动?

 


 

------------------------------------------------------------------------------------------------------

W二?ClassLoader的结?/strong>



ClassLoader 的基本目标是对类的请求提供服务。当 JVM 需要用类Ӟ它根据名U向 ClassLoader hq个c,然后 ClassLoader 试图q回一个表C个类?Class 对象?

通过覆盖对应于这个过E不同阶D늚Ҏ(gu)Q可以创建定制的 ClassLoader?

在本章的其余部分Q?zhn)会学?Java ClassLoader 的关键方法。?zhn)了解每一个方法的作用以及它是如何适合装入cL件这个过E的。?zhn)也会知道Q创q ClassLoader Ӟ需要编写什么代码?

在下一章中Q?zhn)会利用q些知识来用我们的 ClassLoader CZ -- CompilingClassLoader?


Ҏ(gu) loadClass


ClassLoader.loadClass() ?ClassLoader 的入口点。其特征如下Q?

 

Class loadClass( String name, boolean resolve );

name 参数指定?JVM 需要的cȝ名称Q该名称以包表示法表C,?Foo ?java.lang.Object?

resolve 参数告诉Ҏ(gu)是否需要解析类。在准备执行cM前,应考虑c解析。ƈ不L需要解析。如?JVM 只需要知道该cL否存在或扑և该类的超c,那么׃需要解析?

?Java 版本 1.1 和以前的版本中,loadClass Ҏ(gu)是创建定制的 ClassLoader 时唯一需要覆盖的Ҏ(gu)。(Java 2 ?ClassLoader 的变?/a>提供了关?Java 1.2 ?findClass() Ҏ(gu)的信息。)


Ҏ(gu) defineClass

defineClass Ҏ(gu)?ClassLoader 的主要诀H。该Ҏ(gu)接受由原始字节组成的数组q把它{换成 Class 对象。原始数l包含如从文件系l或|络装入的数据?

defineClass 理 JVM 的许多复杂、神U和倚赖于实现的斚w -- 它把字节码分析成q行时数据结构、校验有效性等{。不必担心,(zhn)无需亲自~写它。事实上Q即使?zhn)惌q么做也不能覆盖它,因ؓ它已被标记成最l的?


Ҏ(gu) findSystemClass

findSystemClass Ҏ(gu)从本地文件系l装入文件。它在本地文件系l中LcLӞ如果存在Q就使用 defineClass 原始字节{换成 Class 对象Q以该文g转换成类。当q行 Java 应用E序Ӟq是 JVM 正常装入cȝ~省机制。(Java 2 ?ClassLoader 的变?/a>提供了关?Java 版本 1.2 q个q程变动的详l信息。)

对于定制?ClassLoaderQ只有在试其它Ҏ(gu)装入cM后,再?findSystemClass。原因很单:ClassLoader 是负责执行装入类的特D步骤,不是负责所?/em>cR例如,即 ClassLoader 从远E的 Web 站点装入了某些类Q仍焉要在本地机器上装入大量的基本 Java 库。而这些类不是我们所兛_的,所以要 JVM 以缺省方式装入它们:从本地文件系l。这是 findSystemClass 的用途?

其工作流E如下:

 

  • h定制?ClassLoader 装入cR?
  • 查远E?Web 站点Q查看是否有所需要的cR?
  • 如果有,那么好;抓取q个c,完成d?
  • 如果没有Q假定这个类是在基本 Java 库中Q那么调?findSystemClassQ它从文gpȝ装入该类?

在大多数定制 ClassLoaders 中,首先调用 findSystemClass 以节省在本地可以装入的许多 Java 库类而要在远E?Web 站点上查找所q旉。然而,正如Q在下一章节所看到的,直到信能自动编译我们的应用E序代码Ӟ才让 JVM 从本地文件系l装入类?


Ҏ(gu) resolveClass

正如前面所提到的,可以不完全地Q不带解析)装入c,也可以完全地Q带解析Q装入类。当~写我们自己?loadClass Ӟ可以调用 resolveClassQ这取决?loadClass ?resolve 参数的倹{?/font>

Ҏ(gu) findLoadedClass

findLoadedClass 充当一个缓存:当请?loadClass 装入cLQ它调用该方法来查看 ClassLoader 是否已装入这个类Q这样可以避免重新装入已存在cL造成的麻烦。应首先调用该方法?/font>

l装

 

 

 

让我们看一下如何组装所有方法?

我们?loadClass 实现CZ执行以下步骤。(q里Q我们没有指定生成类文g是采用了哪种技?-- 它可以是?Net 上装入、或者从归档文g中提取、或者实时编译。无论是哪一U,那是U特D的奇方式Q我们获得了原始类文g字节。)

 

  • 调用 findLoadedClass 来查看是否存在已装入的类?br x="7" />
  • 如果没有Q那么采用U特D的奇方式来获取原始字节?br x="7" />
  • 如果已有原始字节Q调?defineClass 它们{换成 Class 对象?br x="7" />
  • 如果没有原始字节Q然后调?findSystemClass 查看是否从本地文件系l获取类?br x="7" />
  • 如果 resolve 参数?trueQ那么调?resolveClass 解析 Class 对象?br x="7" />
  • 如果q没有类Q返?ClassNotFoundException?br x="7" />
  • 否则Q将c返回给调用E序?
推想

现在(zhn)已l了解了 ClassLoader 的工作原理,现在该构Z个了。在下一章中Q我们将讨论 CCL?br />
---------------------------------------------------------------------------------------------

W三章:Compiling ClassLoader

CCL 揭密

我们?ClassLoader (CCL) 的Q务是保代码被编译和更新?

下面描述了它的工作方式:

 

  • 当请求一个类Ӟ先查看它是否在磁盘的当前目录或相应的子目录?br x="7" />
  • 如果该类不存在,但源码中有,那么调用 Java ~译器来生成cL件?br x="7" />
  • 如果该类已存在,查它是否比源码旧。如果是Q调?Java ~译器来重新生成cL件?br x="7" />
  • 如果~译p|Q或者由于其它原因不能从现有的源码中生成cLӞq回 ClassNotFoundException?br x="7" />
  • 如果仍然没有该类Q也许它在其它库中,所以调?findSystemClass 来寻找该cR?br x="7" />
  • 如果q是没有Q则q回 ClassNotFoundException?br x="7" />
  • 否则Q返回该cR?
Java ~译的工作方?/strong>

 

在深入讨Z前,应该先退一步,讨论 Java ~译。通常QJava ~译器不只是~译(zhn)要求它~译的类。它q会~译其它c,如果q些cL(zhn)要求编译的cL需要的cR?

CCL 逐个~译应用E序中的需要编译的每一个类。但一般来_在编译器~译完第一个类后,CCL 会查找所有需要编译的c,然后~译它。ؓ什么?Java ~译器类g我们正在使用的规则:如果cM存在Q或者与它的源码相比Q它比较旧,那么它需要编译。其实,Java ~译器在 CCL 之前的一个步骤,它会做大部分的工作?

?CCL ~译它们Ӟ会报告它正在~译哪个应用E序上的cR在大多数的情况下,CCL 会在E序中的ȝ上调用编译器Q它会做完所有要做的 -- ~译器的单一调用已够了?

然而,有一U情形,在第一步时不会~译某些cR如果?Class.forName Ҏ(gu)Q通过名称来装入类QJava ~译器会不知道这个类时所需要的。在q种情况下,(zhn)会看到 CCL 再次q行 Java ~译器来~译q个cR在源代?/a>中演CZq个q程?

使用 CompilationClassLoader

要?CCLQ必MҎ(gu)方式调用E序。不能直接运行该E序Q如Q?

 

% java Foo arg1 arg2

应以下列方式q行它:

 

% java CCLRun Foo arg1 arg2

CCLRun 是一个特D的存根E序Q它创徏 CompilingClassLoader q用它来装入E序的主c,以确保通过 CompilingClassLoader 来装入整个程序。CCLRun 使用 Java Reflection API 来调用特定类的主Ҏ(gu)q把参数传递给它。有兌l信息,请参?a >源代?/a>?

q行CZ

源码包括了一l小c,它们演示了工作方式。主E序?Foo c,它创建类 Bar 的实例。类 Bar 创徏另一个类 Baz 的实例,它在 baz 包内Q这是ؓ了展C?CCL 是如何处理子包里的代码?code style="font-size: 12px; font-family: Courier New,Courier,monospace">Bar 也是通过名称装入的,其名UCؓ BooQ这用来展示它也能与 CCL 工作?

每个c都声明已被装入q运行。现在用源代?/a>来试一下。编?CCLRun ?CompilingClassLoader。确保不要编译其它类Q?code style="font-size: 12px; font-family: Courier New,Courier,monospace">Foo?code style="font-size: 12px; font-family: Courier New,Courier,monospace">Bar?code style="font-size: 12px; font-family: Courier New,Courier,monospace">Baz ?BooQ,否则不会?CCLQ因些类已经~译q了?

 


% java CCLRun Foo arg1 arg2
CCL: Compiling Foo.java...
foo! arg1 arg2
bar! arg1 arg2
baz! arg1 arg2
CCL: Compiling Boo.java...
Boo!

h意,首先调用~译器,Foo.javaBar ?baz.Baz。直?Bar 通过名称来装?Boo Ӟ被调用它Q这?CCL 会再ơ调用编译器来编译它?

 

 

 

 

--------------------------------------------------------------------------------------

W四章:java2 中ClassLoader的变?/strong>


概述

?Java 版本 1.2 和以后的版本中,?ClassLoader 做了一些改q。Q何ؓ老系l编写的代码可以在新版本中运行,但新pȝ为?zhn)提供了一些便利?

新模型是委托模型Q这意味着如果 ClassLoader 不能扑ֈc,它会h父代 ClassLoader 来执行此Q务。所?ClassLoaders 的根是系l?ClassLoaderQ它会以~省方式装入c?-- 卻I从本地文件系l?

loadClass 的缺省实?/strong>

定制~写?loadClass Ҏ(gu)一般尝试几U方式来装入所h的类Q如果?zhn)~写许多c,会发Cơ次地在相同的、很复杂的方法上~写变量?

?Java 1.2 ?loadClass 的实现嵌入了大多数查扄的一般方法,q(zhn)通过覆盖 findClass Ҏ(gu)来定制它Q在适当的时?findClass 会调?loadClass?

q种方式的好处是(zhn)可能不一定要覆盖 loadClassQ只要覆?findClass p了,q减了工作量?

新方法:findClass

loadClass 的缺省实现调用这个新Ҏ(gu)?code style="font-size: 12px; font-family: Courier New,Courier,monospace">findClass 的用途包含?zhn)?ClassLoader 的所有特D代码,而无需要复制其它代码(例如Q当专门的方法失败时Q调用系l?ClassLoaderQ?/font>

新方法:getSystemClassLoader

如果覆盖 findClass ?loadClassQ?code style="font-size: 12px; font-family: Courier New,Courier,monospace">getSystemClassLoader 使?zhn)能以实?ClassLoader 对象来访问系l?ClassLoaderQ而不是固定的?findSystemClass 调用它)?/font>

新方法:getParent

Z类h委托l父?ClassLoaderQ这个新Ҏ(gu)允许 ClassLoader 获取它的父代 ClassLoader。当使用Ҏ(gu)Ҏ(gu)Q定制的 ClassLoader 不能扑ֈcLQ可以用这U方法?

父代 ClassLoader 被定义成创徏?ClassLoader 所包含代码的对象的 ClassLoader?

----------------------------------------------------------------------------------

 

 

 

W五?源代?/strong>

 

CompilingClassLoader.java

以下?CompilingClassLoader.java 的源代码

// $Id$
import java.io.*;
/*
A CompilingClassLoader compiles your Java source on-the-fly. It checks
for nonexistent .class files, or .class files that are older than their
corresponding source code.*/
public class CompilingClassLoader extends ClassLoader
{
// Given a filename, read the entirety of that file from disk
// and return it as a byte array.
private byte[] getBytes( String filename ) throws IOException {
// Find out the length of the file
File file = new File( filename );
long len = file.length();
// Create an array that's just the right size for the file's
// contents
byte raw[] = new byte[(int)len];
// Open the file
FileInputStream fin = new FileInputStream( file );
// Read all of it into the array; if we don't get all,
// then it's an error.
int r = fin.read( raw );
if (r != len)
throw new IOException( "Can't read all, "+r+" != "+len );
// Don't forget to close the file!
fin.close();
// And finally return the file contents as an array
return raw;
}
// Spawn a process to compile the java source code file
// specified in the 'javaFile' parameter. Return a true if
// the compilation worked, false otherwise.
private boolean compile( String javaFile ) throws IOException {
// Let the user know what's going on
System.out.println( "CCL: Compiling "+javaFile+"..." );
// Start up the compiler
Process p = Runtime.getRuntime().exec( "javac "+javaFile );
// Wait for it to finish running
try {
p.waitFor();
} catch( InterruptedException ie ) { System.out.println( ie ); }
// Check the return code, in case of a compilation error
int ret = p.exitValue();
// Tell whether the compilation worked
return ret==0;
}
// The heart of the ClassLoader -- automatically compile
// source as necessary when looking for class files
public Class loadClass( String name, boolean resolve )
throws ClassNotFoundException {

// Our goal is to get a Class object
Class clas = null;

// First, see if we've already dealt with this one
clas = findLoadedClass( name );

//System.out.println( "findLoadedClass: "+clas );

// Create a pathname from the class name
// E.g. java.lang.Object => java/lang/Object
String fileStub = name.replace( '.', '/' );

// Build objects pointing to the source code (.java) and object
// code (.class)
String javaFilename = fileStub+".java";
String classFilename = fileStub+".class";

File javaFile = new File( javaFilename );
File classFile = new File( classFilename );

//System.out.println( "j "+javaFile.lastModified()+" c "+
// classFile.lastModified() );

// First, see if we want to try compiling. We do if (a) there
// is source code, and either (b0) there is no object code,
// or (b1) there is object code, but it's older than the source
if (javaFile.exists() &&
(!classFile.exists() ||
javaFile.lastModified() > classFile.lastModified())) {

try {
// Try to compile it. If this doesn't work, then
// we must declare failure. (It's not good enough to use
// and already-existing, but out-of-date, classfile)
if (!compile( javaFilename ) || !classFile.exists()) {
throw new ClassNotFoundException( "Compile failed: "+javaFilename );
}
} catch( IOException ie ) {

// Another place where we might come to if we fail
// to compile
throw new ClassNotFoundException( ie.toString() );
}
}

// Let's try to load up the raw bytes, assuming they were
// properly compiled, or didn't need to be compiled
try {

// read the bytes
byte raw[] = getBytes( classFilename );

// try to turn them into a class
clas = defineClass( name, raw, 0, raw.length );
} catch( IOException ie ) {
// This is not a failure! If we reach here, it might
// mean that we are dealing with a class in a library,
// such as java.lang.Object
}

//System.out.println( "defineClass: "+clas );

// Maybe the class is in a library -- try loading
// the normal way
if (clas==null) {
clas = findSystemClass( name );
}

//System.out.println( "findSystemClass: "+clas );

// Resolve the class, if any, but only if the "resolve"
// flag is set to true
if (resolve && clas != null)
resolveClass( clas );

// If we still don't have a class, it's an error
if (clas == null)
throw new ClassNotFoundException( name );

// Otherwise, return the class
return clas;
}
 }
CCRun.java


以下?CCRun.java 的源代码


// $Id$

import java.lang.reflect.*;

/*

CCLRun executes a Java program by loading it through a
CompilingClassLoader.

*/

public class CCLRun
{
static public void main( String args[] ) throws Exception {

// The first argument is the Java program (class) the user
// wants to run
String progClass = args[0];

// And the arguments to that program are just
// arguments 1..n, so separate those out into
// their own array
String progArgs[] = new String[args.length-1];
System.arraycopy( args, 1, progArgs, 0, progArgs.length );

// Create a CompilingClassLoader
CompilingClassLoader ccl = new CompilingClassLoader();

// Load the main class through our CCL
Class clas = ccl.loadClass( progClass );

// Use reflection to call its main() method, and to
// pass the arguments in.

// Get a class representing the type of the main method's argument
Class mainArgType[] = { (new String[0]).getClass() };

// Find the standard main method in the class
Method main = clas.getMethod( "main", mainArgType );

// Create a list containing the arguments -- in this case,
// an array of strings
Object argsArray[] = { progArgs };

// Call the method
main.invoke( null, argsArray );
}
}
Foo.java


以下?Foo.java 的源代码



// $Id$

public class Foo
{
static public void main( String args[] ) throws Exception {
System.out.println( "foo! "+args[0]+" "+args[1] );
new Bar( args[0], args[1] );
}
}
Bar.java


以下?Bar.java 的源代码


// $Id$

import baz.*;

public class Bar
{
public Bar( String a, String b ) {
System.out.println( "bar! "+a+" "+b );
new Baz( a, b );

try {
Class booClass = Class.forName( "Boo" );
Object boo = booClass.newInstance();
} catch( Exception e ) {
e.printStackTrace();
}
}
}
baz/Baz.java


以下?baz/Baz.java 的源代码


// $Id$

package baz;

public class Baz
{
public Baz( String a, String b ) {
System.out.println( "baz! "+a+" "+b );
}
}

Boo.java


以下?Boo.java 的源代码


// $Id$

public class Boo
{
public Boo() {
System.out.println( "Boo!" );
}
}



菠萝 2008-01-25 13:52 发表评论
]]>eclipse配置weblogic(?http://m.tkk7.com/boluobn/archive/2008/01/24/177510.html菠萝菠萝Thu, 24 Jan 2008 07:33:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/24/177510.htmlhttp://m.tkk7.com/boluobn/comments/177510.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/24/177510.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/177510.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/177510.html安装WebLogic8.1
安装WebLogic比较Ҏ(gu)Q在q里׃再篏qCQ大家可以参阅相x档。现在着重讲一下WebLogic的配|,因ؓ后面在配|MyEclipse时将用到q里的有关信息?
(1)q行开始\E序\BEA WebLogic PlatFORM 8.1\Configuration Wizard?
(2)选择Create a new WebLogic configurationQ下一步?
(3)选择Basic WebLogic Server DomainQ下一步?
(4)选择CustomQ下一步?
(5)在Name处输入adminQListen Address处选择localhostQ以下两个Port均采用默认|下一步?
(6)选择Skip跌Multiple ServersQClustersQand Machines OptionsQ下一步?
(7)选择Skip跌JDBCq接池的配置Q注QJDBCq接池的配置可以在启动WebLogic后到控制Cq行Q大家可以参阅相x档)Q下一步?
(选择Skip跌JMS的配|(同样留到控制C做)Q下一步?
(9)l箋跌Q下一步?
(10)选择YesQ下一步?
(11)在User늂击AddQ随意添加一个用户userQ密?2345678Q下一步?
(12)用户user分配到Administratorsl(q可以同时分配到其它l,Ҏ(gu)是选中待加入的l,然后勾中user前的复选框卛_Q,下一步?
(13)直接点击下一步蟩q?
(14)讄用户user的权限,选中AdminQ勾中user前的复选框Q要指定其它权限依次cLQ,下一步?
(15)采用默认讄Q直接点M一步蟩q?
(16)同样采用默认讄Q直接点M一步蟩q?
(17)配置JDKQ采用WebLogic的默认|直接点击下一步蟩q?
(1最后在Configuration Name处输入devQ然后点击Create生成配置Q完毕点击Done关闭Configuration Wizard对话框?
5.配置MyEclipse的WebLogic服务?
MyEclipse默认的应用服务器为JBoss3Q这里我们用WebLogic8.1。启动EclipseQ选择“H口\首选项”菜单Q打开首选项对话框。展开MyEclipse下的Application Serversl点Q点击JBoss 3Q选中右面的Disable单选按钮,停用JBoss 3。然后点击WebLogic 8Q选中双的Enable单选按钮,启用WebLogic服务器。同时下面的配置如下Q?
(1)BEA home directoryQD:\BEA。假定WebLogic安装在D:\BEA文g夹中?
(2)WebLogic installation directoryQD:\BEA\weblogic81?
(3)Admin usernameQuser?
(4)Admin passwordQ?2345678?
(5)Execution domain rootQD:\BEA\user_projects\dev?
(6)Execution domain nameQdev?
(7)Execution server nameQadmin?
(8)Hostname:PortNumberQlocalhost:7001?
(9)Security policy fileQD:\BEA\weblogic81\server\lib\weblogic.policy?
(10)JAAS login configuration fileQ省略?
接着展开WebLogic 8l点Q点击JDKQ在双的WLS JDK name处选择WebLogic 8的默认JDK。这里组合框中缺省ؓj2re1.4.2_03Q即之前单独安装的jre。单击Add按钮Q弹出WebLogic > Add JVM对话框,在JRE名称处随便输入一个名字,如jre1.4.1_02。然后在JREȝ录处选择WebLogic安装文g夹中的JDK文g夹,如D:\BEA\jdk141_02Q程序会自动填充Javadoc URL文本框和JREpȝ库列表框。单ȝ定按钮关闭对话框。这时候就可以在WLS JDK namel合框中选择jre1.4.1_02了。之后还要在下面的Optional Java VM argumentsQ如-ms64m -mx64m -Djava.library.path="D:/BEA/weblogic81/server/bin" -Dweblogic.management.discover=false -Dweblogic.ProductionModeEnabled=false
最后点击PathsQ在双的Prepend to classpath列表框中Q通过Add JAR/ZIP按钮Q加入D:\BEA\weblogic81\server\lib\weblogic.jar、D:\BEA\weblogic81\server\lib\webservices.jar。如果用到数据库Q还需把数据库的驱动类库加q来Q这里我们用WebLogic自带的SQL Server数据库驱动库D:\BEA\weblogic81\server\lib\mssqlserver4v65.jar?
xQMyEclipse中WebLogic8的配|工作就完成了。下面可以看看在Eclipse中能否启动WebLogic了?自从安装了MyEclipse之后QEclipse工具栏中׃有一个Run/Stop Servers下拉按钮。点击该按钮的下拉部分,选择“WebLogic 8\Start”菜单Q即开始启动WebLogic了。通过查看下面的控制台消息Q就可以知道启动是否成功Q或有什么异常发生。停止WebLogic可选择“WebLogic\Stop”菜单?nbsp;



菠萝 2008-01-24 15:33 发表评论
]]>J2EE配置WebLogic-Eclipse插g(?http://m.tkk7.com/boluobn/archive/2008/01/24/177508.html菠萝菠萝Thu, 24 Jan 2008 07:32:00 GMThttp://m.tkk7.com/boluobn/archive/2008/01/24/177508.htmlhttp://m.tkk7.com/boluobn/comments/177508.htmlhttp://m.tkk7.com/boluobn/archive/2008/01/24/177508.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/177508.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/177508.html服务?/a>c\径和JVM选项后,卛_通过Eclipse IDE配置和管理WebLogic Server.

  概述

  J2EE开发h员经帔R要管理WebLogic Serverq调试WebLogic Server上部|的应用E序?WebLogic Server理控制台虽然能够启动和停止WebLogic ServerQ却不能讄JVM选项?a class="channel_keylink" target="_blank">服务?/a>c\径。必M用startWebLogic脚本来设|JVM选项和服务器c\径。而要调试WebLogic Server上部|的应用E序Q则需要带q程调试器的IDE.有了WebLogic插g后,可以通过Eclipse IDE理WebLogic Server. 在文本中Q我们将开发一个包括会话EJB和servlet的J2EE应用E序、通过Eclipse IDE在WebLogic Server中部|应用程序、在Eclipse中调试应用程序?/p>

  安装准备

  下蝲q安装Eclipse 3.0 IDEQ?a >www.eclipse.org

  下蝲q安装WebLogic Server 8.1Q?/p>

  www.bea.com/framework.jspQCNT=index.htm&FP=/content/products/weblogic/server

  安装WebLogic-Eclipse插g

  现在安装WebLogic-Eclipse IDE.在Eclipse IDE上,选择Help>Software Updates>Find and InstallQ将昄Install/UpdateH体。选择Search for new features to installQ然后单击Next按钮。在昄的InstallH体中,单击New Remote Site按钮指定要从其安装插件的更新Web站点。在New Update SiteH体中,指定名称和安装WebLogic-Eclipse插g的URL.WebLogic-Eclipse插g的URL?

  选择许可条款q单击Next按钮。在Install locationH体中指定将安装WebLogic-Eclipse插g的目录。单击Finish按钮完成WebLogic插g的配|。在昄的JAR VerificationH体中,单击Install按钮安装WebLogic-Eclipse插g。重启Eclipse工作台完成插件安装。现在WebLogic-Eclipse插g便安装在 Eclipse IDE中了。Eclipse中新MRun>Start WebLogic和Run>Stop WebLogic两个功能?/p>

  配置WebLogic-Eclipse插g

  安装了WebLogic-Eclipse插g后,我们在Eclipse IDE中配|该插g。首先,创徏一个用于配|WebLogic插g的项目。选择File>New>Project.在New ProjectH体中选择Java>Java ProjectQ然后单击Next按钮。在Create a Java projectH体中指定项目名Uͼ然后单击Next按钮。在Java SettingsH体中ؓ目d源文件夹。单击Add Folder按钮。在New Source FolderH体中指定文件夹名称。出C个消息窗体提C|bin文g夹作为构出文件夹。接下来Q添加项目所需的库。示例应用程序需要在c\径中dJ2EE JAR.选择Libraries选项卡,然后单击Add External JARs按钮?/p>

  为项目添加J2EE 1.4 j2ee.jar文g?.4 j2ee.jar在目库中列出。单击Finish按钮完成目配置。这样便一个项目添加到Eclipse IDE Package Explorer视图中?/p>

  接下来指定WebLogic Server配置。选择Window>Preferences.在出现的PreferencesH体中,选择WebLogic节点。在WebLogic preference面Q选择要配|的WebLogic Server版本。指定不同的字段|?? 所C。由于安装服务器和配|域的目录不同,g有所不同。单击Apply按钮应用指定的倹{?/p>

  字段描述?/strong>

  ? WebLogic-Eclipse插g

  如果必须向服务器c\径添加JAR文gQ请选择WebLogic>Classpath节点。可以在dWebLogic库之前或之后dJAR/Zip文g或目录。选择WebLogic>JavaVM Options节点指定JavaVM选项。例如,修改weblogic.ProductionModeEnabled属性。将属性D|ؓfalse可用开发模式启动服务器。单击Apply按钮应用JavaVM选项?/p>

  接下来,指定要用WebLogic Server配置q行调试的项目。单击Add按钮Q选择要添加到插g配置的项目。若要调试某个项目,该项目必M于插仉|中。单击OK按钮?/p>

  q样便将选择的项目添加到目列表中了。单击Apply按钮Q然后单击OK按钮Q用项目和WebLogic Server完成WebLogic插g的配|?/p>

  开发和调试WebLogic应用E序

  配置了WebLogic插g后,开发一个J2EE应用E序在WebLogic Server中进行部|和调试。示例J2EE应用E序由Session EJB和客Lservletl成。可从资源zip文g中获取该 J2EE应用E序Q关于本文的源代码,可在U查看WLDJ归档文g中的文章 http://wldj.sys-con.com/read/issue/archives/QVol. 5Qiss. 2Q。将资源zip文g提取到目录。在上文中配|的Eclipse目EclipseWebLogic中,选择File>Import导入J2EE应用E序的src目录。在ImportH体中,选择File System节点Q然后单击Next按钮。在File systemH体中,选择directories/filesd目Q然后单击Finish按钮Q见?Q?/p>

配置WebLogic-Eclipse插g ?1

  ?

  q样便将CZJ2EE应用E序文gd到项目中。用Ant build.xml文g构徏目。右键单击build.xmlQ选择Run>Ant Build卛_构徏J2EE应用E序q将光|在WebLogic Server应用E序目录中。接下来Q选择Run>Start WebLogic在Eclipse IDE中启动WebLogic Server.q样便将Session EJB/Servlet应用E序部v?WebLogic Server中,如应用程序节Ҏ(gu)C?/p>

  在浏览器中输入URL http://localhostQ?001/weblogic/webLogicPlug-inq行WebLogicServlet. servlet的输出将在浏览器中显C。接下来向客Lservletd一个异常(NullPointerExceptionQ,以验证WebLogic插g的调试功能。在WebLogicServlet servlet中将Q?/p>

  out.printlnQsessionEJB.getEclipsePlug-inQ)Q;

  替换为:

  String str=nullQ?/p>

  out.printlnQstr.toStringQ)Q;

  选择Run>Add Java Exception Breakpoint向servletd一个断炏V在Add Java Exception BreakpointH体中,选择NullPointerException.删除之前构徏的目录ƈ使用build.xml构徏应用E序。选择Debug perspective.在Debug perspective可以看到WebLogic Server正运行在localhostL中?/p>

  在浏览器中运行示例servletQ带NullPointerExceptionQ。因为servlet带有异常Q所以服务器被中断,q且Debug perspective昄NullPointerException.使用Run菜单中的调试功能可以调试应用程序?/p>

  l束?/p>

  lg所qͼ使用WebLogic插g可以通过Eclipse IDE理WebLogic ServerQ还可通过Eclipse IDE调试服务器中部v的应用程序。WebLogic插g的局限性在于不支持JSP调试。该插g?.0版本有更多功能?/p> J2EE配置WebLogic-Eclipse插g

菠萝 2008-01-24 15:32 发表评论
]]>
վ֩ģ壺 ޹˾þһþ| һۺ | ŮĻ| vvvv99պƷ| һ߹ۿƵ| ձ˳ww555| רëƬ߳ˮ| avۺ| ˾޾ƷӰԺ | һaƵ | 벻Ƶ߹ۿ| ձһƷƵ| Ůվ߹ۿƵѵ | ޹˾Ʒþþþþۺ | AV˾Ʒһ| ޻ɫ߹ۿƵ| av֮˵վ| þù޾ƷӰԺ| jizzjizzѿjizz| һƷһAVһи| ѹ˸߹ۿվ | һ| һ| ˳ַ߹ۿ| ޵Ӱһ| AVһϵ | ߾Ʒۿѹۿ | պƷ侫| þþþ޾Ʒþþþþþ | avպav| þþŷղũ| ޙպ߶| ߾ƷһӰȷ | 91޹߲ҹ| ޾Ʒ߹ۿ| ޾Ʒ߹ۿƵ| þþƷAVũ帾Ů| ޻ɫ߹ۿ| ޹ƷþþþϼӰԺ | ŮſȸͰƵ| jjzz߲Ź|