﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Java User's Tech Diary</title><link>http://www.blogjava.net/SimonLei/</link><description>You may say I am a dreamer, but I am not the only one.</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 16:31:40 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 16:31:40 GMT</pubDate><ttl>60</ttl><item><title>grails wicket plugin 的一个问题及修正</title><link>http://www.blogjava.net/SimonLei/archive/2008/01/15/175390.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Tue, 15 Jan 2008 02:38:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2008/01/15/175390.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/175390.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2008/01/15/175390.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/175390.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/175390.html</trackback:ping><description><![CDATA[grails 有一个 wicket 的插件：<br />
<br />
<a>http://graemerocher.blogspot.com/2007/05/grails-wicket-wonders-of-grails-plug-in.html</a><br />
<br />
我试了一下，发现最新版本(0.3)的wicket插件，运行helloworld都有问题，错误是：<br />
<br />
wicket.markup.MarkupNotFoundException: Markup not found.<br />
<br />
查看了一下原因，按照文档， HelloWorld.html 是放在 grails-app/views 目录下的，但是 wicket 插件 没有修改classpath 和 resource 装载的路径，也就是说，实际上这个 HelloWorld.html 对于 wicket 来说 是不可见的。但是如果把这个 HelloWorld.html 放在 src/java 目录下，则可以正常运行。<br />
想到了一个简单的解决方案，修改 $GRAILS_HOME/scripts/Package.groovy，在 146 行增加： <br />
<div style='background-color: #eeeeee; font-size: 13px; border-top-color: #cccccc; border-left-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-top-width: 1px; border-left-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-top-style: solid; border-left-style: solid; border-right-style: solid; border-bottom-style: solid; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%'><span style='color: #000000'>fileset(dir:</span><span style='color: #000000'>"</span><span style='color: #000000'>${basedir}/grails-app/views</span><span style='color: #000000'>"</span><span style='color: #000000'>) {<br />
include(name:</span><span style='color: #000000'>"</span><span style='color: #000000'>**/**</span><span style='color: #000000'>"</span><span style='color: #000000'>)<br />
exclude(name:</span><span style='color: #000000'>"</span><span style='color: #000000'>**/*.groovy</span><span style='color: #000000'>"</span><span style='color: #000000'>)<br />
}</span></div>
<br />
就像 src/java 当中的资源一样，全部拷贝到目标目录下，这样的效果就和放在 src/java 目录下一样了。<br />
<br />
主站： <a>http://blogsite.3322.org/</a><br />
<br />
<img src ="http://www.blogjava.net/SimonLei/aggbug/175390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2008-01-15 10:38 <a href="http://www.blogjava.net/SimonLei/archive/2008/01/15/175390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>经验主义害死人啊（spring与osgi结合当中遇到的问题）</title><link>http://www.blogjava.net/SimonLei/archive/2006/12/28/90442.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Thu, 28 Dec 2006 02:37:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2006/12/28/90442.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/90442.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2006/12/28/90442.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/90442.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/90442.html</trackback:ping><description><![CDATA[
		<p>首先看看我前几天的一篇blog</p>
		<p>
				<font style="BACKGROUND-COLOR: #808080" size="1">spring 与 osgi的第一个障碍 </font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #808080" size="1">eclipse3.1, spring2.0.1，将spring.jar放到一个插件中，在另一个插件中去使用。 最简单的例子，在context.getBean的时候就报了一个异常：<br /></font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font style="BACKGROUND-COLOR: #808080" size="1">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">Caused by: org.xml.sax.SAXParseException: cvc</span>
						<span style="COLOR: #000000">-</span>
						<span style="COLOR: #000000">elt.</span>
						<span style="COLOR: #000000">1</span>
						<span style="COLOR: #000000">: Cannot find the declaration of element </span>
						<span style="COLOR: #000000">'</span>
						<span style="COLOR: #000000">beans</span>
						<span style="COLOR: #000000">'</span>
				</font>
				<span style="COLOR: #000000">
						<font size="1">
								<font style="BACKGROUND-COLOR: #808080">.<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></font>
						</font>
				</span>
		</div>
		<p>
				<font size="1">
						<font style="BACKGROUND-COLOR: #808080">先是搜了一遍，没有发现很有帮助的内容。然后跟了一下，发现还是因为xsd的映射找不到。而造成这个问题的原因， 是在 spring.jar当中的META-INF/spring.schemas 这个找不到。</font>
				</font>
		</p>
		<p>
				<font size="1">
						<font style="BACKGROUND-COLOR: #808080">而这个找不到的最根本原因，是因为在eclipse当中，META-INF目录是不能够被其他插件找到的。也就是说，META-INF 目录是拥有spring.jar的那个插件所独占的，而其他插件就算依赖于这个插件，也是无法找到META-INF目录下的文件， 从而抛出这个异常。</font>
				</font>
		</p>
		<p>
				<font size="1">
						<font style="BACKGROUND-COLOR: #808080">解决问题的办法有几个，最简单的莫过于拷贝spring.schemas文件到需要的插件中，另一个办法是把spring的context 装载就放在spring.jar所在的插件中，或者改eclipse的代码。 :(</font>
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #808080" size="1">这个问题解决之后，紧接着第二个问题就是 <br /></font>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<font style="BACKGROUND-COLOR: #808080" size="1">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #000000">Unable to locate NamespaceHandler </span>
						<span style="COLOR: #0000ff">for</span>
						<span style="COLOR: #000000"> namespace http:</span>
						<span style="COLOR: #008000">//</span>
				</font>
				<span style="COLOR: #008000">
						<font size="1">
								<font style="BACKGROUND-COLOR: #808080">www.springframework.org/schema/aop<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></font>
						</font>
				</span>
		</div>
		<p>
				<font style="BACKGROUND-COLOR: #808080" size="2">
						<font size="1">造成这个的原因和第一个类似，将spring.handlers拷贝到META-INF目录下就ok了。<br /></font>
						<br />
						<font style="BACKGROUND-COLOR: #ffffff">上面是我以前的一个经验，今天仔细研究了一下，发现自己掉进了 经验主义的圈套。</font>
				</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" size="2">这个经验是这样积累起来的：在刚开始尝试使用eclipse的时候，用的是3.0和3.1Mx系列，当时 不知道osgi是个什么东西 :$ 创建的几个插件，都没有创建osgi bundle manifest。也就是说， 只有plugin.xml，而没有META-INF/MANIFEST.MF文件的。但是在运行期，eclipse会自动的 从plugin.xml当中读取信息，生成临时的MANIFEST.MF文件，放在 runtime的 configuration/org.eclipse.osgi/manifests 目录下。而生成这个MANIFEST.MF文件，是 通过 PluginConverterImpl 这个类来实现的，在它的 isValidPackageName 方法中，所有的 META-INF或者以META-INF开头的目录，都不会被自动的export出去，从而在临时生成的MANIFEST.MF 文件中，永远不会有META-INF目录的export。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" size="2">当时刚开始接触eclipse和osgi，根本不知道自己当时最佳的解决方案就是创建一个 bundle manifest， 然后在其中将META-INF目录export出来。而是通过盲目的修改代码来绕过这个弯。后来这个弯绕过去了， 留给我的经验就是：META-INF这个目录，是插件独享的，别的插件不允许访问的。</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff" size="2">于是，在前几天，当spring.jar当中的几个META-INF目录下的文件访问不了时，我也认为这个经验有用， 差点就去改eclipse的代码了。幸好尝试了一下，把spring.jar所在的插件中，将META-INF目录共享出来， 居然就好了。仔细查了一下，发现屏蔽META-INF的代码只出现在PluginConverterImpl这个类当中。 回头想了想，终于明白自己这次是掉在经验主义的坑里面了。</font>
		</p>
		<p>
				<font size="2">
						<font style="BACKGROUND-COLOR: #000000">
								<font style="BACKGROUND-COLOR: #ffffff">经验主义害死人啊。唉。<br /><br />主站： <a href="http://blogsite.3322.org/">http://blogsite.3322.org/</a><br /></font>
								<br />
						</font>
				</font>
		</p>
<img src ="http://www.blogjava.net/SimonLei/aggbug/90442.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2006-12-28 10:37 <a href="http://www.blogjava.net/SimonLei/archive/2006/12/28/90442.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SUN Tech 2006 见闻</title><link>http://www.blogjava.net/SimonLei/archive/2006/09/29/72729.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Fri, 29 Sep 2006 02:09:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2006/09/29/72729.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/72729.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2006/09/29/72729.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/72729.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/72729.html</trackback:ping><description><![CDATA[SUN Tech 2006第一天 <br /><br />会场设在最拥堵的北四环中路，赶到会场已经接近9点，匆忙报道之后， <br />第一感觉是不像去年那么大的场面了，只有两个会场，而且很奇怪的是， <br />参展的其他厂商，也只有AMD一家，显得有点冷清。 <br /><br />James Gosling又一次出现了，不过做的演讲并没有很多新鲜的东西，值得 <br />注意的倒是Ruby on Rails出现在他的演讲内容当中，这大概也与JDK未来版本 <br />要支持动态语言，以及SUN把jruby的两个人招进去有一系列的关系。随后有 <br />一个SUN的技术展示，其中有意思的一个是 SPOT(Small Programmable Object Tech)，<br />有点象《少数派报告》当中阿汤哥用的手套，用手套来当做鼠标一样的在 <br />空中使用，很是不错。 <br /><br />随后一整天的演讲，给我的感觉，重头戏是Netbeans，其次是Ajax，再其次是 <br />Java EE 5。感觉今天一系列的活动都与Netbeans有关，Ajax和Java EE 5包括 <br />Java ME，都时不时的与Netbeans挂上钩。从今天被Netbeans洗脑的结果来看， <br />Netbeans现在确实越来越好用，功能也越来越强大。Eclipse如果按照现在的发展 <br />速度，确实有些危险。不过，从另一个角度看，有竞争才能促进发展，也不算是件 <br />坏事。 <br /><br />其他方面的收获，包括对JAVA SE 7 的一些特性了解，Java EE 5的一些介绍，以及 <br />关于Java EE 5的参考实现 GlassFish的介绍，顺便还听了一些Java ME的东西，也 <br />有些意思，可惜暂时用不上。 <br /><br />今天有一些感触：<br /> <br />好的技术，如果没有好的工具支持，也是很难生存的。这就联想到我们自己的IMP框架，<br />过去将重点放在framework和engine上，而对于designer的投入则远远不够。这样造成的现<br />象就是限制了开发效率，从而没有能够最大的发挥IMP框架的作用。 <br /><br />Netbeans虽然好用，也能够从一定程度上提高生产力。但是我还是那种观点，看上去<br />很美的代码生成机制，往往只是节省了“创建”的时间成本，而对于“修改”的效<br />率提高，却不一定有帮助。 <br /><br />JSF感觉还是沿袭了Struts的东西太多，就算通过Ajax的render，感觉还是不能算非常好的<br />Component Framework。还是不如Echo2 ;) <br /><br />回家的时候，正赶上北四环的拥堵高峰，回到家已经很晚了，写的很零乱，不知道明天<br />会不会有什么大的收获。反正今天感觉就是被洗了一天的脑，害得我都想装一个Netbeans<br />来玩玩了。 <br /><br />SUN Tech 2006第二天 <br /><br />又经历了痛苦的2个小时到达了会场，今天的SUN公司主题居然是“开源的好处”， <br />重点提出开源最终有利于开源者，号称SUN从OpenSaloris的开源当中获得了很多 <br />好处。不知道前几年大家强烈要求SUN 开源的时候，是不是也是这种论调。也懒得 <br />去查以前的新闻了，不过总算逐渐有将Java开源的打算了，而且SUN号称要将所有的 <br />软件开源，这对于open source社区，也算是件好事。 <br /><br />今天总的来说内容不是很丰富，这一次的Tech Day，总共也就是几个人在讲，一个人 <br />讲好几场，这在以前的Tech Day是很少出现的。<br /><br />今天的收获如下： <br /><br />听了一场关于swing和美化swing的讲座，感觉SUN对于java的投入，比以前更大了。<br />以前，关于swing的微词很多，也有很多不好用的反馈，但是在几个jdk版本的发布过<br />程当中都没有改进，最典型的莫过于ContentPane，"Lastly, after seven years, we've made <br />jFrame.add equivalent to jFrame.getContentPane().add()."。在JDK5之后，可以感觉到SUN<br />对于用户社区的反馈开始逐渐重视。对于swing当中的功能较弱的问题，专门整了一个<br />swinglab来解决。其中还有个swingx的子项目，也有不少的swing功能增强组件可以用。 <br /><br />Apache Derby，也就是原来IBM收购informix时收购到的Cloudscape，现在又有了一个新<br />名字叫 Java DB，而且会随着JDK6一起发布。Java DB的功能比较完善，据说性能也不<br />错，号称支持300G的数据量没有问题。如果这样的话，不仅hsql可以抛掉，而且说不定<br />mysql也可以不用了。我现在也很喜欢这种既可以embed，又可以做为cs的数据库，现在<br />做rails的就是用sqlite，感觉也够用了。Java DB还有个很强的功能是，可以将数据打包为<br />jar文件，做为只读的db，放在光盘或者其他地方，做为备份和还原，以及做demo应用放<br />在光盘上，应该都有很大的用处。 <br /><br />JDK for script language. 在JDK6当中，已经支持 ruby和javascript两种脚本语言了。<br />功能上感觉有点象BSF，但是由于随着JDK6一起发布，所以以后影响力会更大。<br />而且，做演讲的人也提到，jruby的开发者进入SUN公司，恐怕不只是用ScriptEngine<br />支持script语言这么简单。今天体验了一下印度人说英语，确实是强... <br /><br />另外还听了一下 MBean，Concurrence方面的东西，收获也有一些。例如在JDK6当中，<br />MBeanServer缺省就启动了，而不像JDK5里，需要用一个命令行参数才能启动。 <br />两天下来，感觉这一期的SUN Tech Day和以往最大的区别就是，这一期完全是被<br />SUN自己垄断了，没有别的公司演讲， 不讨论别的公司的内容，没有别的公司参展。<br />言必称 NetBeans，操作系统必称 Solaris。从一个角度来看，SUN公司确实 积极的<br />参与到了开源社区当中，并且比以前更加接近用户，也更积极的响应用户的request。<br />这一点，从Netbeans的进展神速， 到JDK最近几个版本的新特性增加速度，都比JDK5<br />以前要好很多。这对于Java的进一步发展，可以说是一件好事。从另一个 角度来看，<br />这一届Tech Day表现出来的情况，不知道是应该说SUN更加有了自主意识，还是应该说<br />SUN确实没有很好的组织 这次会议。从参加演讲的人员，到展厅的布置来看，<br />都不如往届。不知道是不是SUN财务紧张造成的，hoho. <br /><br />又花了两个小时才从首堵北京的北四环中路到了家，感觉今年的Tech Day，<br />最大的收获是被洗脑了，也体会到了目前最火爆的Ajax是如何的火爆。 <br /><br />主站: <a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><img src ="http://www.blogjava.net/SimonLei/aggbug/72729.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2006-09-29 10:09 <a href="http://www.blogjava.net/SimonLei/archive/2006/09/29/72729.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>代码的卫生、习惯及其它...</title><link>http://www.blogjava.net/SimonLei/archive/2006/04/03/38839.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Mon, 03 Apr 2006 02:27:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2006/04/03/38839.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/38839.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2006/04/03/38839.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/38839.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/38839.html</trackback:ping><description><![CDATA[代码的卫生、习惯及其它...<br /><br />最近忙，发现家里开始脏乱差了。仔细想想，其实之所以会这样，<br />是因为经常发现有点脏的地方，也懒得动，总是想等到啥时候大扫除<br />一下子全部清理干净。后来地面越来越脏，就越来越不注意，进入了<br />一个恶性循环。<br /><br />不禁联想到“破窗户”理论，有个破窗户的社区，会逐渐变得不适合居住。<br />又想到一个经常看到的现象，如果一个电线杆下有一包垃圾，只要清理<br />不及时，过段时间，这个电线杆就会变成一个垃圾堆。<br /><br />扯这么多，其实想说的是代码的卫生。代码，刚开始都是很干净的，只是<br />随着时间推移，随手乱扔的果皮纸屑逐渐增多，最后开始发臭，然后这个<br />代码就没有人愿意去碰了。在项目中，经常碰到这样的情况。同样的功能，<br />哪怕以前曾经有人写过，很多人还是倾向于自己重头开始写。原因是什么？<br />程序员只信任自己的代码，这是其中的一个原因。另一个原因是，以前的<br />代码确实有个需要学习上手的时间。打个比方，一间房子，不适合居住，需要<br />进行一番打扫才能住进去，这就是已有代码。而新的代码，则是程序员亲手<br />垒起来，亲手装修的，虽然耗时长，辛苦，但是心理感觉好。但是呢，这个<br />新房子对于其它程序员来说，已经时一个堆满垃圾不适合居住的旧房子了。<br />于是，每个程序员都亲手建一个房子，如此重复下去。<br /><br />那么，要避免这种无意义的重复劳动，一方面是程序员本身意识的纠正。打扫<br />一个旧房子，虽然脏一点，但是通常比新建一个房子还是要快和省力。另一个<br />方面，程序员应该有这样的信念，不能让自己的代码变成垃圾堆。也就是说，<br />不能容忍自己的代码中堆满垃圾。<br /><br />如何避免代码成为垃圾堆？个人认为，就象“破窗户”理论一样，不能对破了<br />的窗户听之任之，而要尽快修复。否则的话，其他人看到第一袋垃圾在这里，<br />觉得扔第二袋垃圾就没有罪恶感，至少罪恶感不那么强。大家可以想象一下，<br />在一个窗明几亮的环境中，你扔果皮纸屑之前都会三思。但是站在一个垃圾堆<br />上面，你扔垃圾之前就不会有什么顾虑了。因此，保持卫生的一个好习惯就是，<br />不放过第一个垃圾。<br /><br />当然，如果判别某段代码是不是垃圾，或者及时发现第一段垃圾代码，那就是<br />另一个话题，例如用ut，用code review，等等。《Working Effectively with Legacy Code》<br />这本书里面，提到了Legacy code 的定义：<br /><br />Code without tests is bad code. It doesn't matter how well written it is; <br />it doesn't matter how pretty or object-oriented or well-encapsulated it is. <br />With tests, we can change the behavior of our code quickly and verifiably. <br />Without them, we really don't know if our code is getting better or worse.<br /><br />有人会觉得我管的太细，不揪架构、设计，反而去管代码，只见树木不见森林。我个人<br />的看法，架构、设计再好，都需要代码来进行实现。如果这个基础没打好，以后这个<br />代码总是会变成无人想碰的垃圾堆。<br /><br />当然，我也反对无意义的追求完美。我不是个有洁癖的人，所以，代码到什么程度就算是<br />干净的了？我个人的看法是，Clean code that works。当然这一点其实不容易达到，但是<br />做为一个程序员，我还是努力去追求这一点的。<br /><br />主站： <a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><br /><img src ="http://www.blogjava.net/SimonLei/aggbug/38839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2006-04-03 10:27 <a href="http://www.blogjava.net/SimonLei/archive/2006/04/03/38839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在eclipse为核心的framework中支持Jsp</title><link>http://www.blogjava.net/SimonLei/archive/2005/12/26/25411.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Mon, 26 Dec 2005 02:58:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/12/26/25411.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/25411.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/12/26/25411.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/25411.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/25411.html</trackback:ping><description><![CDATA[<span><span><span>在<a href="http://blogsite.3322.org/jspwiki/pages/viewblog?id=2264">上次的文章</a>当中，把 
eclipse做为web framework的核心，并且使得 servlet 的定义和mapping做为扩展点，确实狠
方便。不过现在又面临一个问题，有个历史遗留系统当中，有jsp 的应用。而jsp与servlet 的一个
很大的区别在于，它需要用 javac 去做编译。这就使得问题复杂化了，特别是使得 class loader
的关系变得更复杂。<p>我们首先看一下这里面有几种 class loader，首先，启动 eclipse 的是一个system loader，然后
是 eclipse starter 的 loader，启动我们的核心class loader，这个核心负责启动 jetty 和我们
的 web app两个插件，每个插件都有自己的 eclipse bundler loader。而jetty插件启动jetty 
应用服务器，应用服务器本身有 context class loader，它还要负责去装载 WEB-INF/lib 
下的所有jar文件，以及 WEB-INF/classes 目录下的文件，做为编译期使用。</p><p>这里不仅class loader 众多，而且关系复杂。一不小心就容易抛出 class not found 异常，或者是
class cast 异常。相对而言，只支持servlet 就狠简单，因为只要把 servlet 的 context class
loader 用 eclipse bundler loader 替换掉就行。而jsp的编译机制，导致了问题的出现。</p><p>我对于这种复杂classloader情况的心得，就是把错综复杂的 class loader 关系网拉直，变成一棵
树。这样的好处就是，对于loader 的关系比较清晰，出现ClassNotFoundException和
ClassCastException这两种情况的时候，都狠容易判断怎么回事，不会被绕晕。这种时候，单步跟踪
只是找死，把classloader关系画出来，有利于对问题的分析。</p><p>于是画了这样一个图，把复杂的网拉直了，问题就迎刃而解了。</p><p><img src="http://blogsite.3322.org/jspwiki/download/2351/loaders.jpg"><br></p><p><span><span><span><p>其中的关键就是 LauncherClassLoader。这个就是我们自己的ClassLoader，把它设置为 servlet
context classloader 的 parent，并且把 context classloader 的装载顺序改变成为先由parent
装载，再自己装载的模式。这样，jsp的编译还是由 context loader 去处理，我就不管了。其他的
该装载的地方，还是有 eclipse bundler 去装载，这样问题基本解决。</p><p>不过这样其实还是有个问题，如果要在 jsp 当中调用某个插件当中的 class，那么在编译期就会出现
问题。不过由于目前只是解决 legacy jsp 应用的问题，所以这个暂时不存在。我能想到的解决方案
其实也狠简单，把这些 jar 文件的url也做为扩展点出现，那么当jsp需要某个class时，只要把它
所需要的 jar 文件的 url 做为一个扩展，在 LauncherClassLoader 当中将这些jar文件添加到
url loader 当中，而这些 url 会出现在 jsp 的编译class path当中。</p><p>主站：<a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><br></p></span></span></span></p></span></span></span><img src ="http://www.blogjava.net/SimonLei/aggbug/25411.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-12-26 10:58 <a href="http://www.blogjava.net/SimonLei/archive/2005/12/26/25411.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>忍无可忍，无需再忍——终于决定改eclipse代码了</title><link>http://www.blogjava.net/SimonLei/archive/2005/12/15/24028.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Thu, 15 Dec 2005 06:01:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/12/15/24028.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/24028.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/12/15/24028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/24028.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/24028.html</trackback:ping><description><![CDATA[<span><span><span>一直以来，eclipse 对于 fragment 的概念都是一种补充，而不是覆盖的机制。
也就是说，fragment 里的 class 会在 host plugin 的 class 装载之后而装载。
只有 host plugin 里面没有找到，才会去找 fragment 里面的类。<p>我们的framework，目前是由一个专门的小组在维护。其他小组是不能随意改它的代码的。
但是，当有些情况下，使用这个framework的开发小组需要修改这部分代码，而这个修改
又只是局部的，只有这个小组需要用的，那么现在就很头痛。后来用一种jar替换的方式
来满足这个需要，但是搞得开发起来很繁琐，需要经常的export。</p><p>一直以来也没有去动 eclipse 的代码，这次把应用启动的模式从deploy改成launch 之后，
别的地方都好说，唯有需要处理 fragment 的这个地方很头痛。</p><p>如果把eclipse fragment的装载顺序调整一下，先装载 fragment 里的class，再装载
host plugin 里面的 class，这个问题就迎刃而解了。framework开发小组只需要处理
公用的代码，使用 framework 的小组就可以用自己的 fragment 去处理特殊的代码，
这个世界就清净了。大家都可以用 launch 这种模式来启动应用，加快应用开发的效率。</p><p>刚才改了一下，其实很简单，只是改 DefaultClassLoader 就行了，看一下代码就知道该
怎么改。后悔怎么没有早点改，呵呵。</p>主站： <a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><a><br></a></span></span></span><img src ="http://www.blogjava.net/SimonLei/aggbug/24028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-12-15 14:01 <a href="http://www.blogjava.net/SimonLei/archive/2005/12/15/24028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我不喜欢ror的一点——代码生成</title><link>http://www.blogjava.net/SimonLei/archive/2005/12/07/22830.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Wed, 07 Dec 2005 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/12/07/22830.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/22830.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/12/07/22830.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/22830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/22830.html</trackback:ping><description><![CDATA[<span><span><span>目前来说，最不喜欢的就是代码生成这种机制。这个机制看起来
很快，能够快速的开发一个简单的应用。不敢说这是rails 的
核心，至少是它吸引人的一个优势，而正好是我所不喜欢的一点。<p>其实对于代码生成这种机制，在 Pragmatic Programmer 里面
就已经提到了，叫做 evil wizard。我很认同那本书里面的说法，
大部分的软件开发过程，是 修改 而不是 新建 代码。也就<br>是说，
真正好的代码和框架，应该有对 change 支持比较好的机制。</p><p>ruby on rails 能够根据model快速的生成代码，确实有一些吸引力。
但是，一旦 model 发生变化，这时候代码生成就不能起作用了，因为
我重新生成代码会把我修改过的代码覆盖掉。如果手工进行编码的话，我也
没看出来它相当于jsp的优势。当然，它的 mvc 以及 helper 分离的
机制确实比纯粹的 jsp 要好，不过对于代码生成这一部分，我不觉得
是 rails 对我的吸引。</p><p>ror大概也考虑到这一点，所以也有对 plugin 和 engine 的支持。
这两个东西我现在还没有研究，应该会比较有意思吧。</p><br>主站：<a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><br></span></span></span><img src ="http://www.blogjava.net/SimonLei/aggbug/22830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-12-07 11:29 <a href="http://www.blogjava.net/SimonLei/archive/2005/12/07/22830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自己启动jetty所遇到的 session reset 问题</title><link>http://www.blogjava.net/SimonLei/archive/2005/11/29/21833.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Tue, 29 Nov 2005 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/11/29/21833.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/21833.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/11/29/21833.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/21833.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/21833.html</trackback:ping><description><![CDATA[自己启动jetty所遇到的 session reset 问题<br><br>在eclipse 当中启动的 jetty 时，由于要根据 extension point 来找到<br>相应的 servlet 定义和 mapping，因此自己取得一个 context，然后往里面<br>addHandler。开始只有一个 servlet ，没有问题，后来又有两个plugin，其中<br>也有servlet/mapping的定义，然后就总是出现 session reset 的问题。<br><br>开始还以为是自己做的classloader 的问题，因为担心自己做的 loader 会产生<br>不好的影响。后来把日志级别调高之后，发现如果连续只访问一个servlet, 就不会<br>有 session reset 问题，如果这时候再访问另一个 servlet，它就会赋予另外一个<br>session id。再仔细看了一下增加 servlet mapping 的代码：<br><pre>for (ExtensionBean bean : servletMappingBeans) {<br>&nbsp; ServletHandler handler = new ServletHandler();<br>&nbsp; handler.addServlet( bean.getProperty( "mapping"), bean.getClassName());<br>&nbsp; context.addHandler( handler);<br>}</pre><br><br>这样，相当于在 context 里面增加了多个 servlet handler，每个handler有一个自己的<br>session manager，由此导致访问不同的 servlet，使用不同的session id 的问题，从而<br>导致客户端认为 session reset 了。因此，稍微修改一下就解决了这个问题：<br><br><pre>ServletHandler handler = new ServletHandler();<br>for (ExtensionBean bean : servletMappingBeans) {<br>&nbsp; handler.addServlet( bean.getProperty( "mapping"), bean.getClassName());<br>}<br>context.addHandler( handler);</pre><br><br>教训：一开始就觉得这个问题不是个大问题，但是由于在后台老是没有异常，日志文件中也<br>没有提供足够的信息，因此一开始花了很长时间进行调试和单步跟踪（虽然不喜欢，但是当时<br>也没有想出其他办法）。后来把日志级别提高了，把jetty的debug enable之后，发现访问<br>不同的servlet将造成session id 的变化，从而很快的定位到问题并且解决问题。<br><br>也就是说，碰到问题，还是应该冷静，尽量用日志去定位问题，而不是用debug去定位问题。<br><br>主站： <a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><br><img src ="http://www.blogjava.net/SimonLei/aggbug/21833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-11-29 15:53 <a href="http://www.blogjava.net/SimonLei/archive/2005/11/29/21833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse 做为 webapp 核心的几种做法以及 classloader 研究</title><link>http://www.blogjava.net/SimonLei/archive/2005/11/28/21608.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Mon, 28 Nov 2005 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/11/28/21608.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/21608.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/11/28/21608.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/21608.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/21608.html</trackback:ping><description><![CDATA[<img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot.jpg" alt="">做法1：以Eclipse为启动点，将appserver做为一个应用启动。<br><br><img src="http://blogsite.3322.org/jspwiki/download/2264/1.jpg" alt="1.jpg" border="0" height="291" width="498"><br>做法：<br>在Launcher 当中启动Eclipse Platform。此处的ClassLoader 为系统的loader。<br>Eclipse Platform 会查找到Core Application，并且将其启动。<br>在Core Application 当中，ClassLoader 为 Eclipse 的 ClassLoader。<br>在Core Application 当中，我们启动Jetty，并处于等待状态。<br>当Servlet/JSP被调用时，Jetty 将Servlet/JSP初始化，并执行相应动作。<br>Servlet 的 ClassLoader 是 Context ClassLoader，符合Servlet 规范的。<br><br>曾经碰到的问题：<br>Core Application采用的是Eclipse ClassLoader，缺省情况下，该ClassLoader 的 parent 为 null。这样，在Servlet ClassLoader 当中，能够接触到System ClassLoader，但是Core Application 不能访问，它们相互间不可见。<br>解决办法：EclipseStarter 有个配置项叫做parent.Classloader，将其设置为app，即可解决该问题。<br>Servlet ClassLoader按照Servlet 2.3的规范，首先由Context ClassLoader去查找，如果找不到，再交由parent 去load。而当时我在webapp/WEB-INF/lib目录下放了一个runtime.jar文件。这样，runtime.jar当中的类都被Context ClassLoader给装载进来了，而对于EclipseStarter当中装载的runtime.jar中的类互相不可见，从而也出现问题。<br>解决办法：把lib目录下的runtime.jar删除就好了。<br><br>由于所有的与eclipse有关的内容，只能由Core Application 的ClassLoader才能装载，因而相互间是可见的。从而达到了利用eclipse核心的目的。<br>做法2：以app server 为启动点，以eclipse 核心为web app的核心：<br><img src="http://blogsite.3322.org/jspwiki/download/2264/2.jpg" alt="2.jpg" border="0" height="295" width="479"><br><br><br>和做法1一样，重点是将Core Application的ClassLoader设置为System的loader，这样，在其他的地方（例如Servlet当中）也同样可见了。<br><br>很重要：runtime.jar和osgi.jar一定要放在jetty的启动路径当中。这样才会用System的loader 首先找到这两个jar文件，从而保证大家都在这个基础上来互相看到。<br><br>做法3：以Eclipse为启动点，将appserver做为一个应用启动，appserver以dispatcher身份出现。<br><br>这个做法和做法1一致。区别在于，appserver 本身不做任何事情，只是做为一个 dispatcher 出现。它提供一个 extension point，其他插件扩展该 extension，相当于注册 servlet，以及mapping。当有http request 时，dispatcher根据 servlet 的注册和mapping，自动的分发给对应的servlet。此时，各个servlet的 class loader 还是 eclipse classloader，而 servlet 的 context classloader 在这种模式当中只是昙花一现，做了一个 dispatcher 之后，就将工作移交给了定义serlvet 的插件的那个 eclipse classloader。<br><br>这样，servlet 是可扩展的，再也不依赖于 web.xml了。<br><br>主站： <a href="http://blogsite.3322.org/jspwiki/">http://blogsite.3322.org/jspwiki/</a><br><img src ="http://www.blogjava.net/SimonLei/aggbug/21608.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-11-28 09:56 <a href="http://www.blogjava.net/SimonLei/archive/2005/11/28/21608.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>开发的三种模式</title><link>http://www.blogjava.net/SimonLei/archive/2005/11/24/21315.html</link><dc:creator>SimonLei</dc:creator><author>SimonLei</author><pubDate>Thu, 24 Nov 2005 09:43:00 GMT</pubDate><guid>http://www.blogjava.net/SimonLei/archive/2005/11/24/21315.html</guid><wfw:comment>http://www.blogjava.net/SimonLei/comments/21315.html</wfw:comment><comments>http://www.blogjava.net/SimonLei/archive/2005/11/24/21315.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/SimonLei/comments/commentRss/21315.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/SimonLei/services/trackbacks/21315.html</trackback:ping><description><![CDATA[<span><span><span>第一种： script 模式，如jsp/php等，修改了代码，直接刷新页面就可以看到
结果，这种开发模式最爽，都不用重启应用服务器。<p>第二种：应用服务器模式，修改了代码之后，需要重启一下应用服务器，然后才能
看到修改的效果，这种模式一般爽，但是也还可以接受。如果应用服务器支持hot-deploy，
那就接近第一种开发模式了。</p><p>第三种：部署模式，修改了代码之后，必须首先部署，然后重启应用服务器才能看到
修改效果。这种模式最不爽，传统的ejb开发就是这种模式。</p><p>目前我们将 eclipse 做为核心的 web app，还是第三种开发模式。造成这种开发模式
的原因，可以说是因为当时对 eclipse 不熟悉，对 osgi 不熟悉，对 eclipse class
loader 不熟悉造成的。我打算将其改造成第二种模式，然后再考虑第一种是否可行。最近
看 ror, 它将环境分为 dev/product/test 几种，很受启发。我可以在product环境下
采用第二种，在dev环境下采用第一种模式。</p>主站： http://blogsite.3322.org/jspwiki/<br></span></span></span><img src ="http://www.blogjava.net/SimonLei/aggbug/21315.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/SimonLei/" target="_blank">SimonLei</a> 2005-11-24 17:43 <a href="http://www.blogjava.net/SimonLei/archive/2005/11/24/21315.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>